usp10: Properly adjust LogClust when decomposing indic vowels.
[wine.git] / dlls / d3d9 / device.c
blob8dc7334ecd8c7be62094e69605cef6968e14af36
1 /*
2 * IDirect3DDevice9 implementation
4 * Copyright 2002-2005 Jason Edmeades
5 * Copyright 2002-2005 Raphael Junqueira
6 * Copyright 2005 Oliver Stieber
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "config.h"
24 #include "d3d9_private.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
28 D3DFORMAT d3dformat_from_wined3dformat(enum wined3d_format_id format)
30 BYTE *c = (BYTE *)&format;
32 /* Don't translate FOURCC formats */
33 if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
35 switch(format)
37 case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN;
38 case WINED3DFMT_B8G8R8_UNORM: return D3DFMT_R8G8B8;
39 case WINED3DFMT_B8G8R8A8_UNORM: return D3DFMT_A8R8G8B8;
40 case WINED3DFMT_B8G8R8X8_UNORM: return D3DFMT_X8R8G8B8;
41 case WINED3DFMT_B5G6R5_UNORM: return D3DFMT_R5G6B5;
42 case WINED3DFMT_B5G5R5X1_UNORM: return D3DFMT_X1R5G5B5;
43 case WINED3DFMT_B5G5R5A1_UNORM: return D3DFMT_A1R5G5B5;
44 case WINED3DFMT_B4G4R4A4_UNORM: return D3DFMT_A4R4G4B4;
45 case WINED3DFMT_B2G3R3_UNORM: return D3DFMT_R3G3B2;
46 case WINED3DFMT_A8_UNORM: return D3DFMT_A8;
47 case WINED3DFMT_B2G3R3A8_UNORM: return D3DFMT_A8R3G3B2;
48 case WINED3DFMT_B4G4R4X4_UNORM: return D3DFMT_X4R4G4B4;
49 case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10;
50 case WINED3DFMT_R8G8B8A8_UNORM: return D3DFMT_A8B8G8R8;
51 case WINED3DFMT_R8G8B8X8_UNORM: return D3DFMT_X8B8G8R8;
52 case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16;
53 case WINED3DFMT_B10G10R10A2_UNORM: return D3DFMT_A2R10G10B10;
54 case WINED3DFMT_R16G16B16A16_UNORM: return D3DFMT_A16B16G16R16;
55 case WINED3DFMT_P8_UINT_A8_UNORM: return D3DFMT_A8P8;
56 case WINED3DFMT_P8_UINT: return D3DFMT_P8;
57 case WINED3DFMT_L8_UNORM: return D3DFMT_L8;
58 case WINED3DFMT_L8A8_UNORM: return D3DFMT_A8L8;
59 case WINED3DFMT_L4A4_UNORM: return D3DFMT_A4L4;
60 case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8;
61 case WINED3DFMT_R5G5_SNORM_L6_UNORM: return D3DFMT_L6V5U5;
62 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: return D3DFMT_X8L8V8U8;
63 case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
64 case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
65 case WINED3DFMT_R10G10B10_SNORM_A2_UNORM: return D3DFMT_A2W10V10U10;
66 case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
67 case WINED3DFMT_D32_UNORM: return D3DFMT_D32;
68 case WINED3DFMT_S1_UINT_D15_UNORM: return D3DFMT_D15S1;
69 case WINED3DFMT_D24_UNORM_S8_UINT: return D3DFMT_D24S8;
70 case WINED3DFMT_X8D24_UNORM: return D3DFMT_D24X8;
71 case WINED3DFMT_S4X4_UINT_D24_UNORM: return D3DFMT_D24X4S4;
72 case WINED3DFMT_D16_UNORM: return D3DFMT_D16;
73 case WINED3DFMT_L16_UNORM: return D3DFMT_L16;
74 case WINED3DFMT_D32_FLOAT: return D3DFMT_D32F_LOCKABLE;
75 case WINED3DFMT_S8_UINT_D24_FLOAT: return D3DFMT_D24FS8;
76 case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA;
77 case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16;
78 case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32;
79 case WINED3DFMT_R16G16B16A16_SNORM: return D3DFMT_Q16W16V16U16;
80 case WINED3DFMT_R16_FLOAT: return D3DFMT_R16F;
81 case WINED3DFMT_R16G16_FLOAT: return D3DFMT_G16R16F;
82 case WINED3DFMT_R16G16B16A16_FLOAT: return D3DFMT_A16B16G16R16F;
83 case WINED3DFMT_R32_FLOAT: return D3DFMT_R32F;
84 case WINED3DFMT_R32G32_FLOAT: return D3DFMT_G32R32F;
85 case WINED3DFMT_R32G32B32A32_FLOAT: return D3DFMT_A32B32G32R32F;
86 case WINED3DFMT_R8G8_SNORM_Cx: return D3DFMT_CxV8U8;
87 default:
88 FIXME("Unhandled wined3d format %#x.\n", format);
89 return D3DFMT_UNKNOWN;
93 enum wined3d_format_id wined3dformat_from_d3dformat(D3DFORMAT format)
95 BYTE *c = (BYTE *)&format;
97 /* Don't translate FOURCC formats */
98 if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
100 switch(format)
102 case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN;
103 case D3DFMT_R8G8B8: return WINED3DFMT_B8G8R8_UNORM;
104 case D3DFMT_A8R8G8B8: return WINED3DFMT_B8G8R8A8_UNORM;
105 case D3DFMT_X8R8G8B8: return WINED3DFMT_B8G8R8X8_UNORM;
106 case D3DFMT_R5G6B5: return WINED3DFMT_B5G6R5_UNORM;
107 case D3DFMT_X1R5G5B5: return WINED3DFMT_B5G5R5X1_UNORM;
108 case D3DFMT_A1R5G5B5: return WINED3DFMT_B5G5R5A1_UNORM;
109 case D3DFMT_A4R4G4B4: return WINED3DFMT_B4G4R4A4_UNORM;
110 case D3DFMT_R3G3B2: return WINED3DFMT_B2G3R3_UNORM;
111 case D3DFMT_A8: return WINED3DFMT_A8_UNORM;
112 case D3DFMT_A8R3G3B2: return WINED3DFMT_B2G3R3A8_UNORM;
113 case D3DFMT_X4R4G4B4: return WINED3DFMT_B4G4R4X4_UNORM;
114 case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM;
115 case D3DFMT_A8B8G8R8: return WINED3DFMT_R8G8B8A8_UNORM;
116 case D3DFMT_X8B8G8R8: return WINED3DFMT_R8G8B8X8_UNORM;
117 case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM;
118 case D3DFMT_A2R10G10B10: return WINED3DFMT_B10G10R10A2_UNORM;
119 case D3DFMT_A16B16G16R16: return WINED3DFMT_R16G16B16A16_UNORM;
120 case D3DFMT_A8P8: return WINED3DFMT_P8_UINT_A8_UNORM;
121 case D3DFMT_P8: return WINED3DFMT_P8_UINT;
122 case D3DFMT_L8: return WINED3DFMT_L8_UNORM;
123 case D3DFMT_A8L8: return WINED3DFMT_L8A8_UNORM;
124 case D3DFMT_A4L4: return WINED3DFMT_L4A4_UNORM;
125 case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM;
126 case D3DFMT_L6V5U5: return WINED3DFMT_R5G5_SNORM_L6_UNORM;
127 case D3DFMT_X8L8V8U8: return WINED3DFMT_R8G8_SNORM_L8X8_UNORM;
128 case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
129 case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
130 case D3DFMT_A2W10V10U10: return WINED3DFMT_R10G10B10_SNORM_A2_UNORM;
131 case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
132 case D3DFMT_D32: return WINED3DFMT_D32_UNORM;
133 case D3DFMT_D15S1: return WINED3DFMT_S1_UINT_D15_UNORM;
134 case D3DFMT_D24S8: return WINED3DFMT_D24_UNORM_S8_UINT;
135 case D3DFMT_D24X8: return WINED3DFMT_X8D24_UNORM;
136 case D3DFMT_D24X4S4: return WINED3DFMT_S4X4_UINT_D24_UNORM;
137 case D3DFMT_D16: return WINED3DFMT_D16_UNORM;
138 case D3DFMT_L16: return WINED3DFMT_L16_UNORM;
139 case D3DFMT_D32F_LOCKABLE: return WINED3DFMT_D32_FLOAT;
140 case D3DFMT_D24FS8: return WINED3DFMT_S8_UINT_D24_FLOAT;
141 case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA;
142 case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT;
143 case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT;
144 case D3DFMT_Q16W16V16U16: return WINED3DFMT_R16G16B16A16_SNORM;
145 case D3DFMT_R16F: return WINED3DFMT_R16_FLOAT;
146 case D3DFMT_G16R16F: return WINED3DFMT_R16G16_FLOAT;
147 case D3DFMT_A16B16G16R16F: return WINED3DFMT_R16G16B16A16_FLOAT;
148 case D3DFMT_R32F: return WINED3DFMT_R32_FLOAT;
149 case D3DFMT_G32R32F: return WINED3DFMT_R32G32_FLOAT;
150 case D3DFMT_A32B32G32R32F: return WINED3DFMT_R32G32B32A32_FLOAT;
151 case D3DFMT_CxV8U8: return WINED3DFMT_R8G8_SNORM_Cx;
152 default:
153 FIXME("Unhandled D3DFORMAT %#x\n", format);
154 return WINED3DFMT_UNKNOWN;
158 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
160 switch(primitive_type)
162 case D3DPT_POINTLIST:
163 return primitive_count;
165 case D3DPT_LINELIST:
166 return primitive_count * 2;
168 case D3DPT_LINESTRIP:
169 return primitive_count + 1;
171 case D3DPT_TRIANGLELIST:
172 return primitive_count * 3;
174 case D3DPT_TRIANGLESTRIP:
175 case D3DPT_TRIANGLEFAN:
176 return primitive_count + 2;
178 default:
179 FIXME("Unhandled primitive type %#x\n", primitive_type);
180 return 0;
184 static inline IDirect3DDevice9Impl *impl_from_IDirect3DDevice9Ex(IDirect3DDevice9Ex *iface)
186 return CONTAINING_RECORD(iface, IDirect3DDevice9Impl, IDirect3DDevice9Ex_iface);
189 static HRESULT WINAPI IDirect3DDevice9Impl_QueryInterface(IDirect3DDevice9Ex *iface, REFIID riid,
190 void **ppobj)
192 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
193 IDirect3D9 *d3d;
194 IDirect3D9Impl *d3dimpl;
196 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj);
198 if (IsEqualGUID(riid, &IID_IUnknown)
199 || IsEqualGUID(riid, &IID_IDirect3DDevice9)) {
200 IDirect3DDevice9Ex_AddRef(iface);
201 *ppobj = This;
202 TRACE("Returning IDirect3DDevice9 interface at %p\n", *ppobj);
203 return S_OK;
204 } else if(IsEqualGUID(riid, &IID_IDirect3DDevice9Ex)) {
205 /* Find out if the creating d3d9 interface was created with Direct3DCreate9Ex.
206 * It doesn't matter with which function the device was created.
208 IDirect3DDevice9_GetDirect3D(iface, &d3d);
209 d3dimpl = (IDirect3D9Impl *) d3d;
211 if(d3dimpl->extended) {
212 *ppobj = iface;
213 IDirect3DDevice9Ex_AddRef((IDirect3DDevice9Ex *) *ppobj);
214 IDirect3D9_Release(d3d);
215 TRACE("Returning IDirect3DDevice9Ex interface at %p\n", *ppobj);
216 return S_OK;
217 } else {
218 WARN("IDirect3D9 instance wasn't created with CreateDirect3D9Ex, returning E_NOINTERFACE\n");
219 IDirect3D9_Release(d3d);
220 *ppobj = NULL;
221 return E_NOINTERFACE;
225 WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
226 *ppobj = NULL;
227 return E_NOINTERFACE;
230 static ULONG WINAPI IDirect3DDevice9Impl_AddRef(IDirect3DDevice9Ex *iface)
232 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
233 ULONG ref = InterlockedIncrement(&This->ref);
235 TRACE("%p increasing refcount to %u.\n", iface, ref);
237 return ref;
240 static ULONG WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Release(IDirect3DDevice9Ex *iface)
242 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
243 ULONG ref;
245 if (This->inDestruction) return 0;
246 ref = InterlockedDecrement(&This->ref);
248 TRACE("%p decreasing refcount to %u.\n", iface, ref);
250 if (ref == 0) {
251 unsigned i;
252 This->inDestruction = TRUE;
254 wined3d_mutex_lock();
255 for(i = 0; i < This->numConvertedDecls; i++) {
256 /* Unless Wine is buggy or the app has a bug the refcount will be 0, because decls hold a reference to the
257 * device
259 IDirect3DVertexDeclaration9Impl_Destroy(This->convertedDecls[i]);
261 HeapFree(GetProcessHeap(), 0, This->convertedDecls);
263 wined3d_device_uninit_3d(This->wined3d_device);
264 wined3d_device_release_focus_window(This->wined3d_device);
265 wined3d_device_decref(This->wined3d_device);
266 wined3d_mutex_unlock();
268 IDirect3D9_Release(This->d3d_parent);
270 HeapFree(GetProcessHeap(), 0, This);
272 return ref;
275 static HRESULT WINAPI IDirect3DDevice9Impl_TestCooperativeLevel(IDirect3DDevice9Ex *iface)
277 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
279 TRACE("iface %p.\n", iface);
281 if (This->notreset)
283 TRACE("D3D9 device is marked not reset.\n");
284 return D3DERR_DEVICENOTRESET;
287 return D3D_OK;
290 static UINT WINAPI IDirect3DDevice9Impl_GetAvailableTextureMem(IDirect3DDevice9Ex *iface)
292 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
293 HRESULT hr;
295 TRACE("iface %p.\n", iface);
297 wined3d_mutex_lock();
298 hr = wined3d_device_get_available_texture_mem(This->wined3d_device);
299 wined3d_mutex_unlock();
301 return hr;
304 static HRESULT WINAPI IDirect3DDevice9Impl_EvictManagedResources(IDirect3DDevice9Ex *iface)
306 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
308 TRACE("iface %p.\n", iface);
310 wined3d_mutex_lock();
311 wined3d_device_evict_managed_resources(This->wined3d_device);
312 wined3d_mutex_unlock();
314 return D3D_OK;
317 static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(IDirect3DDevice9Ex *iface,
318 IDirect3D9 **ppD3D9)
320 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
322 TRACE("iface %p, d3d9 %p.\n", iface, ppD3D9);
324 if (NULL == ppD3D9) {
325 return D3DERR_INVALIDCALL;
328 return IDirect3D9Ex_QueryInterface(This->d3d_parent, &IID_IDirect3D9, (void **)ppD3D9);
331 static HRESULT WINAPI IDirect3DDevice9Impl_GetDeviceCaps(IDirect3DDevice9Ex *iface, D3DCAPS9 *pCaps)
333 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
334 HRESULT hrc = D3D_OK;
335 WINED3DCAPS *pWineCaps;
337 TRACE("iface %p, caps %p.\n", iface, pCaps);
339 if(NULL == pCaps){
340 return D3DERR_INVALIDCALL;
342 pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS));
343 if(pWineCaps == NULL){
344 return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
347 memset(pCaps, 0, sizeof(*pCaps));
349 wined3d_mutex_lock();
350 hrc = wined3d_device_get_device_caps(This->wined3d_device, pWineCaps);
351 wined3d_mutex_unlock();
353 WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
354 HeapFree(GetProcessHeap(), 0, pWineCaps);
356 /* Some functionality is implemented in d3d9.dll, not wined3d.dll. Add the needed caps */
357 pCaps->DevCaps2 |= D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES;
359 filter_caps(pCaps);
361 TRACE("Returning %p %p\n", This, pCaps);
362 return hrc;
365 static HRESULT WINAPI IDirect3DDevice9Impl_GetDisplayMode(IDirect3DDevice9Ex *iface,
366 UINT iSwapChain, D3DDISPLAYMODE *pMode)
368 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
369 HRESULT hr;
371 TRACE("iface %p, swapchain %u, mode %p.\n", iface, iSwapChain, pMode);
373 wined3d_mutex_lock();
374 hr = wined3d_device_get_display_mode(This->wined3d_device, iSwapChain, (WINED3DDISPLAYMODE *)pMode);
375 wined3d_mutex_unlock();
377 if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
379 return hr;
382 static HRESULT WINAPI IDirect3DDevice9Impl_GetCreationParameters(IDirect3DDevice9Ex *iface,
383 D3DDEVICE_CREATION_PARAMETERS *pParameters)
385 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
386 HRESULT hr;
388 TRACE("iface %p, parameters %p.\n", iface, pParameters);
390 wined3d_mutex_lock();
391 hr = wined3d_device_get_creation_parameters(This->wined3d_device,
392 (WINED3DDEVICE_CREATION_PARAMETERS *)pParameters);
393 wined3d_mutex_unlock();
395 return hr;
398 static HRESULT WINAPI IDirect3DDevice9Impl_SetCursorProperties(IDirect3DDevice9Ex *iface,
399 UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9 *pCursorBitmap)
401 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
402 IDirect3DSurface9Impl *pSurface = unsafe_impl_from_IDirect3DSurface9(pCursorBitmap);
403 HRESULT hr;
405 TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n",
406 iface, XHotSpot, YHotSpot, pCursorBitmap);
408 if (!pCursorBitmap)
410 WARN("No cursor bitmap, returning D3DERR_INVALIDCALL.\n");
411 return D3DERR_INVALIDCALL;
414 wined3d_mutex_lock();
415 hr = wined3d_device_set_cursor_properties(This->wined3d_device, XHotSpot, YHotSpot, pSurface->wined3d_surface);
416 wined3d_mutex_unlock();
418 return hr;
421 static void WINAPI IDirect3DDevice9Impl_SetCursorPosition(IDirect3DDevice9Ex *iface,
422 int XScreenSpace, int YScreenSpace, DWORD Flags)
424 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
426 TRACE("iface %p, x %u, y %u, flags %#x.\n", iface, XScreenSpace, YScreenSpace, Flags);
428 wined3d_mutex_lock();
429 wined3d_device_set_cursor_position(This->wined3d_device, XScreenSpace, YScreenSpace, Flags);
430 wined3d_mutex_unlock();
433 static BOOL WINAPI IDirect3DDevice9Impl_ShowCursor(IDirect3DDevice9Ex *iface, BOOL bShow)
435 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
436 BOOL ret;
438 TRACE("iface %p, show %#x.\n", iface, bShow);
440 wined3d_mutex_lock();
441 ret = wined3d_device_show_cursor(This->wined3d_device, bShow);
442 wined3d_mutex_unlock();
444 return ret;
447 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_CreateAdditionalSwapChain(IDirect3DDevice9Ex *iface,
448 D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain9 **swapchain)
450 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
451 IDirect3DSwapChain9Impl *object;
452 HRESULT hr;
454 TRACE("iface %p, present_parameters %p, swapchain %p.\n",
455 iface, present_parameters, swapchain);
457 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
458 if (!object)
460 ERR("Failed to allocate swapchain memory.\n");
461 return E_OUTOFMEMORY;
464 hr = swapchain_init(object, This, present_parameters);
465 if (FAILED(hr))
467 WARN("Failed to initialize swapchain, hr %#x.\n", hr);
468 HeapFree(GetProcessHeap(), 0, object);
469 return hr;
472 TRACE("Created swapchain %p.\n", object);
473 *swapchain = (IDirect3DSwapChain9 *)object;
475 return D3D_OK;
478 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_GetSwapChain(IDirect3DDevice9Ex *iface,
479 UINT swapchain_idx, IDirect3DSwapChain9 **swapchain)
481 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
482 struct wined3d_swapchain *wined3d_swapchain = NULL;
483 HRESULT hr;
485 TRACE("iface %p, swapchain_idx %u, swapchain %p.\n", iface, swapchain_idx, swapchain);
487 wined3d_mutex_lock();
488 hr = wined3d_device_get_swapchain(This->wined3d_device, swapchain_idx, &wined3d_swapchain);
489 if (SUCCEEDED(hr) && wined3d_swapchain)
491 *swapchain = wined3d_swapchain_get_parent(wined3d_swapchain);
492 IDirect3DSwapChain9_AddRef(*swapchain);
493 wined3d_swapchain_decref(wined3d_swapchain);
495 else
497 *swapchain = NULL;
499 wined3d_mutex_unlock();
501 return hr;
504 static UINT WINAPI IDirect3DDevice9Impl_GetNumberOfSwapChains(IDirect3DDevice9Ex *iface)
506 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
507 UINT count;
509 TRACE("iface %p.\n", iface);
511 wined3d_mutex_lock();
512 count = wined3d_device_get_swapchain_count(This->wined3d_device);
513 wined3d_mutex_unlock();
515 return count;
518 static HRESULT CDECL reset_enum_callback(struct wined3d_resource *resource)
520 struct wined3d_resource_desc desc;
522 wined3d_resource_get_desc(resource, &desc);
523 if (desc.pool == WINED3DPOOL_DEFAULT)
525 IDirect3DSurface9 *surface;
527 if (desc.resource_type != WINED3DRTYPE_SURFACE)
529 WARN("Resource %p in pool D3DPOOL_DEFAULT blocks the Reset call.\n", resource);
530 return D3DERR_INVALIDCALL;
533 surface = wined3d_resource_get_parent(resource);
535 IDirect3DSurface9_AddRef(surface);
536 if (IDirect3DSurface9_Release(surface))
538 WARN("Surface %p (resource %p) in pool D3DPOOL_DEFAULT blocks the Reset call.\n", surface, resource);
539 return D3DERR_INVALIDCALL;
542 WARN("Surface %p (resource %p) is an implicit resource with ref 0.\n", surface, resource);
545 return D3D_OK;
548 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Reset(IDirect3DDevice9Ex *iface,
549 D3DPRESENT_PARAMETERS *pPresentationParameters)
551 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
552 WINED3DPRESENT_PARAMETERS localParameters;
553 HRESULT hr;
555 TRACE("iface %p, present_parameters %p.\n", iface, pPresentationParameters);
557 /* Reset states that hold a COM object. WineD3D holds an internal reference to set objects, because
558 * such objects can still be used for rendering after their external d3d9 object has been destroyed.
559 * These objects must not be enumerated. Unsetting them tells WineD3D that the application will not
560 * make use of the hidden reference and destroys the objects.
562 * Unsetting them is no problem, because the states are supposed to be reset anyway. If the validation
563 * below fails, the device is considered "lost", and _Reset and _Release are the only allowed calls
565 wined3d_mutex_lock();
567 localParameters.BackBufferWidth = pPresentationParameters->BackBufferWidth;
568 localParameters.BackBufferHeight = pPresentationParameters->BackBufferHeight;
569 localParameters.BackBufferFormat = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
570 localParameters.BackBufferCount = pPresentationParameters->BackBufferCount;
571 localParameters.MultiSampleType = pPresentationParameters->MultiSampleType;
572 localParameters.MultiSampleQuality = pPresentationParameters->MultiSampleQuality;
573 localParameters.SwapEffect = pPresentationParameters->SwapEffect;
574 localParameters.hDeviceWindow = pPresentationParameters->hDeviceWindow;
575 localParameters.Windowed = pPresentationParameters->Windowed;
576 localParameters.EnableAutoDepthStencil = pPresentationParameters->EnableAutoDepthStencil;
577 localParameters.AutoDepthStencilFormat = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
578 localParameters.Flags = pPresentationParameters->Flags;
579 localParameters.FullScreen_RefreshRateInHz = pPresentationParameters->FullScreen_RefreshRateInHz;
580 localParameters.PresentationInterval = pPresentationParameters->PresentationInterval;
581 localParameters.AutoRestoreDisplayMode = TRUE;
583 hr = wined3d_device_reset(This->wined3d_device, &localParameters, reset_enum_callback);
584 if (FAILED(hr))
586 This->notreset = TRUE;
588 pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth;
589 pPresentationParameters->BackBufferHeight = localParameters.BackBufferHeight;
590 pPresentationParameters->BackBufferFormat = d3dformat_from_wined3dformat(localParameters.BackBufferFormat);
591 pPresentationParameters->BackBufferCount = localParameters.BackBufferCount;
592 pPresentationParameters->MultiSampleType = localParameters.MultiSampleType;
593 pPresentationParameters->MultiSampleQuality = localParameters.MultiSampleQuality;
594 pPresentationParameters->SwapEffect = localParameters.SwapEffect;
595 pPresentationParameters->hDeviceWindow = localParameters.hDeviceWindow;
596 pPresentationParameters->Windowed = localParameters.Windowed;
597 pPresentationParameters->EnableAutoDepthStencil = localParameters.EnableAutoDepthStencil;
598 pPresentationParameters->AutoDepthStencilFormat = d3dformat_from_wined3dformat(localParameters.AutoDepthStencilFormat);
599 pPresentationParameters->Flags = localParameters.Flags;
600 pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz;
601 pPresentationParameters->PresentationInterval = localParameters.PresentationInterval;
602 } else {
603 This->notreset = FALSE;
606 wined3d_mutex_unlock();
608 return hr;
611 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Present(IDirect3DDevice9Ex *iface,
612 const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride,
613 const RGNDATA *pDirtyRegion)
615 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
616 HRESULT hr;
618 TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n",
619 iface, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
621 wined3d_mutex_lock();
622 hr = wined3d_device_present(This->wined3d_device, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
623 wined3d_mutex_unlock();
625 return hr;
628 static HRESULT WINAPI IDirect3DDevice9Impl_GetBackBuffer(IDirect3DDevice9Ex *iface,
629 UINT iSwapChain, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 **ppBackBuffer)
631 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
632 struct wined3d_surface *wined3d_surface = NULL;
633 HRESULT hr;
635 TRACE("iface %p, swapchain %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
636 iface, iSwapChain, BackBuffer, Type, ppBackBuffer);
638 wined3d_mutex_lock();
639 hr = wined3d_device_get_back_buffer(This->wined3d_device, iSwapChain,
640 BackBuffer, (WINED3DBACKBUFFER_TYPE) Type, &wined3d_surface);
641 if (SUCCEEDED(hr) && wined3d_surface && ppBackBuffer)
643 *ppBackBuffer = wined3d_surface_get_parent(wined3d_surface);
644 IDirect3DSurface9_AddRef(*ppBackBuffer);
645 wined3d_surface_decref(wined3d_surface);
647 wined3d_mutex_unlock();
649 return hr;
651 static HRESULT WINAPI IDirect3DDevice9Impl_GetRasterStatus(IDirect3DDevice9Ex *iface,
652 UINT iSwapChain, D3DRASTER_STATUS *pRasterStatus)
654 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
655 HRESULT hr;
657 TRACE("iface %p, swapchain %u, raster_status %p.\n", iface, iSwapChain, pRasterStatus);
659 wined3d_mutex_lock();
660 hr = wined3d_device_get_raster_status(This->wined3d_device, iSwapChain, (WINED3DRASTER_STATUS *)pRasterStatus);
661 wined3d_mutex_unlock();
663 return hr;
666 static HRESULT WINAPI IDirect3DDevice9Impl_SetDialogBoxMode(IDirect3DDevice9Ex *iface,
667 BOOL bEnableDialogs)
669 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
670 HRESULT hr;
672 TRACE("iface %p, enable %#x.\n", iface, bEnableDialogs);
674 wined3d_mutex_lock();
675 hr = wined3d_device_set_dialog_box_mode(This->wined3d_device, bEnableDialogs);
676 wined3d_mutex_unlock();
678 return hr;
681 static void WINAPI IDirect3DDevice9Impl_SetGammaRamp(IDirect3DDevice9Ex *iface, UINT iSwapChain,
682 DWORD Flags, const D3DGAMMARAMP *pRamp)
684 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
686 TRACE("iface %p, swapchain %u, flags %#x, ramp %p.\n", iface, iSwapChain, Flags, pRamp);
688 /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
689 wined3d_mutex_lock();
690 wined3d_device_set_gamma_ramp(This->wined3d_device, iSwapChain, Flags, (const WINED3DGAMMARAMP *)pRamp);
691 wined3d_mutex_unlock();
694 static void WINAPI IDirect3DDevice9Impl_GetGammaRamp(IDirect3DDevice9Ex *iface, UINT iSwapChain,
695 D3DGAMMARAMP *pRamp)
697 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
699 TRACE("iface %p, swapchain %u, ramp %p.\n", iface, iSwapChain, pRamp);
701 /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
702 wined3d_mutex_lock();
703 wined3d_device_get_gamma_ramp(This->wined3d_device, iSwapChain, (WINED3DGAMMARAMP *)pRamp);
704 wined3d_mutex_unlock();
707 static HRESULT WINAPI IDirect3DDevice9Impl_CreateTexture(IDirect3DDevice9Ex *iface,
708 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
709 D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle)
711 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
712 IDirect3DTexture9Impl *object;
713 HRESULT hr;
715 TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
716 iface, width, height, levels, usage, format, pool, texture, shared_handle);
718 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
719 if (!object)
721 ERR("Failed to allocate texture memory.\n");
722 return D3DERR_OUTOFVIDEOMEMORY;
725 hr = texture_init(object, This, width, height, levels, usage, format, pool);
726 if (FAILED(hr))
728 WARN("Failed to initialize texture, hr %#x.\n", hr);
729 HeapFree(GetProcessHeap(), 0, object);
730 return hr;
733 TRACE("Created texture %p.\n", object);
734 *texture = &object->IDirect3DTexture9_iface;
736 return D3D_OK;
739 static HRESULT WINAPI IDirect3DDevice9Impl_CreateVolumeTexture(IDirect3DDevice9Ex *iface,
740 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format,
741 D3DPOOL pool, IDirect3DVolumeTexture9 **texture, HANDLE *shared_handle)
743 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
744 IDirect3DVolumeTexture9Impl *object;
745 HRESULT hr;
747 TRACE("iface %p, width %u, height %u, depth %u, levels %u\n",
748 iface, width, height, depth, levels);
749 TRACE("usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
750 usage, format, pool, texture, shared_handle);
752 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
753 if (!object)
755 ERR("Failed to allocate volume texture memory.\n");
756 return D3DERR_OUTOFVIDEOMEMORY;
759 hr = volumetexture_init(object, This, width, height, depth, levels, usage, format, pool);
760 if (FAILED(hr))
762 WARN("Failed to initialize volume texture, hr %#x.\n", hr);
763 HeapFree(GetProcessHeap(), 0, object);
764 return hr;
767 TRACE("Created volume texture %p.\n", object);
768 *texture = &object->IDirect3DVolumeTexture9_iface;
770 return D3D_OK;
773 static HRESULT WINAPI IDirect3DDevice9Impl_CreateCubeTexture(IDirect3DDevice9Ex *iface,
774 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool,
775 IDirect3DCubeTexture9 **texture, HANDLE *shared_handle)
777 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
778 IDirect3DCubeTexture9Impl *object;
779 HRESULT hr;
781 TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
782 iface, edge_length, levels, usage, format, pool, texture, shared_handle);
784 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
785 if (!object)
787 ERR("Failed to allocate cube texture memory.\n");
788 return D3DERR_OUTOFVIDEOMEMORY;
791 hr = cubetexture_init(object, This, edge_length, levels, usage, format, pool);
792 if (FAILED(hr))
794 WARN("Failed to initialize cube texture, hr %#x.\n", hr);
795 HeapFree(GetProcessHeap(), 0, object);
796 return hr;
799 TRACE("Created cube texture %p.\n", object);
800 *texture = &object->IDirect3DCubeTexture9_iface;
802 return D3D_OK;
805 static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(IDirect3DDevice9Ex *iface, UINT size,
806 DWORD usage, DWORD fvf, D3DPOOL pool, IDirect3DVertexBuffer9 **buffer,
807 HANDLE *shared_handle)
809 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
810 IDirect3DVertexBuffer9Impl *object;
811 HRESULT hr;
813 TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p, shared_handle %p.\n",
814 iface, size, usage, fvf, pool, buffer, shared_handle);
816 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
817 if (!object)
819 ERR("Failed to allocate buffer memory.\n");
820 return D3DERR_OUTOFVIDEOMEMORY;
823 hr = vertexbuffer_init(object, This, size, usage, fvf, pool);
824 if (FAILED(hr))
826 WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
827 HeapFree(GetProcessHeap(), 0, object);
828 return hr;
831 TRACE("Created vertex buffer %p.\n", object);
832 *buffer = &object->IDirect3DVertexBuffer9_iface;
834 return D3D_OK;
837 static HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(IDirect3DDevice9Ex *iface, UINT size,
838 DWORD usage, D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **buffer,
839 HANDLE *shared_handle)
841 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
842 IDirect3DIndexBuffer9Impl *object;
843 HRESULT hr;
845 TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p, shared_handle %p.\n",
846 iface, size, usage, format, pool, buffer, shared_handle);
848 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
849 if (!object)
851 ERR("Failed to allocate buffer memory.\n");
852 return D3DERR_OUTOFVIDEOMEMORY;
855 hr = indexbuffer_init(object, This, size, usage, format, pool);
856 if (FAILED(hr))
858 WARN("Failed to initialize index buffer, hr %#x.\n", hr);
859 HeapFree(GetProcessHeap(), 0, object);
860 return hr;
863 TRACE("Created index buffer %p.\n", object);
864 *buffer = &object->IDirect3DIndexBuffer9_iface;
866 return D3D_OK;
869 static HRESULT IDirect3DDevice9Impl_CreateSurface(IDirect3DDevice9Impl *device, UINT Width,
870 UINT Height, D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level,
871 IDirect3DSurface9 **ppSurface, UINT Usage, D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample,
872 DWORD MultisampleQuality)
874 IDirect3DSurface9Impl *object;
875 HRESULT hr;
877 TRACE("device %p, width %u, height %u, format %#x, lockable %#x, discard %#x, level %u, surface %p.\n"
878 "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n",
879 device, Width, Height, Format, Lockable, Discard, Level, ppSurface, Usage, Pool,
880 MultiSample, MultisampleQuality);
882 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface9Impl));
883 if (!object)
885 FIXME("Failed to allocate surface memory.\n");
886 return D3DERR_OUTOFVIDEOMEMORY;
889 hr = surface_init(object, device, Width, Height, Format, Lockable, Discard, Level, Usage, Pool,
890 MultiSample, MultisampleQuality);
891 if (FAILED(hr))
893 WARN("Failed to initialize surface, hr %#x.\n", hr);
894 HeapFree(GetProcessHeap(), 0, object);
895 return hr;
898 TRACE("Created surface %p.\n", object);
899 *ppSurface = &object->IDirect3DSurface9_iface;
901 return D3D_OK;
904 static HRESULT WINAPI IDirect3DDevice9Impl_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT Width,
905 UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality,
906 BOOL Lockable, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle)
908 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
909 HRESULT hr;
911 TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
912 "lockable %#x, surface %p, shared_handle %p.\n",
913 iface, Width, Height, Format, MultiSample, MultisampleQuality,
914 Lockable, ppSurface, pSharedHandle);
916 hr = IDirect3DDevice9Impl_CreateSurface(This, Width, Height, Format, Lockable,
917 FALSE /* Discard */, 0 /* Level */, ppSurface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT,
918 MultiSample, MultisampleQuality);
920 return hr;
923 static HRESULT WINAPI IDirect3DDevice9Impl_CreateDepthStencilSurface(IDirect3DDevice9Ex *iface,
924 UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
925 DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9 **ppSurface,
926 HANDLE *pSharedHandle)
928 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
929 HRESULT hr;
931 TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
932 "discard %#x, surface %p, shared_handle %p.\n",
933 iface, Width, Height, Format, MultiSample, MultisampleQuality,
934 Discard, ppSurface, pSharedHandle);
936 hr = IDirect3DDevice9Impl_CreateSurface(This, Width, Height, Format, TRUE /* Lockable */,
937 Discard, 0 /* Level */, ppSurface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, MultiSample,
938 MultisampleQuality);
940 return hr;
944 static HRESULT WINAPI IDirect3DDevice9Impl_UpdateSurface(IDirect3DDevice9Ex *iface,
945 IDirect3DSurface9 *pSourceSurface, const RECT *pSourceRect,
946 IDirect3DSurface9 *pDestinationSurface, const POINT *pDestPoint)
948 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
949 IDirect3DSurface9Impl *src = unsafe_impl_from_IDirect3DSurface9(pSourceSurface);
950 IDirect3DSurface9Impl *dst = unsafe_impl_from_IDirect3DSurface9(pDestinationSurface);
951 HRESULT hr;
953 TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_point %p.\n",
954 iface, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
956 wined3d_mutex_lock();
957 hr = wined3d_device_update_surface(This->wined3d_device, src->wined3d_surface, pSourceRect,
958 dst->wined3d_surface, pDestPoint);
959 wined3d_mutex_unlock();
961 return hr;
964 static HRESULT WINAPI IDirect3DDevice9Impl_UpdateTexture(IDirect3DDevice9Ex *iface,
965 IDirect3DBaseTexture9 *src_texture, IDirect3DBaseTexture9 *dst_texture)
967 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
968 HRESULT hr;
970 TRACE("iface %p, src_texture %p, dst_texture %p.\n", iface, src_texture, dst_texture);
972 wined3d_mutex_lock();
973 hr = wined3d_device_update_texture(This->wined3d_device,
974 ((IDirect3DBaseTexture9Impl *)src_texture)->wined3d_texture,
975 ((IDirect3DBaseTexture9Impl *)dst_texture)->wined3d_texture);
976 wined3d_mutex_unlock();
978 return hr;
981 static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderTargetData(IDirect3DDevice9Ex *iface,
982 IDirect3DSurface9 *pRenderTarget, IDirect3DSurface9 *pDestSurface)
984 IDirect3DSurface9Impl *renderTarget = unsafe_impl_from_IDirect3DSurface9(pRenderTarget);
985 IDirect3DSurface9Impl *destSurface = unsafe_impl_from_IDirect3DSurface9(pDestSurface);
986 HRESULT hr;
988 TRACE("iface %p, render_target %p, dst_surface %p.\n", iface, pRenderTarget, pDestSurface);
990 wined3d_mutex_lock();
991 hr = wined3d_surface_bltfast(destSurface->wined3d_surface, 0, 0,
992 renderTarget->wined3d_surface, NULL, WINEDDBLTFAST_NOCOLORKEY);
993 wined3d_mutex_unlock();
995 return hr;
998 static HRESULT WINAPI IDirect3DDevice9Impl_GetFrontBufferData(IDirect3DDevice9Ex *iface,
999 UINT iSwapChain, IDirect3DSurface9 *pDestSurface)
1001 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1002 IDirect3DSurface9Impl *destSurface = unsafe_impl_from_IDirect3DSurface9(pDestSurface);
1003 HRESULT hr;
1005 TRACE("iface %p, swapchain %u, dst_surface %p.\n", iface, iSwapChain, pDestSurface);
1007 wined3d_mutex_lock();
1008 hr = wined3d_device_get_front_buffer_data(This->wined3d_device, iSwapChain, destSurface->wined3d_surface);
1009 wined3d_mutex_unlock();
1011 return hr;
1014 static HRESULT WINAPI IDirect3DDevice9Impl_StretchRect(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *pSourceSurface,
1015 const RECT *pSourceRect, IDirect3DSurface9 *pDestSurface, const RECT *pDestRect, D3DTEXTUREFILTERTYPE Filter)
1017 IDirect3DSurface9Impl *src = unsafe_impl_from_IDirect3DSurface9(pSourceSurface);
1018 IDirect3DSurface9Impl *dst = unsafe_impl_from_IDirect3DSurface9(pDestSurface);
1019 HRESULT hr;
1021 TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n",
1022 iface, pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter);
1024 wined3d_mutex_lock();
1025 hr = wined3d_surface_blt(dst->wined3d_surface, pDestRect, src->wined3d_surface, pSourceRect, 0, NULL, Filter);
1026 if (hr == WINEDDERR_INVALIDRECT)
1027 hr = D3DERR_INVALIDCALL;
1028 wined3d_mutex_unlock();
1030 return hr;
1033 static HRESULT WINAPI IDirect3DDevice9Impl_ColorFill(IDirect3DDevice9Ex *iface,
1034 IDirect3DSurface9 *pSurface, const RECT *pRect, D3DCOLOR color)
1036 const WINED3DCOLORVALUE c =
1038 ((color >> 16) & 0xff) / 255.0f,
1039 ((color >> 8) & 0xff) / 255.0f,
1040 (color & 0xff) / 255.0f,
1041 ((color >> 24) & 0xff) / 255.0f,
1043 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1044 IDirect3DSurface9Impl *surface = unsafe_impl_from_IDirect3DSurface9(pSurface);
1045 struct wined3d_resource *wined3d_resource;
1046 struct wined3d_resource_desc desc;
1047 HRESULT hr;
1049 TRACE("iface %p, surface %p, rect %p, color 0x%08x.\n", iface, pSurface, pRect, color);
1051 wined3d_mutex_lock();
1053 wined3d_resource = wined3d_surface_get_resource(surface->wined3d_surface);
1054 wined3d_resource_get_desc(wined3d_resource, &desc);
1056 /* This method is only allowed with surfaces that are render targets, or
1057 * offscreen plain surfaces in D3DPOOL_DEFAULT. */
1058 if (!(desc.usage & WINED3DUSAGE_RENDERTARGET) && desc.pool != WINED3DPOOL_DEFAULT)
1060 wined3d_mutex_unlock();
1061 WARN("Surface is not a render target, or not a stand-alone D3DPOOL_DEFAULT surface\n");
1062 return D3DERR_INVALIDCALL;
1065 /* Colorfill can only be used on rendertarget surfaces, or offscreen plain surfaces in D3DPOOL_DEFAULT */
1066 hr = wined3d_device_color_fill(This->wined3d_device, surface->wined3d_surface, pRect, &c);
1068 wined3d_mutex_unlock();
1070 return hr;
1073 static HRESULT WINAPI IDirect3DDevice9Impl_CreateOffscreenPlainSurface(IDirect3DDevice9Ex *iface,
1074 UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9 **ppSurface,
1075 HANDLE *pSharedHandle)
1077 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1078 HRESULT hr;
1080 TRACE("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p.\n",
1081 iface, Width, Height, Format, Pool, ppSurface, pSharedHandle);
1083 if(Pool == D3DPOOL_MANAGED ){
1084 FIXME("Attempting to create a managed offscreen plain surface\n");
1085 return D3DERR_INVALIDCALL;
1088 'Off-screen plain surfaces are always lockable, regardless of their pool types.'
1089 but then...
1090 D3DPOOL_DEFAULT is the appropriate pool for use with the IDirect3DDevice9::StretchRect and IDirect3DDevice9::ColorFill.
1091 Why, their always lockable?
1092 should I change the usage to dynamic?
1094 hr = IDirect3DDevice9Impl_CreateSurface(This, Width, Height, Format, TRUE /* Lockable */,
1095 FALSE /* Discard */, 0 /* Level */, ppSurface, 0 /* Usage (undefined/none) */,
1096 Pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
1098 return hr;
1101 /* TODO: move to wineD3D */
1102 static HRESULT WINAPI IDirect3DDevice9Impl_SetRenderTarget(IDirect3DDevice9Ex *iface,
1103 DWORD RenderTargetIndex, IDirect3DSurface9 *pRenderTarget)
1105 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1106 IDirect3DSurface9Impl *pSurface = unsafe_impl_from_IDirect3DSurface9(pRenderTarget);
1107 HRESULT hr;
1109 TRACE("iface %p, idx %u, surface %p.\n", iface, RenderTargetIndex, pRenderTarget);
1111 if (RenderTargetIndex >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
1113 WARN("Invalid index %u specified.\n", RenderTargetIndex);
1114 return D3DERR_INVALIDCALL;
1117 wined3d_mutex_lock();
1118 hr = wined3d_device_set_render_target(This->wined3d_device, RenderTargetIndex,
1119 pSurface ? pSurface->wined3d_surface : NULL, TRUE);
1120 wined3d_mutex_unlock();
1122 return hr;
1125 static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderTarget(IDirect3DDevice9Ex *iface,
1126 DWORD RenderTargetIndex, IDirect3DSurface9 **ppRenderTarget)
1128 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1129 struct wined3d_surface *wined3d_surface;
1130 HRESULT hr;
1132 TRACE("iface %p, idx %u, surface %p.\n", iface, RenderTargetIndex, ppRenderTarget);
1134 if (ppRenderTarget == NULL) {
1135 return D3DERR_INVALIDCALL;
1138 if (RenderTargetIndex >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
1140 WARN("Invalid index %u specified.\n", RenderTargetIndex);
1141 return D3DERR_INVALIDCALL;
1144 wined3d_mutex_lock();
1145 hr = wined3d_device_get_render_target(This->wined3d_device, RenderTargetIndex, &wined3d_surface);
1146 if (SUCCEEDED(hr))
1148 *ppRenderTarget = wined3d_surface_get_parent(wined3d_surface);
1149 IDirect3DSurface9_AddRef(*ppRenderTarget);
1150 wined3d_surface_decref(wined3d_surface);
1152 else
1154 if (hr != WINED3DERR_NOTFOUND)
1155 WARN("Failed to get render target %u, hr %#x.\n", RenderTargetIndex, hr);
1156 *ppRenderTarget = NULL;
1158 wined3d_mutex_unlock();
1160 return hr;
1163 static HRESULT WINAPI IDirect3DDevice9Impl_SetDepthStencilSurface(IDirect3DDevice9Ex *iface,
1164 IDirect3DSurface9 *pZStencilSurface)
1166 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1167 IDirect3DSurface9Impl *pSurface = unsafe_impl_from_IDirect3DSurface9(pZStencilSurface);
1168 HRESULT hr;
1170 TRACE("iface %p, depth_stencil %p.\n", iface, pZStencilSurface);
1172 wined3d_mutex_lock();
1173 hr = wined3d_device_set_depth_stencil(This->wined3d_device, pSurface ? pSurface->wined3d_surface : NULL);
1174 wined3d_mutex_unlock();
1176 return hr;
1179 static HRESULT WINAPI IDirect3DDevice9Impl_GetDepthStencilSurface(IDirect3DDevice9Ex *iface,
1180 IDirect3DSurface9 **ppZStencilSurface)
1182 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1183 struct wined3d_surface *wined3d_surface;
1184 HRESULT hr;
1186 TRACE("iface %p, depth_stencil %p.\n", iface, ppZStencilSurface);
1188 if(ppZStencilSurface == NULL){
1189 return D3DERR_INVALIDCALL;
1192 wined3d_mutex_lock();
1193 hr = wined3d_device_get_depth_stencil(This->wined3d_device, &wined3d_surface);
1194 if (SUCCEEDED(hr))
1196 *ppZStencilSurface = wined3d_surface_get_parent(wined3d_surface);
1197 IDirect3DSurface9_AddRef(*ppZStencilSurface);
1198 wined3d_surface_decref(wined3d_surface);
1200 else
1202 if (hr != WINED3DERR_NOTFOUND)
1203 WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
1204 *ppZStencilSurface = NULL;
1206 wined3d_mutex_unlock();
1208 return hr;
1211 static HRESULT WINAPI IDirect3DDevice9Impl_BeginScene(IDirect3DDevice9Ex *iface)
1213 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1214 HRESULT hr;
1216 TRACE("iface %p.\n", iface);
1218 wined3d_mutex_lock();
1219 hr = wined3d_device_begin_scene(This->wined3d_device);
1220 wined3d_mutex_unlock();
1222 return hr;
1225 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_EndScene(IDirect3DDevice9Ex *iface)
1227 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1228 HRESULT hr;
1230 TRACE("iface %p.\n", iface);
1232 wined3d_mutex_lock();
1233 hr = wined3d_device_end_scene(This->wined3d_device);
1234 wined3d_mutex_unlock();
1236 return hr;
1239 static HRESULT WINAPI IDirect3DDevice9Impl_Clear(IDirect3DDevice9Ex *iface, DWORD Count,
1240 const D3DRECT *pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil)
1242 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1243 HRESULT hr;
1245 TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n",
1246 iface, Count, pRects, Flags, Color, Z, Stencil);
1248 /* Note: D3DRECT is compatible with WINED3DRECT */
1249 wined3d_mutex_lock();
1250 hr = wined3d_device_clear(This->wined3d_device, Count, (const RECT *)pRects, Flags, Color, Z, Stencil);
1251 wined3d_mutex_unlock();
1253 return hr;
1256 static HRESULT WINAPI IDirect3DDevice9Impl_SetTransform(IDirect3DDevice9Ex *iface,
1257 D3DTRANSFORMSTATETYPE State, const D3DMATRIX *lpMatrix)
1259 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1260 HRESULT hr;
1262 TRACE("iface %p, state %#x, matrix %p.\n", iface, State, lpMatrix);
1264 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
1265 wined3d_mutex_lock();
1266 hr = wined3d_device_set_transform(This->wined3d_device, State, (const WINED3DMATRIX *)lpMatrix);
1267 wined3d_mutex_unlock();
1269 return hr;
1272 static HRESULT WINAPI IDirect3DDevice9Impl_GetTransform(IDirect3DDevice9Ex *iface,
1273 D3DTRANSFORMSTATETYPE State, D3DMATRIX *pMatrix)
1275 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1276 HRESULT hr;
1278 TRACE("iface %p, state %#x, matrix %p.\n", iface, State, pMatrix);
1280 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
1281 wined3d_mutex_lock();
1282 hr = wined3d_device_get_transform(This->wined3d_device, State, (WINED3DMATRIX *)pMatrix);
1283 wined3d_mutex_unlock();
1285 return hr;
1288 static HRESULT WINAPI IDirect3DDevice9Impl_MultiplyTransform(IDirect3DDevice9Ex *iface,
1289 D3DTRANSFORMSTATETYPE State, const D3DMATRIX *pMatrix)
1291 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1292 HRESULT hr;
1294 TRACE("iface %p, state %#x, matrix %p.\n", iface, State, pMatrix);
1296 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
1297 wined3d_mutex_lock();
1298 hr = wined3d_device_multiply_transform(This->wined3d_device, State, (const WINED3DMATRIX *)pMatrix);
1299 wined3d_mutex_unlock();
1301 return hr;
1304 static HRESULT WINAPI IDirect3DDevice9Impl_SetViewport(IDirect3DDevice9Ex *iface,
1305 const D3DVIEWPORT9 *pViewport)
1307 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1308 HRESULT hr;
1310 TRACE("iface %p, viewport %p.\n", iface, pViewport);
1312 /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
1313 wined3d_mutex_lock();
1314 hr = wined3d_device_set_viewport(This->wined3d_device, (const WINED3DVIEWPORT *)pViewport);
1315 wined3d_mutex_unlock();
1317 return hr;
1320 static HRESULT WINAPI IDirect3DDevice9Impl_GetViewport(IDirect3DDevice9Ex *iface,
1321 D3DVIEWPORT9 *pViewport)
1323 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1324 HRESULT hr;
1326 TRACE("iface %p, viewport %p.\n", iface, pViewport);
1328 /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
1329 wined3d_mutex_lock();
1330 hr = wined3d_device_get_viewport(This->wined3d_device, (WINED3DVIEWPORT *)pViewport);
1331 wined3d_mutex_unlock();
1333 return hr;
1336 static HRESULT WINAPI IDirect3DDevice9Impl_SetMaterial(IDirect3DDevice9Ex *iface,
1337 const D3DMATERIAL9 *pMaterial)
1339 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1340 HRESULT hr;
1342 TRACE("iface %p, material %p.\n", iface, pMaterial);
1344 /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
1345 wined3d_mutex_lock();
1346 hr = wined3d_device_set_material(This->wined3d_device, (const WINED3DMATERIAL *)pMaterial);
1347 wined3d_mutex_unlock();
1349 return hr;
1352 static HRESULT WINAPI IDirect3DDevice9Impl_GetMaterial(IDirect3DDevice9Ex *iface,
1353 D3DMATERIAL9 *pMaterial)
1355 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1356 HRESULT hr;
1358 TRACE("iface %p, material %p.\n", iface, pMaterial);
1360 /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
1361 wined3d_mutex_lock();
1362 hr = wined3d_device_get_material(This->wined3d_device, (WINED3DMATERIAL *)pMaterial);
1363 wined3d_mutex_unlock();
1365 return hr;
1368 static HRESULT WINAPI IDirect3DDevice9Impl_SetLight(IDirect3DDevice9Ex *iface, DWORD Index,
1369 const D3DLIGHT9 *pLight)
1371 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1372 HRESULT hr;
1374 TRACE("iface %p, index %u, light %p.\n", iface, Index, pLight);
1376 /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
1377 wined3d_mutex_lock();
1378 hr = wined3d_device_set_light(This->wined3d_device, Index, (const WINED3DLIGHT *)pLight);
1379 wined3d_mutex_unlock();
1381 return hr;
1384 static HRESULT WINAPI IDirect3DDevice9Impl_GetLight(IDirect3DDevice9Ex *iface, DWORD Index,
1385 D3DLIGHT9 *pLight)
1387 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1388 HRESULT hr;
1390 TRACE("iface %p, index %u, light %p.\n", iface, Index, pLight);
1392 /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
1393 wined3d_mutex_lock();
1394 hr = wined3d_device_get_light(This->wined3d_device, Index, (WINED3DLIGHT *)pLight);
1395 wined3d_mutex_unlock();
1397 return hr;
1400 static HRESULT WINAPI IDirect3DDevice9Impl_LightEnable(IDirect3DDevice9Ex *iface, DWORD Index,
1401 BOOL Enable)
1403 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1404 HRESULT hr;
1406 TRACE("iface %p, index %u, enable %#x.\n", iface, Index, Enable);
1408 wined3d_mutex_lock();
1409 hr = wined3d_device_set_light_enable(This->wined3d_device, Index, Enable);
1410 wined3d_mutex_unlock();
1412 return hr;
1415 static HRESULT WINAPI IDirect3DDevice9Impl_GetLightEnable(IDirect3DDevice9Ex *iface, DWORD Index,
1416 BOOL *pEnable)
1418 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1419 HRESULT hr;
1421 TRACE("iface %p, index %u, enable %p.\n", iface, Index, pEnable);
1423 wined3d_mutex_lock();
1424 hr = wined3d_device_get_light_enable(This->wined3d_device, Index, pEnable);
1425 wined3d_mutex_unlock();
1427 return hr;
1430 static HRESULT WINAPI IDirect3DDevice9Impl_SetClipPlane(IDirect3DDevice9Ex *iface, DWORD Index,
1431 const float *pPlane)
1433 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1434 HRESULT hr;
1436 TRACE("iface %p, index %u, plane %p.\n", iface, Index, pPlane);
1438 wined3d_mutex_lock();
1439 hr = wined3d_device_set_clip_plane(This->wined3d_device, Index, pPlane);
1440 wined3d_mutex_unlock();
1442 return hr;
1445 static HRESULT WINAPI IDirect3DDevice9Impl_GetClipPlane(IDirect3DDevice9Ex *iface, DWORD Index,
1446 float *pPlane)
1448 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1449 HRESULT hr;
1451 TRACE("iface %p, index %u, plane %p.\n", iface, Index, pPlane);
1453 wined3d_mutex_lock();
1454 hr = wined3d_device_get_clip_plane(This->wined3d_device, Index, pPlane);
1455 wined3d_mutex_unlock();
1457 return hr;
1460 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_SetRenderState(IDirect3DDevice9Ex *iface,
1461 D3DRENDERSTATETYPE State, DWORD Value)
1463 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1464 HRESULT hr;
1466 TRACE("iface %p, state %#x, value %#x.\n", iface, State, Value);
1468 wined3d_mutex_lock();
1469 hr = wined3d_device_set_render_state(This->wined3d_device, State, Value);
1470 wined3d_mutex_unlock();
1472 return hr;
1475 static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderState(IDirect3DDevice9Ex *iface,
1476 D3DRENDERSTATETYPE State, DWORD *pValue)
1478 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1479 HRESULT hr;
1481 TRACE("iface %p, state %#x, value %p.\n", iface, State, pValue);
1483 wined3d_mutex_lock();
1484 hr = wined3d_device_get_render_state(This->wined3d_device, State, pValue);
1485 wined3d_mutex_unlock();
1487 return hr;
1490 static HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(IDirect3DDevice9Ex *iface,
1491 D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateblock)
1493 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1494 IDirect3DStateBlock9Impl *object;
1495 HRESULT hr;
1497 TRACE("iface %p, type %#x, stateblock %p.\n", iface, type, stateblock);
1499 if (type != D3DSBT_ALL && type != D3DSBT_PIXELSTATE && type != D3DSBT_VERTEXSTATE)
1501 WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL.\n");
1502 return D3DERR_INVALIDCALL;
1505 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1506 if (!object)
1508 ERR("Failed to allocate stateblock memory.\n");
1509 return E_OUTOFMEMORY;
1512 hr = stateblock_init(object, This, type, NULL);
1513 if (FAILED(hr))
1515 WARN("Failed to initialize stateblock, hr %#x.\n", hr);
1516 HeapFree(GetProcessHeap(), 0, object);
1517 return hr;
1520 TRACE("Created stateblock %p.\n", object);
1521 *stateblock = &object->IDirect3DStateBlock9_iface;
1523 return D3D_OK;
1526 static HRESULT WINAPI IDirect3DDevice9Impl_BeginStateBlock(IDirect3DDevice9Ex *iface)
1528 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1529 HRESULT hr;
1531 TRACE("iface %p.\n", iface);
1533 wined3d_mutex_lock();
1534 hr = wined3d_device_begin_stateblock(This->wined3d_device);
1535 wined3d_mutex_unlock();
1537 return hr;
1540 static HRESULT WINAPI IDirect3DDevice9Impl_EndStateBlock(IDirect3DDevice9Ex *iface,
1541 IDirect3DStateBlock9 **stateblock)
1543 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1544 struct wined3d_stateblock *wined3d_stateblock;
1545 IDirect3DStateBlock9Impl *object;
1546 HRESULT hr;
1548 TRACE("iface %p, stateblock %p.\n", iface, stateblock);
1550 wined3d_mutex_lock();
1551 hr = wined3d_device_end_stateblock(This->wined3d_device, &wined3d_stateblock);
1552 wined3d_mutex_unlock();
1553 if (FAILED(hr))
1555 WARN("IWineD3DDevice_EndStateBlock() failed, hr %#x.\n", hr);
1556 return hr;
1559 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1560 if (!object)
1562 ERR("Failed to allocate stateblock memory.\n");
1563 wined3d_mutex_lock();
1564 wined3d_stateblock_decref(wined3d_stateblock);
1565 wined3d_mutex_unlock();
1566 return E_OUTOFMEMORY;
1569 hr = stateblock_init(object, This, 0, wined3d_stateblock);
1570 if (FAILED(hr))
1572 WARN("Failed to initialize stateblock, hr %#x.\n", hr);
1573 wined3d_mutex_lock();
1574 wined3d_stateblock_decref(wined3d_stateblock);
1575 wined3d_mutex_unlock();
1576 HeapFree(GetProcessHeap(), 0, object);
1577 return hr;
1580 TRACE("Created stateblock %p.\n", object);
1581 *stateblock = &object->IDirect3DStateBlock9_iface;
1583 return D3D_OK;
1586 static HRESULT WINAPI IDirect3DDevice9Impl_SetClipStatus(IDirect3DDevice9Ex *iface,
1587 const D3DCLIPSTATUS9 *pClipStatus)
1589 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1590 HRESULT hr;
1592 TRACE("iface %p, clip_status %p.\n", iface, pClipStatus);
1594 wined3d_mutex_lock();
1595 hr = wined3d_device_set_clip_status(This->wined3d_device, (const WINED3DCLIPSTATUS *)pClipStatus);
1596 wined3d_mutex_unlock();
1598 return hr;
1601 static HRESULT WINAPI IDirect3DDevice9Impl_GetClipStatus(IDirect3DDevice9Ex *iface,
1602 D3DCLIPSTATUS9 *pClipStatus)
1604 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1605 HRESULT hr;
1607 TRACE("iface %p, clip_status %p.\n", iface, pClipStatus);
1609 wined3d_mutex_lock();
1610 hr = wined3d_device_get_clip_status(This->wined3d_device, (WINED3DCLIPSTATUS *)pClipStatus);
1611 wined3d_mutex_unlock();
1613 return hr;
1616 static HRESULT WINAPI IDirect3DDevice9Impl_GetTexture(IDirect3DDevice9Ex *iface, DWORD Stage,
1617 IDirect3DBaseTexture9 **ppTexture)
1619 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1620 struct wined3d_texture *wined3d_texture = NULL;
1621 HRESULT hr;
1623 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, ppTexture);
1625 if(ppTexture == NULL){
1626 return D3DERR_INVALIDCALL;
1629 wined3d_mutex_lock();
1630 hr = wined3d_device_get_texture(This->wined3d_device, Stage, &wined3d_texture);
1631 if (SUCCEEDED(hr) && wined3d_texture)
1633 *ppTexture = wined3d_texture_get_parent(wined3d_texture);
1634 IDirect3DBaseTexture9_AddRef(*ppTexture);
1635 wined3d_texture_decref(wined3d_texture);
1637 else
1639 if (FAILED(hr))
1641 WARN("Call to get texture (%u) failed (%p).\n", Stage, wined3d_texture);
1643 *ppTexture = NULL;
1645 wined3d_mutex_unlock();
1647 return hr;
1650 static HRESULT WINAPI IDirect3DDevice9Impl_SetTexture(IDirect3DDevice9Ex *iface, DWORD stage,
1651 IDirect3DBaseTexture9 *texture)
1653 IDirect3DDevice9Impl *device = impl_from_IDirect3DDevice9Ex(iface);
1654 HRESULT hr;
1656 TRACE("iface %p, stage %u, texture %p.\n", iface, stage, texture);
1658 wined3d_mutex_lock();
1659 hr = wined3d_device_set_texture(device->wined3d_device, stage,
1660 texture ? ((IDirect3DBaseTexture9Impl *)texture)->wined3d_texture : NULL);
1661 wined3d_mutex_unlock();
1663 return hr;
1666 static const WINED3DTEXTURESTAGESTATETYPE tss_lookup[] =
1668 WINED3DTSS_FORCE_DWORD, /* 0, unused */
1669 WINED3DTSS_COLOROP, /* 1, D3DTSS_COLOROP */
1670 WINED3DTSS_COLORARG1, /* 2, D3DTSS_COLORARG1 */
1671 WINED3DTSS_COLORARG2, /* 3, D3DTSS_COLORARG2 */
1672 WINED3DTSS_ALPHAOP, /* 4, D3DTSS_ALPHAOP */
1673 WINED3DTSS_ALPHAARG1, /* 5, D3DTSS_ALPHAARG1 */
1674 WINED3DTSS_ALPHAARG2, /* 6, D3DTSS_ALPHAARG2 */
1675 WINED3DTSS_BUMPENVMAT00, /* 7, D3DTSS_BUMPENVMAT00 */
1676 WINED3DTSS_BUMPENVMAT01, /* 8, D3DTSS_BUMPENVMAT01 */
1677 WINED3DTSS_BUMPENVMAT10, /* 9, D3DTSS_BUMPENVMAT10 */
1678 WINED3DTSS_BUMPENVMAT11, /* 10, D3DTSS_BUMPENVMAT11 */
1679 WINED3DTSS_TEXCOORDINDEX, /* 11, D3DTSS_TEXCOORDINDEX */
1680 WINED3DTSS_FORCE_DWORD, /* 12, unused */
1681 WINED3DTSS_FORCE_DWORD, /* 13, unused */
1682 WINED3DTSS_FORCE_DWORD, /* 14, unused */
1683 WINED3DTSS_FORCE_DWORD, /* 15, unused */
1684 WINED3DTSS_FORCE_DWORD, /* 16, unused */
1685 WINED3DTSS_FORCE_DWORD, /* 17, unused */
1686 WINED3DTSS_FORCE_DWORD, /* 18, unused */
1687 WINED3DTSS_FORCE_DWORD, /* 19, unused */
1688 WINED3DTSS_FORCE_DWORD, /* 20, unused */
1689 WINED3DTSS_FORCE_DWORD, /* 21, unused */
1690 WINED3DTSS_BUMPENVLSCALE, /* 22, D3DTSS_BUMPENVLSCALE */
1691 WINED3DTSS_BUMPENVLOFFSET, /* 23, D3DTSS_BUMPENVLOFFSET */
1692 WINED3DTSS_TEXTURETRANSFORMFLAGS, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
1693 WINED3DTSS_FORCE_DWORD, /* 25, unused */
1694 WINED3DTSS_COLORARG0, /* 26, D3DTSS_COLORARG0 */
1695 WINED3DTSS_ALPHAARG0, /* 27, D3DTSS_ALPHAARG0 */
1696 WINED3DTSS_RESULTARG, /* 28, D3DTSS_RESULTARG */
1697 WINED3DTSS_FORCE_DWORD, /* 29, unused */
1698 WINED3DTSS_FORCE_DWORD, /* 30, unused */
1699 WINED3DTSS_FORCE_DWORD, /* 31, unused */
1700 WINED3DTSS_CONSTANT, /* 32, D3DTSS_CONSTANT */
1703 static HRESULT WINAPI IDirect3DDevice9Impl_GetTextureStageState(IDirect3DDevice9Ex *iface,
1704 DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD *pValue)
1706 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1707 HRESULT hr;
1709 TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, Stage, Type, pValue);
1711 if (Type >= sizeof(tss_lookup) / sizeof(*tss_lookup))
1713 WARN("Invalid Type %#x passed.\n", Type);
1714 return D3D_OK;
1717 wined3d_mutex_lock();
1718 hr = wined3d_device_get_texture_stage_state(This->wined3d_device, Stage, tss_lookup[Type], pValue);
1719 wined3d_mutex_unlock();
1721 return hr;
1724 static HRESULT WINAPI IDirect3DDevice9Impl_SetTextureStageState(IDirect3DDevice9Ex *iface,
1725 DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value)
1727 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1728 HRESULT hr;
1730 TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, Stage, Type, Value);
1732 if (Type >= sizeof(tss_lookup) / sizeof(*tss_lookup))
1734 WARN("Invalid Type %#x passed.\n", Type);
1735 return D3D_OK;
1738 wined3d_mutex_lock();
1739 hr = wined3d_device_set_texture_stage_state(This->wined3d_device, Stage, tss_lookup[Type], Value);
1740 wined3d_mutex_unlock();
1742 return hr;
1745 static HRESULT WINAPI IDirect3DDevice9Impl_GetSamplerState(IDirect3DDevice9Ex *iface, DWORD Sampler,
1746 D3DSAMPLERSTATETYPE Type, DWORD *pValue)
1748 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1749 HRESULT hr;
1751 TRACE("iface %p, sampler %u, state %#x, value %p.\n", iface, Sampler, Type, pValue);
1753 wined3d_mutex_lock();
1754 hr = wined3d_device_get_sampler_state(This->wined3d_device, Sampler, Type, pValue);
1755 wined3d_mutex_unlock();
1757 return hr;
1760 static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_SetSamplerState(IDirect3DDevice9Ex *iface,
1761 DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
1763 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1764 HRESULT hr;
1766 TRACE("iface %p, sampler %u, state %#x, value %#x.\n", iface, Sampler, Type, Value);
1768 wined3d_mutex_lock();
1769 hr = wined3d_device_set_sampler_state(This->wined3d_device, Sampler, Type, Value);
1770 wined3d_mutex_unlock();
1772 return hr;
1775 static HRESULT WINAPI IDirect3DDevice9Impl_ValidateDevice(IDirect3DDevice9Ex *iface,
1776 DWORD *pNumPasses)
1778 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1779 HRESULT hr;
1781 TRACE("iface %p, pass_count %p.\n", iface, pNumPasses);
1783 wined3d_mutex_lock();
1784 hr = wined3d_device_validate_device(This->wined3d_device, pNumPasses);
1785 wined3d_mutex_unlock();
1787 return hr;
1790 static HRESULT WINAPI IDirect3DDevice9Impl_SetPaletteEntries(IDirect3DDevice9Ex *iface,
1791 UINT PaletteNumber, const PALETTEENTRY *pEntries)
1793 FIXME("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, PaletteNumber, pEntries);
1795 return D3DERR_INVALIDCALL;
1798 static HRESULT WINAPI IDirect3DDevice9Impl_GetPaletteEntries(IDirect3DDevice9Ex *iface,
1799 UINT PaletteNumber, PALETTEENTRY *pEntries)
1801 FIXME("iface %p, palette_idx %u, entries %p unimplemented.\n", iface, PaletteNumber, pEntries);
1803 return D3DERR_INVALIDCALL;
1806 static HRESULT WINAPI IDirect3DDevice9Impl_SetCurrentTexturePalette(IDirect3DDevice9Ex *iface,
1807 UINT PaletteNumber)
1809 FIXME("iface %p, palette_idx %u unimplemented.\n", iface, PaletteNumber);
1811 return D3DERR_INVALIDCALL;
1814 static HRESULT WINAPI IDirect3DDevice9Impl_GetCurrentTexturePalette(IDirect3DDevice9Ex *iface,
1815 UINT *PaletteNumber)
1817 FIXME("iface %p, palette_idx %p.\n", iface, PaletteNumber);
1819 return D3DERR_INVALIDCALL;
1822 static HRESULT WINAPI IDirect3DDevice9Impl_SetScissorRect(IDirect3DDevice9Ex *iface,
1823 const RECT *pRect)
1825 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1826 HRESULT hr;
1828 TRACE("iface %p, rect %p.\n", iface, pRect);
1830 wined3d_mutex_lock();
1831 hr = wined3d_device_set_scissor_rect(This->wined3d_device, pRect);
1832 wined3d_mutex_unlock();
1834 return hr;
1837 static HRESULT WINAPI IDirect3DDevice9Impl_GetScissorRect(IDirect3DDevice9Ex *iface, RECT *pRect)
1839 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1840 HRESULT hr;
1842 TRACE("iface %p, rect %p.\n", iface, pRect);
1844 wined3d_mutex_lock();
1845 hr = wined3d_device_get_scissor_rect(This->wined3d_device, pRect);
1846 wined3d_mutex_unlock();
1848 return hr;
1851 static HRESULT WINAPI IDirect3DDevice9Impl_SetSoftwareVertexProcessing(IDirect3DDevice9Ex *iface,
1852 BOOL bSoftware)
1854 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1855 HRESULT hr;
1857 TRACE("iface %p, software %#x.\n", iface, bSoftware);
1859 wined3d_mutex_lock();
1860 hr = wined3d_device_set_software_vertex_processing(This->wined3d_device, bSoftware);
1861 wined3d_mutex_unlock();
1863 return hr;
1866 static BOOL WINAPI IDirect3DDevice9Impl_GetSoftwareVertexProcessing(IDirect3DDevice9Ex *iface)
1868 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1869 BOOL ret;
1871 TRACE("iface %p.\n", iface);
1873 wined3d_mutex_lock();
1874 ret = wined3d_device_get_software_vertex_processing(This->wined3d_device);
1875 wined3d_mutex_unlock();
1877 return ret;
1880 static HRESULT WINAPI IDirect3DDevice9Impl_SetNPatchMode(IDirect3DDevice9Ex *iface, float nSegments)
1882 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1883 HRESULT hr;
1885 TRACE("iface %p, segment_count %.8e.\n", iface, nSegments);
1887 wined3d_mutex_lock();
1888 hr = wined3d_device_set_npatch_mode(This->wined3d_device, nSegments);
1889 wined3d_mutex_unlock();
1891 return hr;
1894 static float WINAPI IDirect3DDevice9Impl_GetNPatchMode(IDirect3DDevice9Ex *iface)
1896 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1897 float ret;
1899 TRACE("iface %p.\n", iface);
1901 wined3d_mutex_lock();
1902 ret = wined3d_device_get_npatch_mode(This->wined3d_device);
1903 wined3d_mutex_unlock();
1905 return ret;
1908 static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(IDirect3DDevice9Ex *iface,
1909 D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount)
1911 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1912 HRESULT hr;
1914 TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n",
1915 iface, PrimitiveType, StartVertex, PrimitiveCount);
1917 wined3d_mutex_lock();
1918 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
1919 hr = wined3d_device_draw_primitive(This->wined3d_device, StartVertex,
1920 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
1921 wined3d_mutex_unlock();
1923 return hr;
1926 static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitive(IDirect3DDevice9Ex *iface,
1927 D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices,
1928 UINT startIndex, UINT primCount)
1930 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1931 HRESULT hr;
1933 TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u,\n"
1934 "vertex_count %u, start_idx %u, primitive_count %u.\n",
1935 iface, PrimitiveType, BaseVertexIndex, MinVertexIndex,
1936 NumVertices, startIndex, primCount);
1938 wined3d_mutex_lock();
1939 wined3d_device_set_base_vertex_index(This->wined3d_device, BaseVertexIndex);
1940 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
1941 hr = wined3d_device_draw_indexed_primitive(This->wined3d_device, startIndex,
1942 vertex_count_from_primitive_count(PrimitiveType, primCount));
1943 wined3d_mutex_unlock();
1945 return hr;
1948 static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitiveUP(IDirect3DDevice9Ex *iface,
1949 D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, const void *pVertexStreamZeroData,
1950 UINT VertexStreamZeroStride)
1952 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1953 HRESULT hr;
1955 TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n",
1956 iface, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
1958 wined3d_mutex_lock();
1959 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
1960 hr = wined3d_device_draw_primitive_up(This->wined3d_device,
1961 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
1962 pVertexStreamZeroData, VertexStreamZeroStride);
1963 wined3d_mutex_unlock();
1965 return hr;
1968 static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(IDirect3DDevice9Ex *iface,
1969 D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertexIndices,
1970 UINT PrimitiveCount, const void *pIndexData, D3DFORMAT IndexDataFormat,
1971 const void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
1973 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1974 HRESULT hr;
1976 TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, index_count %u, primitive_count %u,\n"
1977 "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n",
1978 iface, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount,
1979 pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
1981 wined3d_mutex_lock();
1982 wined3d_device_set_primitive_type(This->wined3d_device, PrimitiveType);
1983 hr = wined3d_device_draw_indexed_primitive_up(This->wined3d_device,
1984 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
1985 wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
1986 wined3d_mutex_unlock();
1988 return hr;
1991 static HRESULT WINAPI IDirect3DDevice9Impl_ProcessVertices(IDirect3DDevice9Ex *iface,
1992 UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9 *pDestBuffer,
1993 IDirect3DVertexDeclaration9 *pVertexDecl, DWORD Flags)
1995 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
1996 IDirect3DVertexBuffer9Impl *dest = unsafe_impl_from_IDirect3DVertexBuffer9(pDestBuffer);
1997 IDirect3DVertexDeclaration9Impl *Decl = (IDirect3DVertexDeclaration9Impl *) pVertexDecl;
1998 HRESULT hr;
2000 TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, declaration %p, flags %#x.\n",
2001 iface, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags);
2003 wined3d_mutex_lock();
2004 hr = wined3d_device_process_vertices(This->wined3d_device, SrcStartIndex, DestIndex, VertexCount,
2005 dest->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags, dest->fvf);
2006 wined3d_mutex_unlock();
2008 return hr;
2011 static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(IDirect3DDevice9Ex *iface,
2012 const D3DVERTEXELEMENT9 *elements, IDirect3DVertexDeclaration9 **declaration)
2014 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2015 IDirect3DVertexDeclaration9Impl *object;
2016 HRESULT hr;
2018 TRACE("iface %p, elements %p, declaration %p.\n", iface, elements, declaration);
2020 if (!declaration)
2022 WARN("Caller passed a NULL declaration, returning D3DERR_INVALIDCALL.\n");
2023 return D3DERR_INVALIDCALL;
2026 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2027 if (!object)
2029 ERR("Failed to allocate vertex declaration memory.\n");
2030 return E_OUTOFMEMORY;
2033 hr = vertexdeclaration_init(object, This, elements);
2034 if (FAILED(hr))
2036 WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
2037 HeapFree(GetProcessHeap(), 0, object);
2038 return hr;
2041 TRACE("Created vertex declaration %p.\n", object);
2042 *declaration = (IDirect3DVertexDeclaration9 *)object;
2044 return D3D_OK;
2047 static HRESULT WINAPI IDirect3DDevice9Impl_SetVertexDeclaration(IDirect3DDevice9Ex *iface,
2048 IDirect3DVertexDeclaration9 *declaration)
2050 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2051 HRESULT hr;
2053 TRACE("iface %p, declaration %p.\n", iface, declaration);
2055 wined3d_mutex_lock();
2056 hr = wined3d_device_set_vertex_declaration(This->wined3d_device,
2057 declaration ? ((IDirect3DVertexDeclaration9Impl *)declaration)->wineD3DVertexDeclaration : NULL);
2058 wined3d_mutex_unlock();
2060 return hr;
2063 static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexDeclaration(IDirect3DDevice9Ex *iface,
2064 IDirect3DVertexDeclaration9 **declaration)
2066 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2067 struct wined3d_vertex_declaration *wined3d_declaration = NULL;
2068 HRESULT hr;
2070 TRACE("iface %p, declaration %p.\n", iface, declaration);
2072 if (!declaration) return D3DERR_INVALIDCALL;
2074 wined3d_mutex_lock();
2075 hr = wined3d_device_get_vertex_declaration(This->wined3d_device, &wined3d_declaration);
2076 if (SUCCEEDED(hr) && wined3d_declaration)
2078 *declaration = wined3d_vertex_declaration_get_parent(wined3d_declaration);
2079 IDirect3DVertexDeclaration9_AddRef(*declaration);
2080 wined3d_vertex_declaration_decref(wined3d_declaration);
2082 else
2084 *declaration = NULL;
2086 wined3d_mutex_unlock();
2088 TRACE("Returning %p.\n", *declaration);
2089 return hr;
2092 static IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, DWORD fvf) {
2093 HRESULT hr;
2094 D3DVERTEXELEMENT9* elements = NULL;
2095 IDirect3DVertexDeclaration9* pDecl = NULL;
2096 int p, low, high; /* deliberately signed */
2097 IDirect3DVertexDeclaration9 **convertedDecls = This->convertedDecls;
2099 TRACE("Searching for declaration for fvf %08x... ", fvf);
2101 low = 0;
2102 high = This->numConvertedDecls - 1;
2103 while(low <= high) {
2104 p = (low + high) >> 1;
2105 TRACE("%d ", p);
2106 if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF == fvf) {
2107 TRACE("found %p\n", convertedDecls[p]);
2108 return convertedDecls[p];
2109 } else if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF < fvf) {
2110 low = p + 1;
2111 } else {
2112 high = p - 1;
2115 TRACE("not found. Creating and inserting at position %d.\n", low);
2117 hr = vdecl_convert_fvf(fvf, &elements);
2118 if (hr != S_OK) return NULL;
2120 hr = IDirect3DDevice9Impl_CreateVertexDeclaration(&This->IDirect3DDevice9Ex_iface, elements,
2121 &pDecl);
2122 HeapFree(GetProcessHeap(), 0, elements); /* CreateVertexDeclaration makes a copy */
2123 if (hr != S_OK) return NULL;
2125 if(This->declArraySize == This->numConvertedDecls) {
2126 int grow = max(This->declArraySize / 2, 8);
2127 convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
2128 sizeof(convertedDecls[0]) * (This->numConvertedDecls + grow));
2129 if(!convertedDecls) {
2130 /* This will destroy it */
2131 IDirect3DVertexDeclaration9_Release(pDecl);
2132 return NULL;
2134 This->convertedDecls = convertedDecls;
2135 This->declArraySize += grow;
2138 memmove(convertedDecls + low + 1, convertedDecls + low, sizeof(IDirect3DVertexDeclaration9Impl *) * (This->numConvertedDecls - low));
2139 convertedDecls[low] = pDecl;
2140 This->numConvertedDecls++;
2142 /* Will prevent the decl from being destroyed */
2143 ((IDirect3DVertexDeclaration9Impl *) pDecl)->convFVF = fvf;
2144 IDirect3DVertexDeclaration9_Release(pDecl); /* Does not destroy now */
2146 TRACE("Returning %p. %d decls in array\n", pDecl, This->numConvertedDecls);
2147 return pDecl;
2150 static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(IDirect3DDevice9Ex *iface, DWORD FVF)
2152 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2153 IDirect3DVertexDeclaration9 *decl;
2154 HRESULT hr;
2156 TRACE("iface %p, fvf %#x.\n", iface, FVF);
2158 if (!FVF)
2160 WARN("%#x is not a valid FVF\n", FVF);
2161 return D3D_OK;
2164 wined3d_mutex_lock();
2165 decl = getConvertedDecl(This, FVF);
2166 wined3d_mutex_unlock();
2168 if (!decl)
2170 /* Any situation when this should happen, except out of memory? */
2171 ERR("Failed to create a converted vertex declaration\n");
2172 return D3DERR_DRIVERINTERNALERROR;
2175 hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, decl);
2176 if (FAILED(hr)) ERR("Failed to set vertex declaration\n");
2178 return hr;
2181 static HRESULT WINAPI IDirect3DDevice9Impl_GetFVF(IDirect3DDevice9Ex *iface, DWORD *pFVF)
2183 IDirect3DVertexDeclaration9 *decl;
2184 HRESULT hr;
2186 TRACE("iface %p, fvf %p.\n", iface, pFVF);
2188 hr = IDirect3DDevice9_GetVertexDeclaration(iface, &decl);
2189 if (FAILED(hr))
2191 WARN("Failed to get vertex declaration, %#x\n", hr);
2192 *pFVF = 0;
2193 return hr;
2196 if (decl)
2198 *pFVF = ((IDirect3DVertexDeclaration9Impl *)decl)->convFVF;
2199 IDirect3DVertexDeclaration9_Release(decl);
2201 else
2203 *pFVF = 0;
2206 TRACE("Returning FVF %#x\n", *pFVF);
2208 return hr;
2211 static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexShader(IDirect3DDevice9Ex *iface,
2212 const DWORD *byte_code, IDirect3DVertexShader9 **shader)
2214 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2215 IDirect3DVertexShader9Impl *object;
2216 HRESULT hr;
2218 TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
2220 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2221 if (!object)
2223 ERR("Failed to allocate vertex shader memory.\n");
2224 return E_OUTOFMEMORY;
2227 hr = vertexshader_init(object, This, byte_code);
2228 if (FAILED(hr))
2230 WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
2231 HeapFree(GetProcessHeap(), 0, object);
2232 return hr;
2235 TRACE("Created vertex shader %p.\n", object);
2236 *shader = &object->IDirect3DVertexShader9_iface;
2238 return D3D_OK;
2241 static HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShader(IDirect3DDevice9Ex *iface,
2242 IDirect3DVertexShader9 *shader)
2244 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2245 IDirect3DVertexShader9Impl *shader_obj = unsafe_impl_from_IDirect3DVertexShader9(shader);
2246 HRESULT hr;
2248 TRACE("iface %p, shader %p.\n", iface, shader);
2250 wined3d_mutex_lock();
2251 hr = wined3d_device_set_vertex_shader(This->wined3d_device,
2252 shader_obj ? shader_obj->wined3d_shader : NULL);
2253 wined3d_mutex_unlock();
2255 return hr;
2258 static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShader(IDirect3DDevice9Ex *iface,
2259 IDirect3DVertexShader9 **shader)
2261 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2262 struct wined3d_shader *wined3d_shader;
2264 TRACE("iface %p, shader %p.\n", iface, shader);
2266 wined3d_mutex_lock();
2267 wined3d_shader = wined3d_device_get_vertex_shader(This->wined3d_device);
2268 if (wined3d_shader)
2270 *shader = wined3d_shader_get_parent(wined3d_shader);
2271 IDirect3DVertexShader9_AddRef(*shader);
2272 wined3d_shader_decref(wined3d_shader);
2274 else
2276 *shader = NULL;
2278 wined3d_mutex_unlock();
2280 TRACE("Returning %p.\n", *shader);
2282 return D3D_OK;
2285 static HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantF(IDirect3DDevice9Ex *iface,
2286 UINT reg_idx, const float *data, UINT count)
2288 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2289 HRESULT hr;
2291 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2293 if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF)
2295 WARN("Trying to access %u constants, but d3d9 only supports %u\n",
2296 reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
2297 return D3DERR_INVALIDCALL;
2300 wined3d_mutex_lock();
2301 hr = wined3d_device_set_vs_consts_f(This->wined3d_device, reg_idx, data, count);
2302 wined3d_mutex_unlock();
2304 return hr;
2307 static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantF(IDirect3DDevice9Ex *iface,
2308 UINT reg_idx, float *data, UINT count)
2310 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2311 HRESULT hr;
2313 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2315 if (reg_idx + count > D3D9_MAX_VERTEX_SHADER_CONSTANTF)
2317 WARN("Trying to access %u constants, but d3d9 only supports %u\n",
2318 reg_idx + count, D3D9_MAX_VERTEX_SHADER_CONSTANTF);
2319 return D3DERR_INVALIDCALL;
2322 wined3d_mutex_lock();
2323 hr = wined3d_device_get_vs_consts_f(This->wined3d_device, reg_idx, data, count);
2324 wined3d_mutex_unlock();
2326 return hr;
2329 static HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantI(IDirect3DDevice9Ex *iface,
2330 UINT reg_idx, const int *data, UINT count)
2332 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2333 HRESULT hr;
2335 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2337 wined3d_mutex_lock();
2338 hr = wined3d_device_set_vs_consts_i(This->wined3d_device, reg_idx, data, count);
2339 wined3d_mutex_unlock();
2341 return hr;
2344 static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantI(IDirect3DDevice9Ex *iface,
2345 UINT reg_idx, int *data, UINT count)
2347 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2348 HRESULT hr;
2350 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2352 wined3d_mutex_lock();
2353 hr = wined3d_device_get_vs_consts_i(This->wined3d_device, reg_idx, data, count);
2354 wined3d_mutex_unlock();
2356 return hr;
2359 static HRESULT WINAPI IDirect3DDevice9Impl_SetVertexShaderConstantB(IDirect3DDevice9Ex *iface,
2360 UINT reg_idx, const BOOL *data, UINT count)
2362 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2363 HRESULT hr;
2365 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2367 wined3d_mutex_lock();
2368 hr = wined3d_device_set_vs_consts_b(This->wined3d_device, reg_idx, data, count);
2369 wined3d_mutex_unlock();
2371 return hr;
2374 static HRESULT WINAPI IDirect3DDevice9Impl_GetVertexShaderConstantB(IDirect3DDevice9Ex *iface,
2375 UINT reg_idx, BOOL *data, UINT count)
2377 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2378 HRESULT hr;
2380 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2382 wined3d_mutex_lock();
2383 hr = wined3d_device_get_vs_consts_b(This->wined3d_device, reg_idx, data, count);
2384 wined3d_mutex_unlock();
2386 return hr;
2389 static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSource(IDirect3DDevice9Ex *iface,
2390 UINT StreamNumber, IDirect3DVertexBuffer9 *pStreamData, UINT OffsetInBytes, UINT Stride)
2392 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2393 IDirect3DVertexBuffer9Impl *streamdata = unsafe_impl_from_IDirect3DVertexBuffer9(pStreamData);
2394 HRESULT hr;
2396 TRACE("iface %p, stream_idx %u, buffer %p, offset %u, stride %u.\n",
2397 iface, StreamNumber, pStreamData, OffsetInBytes, Stride);
2399 wined3d_mutex_lock();
2400 hr = wined3d_device_set_stream_source(This->wined3d_device, StreamNumber,
2401 streamdata ? streamdata->wineD3DVertexBuffer : NULL,
2402 OffsetInBytes, Stride);
2403 wined3d_mutex_unlock();
2405 return hr;
2408 static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(IDirect3DDevice9Ex *iface,
2409 UINT StreamNumber, IDirect3DVertexBuffer9 **pStream, UINT *OffsetInBytes, UINT *pStride)
2411 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2412 struct wined3d_buffer *retStream = NULL;
2413 HRESULT hr;
2415 TRACE("iface %p, stream_idx %u, buffer %p, offset %p, stride %p.\n",
2416 iface, StreamNumber, pStream, OffsetInBytes, pStride);
2418 if(pStream == NULL){
2419 return D3DERR_INVALIDCALL;
2422 wined3d_mutex_lock();
2423 hr = wined3d_device_get_stream_source(This->wined3d_device, StreamNumber, &retStream, OffsetInBytes, pStride);
2424 if (SUCCEEDED(hr) && retStream)
2426 *pStream = wined3d_buffer_get_parent(retStream);
2427 IDirect3DVertexBuffer9_AddRef(*pStream);
2428 wined3d_buffer_decref(retStream);
2430 else
2432 if (FAILED(hr))
2434 FIXME("Call to GetStreamSource failed %p %p\n", OffsetInBytes, pStride);
2436 *pStream = NULL;
2438 wined3d_mutex_unlock();
2440 return hr;
2443 static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSourceFreq(IDirect3DDevice9Ex *iface,
2444 UINT StreamNumber, UINT Divider)
2446 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2447 HRESULT hr;
2449 TRACE("iface %p, stream_idx %u, freq %u.\n", iface, StreamNumber, Divider);
2451 wined3d_mutex_lock();
2452 hr = wined3d_device_set_stream_source_freq(This->wined3d_device, StreamNumber, Divider);
2453 wined3d_mutex_unlock();
2455 return hr;
2458 static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSourceFreq(IDirect3DDevice9Ex *iface,
2459 UINT StreamNumber, UINT *Divider)
2461 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2462 HRESULT hr;
2464 TRACE("iface %p, stream_idx %u, freq %p.\n", iface, StreamNumber, Divider);
2466 wined3d_mutex_lock();
2467 hr = wined3d_device_get_stream_source_freq(This->wined3d_device, StreamNumber, Divider);
2468 wined3d_mutex_unlock();
2470 return hr;
2473 static HRESULT WINAPI IDirect3DDevice9Impl_SetIndices(IDirect3DDevice9Ex *iface,
2474 IDirect3DIndexBuffer9 *pIndexData)
2476 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2477 IDirect3DIndexBuffer9Impl *ib = unsafe_impl_from_IDirect3DIndexBuffer9(pIndexData);
2478 HRESULT hr;
2480 TRACE("iface %p, buffer %p.\n", iface, pIndexData);
2482 wined3d_mutex_lock();
2483 hr = wined3d_device_set_index_buffer(This->wined3d_device,
2484 ib ? ib->wineD3DIndexBuffer : NULL,
2485 ib ? ib->format : WINED3DFMT_UNKNOWN);
2486 wined3d_mutex_unlock();
2488 return hr;
2491 static HRESULT WINAPI IDirect3DDevice9Impl_GetIndices(IDirect3DDevice9Ex *iface,
2492 IDirect3DIndexBuffer9 **ppIndexData)
2494 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2495 struct wined3d_buffer *retIndexData = NULL;
2496 HRESULT hr;
2498 TRACE("iface %p, buffer %p.\n", iface, ppIndexData);
2500 if(ppIndexData == NULL){
2501 return D3DERR_INVALIDCALL;
2504 wined3d_mutex_lock();
2505 hr = wined3d_device_get_index_buffer(This->wined3d_device, &retIndexData);
2506 if (SUCCEEDED(hr) && retIndexData)
2508 *ppIndexData = wined3d_buffer_get_parent(retIndexData);
2509 IDirect3DIndexBuffer9_AddRef(*ppIndexData);
2510 wined3d_buffer_decref(retIndexData);
2512 else
2514 if (FAILED(hr)) FIXME("Call to GetIndices failed\n");
2515 *ppIndexData = NULL;
2517 wined3d_mutex_unlock();
2519 return hr;
2522 static HRESULT WINAPI IDirect3DDevice9Impl_CreatePixelShader(IDirect3DDevice9Ex *iface,
2523 const DWORD *byte_code, IDirect3DPixelShader9 **shader)
2525 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2526 IDirect3DPixelShader9Impl *object;
2527 HRESULT hr;
2529 TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
2531 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2532 if (!object)
2534 FIXME("Failed to allocate pixel shader memory.\n");
2535 return E_OUTOFMEMORY;
2538 hr = pixelshader_init(object, This, byte_code);
2539 if (FAILED(hr))
2541 WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
2542 HeapFree(GetProcessHeap(), 0, object);
2543 return hr;
2546 TRACE("Created pixel shader %p.\n", object);
2547 *shader = &object->IDirect3DPixelShader9_iface;
2549 return D3D_OK;
2552 static HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShader(IDirect3DDevice9Ex *iface,
2553 IDirect3DPixelShader9 *shader)
2555 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2556 IDirect3DPixelShader9Impl *shader_obj = unsafe_impl_from_IDirect3DPixelShader9(shader);
2557 HRESULT hr;
2559 TRACE("iface %p, shader %p.\n", iface, shader);
2561 wined3d_mutex_lock();
2562 hr = wined3d_device_set_pixel_shader(This->wined3d_device,
2563 shader_obj ? shader_obj->wined3d_shader : NULL);
2564 wined3d_mutex_unlock();
2566 return hr;
2569 static HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShader(IDirect3DDevice9Ex *iface,
2570 IDirect3DPixelShader9 **shader)
2572 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2573 struct wined3d_shader *wined3d_shader;
2575 TRACE("iface %p, shader %p.\n", iface, shader);
2577 if (!shader) return D3DERR_INVALIDCALL;
2579 wined3d_mutex_lock();
2580 wined3d_shader = wined3d_device_get_pixel_shader(This->wined3d_device);
2581 if (wined3d_shader)
2583 *shader = wined3d_shader_get_parent(wined3d_shader);
2584 IDirect3DPixelShader9_AddRef(*shader);
2585 wined3d_shader_decref(wined3d_shader);
2587 else
2589 *shader = NULL;
2591 wined3d_mutex_unlock();
2593 TRACE("Returning %p.\n", *shader);
2595 return D3D_OK;
2598 static HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantF(IDirect3DDevice9Ex *iface,
2599 UINT reg_idx, const float *data, UINT count)
2601 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2602 HRESULT hr;
2604 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2606 wined3d_mutex_lock();
2607 hr = wined3d_device_set_ps_consts_f(This->wined3d_device, reg_idx, data, count);
2608 wined3d_mutex_unlock();
2610 return hr;
2613 static HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantF(IDirect3DDevice9Ex *iface,
2614 UINT reg_idx, float *data, UINT count)
2616 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2617 HRESULT hr;
2619 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2621 wined3d_mutex_lock();
2622 hr = wined3d_device_get_ps_consts_f(This->wined3d_device, reg_idx, data, count);
2623 wined3d_mutex_unlock();
2625 return hr;
2628 static HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantI(IDirect3DDevice9Ex *iface,
2629 UINT reg_idx, const int *data, UINT count)
2631 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2632 HRESULT hr;
2634 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2636 wined3d_mutex_lock();
2637 hr = wined3d_device_set_ps_consts_i(This->wined3d_device, reg_idx, data, count);
2638 wined3d_mutex_unlock();
2640 return hr;
2643 static HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantI(IDirect3DDevice9Ex *iface,
2644 UINT reg_idx, int *data, UINT count)
2646 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2647 HRESULT hr;
2649 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2651 wined3d_mutex_lock();
2652 hr = wined3d_device_get_ps_consts_i(This->wined3d_device, reg_idx, data, count);
2653 wined3d_mutex_unlock();
2655 return hr;
2658 static HRESULT WINAPI IDirect3DDevice9Impl_SetPixelShaderConstantB(IDirect3DDevice9Ex *iface,
2659 UINT reg_idx, const BOOL *data, UINT count)
2661 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2662 HRESULT hr;
2664 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2666 wined3d_mutex_lock();
2667 hr = wined3d_device_set_ps_consts_b(This->wined3d_device, reg_idx, data, count);
2668 wined3d_mutex_unlock();
2670 return hr;
2673 static HRESULT WINAPI IDirect3DDevice9Impl_GetPixelShaderConstantB(IDirect3DDevice9Ex *iface,
2674 UINT reg_idx, BOOL *data, UINT count)
2676 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2677 HRESULT hr;
2679 TRACE("iface %p, reg_idx %u, data %p, count %u.\n", iface, reg_idx, data, count);
2681 wined3d_mutex_lock();
2682 hr = wined3d_device_get_ps_consts_b(This->wined3d_device, reg_idx, data, count);
2683 wined3d_mutex_unlock();
2685 return hr;
2688 static HRESULT WINAPI IDirect3DDevice9Impl_DrawRectPatch(IDirect3DDevice9Ex *iface, UINT Handle,
2689 const float *pNumSegs, const D3DRECTPATCH_INFO *pRectPatchInfo)
2691 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2692 HRESULT hr;
2694 TRACE("iface %p, handle %#x, segment_count %p, patch_info %p.\n",
2695 iface, Handle, pNumSegs, pRectPatchInfo);
2697 wined3d_mutex_lock();
2698 hr = wined3d_device_draw_rect_patch(This->wined3d_device, Handle,
2699 pNumSegs, (const WINED3DRECTPATCH_INFO *)pRectPatchInfo);
2700 wined3d_mutex_unlock();
2702 return hr;
2705 static HRESULT WINAPI IDirect3DDevice9Impl_DrawTriPatch(IDirect3DDevice9Ex *iface, UINT Handle,
2706 const float *pNumSegs, const D3DTRIPATCH_INFO *pTriPatchInfo)
2708 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2709 HRESULT hr;
2711 TRACE("iface %p, handle %#x, segment_count %p, patch_info %p.\n",
2712 iface, Handle, pNumSegs, pTriPatchInfo);
2714 wined3d_mutex_lock();
2715 hr = wined3d_device_draw_tri_patch(This->wined3d_device, Handle,
2716 pNumSegs, (const WINED3DTRIPATCH_INFO *)pTriPatchInfo);
2717 wined3d_mutex_unlock();
2719 return hr;
2722 static HRESULT WINAPI IDirect3DDevice9Impl_DeletePatch(IDirect3DDevice9Ex *iface, UINT Handle)
2724 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2725 HRESULT hr;
2727 TRACE("iface %p, handle %#x.\n", iface, Handle);
2729 wined3d_mutex_lock();
2730 hr = wined3d_device_delete_patch(This->wined3d_device, Handle);
2731 wined3d_mutex_unlock();
2733 return hr;
2736 static HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(IDirect3DDevice9Ex *iface, D3DQUERYTYPE type,
2737 IDirect3DQuery9 **query)
2739 IDirect3DDevice9Impl *This = impl_from_IDirect3DDevice9Ex(iface);
2740 IDirect3DQuery9Impl *object;
2741 HRESULT hr;
2743 TRACE("iface %p, type %#x, query %p.\n", iface, type, query);
2745 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2746 if (!object)
2748 ERR("Failed to allocate query memory.\n");
2749 return E_OUTOFMEMORY;
2752 hr = query_init(object, This, type);
2753 if (FAILED(hr))
2755 WARN("Failed to initialize query, hr %#x.\n", hr);
2756 HeapFree(GetProcessHeap(), 0, object);
2757 return hr;
2760 TRACE("Created query %p.\n", object);
2761 if (query) *query = &object->IDirect3DQuery9_iface;
2762 else IDirect3DQuery9_Release(&object->IDirect3DQuery9_iface);
2764 return D3D_OK;
2767 static HRESULT WINAPI IDirect3DDevice9ExImpl_SetConvolutionMonoKernel(IDirect3DDevice9Ex *iface,
2768 UINT width, UINT height, float *rows, float *columns)
2770 FIXME("iface %p, width %u, height %u, rows %p, columns %p stub!\n",
2771 iface, width, height, rows, columns);
2773 return E_NOTIMPL;
2776 static HRESULT WINAPI IDirect3DDevice9ExImpl_ComposeRects(IDirect3DDevice9Ex *iface,
2777 IDirect3DSurface9 *src_surface, IDirect3DSurface9 *dst_surface, IDirect3DVertexBuffer9 *src_descs,
2778 UINT rect_count, IDirect3DVertexBuffer9 *dst_descs, D3DCOMPOSERECTSOP operation, INT offset_x, INT offset_y)
2780 FIXME("iface %p, src_surface %p, dst_surface %p, src_descs %p, rect_count %u,\n"
2781 "dst_descs %p, operation %#x, offset_x %u, offset_y %u stub!\n",
2782 iface, src_surface, dst_surface, src_descs, rect_count,
2783 dst_descs, operation, offset_x, offset_y);
2785 return E_NOTIMPL;
2788 static HRESULT WINAPI IDirect3DDevice9ExImpl_PresentEx(IDirect3DDevice9Ex *iface,
2789 const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
2790 const RGNDATA *dirty_region, DWORD flags)
2792 FIXME("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p, flags %#x stub!\n",
2793 iface, src_rect, dst_rect, dst_window_override, dirty_region, flags);
2795 return E_NOTIMPL;
2798 static HRESULT WINAPI IDirect3DDevice9ExImpl_GetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT *priority)
2800 FIXME("iface %p, priority %p stub!\n", iface, priority);
2802 return E_NOTIMPL;
2805 static HRESULT WINAPI IDirect3DDevice9ExImpl_SetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT priority)
2807 FIXME("iface %p, priority %d stub!\n", iface, priority);
2809 return E_NOTIMPL;
2812 static HRESULT WINAPI IDirect3DDevice9ExImpl_WaitForVBlank(IDirect3DDevice9Ex *iface, UINT swapchain_idx)
2814 FIXME("iface %p, swapchain_idx %u stub!\n", iface, swapchain_idx);
2816 return E_NOTIMPL;
2819 static HRESULT WINAPI IDirect3DDevice9ExImpl_CheckResourceResidency(IDirect3DDevice9Ex *iface,
2820 IDirect3DResource9 **resources, UINT32 resource_count)
2822 FIXME("iface %p, resources %p, resource_count %u stub!\n",
2823 iface, resources, resource_count);
2825 return E_NOTIMPL;
2828 static HRESULT WINAPI IDirect3DDevice9ExImpl_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT max_latency)
2830 FIXME("iface %p, max_latency %u stub!\n", iface, max_latency);
2832 return E_NOTIMPL;
2835 static HRESULT WINAPI IDirect3DDevice9ExImpl_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT *max_latency)
2837 FIXME("iface %p, max_latency %p stub!\n", iface, max_latency);
2839 *max_latency = 2;
2841 return E_NOTIMPL;
2844 static HRESULT WINAPI IDirect3DDevice9ExImpl_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND dst_window)
2846 static int i;
2848 TRACE("iface %p, dst_window %p stub!\n", iface, dst_window);
2850 if (!i++)
2851 FIXME("iface %p, dst_window %p stub!\n", iface, dst_window);
2853 return D3D_OK;
2856 static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateRenderTargetEx(IDirect3DDevice9Ex *iface,
2857 UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
2858 BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage)
2860 FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n"
2861 "lockable %#x, surface %p, shared_handle %p, usage %#x stub!\n",
2862 iface, width, height, format, multisample_type, multisample_quality,
2863 lockable, surface, shared_handle, usage);
2865 return E_NOTIMPL;
2868 static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateOffscreenPlainSurfaceEx(IDirect3DDevice9Ex *iface,
2869 UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface,
2870 HANDLE *shared_handle, DWORD usage)
2872 FIXME("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p, usage %#x stub!\n",
2873 iface, width, height, format, pool, surface, shared_handle, usage);
2875 return E_NOTIMPL;
2878 static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateDepthStencilSurfaceEx(IDirect3DDevice9Ex *iface,
2879 UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
2880 BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage)
2882 FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n"
2883 "discard %#x, surface %p, shared_handle %p, usage %#x stub!\n",
2884 iface, width, height, format, multisample_type, multisample_quality,
2885 discard, surface, shared_handle, usage);
2887 return E_NOTIMPL;
2890 static HRESULT WINAPI IDirect3DDevice9ExImpl_ResetEx(IDirect3DDevice9Ex *iface,
2891 D3DPRESENT_PARAMETERS *present_parameters, D3DDISPLAYMODEEX *mode)
2893 FIXME("iface %p, present_parameters %p, mode %p stub!\n", iface, present_parameters, mode);
2895 return E_NOTIMPL;
2898 static HRESULT WINAPI IDirect3DDevice9ExImpl_GetDisplayModeEx(IDirect3DDevice9Ex *iface,
2899 UINT swapchain_idx, D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation)
2901 FIXME("iface %p, swapchain_idx %u, mode %p, rotation %p stub!\n", iface, swapchain_idx, mode, rotation);
2903 return E_NOTIMPL;
2906 static const IDirect3DDevice9ExVtbl Direct3DDevice9_Vtbl =
2908 /* IUnknown */
2909 IDirect3DDevice9Impl_QueryInterface,
2910 IDirect3DDevice9Impl_AddRef,
2911 IDirect3DDevice9Impl_Release,
2912 /* IDirect3DDevice9 */
2913 IDirect3DDevice9Impl_TestCooperativeLevel,
2914 IDirect3DDevice9Impl_GetAvailableTextureMem,
2915 IDirect3DDevice9Impl_EvictManagedResources,
2916 IDirect3DDevice9Impl_GetDirect3D,
2917 IDirect3DDevice9Impl_GetDeviceCaps,
2918 IDirect3DDevice9Impl_GetDisplayMode,
2919 IDirect3DDevice9Impl_GetCreationParameters,
2920 IDirect3DDevice9Impl_SetCursorProperties,
2921 IDirect3DDevice9Impl_SetCursorPosition,
2922 IDirect3DDevice9Impl_ShowCursor,
2923 IDirect3DDevice9Impl_CreateAdditionalSwapChain,
2924 IDirect3DDevice9Impl_GetSwapChain,
2925 IDirect3DDevice9Impl_GetNumberOfSwapChains,
2926 IDirect3DDevice9Impl_Reset,
2927 IDirect3DDevice9Impl_Present,
2928 IDirect3DDevice9Impl_GetBackBuffer,
2929 IDirect3DDevice9Impl_GetRasterStatus,
2930 IDirect3DDevice9Impl_SetDialogBoxMode,
2931 IDirect3DDevice9Impl_SetGammaRamp,
2932 IDirect3DDevice9Impl_GetGammaRamp,
2933 IDirect3DDevice9Impl_CreateTexture,
2934 IDirect3DDevice9Impl_CreateVolumeTexture,
2935 IDirect3DDevice9Impl_CreateCubeTexture,
2936 IDirect3DDevice9Impl_CreateVertexBuffer,
2937 IDirect3DDevice9Impl_CreateIndexBuffer,
2938 IDirect3DDevice9Impl_CreateRenderTarget,
2939 IDirect3DDevice9Impl_CreateDepthStencilSurface,
2940 IDirect3DDevice9Impl_UpdateSurface,
2941 IDirect3DDevice9Impl_UpdateTexture,
2942 IDirect3DDevice9Impl_GetRenderTargetData,
2943 IDirect3DDevice9Impl_GetFrontBufferData,
2944 IDirect3DDevice9Impl_StretchRect,
2945 IDirect3DDevice9Impl_ColorFill,
2946 IDirect3DDevice9Impl_CreateOffscreenPlainSurface,
2947 IDirect3DDevice9Impl_SetRenderTarget,
2948 IDirect3DDevice9Impl_GetRenderTarget,
2949 IDirect3DDevice9Impl_SetDepthStencilSurface,
2950 IDirect3DDevice9Impl_GetDepthStencilSurface,
2951 IDirect3DDevice9Impl_BeginScene,
2952 IDirect3DDevice9Impl_EndScene,
2953 IDirect3DDevice9Impl_Clear,
2954 IDirect3DDevice9Impl_SetTransform,
2955 IDirect3DDevice9Impl_GetTransform,
2956 IDirect3DDevice9Impl_MultiplyTransform,
2957 IDirect3DDevice9Impl_SetViewport,
2958 IDirect3DDevice9Impl_GetViewport,
2959 IDirect3DDevice9Impl_SetMaterial,
2960 IDirect3DDevice9Impl_GetMaterial,
2961 IDirect3DDevice9Impl_SetLight,
2962 IDirect3DDevice9Impl_GetLight,
2963 IDirect3DDevice9Impl_LightEnable,
2964 IDirect3DDevice9Impl_GetLightEnable,
2965 IDirect3DDevice9Impl_SetClipPlane,
2966 IDirect3DDevice9Impl_GetClipPlane,
2967 IDirect3DDevice9Impl_SetRenderState,
2968 IDirect3DDevice9Impl_GetRenderState,
2969 IDirect3DDevice9Impl_CreateStateBlock,
2970 IDirect3DDevice9Impl_BeginStateBlock,
2971 IDirect3DDevice9Impl_EndStateBlock,
2972 IDirect3DDevice9Impl_SetClipStatus,
2973 IDirect3DDevice9Impl_GetClipStatus,
2974 IDirect3DDevice9Impl_GetTexture,
2975 IDirect3DDevice9Impl_SetTexture,
2976 IDirect3DDevice9Impl_GetTextureStageState,
2977 IDirect3DDevice9Impl_SetTextureStageState,
2978 IDirect3DDevice9Impl_GetSamplerState,
2979 IDirect3DDevice9Impl_SetSamplerState,
2980 IDirect3DDevice9Impl_ValidateDevice,
2981 IDirect3DDevice9Impl_SetPaletteEntries,
2982 IDirect3DDevice9Impl_GetPaletteEntries,
2983 IDirect3DDevice9Impl_SetCurrentTexturePalette,
2984 IDirect3DDevice9Impl_GetCurrentTexturePalette,
2985 IDirect3DDevice9Impl_SetScissorRect,
2986 IDirect3DDevice9Impl_GetScissorRect,
2987 IDirect3DDevice9Impl_SetSoftwareVertexProcessing,
2988 IDirect3DDevice9Impl_GetSoftwareVertexProcessing,
2989 IDirect3DDevice9Impl_SetNPatchMode,
2990 IDirect3DDevice9Impl_GetNPatchMode,
2991 IDirect3DDevice9Impl_DrawPrimitive,
2992 IDirect3DDevice9Impl_DrawIndexedPrimitive,
2993 IDirect3DDevice9Impl_DrawPrimitiveUP,
2994 IDirect3DDevice9Impl_DrawIndexedPrimitiveUP,
2995 IDirect3DDevice9Impl_ProcessVertices,
2996 IDirect3DDevice9Impl_CreateVertexDeclaration,
2997 IDirect3DDevice9Impl_SetVertexDeclaration,
2998 IDirect3DDevice9Impl_GetVertexDeclaration,
2999 IDirect3DDevice9Impl_SetFVF,
3000 IDirect3DDevice9Impl_GetFVF,
3001 IDirect3DDevice9Impl_CreateVertexShader,
3002 IDirect3DDevice9Impl_SetVertexShader,
3003 IDirect3DDevice9Impl_GetVertexShader,
3004 IDirect3DDevice9Impl_SetVertexShaderConstantF,
3005 IDirect3DDevice9Impl_GetVertexShaderConstantF,
3006 IDirect3DDevice9Impl_SetVertexShaderConstantI,
3007 IDirect3DDevice9Impl_GetVertexShaderConstantI,
3008 IDirect3DDevice9Impl_SetVertexShaderConstantB,
3009 IDirect3DDevice9Impl_GetVertexShaderConstantB,
3010 IDirect3DDevice9Impl_SetStreamSource,
3011 IDirect3DDevice9Impl_GetStreamSource,
3012 IDirect3DDevice9Impl_SetStreamSourceFreq,
3013 IDirect3DDevice9Impl_GetStreamSourceFreq,
3014 IDirect3DDevice9Impl_SetIndices,
3015 IDirect3DDevice9Impl_GetIndices,
3016 IDirect3DDevice9Impl_CreatePixelShader,
3017 IDirect3DDevice9Impl_SetPixelShader,
3018 IDirect3DDevice9Impl_GetPixelShader,
3019 IDirect3DDevice9Impl_SetPixelShaderConstantF,
3020 IDirect3DDevice9Impl_GetPixelShaderConstantF,
3021 IDirect3DDevice9Impl_SetPixelShaderConstantI,
3022 IDirect3DDevice9Impl_GetPixelShaderConstantI,
3023 IDirect3DDevice9Impl_SetPixelShaderConstantB,
3024 IDirect3DDevice9Impl_GetPixelShaderConstantB,
3025 IDirect3DDevice9Impl_DrawRectPatch,
3026 IDirect3DDevice9Impl_DrawTriPatch,
3027 IDirect3DDevice9Impl_DeletePatch,
3028 IDirect3DDevice9Impl_CreateQuery,
3029 /* IDirect3DDevice9Ex */
3030 IDirect3DDevice9ExImpl_SetConvolutionMonoKernel,
3031 IDirect3DDevice9ExImpl_ComposeRects,
3032 IDirect3DDevice9ExImpl_PresentEx,
3033 IDirect3DDevice9ExImpl_GetGPUThreadPriority,
3034 IDirect3DDevice9ExImpl_SetGPUThreadPriority,
3035 IDirect3DDevice9ExImpl_WaitForVBlank,
3036 IDirect3DDevice9ExImpl_CheckResourceResidency,
3037 IDirect3DDevice9ExImpl_SetMaximumFrameLatency,
3038 IDirect3DDevice9ExImpl_GetMaximumFrameLatency,
3039 IDirect3DDevice9ExImpl_CheckDeviceState,
3040 IDirect3DDevice9ExImpl_CreateRenderTargetEx,
3041 IDirect3DDevice9ExImpl_CreateOffscreenPlainSurfaceEx,
3042 IDirect3DDevice9ExImpl_CreateDepthStencilSurfaceEx,
3043 IDirect3DDevice9ExImpl_ResetEx,
3044 IDirect3DDevice9ExImpl_GetDisplayModeEx
3047 static inline struct IDirect3DDevice9Impl *device_from_device_parent(struct wined3d_device_parent *device_parent)
3049 return CONTAINING_RECORD(device_parent, struct IDirect3DDevice9Impl, device_parent);
3052 static void CDECL device_parent_wined3d_device_created(struct wined3d_device_parent *device_parent,
3053 struct wined3d_device *device)
3055 TRACE("device_parent %p, device %p.\n", device_parent, device);
3058 static HRESULT CDECL device_parent_create_surface(struct wined3d_device_parent *device_parent,
3059 void *container_parent, UINT width, UINT height, enum wined3d_format_id format, DWORD usage,
3060 WINED3DPOOL pool, UINT level, WINED3DCUBEMAP_FACES face, struct wined3d_surface **surface)
3062 struct IDirect3DDevice9Impl *device = device_from_device_parent(device_parent);
3063 IDirect3DSurface9Impl *d3d_surface;
3064 BOOL lockable = TRUE;
3065 HRESULT hr;
3067 TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, usage %#x,\n"
3068 "\tpool %#x, level %u, face %u, surface %p.\n",
3069 device_parent, container_parent, width, height, format, usage, pool, level, face, surface);
3071 if (pool == WINED3DPOOL_DEFAULT && !(usage & D3DUSAGE_DYNAMIC))
3072 lockable = FALSE;
3074 hr = IDirect3DDevice9Impl_CreateSurface(device, width, height,
3075 d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
3076 (IDirect3DSurface9 **)&d3d_surface, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
3077 if (FAILED(hr))
3079 WARN("Failed to create surface, hr %#x.\n", hr);
3080 return hr;
3083 *surface = d3d_surface->wined3d_surface;
3084 wined3d_surface_incref(*surface);
3086 d3d_surface->container = container_parent;
3087 IDirect3DDevice9Ex_Release(d3d_surface->parentDevice);
3088 d3d_surface->parentDevice = NULL;
3090 IDirect3DSurface9_Release(&d3d_surface->IDirect3DSurface9_iface);
3091 d3d_surface->forwardReference = container_parent;
3093 return hr;
3096 static HRESULT CDECL device_parent_create_rendertarget(struct wined3d_device_parent *device_parent,
3097 void *container_parent, UINT width, UINT height, enum wined3d_format_id format,
3098 WINED3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality, BOOL lockable,
3099 struct wined3d_surface **surface)
3101 struct IDirect3DDevice9Impl *device = device_from_device_parent(device_parent);
3102 IDirect3DSurface9Impl *d3d_surface;
3103 HRESULT hr;
3105 TRACE("device_parent %p, container_parent %p, width %u, height %u, format %#x, multisample_type %#x,\n"
3106 "\tmultisample_quality %u, lockable %u, surface %p.\n",
3107 device_parent, container_parent, width, height, format, multisample_type,
3108 multisample_quality, lockable, surface);
3110 hr = IDirect3DDevice9Impl_CreateRenderTarget(&device->IDirect3DDevice9Ex_iface, width, height,
3111 d3dformat_from_wined3dformat(format), multisample_type, multisample_quality, lockable,
3112 (IDirect3DSurface9 **)&d3d_surface, NULL);
3113 if (FAILED(hr))
3115 WARN("Failed to create rendertarget, hr %#x.\n", hr);
3116 return hr;
3119 *surface = d3d_surface->wined3d_surface;
3120 wined3d_surface_incref(*surface);
3122 d3d_surface->container = container_parent;
3123 /* Implicit surfaces are created with an refcount of 0 */
3124 IDirect3DSurface9_Release(&d3d_surface->IDirect3DSurface9_iface);
3126 return hr;
3129 static HRESULT CDECL device_parent_create_depth_stencil(struct wined3d_device_parent *device_parent,
3130 UINT width, UINT height, enum wined3d_format_id format, WINED3DMULTISAMPLE_TYPE multisample_type,
3131 DWORD multisample_quality, BOOL discard, struct wined3d_surface **surface)
3133 struct IDirect3DDevice9Impl *device = device_from_device_parent(device_parent);
3134 IDirect3DSurface9Impl *d3d_surface;
3135 HRESULT hr;
3137 TRACE("device_parent %p, width %u, height %u, format %#x, multisample_type %#x,\n"
3138 "\tmultisample_quality %u, discard %u, surface %p.\n",
3139 device_parent, width, height, format, multisample_type, multisample_quality, discard, surface);
3141 hr = IDirect3DDevice9Impl_CreateDepthStencilSurface(&device->IDirect3DDevice9Ex_iface, width,
3142 height, d3dformat_from_wined3dformat(format), multisample_type, multisample_quality,
3143 discard, (IDirect3DSurface9 **)&d3d_surface, NULL);
3144 if (FAILED(hr))
3146 WARN("Failed to create depth/stencil surface, hr %#x.\n", hr);
3147 return hr;
3150 *surface = d3d_surface->wined3d_surface;
3151 wined3d_surface_incref(*surface);
3152 d3d_surface->container = (IUnknown *)&device->IDirect3DDevice9Ex_iface;
3153 /* Implicit surfaces are created with an refcount of 0 */
3154 IDirect3DSurface9_Release(&d3d_surface->IDirect3DSurface9_iface);
3156 return hr;
3159 static HRESULT CDECL device_parent_create_volume(struct wined3d_device_parent *device_parent,
3160 void *container_parent, UINT width, UINT height, UINT depth, enum wined3d_format_id format,
3161 WINED3DPOOL pool, DWORD usage, struct wined3d_volume **volume)
3163 struct IDirect3DDevice9Impl *device = device_from_device_parent(device_parent);
3164 IDirect3DVolume9Impl *object;
3165 HRESULT hr;
3167 TRACE("device_parent %p, container_parent %p, width %u, height %u, depth %u, "
3168 "format %#x, pool %#x, usage %#x, volume %p\n",
3169 device_parent, container_parent, width, height, depth,
3170 format, pool, usage, volume);
3172 /* Allocate the storage for the device */
3173 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
3174 if (!object)
3176 FIXME("Allocation of memory failed\n");
3177 *volume = NULL;
3178 return D3DERR_OUTOFVIDEOMEMORY;
3181 hr = volume_init(object, device, width, height, depth, usage, format, pool);
3182 if (FAILED(hr))
3184 WARN("Failed to initialize volume, hr %#x.\n", hr);
3185 HeapFree(GetProcessHeap(), 0, object);
3186 return hr;
3189 *volume = object->wined3d_volume;
3190 wined3d_volume_incref(*volume);
3191 IDirect3DVolume9_Release(&object->IDirect3DVolume9_iface);
3193 object->container = container_parent;
3194 object->forwardReference = container_parent;
3196 TRACE("Created volume %p.\n", object);
3198 return hr;
3201 static HRESULT CDECL device_parent_create_swapchain(struct wined3d_device_parent *device_parent,
3202 WINED3DPRESENT_PARAMETERS *present_parameters, struct wined3d_swapchain **swapchain)
3204 struct IDirect3DDevice9Impl *device = device_from_device_parent(device_parent);
3205 D3DPRESENT_PARAMETERS local_parameters;
3206 IDirect3DSwapChain9 *d3d_swapchain;
3207 HRESULT hr;
3209 TRACE("device_parent %p, present_parameters %p, swapchain %p\n", device_parent, present_parameters, swapchain);
3211 /* Copy the presentation parameters */
3212 local_parameters.BackBufferWidth = present_parameters->BackBufferWidth;
3213 local_parameters.BackBufferHeight = present_parameters->BackBufferHeight;
3214 local_parameters.BackBufferFormat = d3dformat_from_wined3dformat(present_parameters->BackBufferFormat);
3215 local_parameters.BackBufferCount = present_parameters->BackBufferCount;
3216 local_parameters.MultiSampleType = present_parameters->MultiSampleType;
3217 local_parameters.MultiSampleQuality = present_parameters->MultiSampleQuality;
3218 local_parameters.SwapEffect = present_parameters->SwapEffect;
3219 local_parameters.hDeviceWindow = present_parameters->hDeviceWindow;
3220 local_parameters.Windowed = present_parameters->Windowed;
3221 local_parameters.EnableAutoDepthStencil = present_parameters->EnableAutoDepthStencil;
3222 local_parameters.AutoDepthStencilFormat = d3dformat_from_wined3dformat(present_parameters->AutoDepthStencilFormat);
3223 local_parameters.Flags = present_parameters->Flags;
3224 local_parameters.FullScreen_RefreshRateInHz = present_parameters->FullScreen_RefreshRateInHz;
3225 local_parameters.PresentationInterval = present_parameters->PresentationInterval;
3227 hr = IDirect3DDevice9Impl_CreateAdditionalSwapChain(&device->IDirect3DDevice9Ex_iface,
3228 &local_parameters, &d3d_swapchain);
3229 if (FAILED(hr))
3231 WARN("Failed to create swapchain, hr %#x.\n", hr);
3232 *swapchain = NULL;
3233 return hr;
3236 *swapchain = ((IDirect3DSwapChain9Impl *)d3d_swapchain)->wined3d_swapchain;
3237 wined3d_swapchain_incref(*swapchain);
3238 IDirect3DSwapChain9_Release((IDirect3DSwapChain9 *)d3d_swapchain);
3240 /* Copy back the presentation parameters */
3241 present_parameters->BackBufferWidth = local_parameters.BackBufferWidth;
3242 present_parameters->BackBufferHeight = local_parameters.BackBufferHeight;
3243 present_parameters->BackBufferFormat = wined3dformat_from_d3dformat(local_parameters.BackBufferFormat);
3244 present_parameters->BackBufferCount = local_parameters.BackBufferCount;
3245 present_parameters->MultiSampleType = local_parameters.MultiSampleType;
3246 present_parameters->MultiSampleQuality = local_parameters.MultiSampleQuality;
3247 present_parameters->SwapEffect = local_parameters.SwapEffect;
3248 present_parameters->hDeviceWindow = local_parameters.hDeviceWindow;
3249 present_parameters->Windowed = local_parameters.Windowed;
3250 present_parameters->EnableAutoDepthStencil = local_parameters.EnableAutoDepthStencil;
3251 present_parameters->AutoDepthStencilFormat = wined3dformat_from_d3dformat(local_parameters.AutoDepthStencilFormat);
3252 present_parameters->Flags = local_parameters.Flags;
3253 present_parameters->FullScreen_RefreshRateInHz = local_parameters.FullScreen_RefreshRateInHz;
3254 present_parameters->PresentationInterval = local_parameters.PresentationInterval;
3256 return hr;
3259 static const struct wined3d_device_parent_ops d3d9_wined3d_device_parent_ops =
3261 device_parent_wined3d_device_created,
3262 device_parent_create_surface,
3263 device_parent_create_rendertarget,
3264 device_parent_create_depth_stencil,
3265 device_parent_create_volume,
3266 device_parent_create_swapchain,
3269 static void setup_fpu(void)
3271 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
3272 WORD cw;
3273 __asm__ volatile ("fnstcw %0" : "=m" (cw));
3274 cw = (cw & ~0xf3f) | 0x3f;
3275 __asm__ volatile ("fldcw %0" : : "m" (cw));
3276 #elif defined(__i386__) && defined(_MSC_VER)
3277 WORD cw;
3278 __asm fnstcw cw;
3279 cw = (cw & ~0xf3f) | 0x3f;
3280 __asm fldcw cw;
3281 #else
3282 FIXME("FPU setup not implemented for this platform.\n");
3283 #endif
3286 HRESULT device_init(IDirect3DDevice9Impl *device, IDirect3D9Impl *parent, struct wined3d *wined3d, UINT adapter, D3DDEVTYPE device_type,
3287 HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters, D3DDISPLAYMODEEX *mode)
3289 WINED3DPRESENT_PARAMETERS *wined3d_parameters;
3290 UINT i, count = 1;
3291 HRESULT hr;
3293 if (mode)
3294 FIXME("Ignoring display mode.\n");
3296 device->IDirect3DDevice9Ex_iface.lpVtbl = &Direct3DDevice9_Vtbl;
3297 device->device_parent.ops = &d3d9_wined3d_device_parent_ops;
3298 device->ref = 1;
3300 if (!(flags & D3DCREATE_FPU_PRESERVE)) setup_fpu();
3302 wined3d_mutex_lock();
3303 hr = wined3d_device_create(wined3d, adapter, device_type, focus_window, flags, 4,
3304 &device->device_parent, &device->wined3d_device);
3305 if (FAILED(hr))
3307 WARN("Failed to create wined3d device, hr %#x.\n", hr);
3308 wined3d_mutex_unlock();
3309 return hr;
3312 if (flags & D3DCREATE_ADAPTERGROUP_DEVICE)
3314 WINED3DCAPS caps;
3316 wined3d_get_device_caps(wined3d, adapter, device_type, &caps);
3317 count = caps.NumberOfAdaptersInGroup;
3320 if (flags & D3DCREATE_MULTITHREADED)
3321 wined3d_device_set_multithreaded(device->wined3d_device);
3323 if (!parameters->Windowed)
3325 if (!focus_window)
3326 focus_window = parameters->hDeviceWindow;
3327 if (FAILED(hr = wined3d_device_acquire_focus_window(device->wined3d_device, focus_window)))
3329 ERR("Failed to acquire focus window, hr %#x.\n", hr);
3330 wined3d_device_decref(device->wined3d_device);
3331 wined3d_mutex_unlock();
3332 return hr;
3335 for (i = 0; i < count; ++i)
3337 HWND device_window = parameters[i].hDeviceWindow;
3339 if (!device_window) device_window = focus_window;
3340 wined3d_device_setup_fullscreen_window(device->wined3d_device, device_window,
3341 parameters[i].BackBufferWidth,
3342 parameters[i].BackBufferHeight);
3346 wined3d_parameters = HeapAlloc(GetProcessHeap(), 0, sizeof(*wined3d_parameters) * count);
3347 if (!wined3d_parameters)
3349 ERR("Failed to allocate wined3d parameters.\n");
3350 wined3d_device_decref(device->wined3d_device);
3351 wined3d_mutex_unlock();
3352 return E_OUTOFMEMORY;
3355 for (i = 0; i < count; ++i)
3357 wined3d_parameters[i].BackBufferWidth = parameters[i].BackBufferWidth;
3358 wined3d_parameters[i].BackBufferHeight = parameters[i].BackBufferHeight;
3359 wined3d_parameters[i].BackBufferFormat = wined3dformat_from_d3dformat(parameters[i].BackBufferFormat);
3360 wined3d_parameters[i].BackBufferCount = parameters[i].BackBufferCount;
3361 wined3d_parameters[i].MultiSampleType = parameters[i].MultiSampleType;
3362 wined3d_parameters[i].MultiSampleQuality = parameters[i].MultiSampleQuality;
3363 wined3d_parameters[i].SwapEffect = parameters[i].SwapEffect;
3364 wined3d_parameters[i].hDeviceWindow = parameters[i].hDeviceWindow;
3365 wined3d_parameters[i].Windowed = parameters[i].Windowed;
3366 wined3d_parameters[i].EnableAutoDepthStencil = parameters[i].EnableAutoDepthStencil;
3367 wined3d_parameters[i].AutoDepthStencilFormat =
3368 wined3dformat_from_d3dformat(parameters[i].AutoDepthStencilFormat);
3369 wined3d_parameters[i].Flags = parameters[i].Flags;
3370 wined3d_parameters[i].FullScreen_RefreshRateInHz = parameters[i].FullScreen_RefreshRateInHz;
3371 wined3d_parameters[i].PresentationInterval = parameters[i].PresentationInterval;
3372 wined3d_parameters[i].AutoRestoreDisplayMode = TRUE;
3375 hr = wined3d_device_init_3d(device->wined3d_device, wined3d_parameters);
3376 if (FAILED(hr))
3378 WARN("Failed to initialize 3D, hr %#x.\n", hr);
3379 wined3d_device_release_focus_window(device->wined3d_device);
3380 HeapFree(GetProcessHeap(), 0, wined3d_parameters);
3381 wined3d_device_decref(device->wined3d_device);
3382 wined3d_mutex_unlock();
3383 return hr;
3386 wined3d_mutex_unlock();
3388 for (i = 0; i < count; ++i)
3390 parameters[i].BackBufferWidth = wined3d_parameters[i].BackBufferWidth;
3391 parameters[i].BackBufferHeight = wined3d_parameters[i].BackBufferHeight;
3392 parameters[i].BackBufferFormat = d3dformat_from_wined3dformat(wined3d_parameters[i].BackBufferFormat);
3393 parameters[i].BackBufferCount = wined3d_parameters[i].BackBufferCount;
3394 parameters[i].MultiSampleType = wined3d_parameters[i].MultiSampleType;
3395 parameters[i].MultiSampleQuality = wined3d_parameters[i].MultiSampleQuality;
3396 parameters[i].SwapEffect = wined3d_parameters[i].SwapEffect;
3397 parameters[i].hDeviceWindow = wined3d_parameters[i].hDeviceWindow;
3398 parameters[i].Windowed = wined3d_parameters[i].Windowed;
3399 parameters[i].EnableAutoDepthStencil = wined3d_parameters[i].EnableAutoDepthStencil;
3400 parameters[i].AutoDepthStencilFormat =
3401 d3dformat_from_wined3dformat(wined3d_parameters[i].AutoDepthStencilFormat);
3402 parameters[i].Flags = wined3d_parameters[i].Flags;
3403 parameters[i].FullScreen_RefreshRateInHz = wined3d_parameters[i].FullScreen_RefreshRateInHz;
3404 parameters[i].PresentationInterval = wined3d_parameters[i].PresentationInterval;
3406 HeapFree(GetProcessHeap(), 0, wined3d_parameters);
3408 /* Initialize the converted declaration array. This creates a valid pointer
3409 * and when adding decls HeapReAlloc() can be used without further checking. */
3410 device->convertedDecls = HeapAlloc(GetProcessHeap(), 0, 0);
3411 if (!device->convertedDecls)
3413 ERR("Failed to allocate FVF vertex declaration map memory.\n");
3414 wined3d_mutex_lock();
3415 wined3d_device_uninit_3d(device->wined3d_device);
3416 wined3d_device_release_focus_window(device->wined3d_device);
3417 wined3d_device_decref(device->wined3d_device);
3418 wined3d_mutex_unlock();
3419 return E_OUTOFMEMORY;
3422 device->d3d_parent = &parent->IDirect3D9Ex_iface;
3423 IDirect3D9_AddRef(device->d3d_parent);
3425 return D3D_OK;