VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Wine/d3d9/device.c@ 32281

Last change on this file since 32281 was 32281, checked in by vboxsync, 14 years ago

wddm/3d: basics for early d3d device creation (needed for win7), wine/d3d: stub for device settings update

  • Property svn:eol-style set to native
File size: 114.8 KB
Line 
1/*
2 * IDirect3DDevice9 implementation
3 *
4 * Copyright 2002-2005 Jason Edmeades
5 * Copyright 2002-2005 Raphael Junqueira
6 * Copyright 2005 Oliver Stieber
7 *
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.
12 *
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.
17 *
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
21 */
22
23/*
24 * Sun LGPL Disclaimer: For the avoidance of doubt, except that if any license choice
25 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
26 * the Lesser General Public License version 2.1 (LGPLv2) at this time for any software where
27 * a choice of LGPL license versions is made available with the language indicating
28 * that LGPLv2 or any later version may be used, or where a choice of which version
29 * of the LGPL is applied is otherwise unspecified.
30 */
31
32#include "config.h"
33#include "d3d9_private.h"
34
35WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
36
37D3DFORMAT d3dformat_from_wined3dformat(WINED3DFORMAT format)
38{
39 BYTE *c = (BYTE *)&format;
40
41 /* Don't translate FOURCC formats */
42 if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
43
44 switch(format)
45 {
46 case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN;
47 case WINED3DFMT_B8G8R8_UNORM: return D3DFMT_R8G8B8;
48 case WINED3DFMT_B8G8R8A8_UNORM: return D3DFMT_A8R8G8B8;
49 case WINED3DFMT_B8G8R8X8_UNORM: return D3DFMT_X8R8G8B8;
50 case WINED3DFMT_B5G6R5_UNORM: return D3DFMT_R5G6B5;
51 case WINED3DFMT_B5G5R5X1_UNORM: return D3DFMT_X1R5G5B5;
52 case WINED3DFMT_B5G5R5A1_UNORM: return D3DFMT_A1R5G5B5;
53 case WINED3DFMT_B4G4R4A4_UNORM: return D3DFMT_A4R4G4B4;
54 case WINED3DFMT_B2G3R3_UNORM: return D3DFMT_R3G3B2;
55 case WINED3DFMT_A8_UNORM: return D3DFMT_A8;
56 case WINED3DFMT_B2G3R3A8_UNORM: return D3DFMT_A8R3G3B2;
57 case WINED3DFMT_B4G4R4X4_UNORM: return D3DFMT_X4R4G4B4;
58 case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10;
59 case WINED3DFMT_R8G8B8A8_UNORM: return D3DFMT_A8B8G8R8;
60 case WINED3DFMT_R8G8B8X8_UNORM: return D3DFMT_X8B8G8R8;
61 case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16;
62 case WINED3DFMT_B10G10R10A2_UNORM: return D3DFMT_A2R10G10B10;
63 case WINED3DFMT_R16G16B16A16_UNORM: return D3DFMT_A16B16G16R16;
64 case WINED3DFMT_P8_UINT_A8_UNORM: return D3DFMT_A8P8;
65 case WINED3DFMT_P8_UINT: return D3DFMT_P8;
66 case WINED3DFMT_L8_UNORM: return D3DFMT_L8;
67 case WINED3DFMT_L8A8_UNORM: return D3DFMT_A8L8;
68 case WINED3DFMT_L4A4_UNORM: return D3DFMT_A4L4;
69 case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8;
70 case WINED3DFMT_R5G5_SNORM_L6_UNORM: return D3DFMT_L6V5U5;
71 case WINED3DFMT_R8G8_SNORM_L8X8_UNORM: return D3DFMT_X8L8V8U8;
72 case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
73 case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
74 case WINED3DFMT_R10G10B10_SNORM_A2_UNORM: return D3DFMT_A2W10V10U10;
75 case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
76 case WINED3DFMT_D32_UNORM: return D3DFMT_D32;
77 case WINED3DFMT_S1_UINT_D15_UNORM: return D3DFMT_D15S1;
78 case WINED3DFMT_D24_UNORM_S8_UINT: return D3DFMT_D24S8;
79 case WINED3DFMT_X8D24_UNORM: return D3DFMT_D24X8;
80 case WINED3DFMT_S4X4_UINT_D24_UNORM: return D3DFMT_D24X4S4;
81 case WINED3DFMT_D16_UNORM: return D3DFMT_D16;
82 case WINED3DFMT_L16_UNORM: return D3DFMT_L16;
83 case WINED3DFMT_D32_FLOAT: return D3DFMT_D32F_LOCKABLE;
84 case WINED3DFMT_S8_UINT_D24_FLOAT: return D3DFMT_D24FS8;
85 case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA;
86 case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16;
87 case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32;
88 case WINED3DFMT_R16G16B16A16_SNORM: return D3DFMT_Q16W16V16U16;
89 case WINED3DFMT_R16_FLOAT: return D3DFMT_R16F;
90 case WINED3DFMT_R16G16_FLOAT: return D3DFMT_G16R16F;
91 case WINED3DFMT_R16G16B16A16_FLOAT: return D3DFMT_A16B16G16R16F;
92 case WINED3DFMT_R32_FLOAT: return D3DFMT_R32F;
93 case WINED3DFMT_R32G32_FLOAT: return D3DFMT_G32R32F;
94 case WINED3DFMT_R32G32B32A32_FLOAT: return D3DFMT_A32B32G32R32F;
95 case WINED3DFMT_R8G8_SNORM_Cx: return D3DFMT_CxV8U8;
96 default:
97 FIXME("Unhandled WINED3DFORMAT %#x\n", format);
98 return D3DFMT_UNKNOWN;
99 }
100}
101
102WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format)
103{
104 BYTE *c = (BYTE *)&format;
105
106 /* Don't translate FOURCC formats */
107 if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
108
109 switch(format)
110 {
111 case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN;
112 case D3DFMT_R8G8B8: return WINED3DFMT_B8G8R8_UNORM;
113 case D3DFMT_A8R8G8B8: return WINED3DFMT_B8G8R8A8_UNORM;
114 case D3DFMT_X8R8G8B8: return WINED3DFMT_B8G8R8X8_UNORM;
115 case D3DFMT_R5G6B5: return WINED3DFMT_B5G6R5_UNORM;
116 case D3DFMT_X1R5G5B5: return WINED3DFMT_B5G5R5X1_UNORM;
117 case D3DFMT_A1R5G5B5: return WINED3DFMT_B5G5R5A1_UNORM;
118 case D3DFMT_A4R4G4B4: return WINED3DFMT_B4G4R4A4_UNORM;
119 case D3DFMT_R3G3B2: return WINED3DFMT_B2G3R3_UNORM;
120 case D3DFMT_A8: return WINED3DFMT_A8_UNORM;
121 case D3DFMT_A8R3G3B2: return WINED3DFMT_B2G3R3A8_UNORM;
122 case D3DFMT_X4R4G4B4: return WINED3DFMT_B4G4R4X4_UNORM;
123 case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM;
124 case D3DFMT_A8B8G8R8: return WINED3DFMT_R8G8B8A8_UNORM;
125 case D3DFMT_X8B8G8R8: return WINED3DFMT_R8G8B8X8_UNORM;
126 case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM;
127 case D3DFMT_A2R10G10B10: return WINED3DFMT_B10G10R10A2_UNORM;
128 case D3DFMT_A16B16G16R16: return WINED3DFMT_R16G16B16A16_UNORM;
129 case D3DFMT_A8P8: return WINED3DFMT_P8_UINT_A8_UNORM;
130 case D3DFMT_P8: return WINED3DFMT_P8_UINT;
131 case D3DFMT_L8: return WINED3DFMT_L8_UNORM;
132 case D3DFMT_A8L8: return WINED3DFMT_L8A8_UNORM;
133 case D3DFMT_A4L4: return WINED3DFMT_L4A4_UNORM;
134 case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM;
135 case D3DFMT_L6V5U5: return WINED3DFMT_R5G5_SNORM_L6_UNORM;
136 case D3DFMT_X8L8V8U8: return WINED3DFMT_R8G8_SNORM_L8X8_UNORM;
137 case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
138 case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
139 case D3DFMT_A2W10V10U10: return WINED3DFMT_R10G10B10_SNORM_A2_UNORM;
140 case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
141 case D3DFMT_D32: return WINED3DFMT_D32_UNORM;
142 case D3DFMT_D15S1: return WINED3DFMT_S1_UINT_D15_UNORM;
143 case D3DFMT_D24S8: return WINED3DFMT_D24_UNORM_S8_UINT;
144 case D3DFMT_D24X8: return WINED3DFMT_X8D24_UNORM;
145 case D3DFMT_D24X4S4: return WINED3DFMT_S4X4_UINT_D24_UNORM;
146 case D3DFMT_D16: return WINED3DFMT_D16_UNORM;
147 case D3DFMT_L16: return WINED3DFMT_L16_UNORM;
148 case D3DFMT_D32F_LOCKABLE: return WINED3DFMT_D32_FLOAT;
149 case D3DFMT_D24FS8: return WINED3DFMT_S8_UINT_D24_FLOAT;
150 case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA;
151 case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT;
152 case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT;
153 case D3DFMT_Q16W16V16U16: return WINED3DFMT_R16G16B16A16_SNORM;
154 case D3DFMT_R16F: return WINED3DFMT_R16_FLOAT;
155 case D3DFMT_G16R16F: return WINED3DFMT_R16G16_FLOAT;
156 case D3DFMT_A16B16G16R16F: return WINED3DFMT_R16G16B16A16_FLOAT;
157 case D3DFMT_R32F: return WINED3DFMT_R32_FLOAT;
158 case D3DFMT_G32R32F: return WINED3DFMT_R32G32_FLOAT;
159 case D3DFMT_A32B32G32R32F: return WINED3DFMT_R32G32B32A32_FLOAT;
160 case D3DFMT_CxV8U8: return WINED3DFMT_R8G8_SNORM_Cx;
161 default:
162 FIXME("Unhandled D3DFORMAT %#x\n", format);
163 return WINED3DFMT_UNKNOWN;
164 }
165}
166
167static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
168{
169 switch(primitive_type)
170 {
171 case D3DPT_POINTLIST:
172 return primitive_count;
173
174 case D3DPT_LINELIST:
175 return primitive_count * 2;
176
177 case D3DPT_LINESTRIP:
178 return primitive_count + 1;
179
180 case D3DPT_TRIANGLELIST:
181 return primitive_count * 3;
182
183 case D3DPT_TRIANGLESTRIP:
184 case D3DPT_TRIANGLEFAN:
185 return primitive_count + 2;
186
187 default:
188 FIXME("Unhandled primitive type %#x\n", primitive_type);
189 return 0;
190 }
191}
192
193static ULONG WINAPI D3D9CB_DestroySwapChain(IWineD3DSwapChain *swapchain)
194{
195 IDirect3DSwapChain9Impl *parent;
196
197 TRACE("swapchain %p.\n", swapchain);
198
199 IWineD3DSwapChain_GetParent(swapchain, (IUnknown **)&parent);
200 parent->isImplicit = FALSE;
201 return IDirect3DSwapChain9_Release((IDirect3DSwapChain9 *)parent);
202}
203
204/* IDirect3D IUnknown parts follow: */
205static HRESULT WINAPI IDirect3DDevice9Impl_QueryInterface(LPDIRECT3DDEVICE9EX iface, REFIID riid, LPVOID* ppobj) {
206 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
207 IDirect3D9 *d3d;
208 IDirect3D9Impl *d3dimpl;
209
210 TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), ppobj);
211
212 if (IsEqualGUID(riid, &IID_IUnknown)
213 || IsEqualGUID(riid, &IID_IDirect3DDevice9)) {
214 IDirect3DDevice9Ex_AddRef(iface);
215 *ppobj = This;
216 TRACE("Returning IDirect3DDevice9 interface at %p\n", *ppobj);
217 return S_OK;
218 } else if(IsEqualGUID(riid, &IID_IDirect3DDevice9Ex)) {
219 /* Find out if the creating d3d9 interface was created with Direct3DCreate9Ex.
220 * It doesn't matter with which function the device was created.
221 */
222 IDirect3DDevice9_GetDirect3D(iface, &d3d);
223 d3dimpl = (IDirect3D9Impl *) d3d;
224
225 if(d3dimpl->extended) {
226 *ppobj = iface;
227 IDirect3DDevice9Ex_AddRef((IDirect3DDevice9Ex *) *ppobj);
228 IDirect3D9_Release(d3d);
229 TRACE("Returning IDirect3DDevice9Ex interface at %p\n", *ppobj);
230 return S_OK;
231 } else {
232 WARN("IDirect3D9 instance wasn't created with CreateDirect3D9Ex, returning E_NOINTERFACE\n");
233 IDirect3D9_Release(d3d);
234 *ppobj = NULL;
235 return E_NOINTERFACE;
236 }
237 }
238
239 if (IsEqualGUID(riid, &IID_IWineD3DDeviceParent))
240 {
241 IUnknown_AddRef((IUnknown *)&This->device_parent_vtbl);
242 *ppobj = &This->device_parent_vtbl;
243 return S_OK;
244 }
245
246 WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
247 *ppobj = NULL;
248 return E_NOINTERFACE;
249}
250
251static ULONG WINAPI IDirect3DDevice9Impl_AddRef(LPDIRECT3DDEVICE9EX iface) {
252 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
253 ULONG ref = InterlockedIncrement(&This->ref);
254
255 TRACE("%p increasing refcount to %u.\n", iface, ref);
256
257 return ref;
258}
259
260static ULONG WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9EX iface) {
261 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
262 ULONG ref;
263
264 if (This->inDestruction) return 0;
265 ref = InterlockedDecrement(&This->ref);
266
267 TRACE("%p decreasing refcount to %u.\n", iface, ref);
268
269 if (ref == 0) {
270 unsigned i;
271 This->inDestruction = TRUE;
272
273 wined3d_mutex_lock();
274 for(i = 0; i < This->numConvertedDecls; i++) {
275 /* Unless Wine is buggy or the app has a bug the refcount will be 0, because decls hold a reference to the
276 * device
277 */
278 IDirect3DVertexDeclaration9Impl_Destroy(This->convertedDecls[i]);
279 }
280 HeapFree(GetProcessHeap(), 0, This->convertedDecls);
281
282 IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroySwapChain);
283 IWineD3DDevice_ReleaseFocusWindow(This->WineD3DDevice);
284 IWineD3DDevice_Release(This->WineD3DDevice);
285 wined3d_mutex_unlock();
286
287 HeapFree(GetProcessHeap(), 0, This);
288 }
289 return ref;
290}
291
292/* IDirect3DDevice Interface follow: */
293static HRESULT WINAPI IDirect3DDevice9Impl_TestCooperativeLevel(IDirect3DDevice9Ex *iface)
294{
295 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
296
297 TRACE("iface %p.\n", iface);
298
299 if (This->notreset)
300 {
301 TRACE("D3D9 device is marked not reset.\n");
302 return D3DERR_DEVICENOTRESET;
303 }
304
305 return D3D_OK;
306}
307
308static UINT WINAPI IDirect3DDevice9Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE9EX iface) {
309 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
310 HRESULT hr;
311
312 TRACE("iface %p.\n", iface);
313
314 wined3d_mutex_lock();
315 hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
316 wined3d_mutex_unlock();
317
318 return hr;
319}
320
321static HRESULT WINAPI IDirect3DDevice9Impl_EvictManagedResources(LPDIRECT3DDEVICE9EX iface) {
322 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
323 HRESULT hr;
324
325 TRACE("iface %p.\n", iface);
326
327 wined3d_mutex_lock();
328 hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
329 wined3d_mutex_unlock();
330
331 return hr;
332}
333
334static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(LPDIRECT3DDEVICE9EX iface, IDirect3D9** ppD3D9) {
335 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
336 HRESULT hr = D3D_OK;
337 IWineD3D* pWineD3D;
338
339 TRACE("iface %p, d3d9 %p.\n", iface, ppD3D9);
340
341 if (NULL == ppD3D9) {
342 return D3DERR_INVALIDCALL;
343 }
344
345 wined3d_mutex_lock();
346 hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
347 if (hr == D3D_OK && pWineD3D != NULL)
348 {
349 IWineD3D_GetParent(pWineD3D,(IUnknown **)ppD3D9);
350 IWineD3D_Release(pWineD3D);
351 } else {
352 FIXME("Call to IWineD3DDevice_GetDirect3D failed\n");
353 *ppD3D9 = NULL;
354 }
355 TRACE("(%p) returning %p\n", This, *ppD3D9);
356 wined3d_mutex_unlock();
357
358 return hr;
359}
360
361static HRESULT WINAPI IDirect3DDevice9Impl_GetDeviceCaps(LPDIRECT3DDEVICE9EX iface, D3DCAPS9* pCaps) {
362 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
363 HRESULT hrc = D3D_OK;
364 WINED3DCAPS *pWineCaps;
365
366 TRACE("iface %p, caps %p.\n", iface, pCaps);
367
368 if(NULL == pCaps){
369 return D3DERR_INVALIDCALL;
370 }
371 pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS));
372 if(pWineCaps == NULL){
373 return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
374 }
375
376 memset(pCaps, 0, sizeof(*pCaps));
377
378 wined3d_mutex_lock();
379 hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
380 wined3d_mutex_unlock();
381
382 WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
383 HeapFree(GetProcessHeap(), 0, pWineCaps);
384
385 /* Some functionality is implemented in d3d9.dll, not wined3d.dll. Add the needed caps */
386 pCaps->DevCaps2 |= D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES;
387
388 filter_caps(pCaps);
389
390 TRACE("Returning %p %p\n", This, pCaps);
391 return hrc;
392}
393
394static HRESULT WINAPI IDirect3DDevice9Impl_GetDisplayMode(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DDISPLAYMODE* pMode) {
395 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
396 HRESULT hr;
397
398 TRACE("iface %p, swapchain %u, mode %p.\n", iface, iSwapChain, pMode);
399
400 wined3d_mutex_lock();
401 hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, iSwapChain, (WINED3DDISPLAYMODE *) pMode);
402 wined3d_mutex_unlock();
403
404 if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
405
406 return hr;
407}
408
409static HRESULT WINAPI IDirect3DDevice9Impl_GetCreationParameters(LPDIRECT3DDEVICE9EX iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
410 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
411 HRESULT hr;
412
413 TRACE("iface %p, parameters %p.\n", iface, pParameters);
414
415 wined3d_mutex_lock();
416 hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
417 wined3d_mutex_unlock();
418
419 return hr;
420}
421
422static HRESULT WINAPI IDirect3DDevice9Impl_SetCursorProperties(LPDIRECT3DDEVICE9EX iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) {
423 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
424 IDirect3DSurface9Impl *pSurface = (IDirect3DSurface9Impl*)pCursorBitmap;
425 HRESULT hr;
426
427 TRACE("iface %p, hotspot_x %u, hotspot_y %u, bitmap %p.\n",
428 iface, XHotSpot, YHotSpot, pCursorBitmap);
429
430 if(!pCursorBitmap) {
431 WARN("No cursor bitmap, returning WINED3DERR_INVALIDCALL\n");
432 return WINED3DERR_INVALIDCALL;
433 }
434
435 wined3d_mutex_lock();
436 hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice, XHotSpot, YHotSpot, pSurface->wineD3DSurface);
437 wined3d_mutex_unlock();
438
439 return hr;
440}
441
442static void WINAPI IDirect3DDevice9Impl_SetCursorPosition(LPDIRECT3DDEVICE9EX iface, int XScreenSpace, int YScreenSpace, DWORD Flags) {
443 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
444
445 TRACE("iface %p, x %u, y %u, flags %#x.\n", iface, XScreenSpace, YScreenSpace, Flags);
446
447 wined3d_mutex_lock();
448 IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
449 wined3d_mutex_unlock();
450}
451
452static BOOL WINAPI IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX iface, BOOL bShow) {
453 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
454 BOOL ret;
455
456 TRACE("iface %p, show %#x.\n", iface, bShow);
457
458 wined3d_mutex_lock();
459 ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
460 wined3d_mutex_unlock();
461
462 return ret;
463}
464
465static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_CreateAdditionalSwapChain(IDirect3DDevice9Ex *iface,
466 D3DPRESENT_PARAMETERS *present_parameters, IDirect3DSwapChain9 **swapchain)
467{
468 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
469 IDirect3DSwapChain9Impl *object;
470 HRESULT hr;
471
472 TRACE("iface %p, present_parameters %p, swapchain %p.\n",
473 iface, present_parameters, swapchain);
474
475 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
476 if (!object)
477 {
478 ERR("Failed to allocate swapchain memory.\n");
479 return E_OUTOFMEMORY;
480 }
481
482 hr = swapchain_init(object, This, present_parameters);
483 if (FAILED(hr))
484 {
485 WARN("Failed to initialize swapchain, hr %#x.\n", hr);
486 HeapFree(GetProcessHeap(), 0, object);
487 return hr;
488 }
489
490 TRACE("Created swapchain %p.\n", object);
491 *swapchain = (IDirect3DSwapChain9 *)object;
492
493 return D3D_OK;
494}
495
496static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) {
497 BOOL *resources_ok = data;
498 D3DRESOURCETYPE type;
499 HRESULT ret = S_OK;
500 WINED3DSURFACE_DESC surface_desc;
501 WINED3DVOLUME_DESC volume_desc;
502 D3DINDEXBUFFER_DESC index_desc;
503 D3DVERTEXBUFFER_DESC vertex_desc;
504 WINED3DPOOL pool;
505 IDirect3DResource9 *parent;
506
507 IWineD3DResource_GetParent(resource, (IUnknown **) &parent);
508 type = IDirect3DResource9_GetType(parent);
509 switch(type) {
510 case D3DRTYPE_SURFACE:
511 IWineD3DSurface_GetDesc((IWineD3DSurface *) resource, &surface_desc);
512 pool = surface_desc.pool;
513 break;
514
515 case D3DRTYPE_VOLUME:
516 IWineD3DVolume_GetDesc((IWineD3DVolume *) resource, &volume_desc);
517 pool = volume_desc.Pool;
518 break;
519
520 case D3DRTYPE_INDEXBUFFER:
521 IDirect3DIndexBuffer9_GetDesc((IDirect3DIndexBuffer9 *) parent, &index_desc);
522 pool = index_desc.Pool;
523 break;
524
525 case D3DRTYPE_VERTEXBUFFER:
526 IDirect3DVertexBuffer9_GetDesc((IDirect3DVertexBuffer9 *)parent, &vertex_desc);
527 pool = vertex_desc.Pool;
528 break;
529
530 /* No need to check for textures. If there is a D3DPOOL_DEFAULT texture, there
531 * is a D3DPOOL_DEFAULT surface or volume as well
532 */
533 default:
534 pool = WINED3DPOOL_SCRATCH; /* a harmless pool */
535 break;
536 }
537
538 if(pool == WINED3DPOOL_DEFAULT) {
539 if(IUnknown_Release(parent) == 0) {
540 TRACE("Parent %p is an implicit resource with ref 0\n", parent);
541 } else {
542 WARN("Resource %p(wineD3D %p) with pool D3DPOOL_DEFAULT blocks the Reset call\n", parent, resource);
543 ret = S_FALSE;
544 *resources_ok = FALSE;
545 }
546 } else {
547 IUnknown_Release(parent);
548 }
549 IWineD3DResource_Release(resource);
550
551 return ret;
552}
553
554static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
555 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
556 WINED3DPRESENT_PARAMETERS localParameters;
557 HRESULT hr;
558 BOOL resources_ok = TRUE;
559 UINT i;
560
561 TRACE("iface %p, present_parameters %p.\n", iface, pPresentationParameters);
562
563 /* Reset states that hold a COM object. WineD3D holds an internal reference to set objects, because
564 * such objects can still be used for rendering after their external d3d9 object has been destroyed.
565 * These objects must not be enumerated. Unsetting them tells WineD3D that the application will not
566 * make use of the hidden reference and destroys the objects.
567 *
568 * Unsetting them is no problem, because the states are supposed to be reset anyway. If the validation
569 * below fails, the device is considered "lost", and _Reset and _Release are the only allowed calls
570 */
571 wined3d_mutex_lock();
572 IWineD3DDevice_SetIndexBuffer(This->WineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
573 for(i = 0; i < 16; i++) {
574 IWineD3DDevice_SetStreamSource(This->WineD3DDevice, i, NULL, 0, 0);
575 }
576 for(i = 0; i < 16; i++) {
577 IWineD3DDevice_SetTexture(This->WineD3DDevice, i, NULL);
578 }
579
580 IWineD3DDevice_EnumResources(This->WineD3DDevice, reset_enum_callback, &resources_ok);
581 if(!resources_ok) {
582 WARN("The application is holding D3DPOOL_DEFAULT resources, rejecting reset\n");
583 This->notreset = TRUE;
584 wined3d_mutex_unlock();
585
586 return WINED3DERR_INVALIDCALL;
587 }
588
589 localParameters.BackBufferWidth = pPresentationParameters->BackBufferWidth;
590 localParameters.BackBufferHeight = pPresentationParameters->BackBufferHeight;
591 localParameters.BackBufferFormat = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
592 localParameters.BackBufferCount = pPresentationParameters->BackBufferCount;
593 localParameters.MultiSampleType = pPresentationParameters->MultiSampleType;
594 localParameters.MultiSampleQuality = pPresentationParameters->MultiSampleQuality;
595 localParameters.SwapEffect = pPresentationParameters->SwapEffect;
596 localParameters.hDeviceWindow = pPresentationParameters->hDeviceWindow;
597 localParameters.Windowed = pPresentationParameters->Windowed;
598 localParameters.EnableAutoDepthStencil = pPresentationParameters->EnableAutoDepthStencil;
599 localParameters.AutoDepthStencilFormat = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
600 localParameters.Flags = pPresentationParameters->Flags;
601 localParameters.FullScreen_RefreshRateInHz = pPresentationParameters->FullScreen_RefreshRateInHz;
602 localParameters.PresentationInterval = pPresentationParameters->PresentationInterval;
603 localParameters.AutoRestoreDisplayMode = TRUE;
604
605 hr = IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);
606 if(FAILED(hr)) {
607 This->notreset = TRUE;
608
609 pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth;
610 pPresentationParameters->BackBufferHeight = localParameters.BackBufferHeight;
611 pPresentationParameters->BackBufferFormat = d3dformat_from_wined3dformat(localParameters.BackBufferFormat);
612 pPresentationParameters->BackBufferCount = localParameters.BackBufferCount;
613 pPresentationParameters->MultiSampleType = localParameters.MultiSampleType;
614 pPresentationParameters->MultiSampleQuality = localParameters.MultiSampleQuality;
615 pPresentationParameters->SwapEffect = localParameters.SwapEffect;
616 pPresentationParameters->hDeviceWindow = localParameters.hDeviceWindow;
617 pPresentationParameters->Windowed = localParameters.Windowed;
618 pPresentationParameters->EnableAutoDepthStencil = localParameters.EnableAutoDepthStencil;
619 pPresentationParameters->AutoDepthStencilFormat = d3dformat_from_wined3dformat(localParameters.AutoDepthStencilFormat);
620 pPresentationParameters->Flags = localParameters.Flags;
621 pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz;
622 pPresentationParameters->PresentationInterval = localParameters.PresentationInterval;
623 } else {
624 This->notreset = FALSE;
625 }
626
627 wined3d_mutex_unlock();
628
629 return hr;
630}
631
632static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_Present(LPDIRECT3DDEVICE9EX iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA*
633 pDirtyRegion) {
634 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
635 HRESULT hr;
636
637 TRACE("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p.\n",
638 iface, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
639
640 wined3d_mutex_lock();
641 hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
642 wined3d_mutex_unlock();
643
644 return hr;
645 }
646
647static HRESULT WINAPI IDirect3DDevice9Impl_GetBackBuffer(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 ** ppBackBuffer) {
648 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
649 IWineD3DSurface *retSurface = NULL;
650 HRESULT rc = D3D_OK;
651
652 TRACE("iface %p, swapchain %u, backbuffer_idx %u, backbuffer_type %#x, backbuffer %p.\n",
653 iface, iSwapChain, BackBuffer, Type, ppBackBuffer);
654
655 wined3d_mutex_lock();
656 rc = IWineD3DDevice_GetBackBuffer(This->WineD3DDevice, iSwapChain, BackBuffer, (WINED3DBACKBUFFER_TYPE) Type, &retSurface);
657 if (rc == D3D_OK && NULL != retSurface && NULL != ppBackBuffer) {
658 IWineD3DSurface_GetParent(retSurface, (IUnknown **)ppBackBuffer);
659 IWineD3DSurface_Release(retSurface);
660 }
661 wined3d_mutex_unlock();
662
663 return rc;
664}
665static HRESULT WINAPI IDirect3DDevice9Impl_GetRasterStatus(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) {
666 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
667 HRESULT hr;
668
669 TRACE("iface %p, swapchain %u, raster_status %p.\n", iface, iSwapChain, pRasterStatus);
670
671 wined3d_mutex_lock();
672 hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, iSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);
673 wined3d_mutex_unlock();
674
675 return hr;
676}
677
678static HRESULT WINAPI IDirect3DDevice9Impl_SetDialogBoxMode(LPDIRECT3DDEVICE9EX iface, BOOL bEnableDialogs) {
679 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
680 HRESULT hr;
681
682 TRACE("iface %p, enable %#x.\n", iface, bEnableDialogs);
683
684 wined3d_mutex_lock();
685 hr = IWineD3DDevice_SetDialogBoxMode(This->WineD3DDevice, bEnableDialogs);
686 wined3d_mutex_unlock();
687
688 return hr;
689}
690
691static void WINAPI IDirect3DDevice9Impl_SetGammaRamp(IDirect3DDevice9Ex *iface, UINT iSwapChain,
692 DWORD Flags, const D3DGAMMARAMP *pRamp)
693{
694 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
695
696 TRACE("iface %p, swapchain %u, flags %#x, ramp %p.\n", iface, iSwapChain, Flags, pRamp);
697
698 /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
699 wined3d_mutex_lock();
700 IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, iSwapChain, Flags, (CONST WINED3DGAMMARAMP *)pRamp);
701 wined3d_mutex_unlock();
702}
703
704static void WINAPI IDirect3DDevice9Impl_GetGammaRamp(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DGAMMARAMP* pRamp) {
705 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
706
707 TRACE("iface %p, swapchain %u, ramp %p.\n", iface, iSwapChain, pRamp);
708
709 /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
710 wined3d_mutex_lock();
711 IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, iSwapChain, (WINED3DGAMMARAMP *) pRamp);
712 wined3d_mutex_unlock();
713}
714
715#ifdef VBOXWDDM
716//#pragma comment(linker, "/export:VBoxWineExD3DDev9Flush=_VBoxWineExD3DDev9Flush@4")
717
718VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Flush(IDirect3DDevice9Ex *iface)
719{
720 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
721 HRESULT hr;
722
723 TRACE("iface %p, Flush\n", iface);
724
725 wined3d_mutex_lock();
726 hr = IWineD3DDevice_Flush(This->WineD3DDevice);
727 wined3d_mutex_unlock();
728
729 return hr;
730}
731
732//#pragma comment(linker, "/export:VBoxWineExD3DDev9CreateTexture=_VBoxWineExD3DDev9CreateTexture@40")
733
734VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9CreateTexture(IDirect3DDevice9Ex *iface,
735 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
736 D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle,
737 void *pvClientMem) /* <- extension arg to pass in the client memory buffer,
738 * applicable ONLY for SYSMEM textures */
739{
740 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
741 IDirect3DTexture9Impl *object;
742 HRESULT hr;
743
744 TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
745 iface, width, height, levels, usage, format, pool, texture, shared_handle);
746
747 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
748 if (!object)
749 {
750 ERR("Failed to allocate texture memory.\n");
751 return D3DERR_OUTOFVIDEOMEMORY;
752 }
753
754 hr = texture_init(object, This, width, height, levels, usage, format, pool
755 , shared_handle
756 , pvClientMem
757 );
758 if (FAILED(hr))
759 {
760 WARN("Failed to initialize texture, hr %#x.\n", hr);
761 HeapFree(GetProcessHeap(), 0, object);
762 return hr;
763 }
764
765 TRACE("Created texture %p.\n", object);
766 *texture = (IDirect3DTexture9 *)object;
767
768 return D3D_OK;
769}
770
771VBOXWINEEX_DECL(HRESULT) VBoxWineExD3DDev9Update(IDirect3DDevice9Ex *iface, D3DPRESENT_PARAMETERS * pParams, IDirect3DDevice9Ex **outIface)
772{
773 IDirect3DDevice9_AddRef(iface);
774 *outIface = iface;
775 return D3D_OK;
776}
777
778#endif
779
780static HRESULT WINAPI IDirect3DDevice9Impl_CreateTexture(IDirect3DDevice9Ex *iface,
781 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
782 D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle)
783{
784#ifdef VBOXWDDM
785 return VBoxWineExD3DDev9CreateTexture(iface, width, height, levels, usage, format,
786 pool, texture, shared_handle, NULL);
787#else
788 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
789 IDirect3DTexture9Impl *object;
790 HRESULT hr;
791
792 TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
793 iface, width, height, levels, usage, format, pool, texture, shared_handle);
794
795 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
796 if (!object)
797 {
798 ERR("Failed to allocate texture memory.\n");
799 return D3DERR_OUTOFVIDEOMEMORY;
800 }
801
802 hr = texture_init(object, This, width, height, levels, usage, format, pool);
803 if (FAILED(hr))
804 {
805 WARN("Failed to initialize texture, hr %#x.\n", hr);
806 HeapFree(GetProcessHeap(), 0, object);
807 return hr;
808 }
809
810 TRACE("Created texture %p.\n", object);
811 *texture = (IDirect3DTexture9 *)object;
812
813 return D3D_OK;
814#endif
815}
816
817static HRESULT WINAPI IDirect3DDevice9Impl_CreateVolumeTexture(IDirect3DDevice9Ex *iface,
818 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format,
819 D3DPOOL pool, IDirect3DVolumeTexture9 **texture, HANDLE *shared_handle)
820{
821 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
822 IDirect3DVolumeTexture9Impl *object;
823 HRESULT hr;
824
825 TRACE("iface %p, width %u, height %u, depth %u, levels %u\n",
826 iface, width, height, depth, levels);
827 TRACE("usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
828 usage, format, pool, texture, shared_handle);
829
830 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
831 if (!object)
832 {
833 ERR("Failed to allocate volume texture memory.\n");
834 return D3DERR_OUTOFVIDEOMEMORY;
835 }
836
837 hr = volumetexture_init(object, This, width, height, depth, levels, usage, format, pool);
838 if (FAILED(hr))
839 {
840 WARN("Failed to initialize volume texture, hr %#x.\n", hr);
841 HeapFree(GetProcessHeap(), 0, object);
842 return hr;
843 }
844
845 TRACE("Created volume texture %p.\n", object);
846 *texture = (IDirect3DVolumeTexture9 *)object;
847
848 return D3D_OK;
849}
850
851static HRESULT WINAPI IDirect3DDevice9Impl_CreateCubeTexture(IDirect3DDevice9Ex *iface,
852 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool,
853 IDirect3DCubeTexture9 **texture, HANDLE *shared_handle)
854{
855 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
856 IDirect3DCubeTexture9Impl *object;
857 HRESULT hr;
858
859 TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
860 iface, edge_length, levels, usage, format, pool, texture, shared_handle);
861
862 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
863 if (!object)
864 {
865 ERR("Failed to allocate cube texture memory.\n");
866 return D3DERR_OUTOFVIDEOMEMORY;
867 }
868
869 hr = cubetexture_init(object, This, edge_length, levels, usage, format, pool);
870 if (FAILED(hr))
871 {
872 WARN("Failed to initialize cube texture, hr %#x.\n", hr);
873 HeapFree(GetProcessHeap(), 0, object);
874 return hr;
875 }
876
877 TRACE("Created cube texture %p.\n", object);
878 *texture = (IDirect3DCubeTexture9 *)object;
879
880 return D3D_OK;
881}
882
883static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(IDirect3DDevice9Ex *iface, UINT size, DWORD usage,
884 DWORD fvf, D3DPOOL pool, IDirect3DVertexBuffer9 **buffer, HANDLE *shared_handle)
885{
886 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
887 IDirect3DVertexBuffer9Impl *object;
888 HRESULT hr;
889
890 TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p, shared_handle %p.\n",
891 iface, size, usage, fvf, pool, buffer, shared_handle);
892
893 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
894 if (!object)
895 {
896 ERR("Failed to allocate buffer memory.\n");
897 return D3DERR_OUTOFVIDEOMEMORY;
898 }
899
900 hr = vertexbuffer_init(object, This, size, usage, fvf, pool);
901 if (FAILED(hr))
902 {
903 WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
904 HeapFree(GetProcessHeap(), 0, object);
905 return hr;
906 }
907
908 TRACE("Created vertex buffer %p.\n", object);
909 *buffer = (IDirect3DVertexBuffer9 *)object;
910
911 return D3D_OK;
912}
913
914static HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(IDirect3DDevice9Ex *iface, UINT size, DWORD usage,
915 D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **buffer, HANDLE *shared_handle)
916{
917 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
918 IDirect3DIndexBuffer9Impl *object;
919 HRESULT hr;
920
921 TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p, shared_handle %p.\n",
922 iface, size, usage, format, pool, buffer, shared_handle);
923
924 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
925 if (!object)
926 {
927 ERR("Failed to allocate buffer memory.\n");
928 return D3DERR_OUTOFVIDEOMEMORY;
929 }
930
931 hr = indexbuffer_init(object, This, size, usage, format, pool);
932 if (FAILED(hr))
933 {
934 WARN("Failed to initialize index buffer, hr %#x.\n", hr);
935 HeapFree(GetProcessHeap(), 0, object);
936 return hr;
937 }
938
939 TRACE("Created index buffer %p.\n", object);
940 *buffer = (IDirect3DIndexBuffer9 *)object;
941
942 return D3D_OK;
943}
944
945static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
946 D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface9 **ppSurface,
947 UINT Usage, D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality
948#ifdef VBOXWDDM
949 , HANDLE *shared_handle
950 , void *pvClientMem
951#endif
952 )
953{
954 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
955 IDirect3DSurface9Impl *object;
956 HRESULT hr;
957
958 TRACE("iface %p, width %u, height %u, format %#x, lockable %#x, discard %#x, level %u, surface %p.\n"
959 "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n",
960 iface, Width, Height, Format, Lockable, Discard, Level, ppSurface,
961 Usage, Pool, MultiSample, MultisampleQuality);
962
963 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface9Impl));
964 if (!object)
965 {
966 FIXME("Failed to allocate surface memory.\n");
967 return D3DERR_OUTOFVIDEOMEMORY;
968 }
969
970 hr = surface_init(object, This, Width, Height, Format, Lockable, Discard,
971 Level, Usage, Pool, MultiSample, MultisampleQuality
972#ifdef VBOXWDDM
973 , shared_handle
974 , pvClientMem
975#endif
976 );
977 if (FAILED(hr))
978 {
979 WARN("Failed to initialize surface, hr %#x.\n", hr);
980 HeapFree(GetProcessHeap(), 0, object);
981 return hr;
982 }
983
984 TRACE("Created surface %p.\n", object);
985 *ppSurface = (IDirect3DSurface9 *)object;
986
987 return D3D_OK;
988}
989
990static HRESULT WINAPI IDirect3DDevice9Impl_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT Width, UINT Height,
991 D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable,
992 IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle)
993{
994 HRESULT hr;
995
996 TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
997 "lockable %#x, surface %p, shared_handle %p.\n",
998 iface, Width, Height, Format, MultiSample, MultisampleQuality,
999 Lockable, ppSurface, pSharedHandle);
1000
1001 hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */,
1002 0 /* Level */, ppSurface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, MultisampleQuality
1003#ifdef VBOXWDDM
1004 , pSharedHandle
1005 , NULL
1006#endif
1007 );
1008
1009 return hr;
1010}
1011
1012static HRESULT WINAPI IDirect3DDevice9Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
1013 D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
1014 DWORD MultisampleQuality, BOOL Discard,
1015 IDirect3DSurface9 **ppSurface, HANDLE* pSharedHandle) {
1016 HRESULT hr;
1017
1018 TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
1019 "discard %#x, surface %p, shared_handle %p.\n",
1020 iface, Width, Height, Format, MultiSample, MultisampleQuality,
1021 Discard, ppSurface, pSharedHandle);
1022
1023 hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, Discard,
1024 0 /* Level */, ppSurface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, MultiSample, MultisampleQuality
1025#ifdef VBOXWDDM
1026 , pSharedHandle
1027 , NULL
1028#endif
1029 );
1030
1031 return hr;
1032}
1033
1034
1035static HRESULT WINAPI IDirect3DDevice9Impl_UpdateSurface(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) {
1036 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1037 HRESULT hr;
1038
1039 TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_point %p.\n",
1040 iface, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
1041
1042 wined3d_mutex_lock();
1043 hr = IWineD3DDevice_UpdateSurface(This->WineD3DDevice, ((IDirect3DSurface9Impl *)pSourceSurface)->wineD3DSurface, pSourceRect, ((IDirect3DSurface9Impl *)pDestinationSurface)->wineD3DSurface, pDestPoint);
1044 wined3d_mutex_unlock();
1045
1046 return hr;
1047}
1048
1049static HRESULT WINAPI IDirect3DDevice9Impl_UpdateTexture(LPDIRECT3DDEVICE9EX iface, IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) {
1050 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1051 HRESULT hr;
1052
1053 TRACE("iface %p, src_texture %p, dst_texture %p.\n", iface, pSourceTexture, pDestinationTexture);
1054
1055 wined3d_mutex_lock();
1056 hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice, ((IDirect3DBaseTexture9Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture9Impl *)pDestinationTexture)->wineD3DBaseTexture);
1057 wined3d_mutex_unlock();
1058
1059 return hr;
1060}
1061
1062static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderTargetData(IDirect3DDevice9Ex *iface,
1063 IDirect3DSurface9 *pRenderTarget, IDirect3DSurface9 *pDestSurface)
1064{
1065 IDirect3DSurface9Impl *renderTarget = (IDirect3DSurface9Impl *)pRenderTarget;
1066 IDirect3DSurface9Impl *destSurface = (IDirect3DSurface9Impl *)pDestSurface;
1067 HRESULT hr;
1068
1069 TRACE("iface %p, render_target %p, dst_surface %p.\n", iface, pRenderTarget, pDestSurface);
1070
1071 wined3d_mutex_lock();
1072 hr = IWineD3DSurface_BltFast(destSurface->wineD3DSurface, 0, 0, renderTarget->wineD3DSurface, NULL, WINEDDBLTFAST_NOCOLORKEY);
1073 wined3d_mutex_unlock();
1074
1075 return hr;
1076}
1077
1078static HRESULT WINAPI IDirect3DDevice9Impl_GetFrontBufferData(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, IDirect3DSurface9* pDestSurface) {
1079 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1080 IDirect3DSurface9Impl *destSurface = (IDirect3DSurface9Impl *)pDestSurface;
1081 HRESULT hr;
1082
1083 TRACE("iface %p, swapchain %u, dst_surface %p.\n", iface, iSwapChain, pDestSurface);
1084
1085 wined3d_mutex_lock();
1086 hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, iSwapChain, destSurface->wineD3DSurface);
1087 wined3d_mutex_unlock();
1088
1089 return hr;
1090}
1091
1092static HRESULT WINAPI IDirect3DDevice9Impl_StretchRect(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *pSourceSurface,
1093 const RECT *pSourceRect, IDirect3DSurface9 *pDestSurface, const RECT *pDestRect, D3DTEXTUREFILTERTYPE Filter)
1094{
1095 IDirect3DSurface9Impl *src = (IDirect3DSurface9Impl *) pSourceSurface;
1096 IDirect3DSurface9Impl *dst = (IDirect3DSurface9Impl *) pDestSurface;
1097 HRESULT hr;
1098
1099 TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n",
1100 iface, pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter);
1101
1102 wined3d_mutex_lock();
1103 hr = IWineD3DSurface_Blt(dst->wineD3DSurface, pDestRect, src->wineD3DSurface, pSourceRect, 0, NULL, Filter);
1104 wined3d_mutex_unlock();
1105
1106 return hr;
1107}
1108
1109static HRESULT WINAPI IDirect3DDevice9Impl_ColorFill(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) {
1110 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1111 IDirect3DSurface9Impl *surface = (IDirect3DSurface9Impl *)pSurface;
1112 WINED3DPOOL pool;
1113 WINED3DRESOURCETYPE restype;
1114 DWORD usage;
1115 WINED3DSURFACE_DESC desc;
1116 HRESULT hr;
1117
1118 TRACE("iface %p, surface %p, rect %p, color 0x%08x.\n", iface, pSurface, pRect, color);
1119
1120 wined3d_mutex_lock();
1121
1122 IWineD3DSurface_GetDesc(surface->wineD3DSurface, &desc);
1123 usage = desc.usage;
1124 pool = desc.pool;
1125 restype = desc.resource_type;
1126
1127 /* This method is only allowed with surfaces that are render targets, or offscreen plain surfaces
1128 * in D3DPOOL_DEFAULT
1129 */
1130 if(!(usage & WINED3DUSAGE_RENDERTARGET) && (pool != WINED3DPOOL_DEFAULT || restype != WINED3DRTYPE_SURFACE)) {
1131 wined3d_mutex_unlock();
1132 WARN("Surface is not a render target, or not a stand-alone D3DPOOL_DEFAULT surface\n");
1133 return D3DERR_INVALIDCALL;
1134 }
1135
1136 /* Colorfill can only be used on rendertarget surfaces, or offscreen plain surfaces in D3DPOOL_DEFAULT */
1137 /* Note: D3DRECT is compatible with WINED3DRECT */
1138 hr = IWineD3DDevice_ColorFill(This->WineD3DDevice, surface->wineD3DSurface, (CONST WINED3DRECT*)pRect, color);
1139
1140 wined3d_mutex_unlock();
1141
1142 return hr;
1143}
1144
1145static HRESULT WINAPI IDirect3DDevice9Impl_CreateOffscreenPlainSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9 **ppSurface, HANDLE* pSharedHandle) {
1146 HRESULT hr;
1147
1148 TRACE("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p.\n",
1149 iface, Width, Height, Format, Pool, ppSurface, pSharedHandle);
1150
1151 if(Pool == D3DPOOL_MANAGED ){
1152 FIXME("Attempting to create a managed offscreen plain surface\n");
1153 return D3DERR_INVALIDCALL;
1154 }
1155 /*
1156 'Off-screen plain surfaces are always lockable, regardless of their pool types.'
1157 but then...
1158 D3DPOOL_DEFAULT is the appropriate pool for use with the IDirect3DDevice9::StretchRect and IDirect3DDevice9::ColorFill.
1159 Why, their always lockable?
1160 should I change the usage to dynamic?
1161 */
1162 hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE /* Discard */,
1163 0 /* Level */, ppSurface, 0 /* Usage (undefined/none) */, (WINED3DPOOL)Pool, D3DMULTISAMPLE_NONE,
1164 0 /* MultisampleQuality */
1165#ifdef VBOXWDDM
1166 , pSharedHandle
1167 , NULL
1168#endif
1169 );
1170
1171 return hr;
1172}
1173
1174/* TODO: move to wineD3D */
1175static HRESULT WINAPI IDirect3DDevice9Impl_SetRenderTarget(LPDIRECT3DDEVICE9EX iface, DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) {
1176 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1177 IDirect3DSurface9Impl *pSurface = (IDirect3DSurface9Impl*)pRenderTarget;
1178 HRESULT hr;
1179
1180 TRACE("iface %p, idx %u, surface %p.\n", iface, RenderTargetIndex, pRenderTarget);
1181
1182 if (RenderTargetIndex >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
1183 {
1184 WARN("Invalid index %u specified.\n", RenderTargetIndex);
1185 return D3DERR_INVALIDCALL;
1186 }
1187
1188 wined3d_mutex_lock();
1189 hr = IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, RenderTargetIndex, pSurface ? pSurface->wineD3DSurface : NULL, TRUE);
1190 wined3d_mutex_unlock();
1191
1192 return hr;
1193}
1194
1195static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9EX iface, DWORD RenderTargetIndex, IDirect3DSurface9 **ppRenderTarget) {
1196 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1197 IWineD3DSurface *pRenderTarget;
1198 HRESULT hr;
1199
1200 TRACE("iface %p, idx %u, surface %p.\n", iface, RenderTargetIndex, ppRenderTarget);
1201
1202 if (ppRenderTarget == NULL) {
1203 return D3DERR_INVALIDCALL;
1204 }
1205
1206 if (RenderTargetIndex >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
1207 {
1208 WARN("Invalid index %u specified.\n", RenderTargetIndex);
1209 return D3DERR_INVALIDCALL;
1210 }
1211
1212 wined3d_mutex_lock();
1213
1214 hr=IWineD3DDevice_GetRenderTarget(This->WineD3DDevice,RenderTargetIndex,&pRenderTarget);
1215
1216 if (FAILED(hr))
1217 {
1218 FIXME("Call to IWineD3DDevice_GetRenderTarget failed, hr %#x\n", hr);
1219 }
1220 else if (!pRenderTarget)
1221 {
1222 *ppRenderTarget = NULL;
1223 }
1224 else
1225 {
1226 IWineD3DSurface_GetParent(pRenderTarget, (IUnknown **)ppRenderTarget);
1227 IWineD3DSurface_Release(pRenderTarget);
1228 }
1229
1230 wined3d_mutex_unlock();
1231
1232 return hr;
1233}
1234
1235static HRESULT WINAPI IDirect3DDevice9Impl_SetDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pZStencilSurface) {
1236 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1237 IDirect3DSurface9Impl *pSurface;
1238 IDirect3DSurface9 *pOldSurface;
1239 HRESULT hr;
1240
1241 TRACE("iface %p, depth_stencil %p.\n", iface, pZStencilSurface);
1242
1243 pSurface = (IDirect3DSurface9Impl*)pZStencilSurface;
1244
1245 wined3d_mutex_lock();
1246 hr = IDirect3DDevice9_GetDepthStencilSurface(iface, &pOldSurface);
1247 if (D3D_OK==hr) {
1248 IDirect3DSurface9_Release(pOldSurface);
1249 IDirect3DSurface9_Release(pOldSurface);
1250 }
1251 hr = IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL==pSurface ? NULL : pSurface->wineD3DSurface);
1252 if (pZStencilSurface) {
1253 IDirect3DSurface9_AddRef(pZStencilSurface);
1254 }
1255 wined3d_mutex_unlock();
1256
1257 return hr;
1258}
1259
1260static HRESULT WINAPI IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9 **ppZStencilSurface) {
1261 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1262 HRESULT hr = D3D_OK;
1263 IWineD3DSurface *pZStencilSurface;
1264
1265 TRACE("iface %p, depth_stencil %p.\n", iface, ppZStencilSurface);
1266
1267 if(ppZStencilSurface == NULL){
1268 return D3DERR_INVALIDCALL;
1269 }
1270
1271 wined3d_mutex_lock();
1272 hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
1273 if (hr == WINED3D_OK) {
1274 IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface);
1275 IWineD3DSurface_Release(pZStencilSurface);
1276 } else {
1277 if (hr != WINED3DERR_NOTFOUND)
1278 WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
1279 *ppZStencilSurface = NULL;
1280 }
1281 wined3d_mutex_unlock();
1282
1283 return hr;
1284}
1285
1286static HRESULT WINAPI IDirect3DDevice9Impl_BeginScene(LPDIRECT3DDEVICE9EX iface) {
1287 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1288 HRESULT hr;
1289
1290 TRACE("iface %p.\n", iface);
1291
1292 wined3d_mutex_lock();
1293 hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
1294 wined3d_mutex_unlock();
1295
1296 return hr;
1297}
1298
1299static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_EndScene(LPDIRECT3DDEVICE9EX iface) {
1300 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1301 HRESULT hr;
1302
1303 TRACE("iface %p.\n", iface);
1304
1305 wined3d_mutex_lock();
1306 hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
1307 wined3d_mutex_unlock();
1308
1309 return hr;
1310}
1311
1312static HRESULT WINAPI IDirect3DDevice9Impl_Clear(LPDIRECT3DDEVICE9EX iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
1313 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1314 HRESULT hr;
1315
1316 TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n",
1317 iface, Count, pRects, Flags, Color, Z, Stencil);
1318
1319 /* Note: D3DRECT is compatible with WINED3DRECT */
1320 wined3d_mutex_lock();
1321 hr = IWineD3DDevice_Clear(This->WineD3DDevice, Count, (CONST WINED3DRECT*) pRects, Flags, Color, Z, Stencil);
1322 wined3d_mutex_unlock();
1323
1324 return hr;
1325}
1326
1327static HRESULT WINAPI IDirect3DDevice9Impl_SetTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* lpMatrix) {
1328 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1329 HRESULT hr;
1330
1331 TRACE("iface %p, state %#x, matrix %p.\n", iface, State, lpMatrix);
1332
1333 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
1334 wined3d_mutex_lock();
1335 hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
1336 wined3d_mutex_unlock();
1337
1338 return hr;
1339}
1340
1341static HRESULT WINAPI IDirect3DDevice9Impl_GetTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) {
1342 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1343 HRESULT hr;
1344
1345 TRACE("iface %p, state %#x, matrix %p.\n", iface, State, pMatrix);
1346
1347 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
1348 wined3d_mutex_lock();
1349 hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
1350 wined3d_mutex_unlock();
1351
1352 return hr;
1353}
1354
1355static HRESULT WINAPI IDirect3DDevice9Impl_MultiplyTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1356 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1357 HRESULT hr;
1358
1359 TRACE("iface %p, state %#x, matrix %p.\n", iface, State, pMatrix);
1360
1361 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
1362 wined3d_mutex_lock();
1363 hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
1364 wined3d_mutex_unlock();
1365
1366 return hr;
1367}
1368
1369static HRESULT WINAPI IDirect3DDevice9Impl_SetViewport(LPDIRECT3DDEVICE9EX iface, CONST D3DVIEWPORT9* pViewport) {
1370 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1371 HRESULT hr;
1372
1373 TRACE("iface %p, viewport %p.\n", iface, pViewport);
1374
1375 /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
1376 wined3d_mutex_lock();
1377 hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
1378 wined3d_mutex_unlock();
1379
1380 return hr;
1381}
1382
1383static HRESULT WINAPI IDirect3DDevice9Impl_GetViewport(LPDIRECT3DDEVICE9EX iface, D3DVIEWPORT9* pViewport) {
1384 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1385 HRESULT hr;
1386
1387 TRACE("iface %p, viewport %p.\n", iface, pViewport);
1388
1389 /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
1390 wined3d_mutex_lock();
1391 hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
1392 wined3d_mutex_unlock();
1393
1394 return hr;
1395}
1396
1397static HRESULT WINAPI IDirect3DDevice9Impl_SetMaterial(LPDIRECT3DDEVICE9EX iface, CONST D3DMATERIAL9* pMaterial) {
1398 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1399 HRESULT hr;
1400
1401 TRACE("iface %p, material %p.\n", iface, pMaterial);
1402
1403 /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
1404 wined3d_mutex_lock();
1405 hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
1406 wined3d_mutex_unlock();
1407
1408 return hr;
1409}
1410
1411static HRESULT WINAPI IDirect3DDevice9Impl_GetMaterial(LPDIRECT3DDEVICE9EX iface, D3DMATERIAL9* pMaterial) {
1412 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1413 HRESULT hr;
1414
1415 TRACE("iface %p, material %p.\n", iface, pMaterial);
1416
1417 /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
1418 wined3d_mutex_lock();
1419 hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
1420 wined3d_mutex_unlock();
1421
1422 return hr;
1423}
1424
1425static HRESULT WINAPI IDirect3DDevice9Impl_SetLight(LPDIRECT3DDEVICE9EX iface, DWORD Index, CONST D3DLIGHT9* pLight) {
1426 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1427 HRESULT hr;
1428
1429 TRACE("iface %p, index %u, light %p.\n", iface, Index, pLight);
1430
1431 /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
1432 wined3d_mutex_lock();
1433 hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
1434 wined3d_mutex_unlock();
1435
1436 return hr;
1437}
1438
1439static HRESULT WINAPI IDirect3DDevice9Impl_GetLight(LPDIRECT3DDEVICE9EX iface, DWORD Index, D3DLIGHT9* pLight) {
1440 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1441 HRESULT hr;
1442
1443 TRACE("iface %p, index %u, light %p.\n", iface, Index, pLight);
1444
1445 /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
1446 wined3d_mutex_lock();
1447 hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
1448 wined3d_mutex_unlock();
1449
1450 return hr;
1451}
1452
1453static HRESULT WINAPI IDirect3DDevice9Impl_LightEnable(LPDIRECT3DDEVICE9EX iface, DWORD Index, BOOL Enable) {
1454 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1455 HRESULT hr;
1456
1457 TRACE("iface %p, index %u, enable %#x.\n", iface, Index, Enable);
1458
1459 wined3d_mutex_lock();
1460 hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
1461 wined3d_mutex_unlock();
1462
1463 return hr;
1464}
1465
1466static HRESULT WINAPI IDirect3DDevice9Impl_GetLightEnable(LPDIRECT3DDEVICE9EX iface, DWORD Index, BOOL* pEnable) {
1467 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1468 HRESULT hr;
1469
1470 TRACE("iface %p, index %u, enable %p.\n", iface, Index, pEnable);
1471
1472 wined3d_mutex_lock();
1473 hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
1474 wined3d_mutex_unlock();
1475
1476 return hr;
1477}
1478
1479static HRESULT WINAPI IDirect3DDevice9Impl_SetClipPlane(LPDIRECT3DDEVICE9EX iface, DWORD Index, CONST float* pPlane) {
1480 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1481 HRESULT hr;
1482
1483 TRACE("iface %p, index %u, plane %p.\n", iface, Index, pPlane);
1484
1485 wined3d_mutex_lock();
1486 hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
1487 wined3d_mutex_unlock();
1488
1489 return hr;
1490}
1491
1492static HRESULT WINAPI IDirect3DDevice9Impl_GetClipPlane(LPDIRECT3DDEVICE9EX iface, DWORD Index, float* pPlane) {
1493 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1494 HRESULT hr;
1495
1496 TRACE("iface %p, index %u, plane %p.\n", iface, Index, pPlane);
1497
1498 wined3d_mutex_lock();
1499 hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
1500 wined3d_mutex_unlock();
1501
1502 return hr;
1503}
1504
1505static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_SetRenderState(LPDIRECT3DDEVICE9EX iface, D3DRENDERSTATETYPE State, DWORD Value) {
1506 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1507 HRESULT hr;
1508
1509 TRACE("iface %p, state %#x, value %#x.\n", iface, State, Value);
1510
1511 wined3d_mutex_lock();
1512 hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
1513 wined3d_mutex_unlock();
1514
1515 return hr;
1516}
1517
1518static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderState(LPDIRECT3DDEVICE9EX iface, D3DRENDERSTATETYPE State, DWORD* pValue) {
1519 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1520 HRESULT hr;
1521
1522 TRACE("iface %p, state %#x, value %p.\n", iface, State, pValue);
1523
1524 wined3d_mutex_lock();
1525 hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
1526 wined3d_mutex_unlock();
1527
1528 return hr;
1529}
1530
1531static HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(IDirect3DDevice9Ex *iface,
1532 D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateblock)
1533{
1534 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1535 IDirect3DStateBlock9Impl *object;
1536 HRESULT hr;
1537
1538 TRACE("iface %p, type %#x, stateblock %p.\n", iface, type, stateblock);
1539
1540 if (type != D3DSBT_ALL && type != D3DSBT_PIXELSTATE && type != D3DSBT_VERTEXSTATE)
1541 {
1542 WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL.\n");
1543 return D3DERR_INVALIDCALL;
1544 }
1545
1546 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1547 if (!object)
1548 {
1549 ERR("Failed to allocate stateblock memory.\n");
1550 return E_OUTOFMEMORY;
1551 }
1552
1553 hr = stateblock_init(object, This, type, NULL);
1554 if (FAILED(hr))
1555 {
1556 WARN("Failed to initialize stateblock, hr %#x.\n", hr);
1557 HeapFree(GetProcessHeap(), 0, object);
1558 return hr;
1559 }
1560
1561 TRACE("Created stateblock %p.\n", object);
1562 *stateblock = (IDirect3DStateBlock9 *)object;
1563
1564 return D3D_OK;
1565}
1566
1567static HRESULT WINAPI IDirect3DDevice9Impl_BeginStateBlock(IDirect3DDevice9Ex *iface)
1568{
1569 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1570 HRESULT hr;
1571
1572 TRACE("iface %p.\n", iface);
1573
1574 wined3d_mutex_lock();
1575 hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
1576 wined3d_mutex_unlock();
1577
1578 return hr;
1579}
1580
1581static HRESULT WINAPI IDirect3DDevice9Impl_EndStateBlock(IDirect3DDevice9Ex *iface, IDirect3DStateBlock9 **stateblock)
1582{
1583 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1584 IWineD3DStateBlock *wined3d_stateblock;
1585 IDirect3DStateBlock9Impl *object;
1586 HRESULT hr;
1587
1588 TRACE("iface %p, stateblock %p.\n", iface, stateblock);
1589
1590 wined3d_mutex_lock();
1591 hr = IWineD3DDevice_EndStateBlock(This->WineD3DDevice, &wined3d_stateblock);
1592 wined3d_mutex_unlock();
1593 if (FAILED(hr))
1594 {
1595 WARN("IWineD3DDevice_EndStateBlock() failed, hr %#x.\n", hr);
1596 return hr;
1597 }
1598
1599 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1600 if (!object)
1601 {
1602 ERR("Failed to allocate stateblock memory.\n");
1603 IWineD3DStateBlock_Release(wined3d_stateblock);
1604 return E_OUTOFMEMORY;
1605 }
1606
1607 hr = stateblock_init(object, This, 0, wined3d_stateblock);
1608 if (FAILED(hr))
1609 {
1610 WARN("Failed to initialize stateblock, hr %#x.\n", hr);
1611 IWineD3DStateBlock_Release(wined3d_stateblock);
1612 HeapFree(GetProcessHeap(), 0, object);
1613 return hr;
1614 }
1615
1616 TRACE("Created stateblock %p.\n", object);
1617 *stateblock = (IDirect3DStateBlock9 *)object;
1618
1619 return D3D_OK;
1620}
1621
1622static HRESULT WINAPI IDirect3DDevice9Impl_SetClipStatus(LPDIRECT3DDEVICE9EX iface, CONST D3DCLIPSTATUS9* pClipStatus) {
1623 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1624 HRESULT hr;
1625
1626 TRACE("iface %p, clip_status %p.\n", iface, pClipStatus);
1627
1628 wined3d_mutex_lock();
1629 hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
1630 wined3d_mutex_unlock();
1631
1632 return hr;
1633}
1634
1635static HRESULT WINAPI IDirect3DDevice9Impl_GetClipStatus(LPDIRECT3DDEVICE9EX iface, D3DCLIPSTATUS9* pClipStatus) {
1636 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1637 HRESULT hr;
1638
1639 TRACE("iface %p, clip_status %p.\n", iface, pClipStatus);
1640
1641 wined3d_mutex_lock();
1642 hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
1643 wined3d_mutex_unlock();
1644
1645 return hr;
1646}
1647
1648static HRESULT WINAPI IDirect3DDevice9Impl_GetTexture(LPDIRECT3DDEVICE9EX iface, DWORD Stage, IDirect3DBaseTexture9 **ppTexture) {
1649 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1650 IWineD3DBaseTexture *retTexture = NULL;
1651 HRESULT rc = D3D_OK;
1652
1653 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, ppTexture);
1654
1655 if(ppTexture == NULL){
1656 return D3DERR_INVALIDCALL;
1657 }
1658
1659 wined3d_mutex_lock();
1660 rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, &retTexture);
1661 if (SUCCEEDED(rc) && NULL != retTexture) {
1662 IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture);
1663 IWineD3DBaseTexture_Release(retTexture);
1664 } else {
1665 if(FAILED(rc)) {
1666 WARN("Call to get texture (%d) failed (%p)\n", Stage, retTexture);
1667 }
1668 *ppTexture = NULL;
1669 }
1670 wined3d_mutex_unlock();
1671
1672 return rc;
1673}
1674
1675static HRESULT WINAPI IDirect3DDevice9Impl_SetTexture(LPDIRECT3DDEVICE9EX iface, DWORD Stage, IDirect3DBaseTexture9* pTexture) {
1676 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1677 HRESULT hr;
1678
1679 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, pTexture);
1680
1681 wined3d_mutex_lock();
1682 hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
1683 pTexture==NULL ? NULL:((IDirect3DBaseTexture9Impl *)pTexture)->wineD3DBaseTexture);
1684 wined3d_mutex_unlock();
1685
1686 return hr;
1687}
1688
1689static const WINED3DTEXTURESTAGESTATETYPE tss_lookup[] =
1690{
1691 WINED3DTSS_FORCE_DWORD, /* 0, unused */
1692 WINED3DTSS_COLOROP, /* 1, D3DTSS_COLOROP */
1693 WINED3DTSS_COLORARG1, /* 2, D3DTSS_COLORARG1 */
1694 WINED3DTSS_COLORARG2, /* 3, D3DTSS_COLORARG2 */
1695 WINED3DTSS_ALPHAOP, /* 4, D3DTSS_ALPHAOP */
1696 WINED3DTSS_ALPHAARG1, /* 5, D3DTSS_ALPHAARG1 */
1697 WINED3DTSS_ALPHAARG2, /* 6, D3DTSS_ALPHAARG2 */
1698 WINED3DTSS_BUMPENVMAT00, /* 7, D3DTSS_BUMPENVMAT00 */
1699 WINED3DTSS_BUMPENVMAT01, /* 8, D3DTSS_BUMPENVMAT01 */
1700 WINED3DTSS_BUMPENVMAT10, /* 9, D3DTSS_BUMPENVMAT10 */
1701 WINED3DTSS_BUMPENVMAT11, /* 10, D3DTSS_BUMPENVMAT11 */
1702 WINED3DTSS_TEXCOORDINDEX, /* 11, D3DTSS_TEXCOORDINDEX */
1703 WINED3DTSS_FORCE_DWORD, /* 12, unused */
1704 WINED3DTSS_FORCE_DWORD, /* 13, unused */
1705 WINED3DTSS_FORCE_DWORD, /* 14, unused */
1706 WINED3DTSS_FORCE_DWORD, /* 15, unused */
1707 WINED3DTSS_FORCE_DWORD, /* 16, unused */
1708 WINED3DTSS_FORCE_DWORD, /* 17, unused */
1709 WINED3DTSS_FORCE_DWORD, /* 18, unused */
1710 WINED3DTSS_FORCE_DWORD, /* 19, unused */
1711 WINED3DTSS_FORCE_DWORD, /* 20, unused */
1712 WINED3DTSS_FORCE_DWORD, /* 21, unused */
1713 WINED3DTSS_BUMPENVLSCALE, /* 22, D3DTSS_BUMPENVLSCALE */
1714 WINED3DTSS_BUMPENVLOFFSET, /* 23, D3DTSS_BUMPENVLOFFSET */
1715 WINED3DTSS_TEXTURETRANSFORMFLAGS, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
1716 WINED3DTSS_FORCE_DWORD, /* 25, unused */
1717 WINED3DTSS_COLORARG0, /* 26, D3DTSS_COLORARG0 */
1718 WINED3DTSS_ALPHAARG0, /* 27, D3DTSS_ALPHAARG0 */
1719 WINED3DTSS_RESULTARG, /* 28, D3DTSS_RESULTARG */
1720 WINED3DTSS_FORCE_DWORD, /* 29, unused */
1721 WINED3DTSS_FORCE_DWORD, /* 30, unused */
1722 WINED3DTSS_FORCE_DWORD, /* 31, unused */
1723 WINED3DTSS_CONSTANT, /* 32, D3DTSS_CONSTANT */
1724};
1725
1726static HRESULT WINAPI IDirect3DDevice9Impl_GetTextureStageState(LPDIRECT3DDEVICE9EX iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) {
1727 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1728 HRESULT hr;
1729
1730 TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, Stage, Type, pValue);
1731
1732 wined3d_mutex_lock();
1733 hr = IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], pValue);
1734 wined3d_mutex_unlock();
1735
1736 return hr;
1737}
1738
1739static HRESULT WINAPI IDirect3DDevice9Impl_SetTextureStageState(LPDIRECT3DDEVICE9EX iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
1740 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1741 HRESULT hr;
1742
1743 TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, Stage, Type, Value);
1744
1745 wined3d_mutex_lock();
1746 hr = IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], Value);
1747 wined3d_mutex_unlock();
1748
1749 return hr;
1750}
1751
1752static HRESULT WINAPI IDirect3DDevice9Impl_GetSamplerState(IDirect3DDevice9Ex *iface, DWORD Sampler,
1753 D3DSAMPLERSTATETYPE Type, DWORD *pValue)
1754{
1755 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1756 HRESULT hr;
1757
1758 TRACE("iface %p, sampler %u, state %#x, value %p.\n", iface, Sampler, Type, pValue);
1759
1760 wined3d_mutex_lock();
1761 hr = IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Sampler, Type, pValue);
1762 wined3d_mutex_unlock();
1763
1764 return hr;
1765}
1766
1767static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_SetSamplerState(LPDIRECT3DDEVICE9EX iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) {
1768 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1769 HRESULT hr;
1770
1771 TRACE("iface %p, sampler %u, state %#x, value %#x.\n", iface, Sampler, Type, Value);
1772
1773 wined3d_mutex_lock();
1774 hr = IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Sampler, Type, Value);
1775 wined3d_mutex_unlock();
1776
1777 return hr;
1778}
1779
1780static HRESULT WINAPI IDirect3DDevice9Impl_ValidateDevice(LPDIRECT3DDEVICE9EX iface, DWORD* pNumPasses) {
1781 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1782 HRESULT hr;
1783
1784 TRACE("iface %p, pass_count %p.\n", iface, pNumPasses);
1785
1786 wined3d_mutex_lock();
1787 hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
1788 wined3d_mutex_unlock();
1789
1790 return hr;
1791}
1792
1793static HRESULT WINAPI IDirect3DDevice9Impl_SetPaletteEntries(IDirect3DDevice9Ex *iface, UINT PaletteNumber,
1794 const PALETTEENTRY *pEntries)
1795{
1796 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1797 HRESULT hr;
1798
1799 TRACE("iface %p, palette_idx %u, entries %p.\n", iface, PaletteNumber, pEntries);
1800
1801 wined3d_mutex_lock();
1802 hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
1803 wined3d_mutex_unlock();
1804
1805 return hr;
1806}
1807
1808static HRESULT WINAPI IDirect3DDevice9Impl_GetPaletteEntries(LPDIRECT3DDEVICE9EX iface, UINT PaletteNumber, PALETTEENTRY* pEntries) {
1809 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1810 HRESULT hr;
1811
1812 TRACE("iface %p, palette_idx %u, entries %p.\n", iface, PaletteNumber, pEntries);
1813
1814 wined3d_mutex_lock();
1815 hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
1816 wined3d_mutex_unlock();
1817
1818 return hr;
1819}
1820
1821static HRESULT WINAPI IDirect3DDevice9Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE9EX iface, UINT PaletteNumber) {
1822 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1823 HRESULT hr;
1824
1825 TRACE("iface %p, palette_idx %u.\n", iface, PaletteNumber);
1826
1827 wined3d_mutex_lock();
1828 hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
1829 wined3d_mutex_unlock();
1830
1831 return hr;
1832}
1833
1834static HRESULT WINAPI IDirect3DDevice9Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE9EX iface, UINT* PaletteNumber) {
1835 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1836 HRESULT hr;
1837
1838 TRACE("iface %p, palette_idx %p.\n", iface, PaletteNumber);
1839
1840 wined3d_mutex_lock();
1841 hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
1842 wined3d_mutex_unlock();
1843
1844 return hr;
1845}
1846
1847static HRESULT WINAPI IDirect3DDevice9Impl_SetScissorRect(LPDIRECT3DDEVICE9EX iface, CONST RECT* pRect) {
1848 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1849 HRESULT hr;
1850
1851 TRACE("iface %p, rect %p.\n", iface, pRect);
1852
1853 wined3d_mutex_lock();
1854 hr = IWineD3DDevice_SetScissorRect(This->WineD3DDevice, pRect);
1855 wined3d_mutex_unlock();
1856
1857 return hr;
1858}
1859
1860static HRESULT WINAPI IDirect3DDevice9Impl_GetScissorRect(LPDIRECT3DDEVICE9EX iface, RECT* pRect) {
1861 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1862 HRESULT hr;
1863
1864 TRACE("iface %p, rect %p.\n", iface, pRect);
1865
1866 wined3d_mutex_lock();
1867 hr = IWineD3DDevice_GetScissorRect(This->WineD3DDevice, pRect);
1868 wined3d_mutex_unlock();
1869
1870 return hr;
1871}
1872
1873static HRESULT WINAPI IDirect3DDevice9Impl_SetSoftwareVertexProcessing(LPDIRECT3DDEVICE9EX iface, BOOL bSoftware) {
1874 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1875 HRESULT hr;
1876
1877 TRACE("iface %p, software %#x.\n", iface, bSoftware);
1878
1879 wined3d_mutex_lock();
1880 hr = IWineD3DDevice_SetSoftwareVertexProcessing(This->WineD3DDevice, bSoftware);
1881 wined3d_mutex_unlock();
1882
1883 return hr;
1884}
1885
1886static BOOL WINAPI IDirect3DDevice9Impl_GetSoftwareVertexProcessing(LPDIRECT3DDEVICE9EX iface) {
1887 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1888 BOOL ret;
1889
1890 TRACE("iface %p.\n", iface);
1891
1892 wined3d_mutex_lock();
1893 ret = IWineD3DDevice_GetSoftwareVertexProcessing(This->WineD3DDevice);
1894 wined3d_mutex_unlock();
1895
1896 return ret;
1897}
1898
1899static HRESULT WINAPI IDirect3DDevice9Impl_SetNPatchMode(LPDIRECT3DDEVICE9EX iface, float nSegments) {
1900 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1901 HRESULT hr;
1902
1903 TRACE("iface %p, segment_count %.8e.\n", iface, nSegments);
1904
1905 wined3d_mutex_lock();
1906 hr = IWineD3DDevice_SetNPatchMode(This->WineD3DDevice, nSegments);
1907 wined3d_mutex_unlock();
1908
1909 return hr;
1910}
1911
1912static float WINAPI IDirect3DDevice9Impl_GetNPatchMode(LPDIRECT3DDEVICE9EX iface) {
1913 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1914 float ret;
1915
1916 TRACE("iface %p.\n", iface);
1917
1918 wined3d_mutex_lock();
1919 ret = IWineD3DDevice_GetNPatchMode(This->WineD3DDevice);
1920 wined3d_mutex_unlock();
1921
1922 return ret;
1923}
1924
1925static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE PrimitiveType,
1926 UINT StartVertex, UINT PrimitiveCount)
1927{
1928 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1929 HRESULT hr;
1930
1931 TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n",
1932 iface, PrimitiveType, StartVertex, PrimitiveCount);
1933
1934 wined3d_mutex_lock();
1935 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1936 hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex,
1937 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
1938 wined3d_mutex_unlock();
1939
1940 return hr;
1941}
1942
1943static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE9EX iface, D3DPRIMITIVETYPE PrimitiveType,
1944 INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) {
1945 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1946 HRESULT hr;
1947
1948 TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u,\n"
1949 "vertex_count %u, start_idx %u, primitive_count %u.\n",
1950 iface, PrimitiveType, BaseVertexIndex, MinVertexIndex,
1951 NumVertices, startIndex, primCount);
1952
1953 wined3d_mutex_lock();
1954 IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, BaseVertexIndex);
1955 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1956 hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, startIndex,
1957 vertex_count_from_primitive_count(PrimitiveType, primCount));
1958 wined3d_mutex_unlock();
1959
1960 return hr;
1961}
1962
1963static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE PrimitiveType,
1964 UINT PrimitiveCount, const void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
1965{
1966 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1967 HRESULT hr;
1968
1969 TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n",
1970 iface, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
1971
1972 wined3d_mutex_lock();
1973 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1974 hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice,
1975 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
1976 pVertexStreamZeroData, VertexStreamZeroStride);
1977 wined3d_mutex_unlock();
1978
1979 return hr;
1980}
1981
1982static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE9EX iface, D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex,
1983 UINT NumVertexIndices, UINT PrimitiveCount, CONST void* pIndexData,
1984 D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) {
1985 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1986 HRESULT hr;
1987
1988 TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, index_count %u, primitive_count %u,\n"
1989 "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n",
1990 iface, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount,
1991 pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
1992
1993 wined3d_mutex_lock();
1994 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1995 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice,
1996 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
1997 wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
1998 wined3d_mutex_unlock();
1999
2000 return hr;
2001}
2002
2003static HRESULT WINAPI IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9EX iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) {
2004 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2005 IDirect3DVertexDeclaration9Impl *Decl = (IDirect3DVertexDeclaration9Impl *) pVertexDecl;
2006 HRESULT hr;
2007 IDirect3DVertexBuffer9Impl *dest = (IDirect3DVertexBuffer9Impl *) pDestBuffer;
2008
2009 TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, declaration %p, flags %#x.\n",
2010 iface, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags);
2011
2012 wined3d_mutex_lock();
2013 hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags, dest->fvf);
2014 wined3d_mutex_unlock();
2015
2016 return hr;
2017}
2018
2019static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(IDirect3DDevice9Ex *iface,
2020 const D3DVERTEXELEMENT9 *elements, IDirect3DVertexDeclaration9 **declaration)
2021{
2022 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2023 IDirect3DVertexDeclaration9Impl *object;
2024 HRESULT hr;
2025
2026 TRACE("iface %p, elements %p, declaration %p.\n", iface, elements, declaration);
2027
2028 if (!declaration)
2029 {
2030 WARN("Caller passed a NULL declaration, returning D3DERR_INVALIDCALL.\n");
2031 return D3DERR_INVALIDCALL;
2032 }
2033
2034 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2035 if (!object)
2036 {
2037 ERR("Failed to allocate vertex declaration memory.\n");
2038 return E_OUTOFMEMORY;
2039 }
2040
2041 hr = vertexdeclaration_init(object, This, elements);
2042 if (FAILED(hr))
2043 {
2044 WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
2045 HeapFree(GetProcessHeap(), 0, object);
2046 return hr;
2047 }
2048
2049 TRACE("Created vertex declaration %p.\n", object);
2050 *declaration = (IDirect3DVertexDeclaration9 *)object;
2051
2052 return D3D_OK;
2053}
2054
2055static IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, DWORD fvf) {
2056 HRESULT hr;
2057 D3DVERTEXELEMENT9* elements = NULL;
2058 IDirect3DVertexDeclaration9* pDecl = NULL;
2059 int p, low, high; /* deliberately signed */
2060 IDirect3DVertexDeclaration9 **convertedDecls = This->convertedDecls;
2061
2062 TRACE("Searching for declaration for fvf %08x... ", fvf);
2063
2064 low = 0;
2065 high = This->numConvertedDecls - 1;
2066 while(low <= high) {
2067 p = (low + high) >> 1;
2068 TRACE("%d ", p);
2069 if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF == fvf) {
2070 TRACE("found %p\n", convertedDecls[p]);
2071 return convertedDecls[p];
2072 } else if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF < fvf) {
2073 low = p + 1;
2074 } else {
2075 high = p - 1;
2076 }
2077 }
2078 TRACE("not found. Creating and inserting at position %d.\n", low);
2079
2080 hr = vdecl_convert_fvf(fvf, &elements);
2081 if (hr != S_OK) return NULL;
2082
2083 hr = IDirect3DDevice9Impl_CreateVertexDeclaration((IDirect3DDevice9Ex *) This, elements, &pDecl);
2084 HeapFree(GetProcessHeap(), 0, elements); /* CreateVertexDeclaration makes a copy */
2085 if (hr != S_OK) return NULL;
2086
2087 if(This->declArraySize == This->numConvertedDecls) {
2088 int grow = max(This->declArraySize / 2, 8);
2089 convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
2090 sizeof(convertedDecls[0]) * (This->numConvertedDecls + grow));
2091 if(!convertedDecls) {
2092 /* This will destroy it */
2093 IDirect3DVertexDeclaration9_Release(pDecl);
2094 return NULL;
2095 }
2096 This->convertedDecls = convertedDecls;
2097 This->declArraySize += grow;
2098 }
2099
2100 memmove(convertedDecls + low + 1, convertedDecls + low, sizeof(IDirect3DVertexDeclaration9Impl *) * (This->numConvertedDecls - low));
2101 convertedDecls[low] = pDecl;
2102 This->numConvertedDecls++;
2103
2104 /* Will prevent the decl from being destroyed */
2105 ((IDirect3DVertexDeclaration9Impl *) pDecl)->convFVF = fvf;
2106 IDirect3DVertexDeclaration9_Release(pDecl); /* Does not destroy now */
2107
2108 TRACE("Returning %p. %d decls in array\n", pDecl, This->numConvertedDecls);
2109 return pDecl;
2110}
2111
2112static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWORD FVF) {
2113 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2114 IDirect3DVertexDeclaration9 *decl;
2115 HRESULT hr;
2116
2117 TRACE("iface %p, fvf %#x.\n", iface, FVF);
2118
2119 if (!FVF)
2120 {
2121 WARN("%#x is not a valid FVF\n", FVF);
2122 return D3D_OK;
2123 }
2124
2125 wined3d_mutex_lock();
2126 decl = getConvertedDecl(This, FVF);
2127 wined3d_mutex_unlock();
2128
2129 if (!decl)
2130 {
2131 /* Any situation when this should happen, except out of memory? */
2132 ERR("Failed to create a converted vertex declaration\n");
2133 return D3DERR_DRIVERINTERNALERROR;
2134 }
2135
2136 hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, decl);
2137 if (FAILED(hr)) ERR("Failed to set vertex declaration\n");
2138
2139 return hr;
2140}
2141
2142static HRESULT WINAPI IDirect3DDevice9Impl_GetFVF(IDirect3DDevice9Ex *iface, DWORD *pFVF)
2143{
2144 IDirect3DVertexDeclaration9 *decl;
2145 HRESULT hr;
2146
2147 TRACE("iface %p, fvf %p.\n", iface, pFVF);
2148
2149 hr = IDirect3DDevice9_GetVertexDeclaration(iface, &decl);
2150 if (FAILED(hr))
2151 {
2152 WARN("Failed to get vertex declaration, %#x\n", hr);
2153 *pFVF = 0;
2154 return hr;
2155 }
2156
2157 if (decl)
2158 {
2159 *pFVF = ((IDirect3DVertexDeclaration9Impl *)decl)->convFVF;
2160 IDirect3DVertexDeclaration9_Release(decl);
2161 }
2162 else
2163 {
2164 *pFVF = 0;
2165 }
2166
2167 TRACE("Returning FVF %#x\n", *pFVF);
2168
2169 return hr;
2170}
2171
2172static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexShader(IDirect3DDevice9Ex *iface,
2173 const DWORD *byte_code, IDirect3DVertexShader9 **shader)
2174{
2175 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2176 IDirect3DVertexShader9Impl *object;
2177 HRESULT hr;
2178
2179 TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
2180
2181 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2182 if (!object)
2183 {
2184 ERR("Failed to allocate vertex shader memory.\n");
2185 return E_OUTOFMEMORY;
2186 }
2187
2188 hr = vertexshader_init(object, This, byte_code);
2189 if (FAILED(hr))
2190 {
2191 WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
2192 HeapFree(GetProcessHeap(), 0, object);
2193 return hr;
2194 }
2195
2196 TRACE("Created vertex shader %p.\n", object);
2197 *shader = (IDirect3DVertexShader9 *)object;
2198
2199 return D3D_OK;
2200}
2201
2202static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSource(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) {
2203 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2204 HRESULT hr;
2205
2206 TRACE("iface %p, stream_idx %u, buffer %p, offset %u, stride %u.\n",
2207 iface, StreamNumber, pStreamData, OffsetInBytes, Stride);
2208
2209 wined3d_mutex_lock();
2210 hr = IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
2211 pStreamData ? ((IDirect3DVertexBuffer9Impl *)pStreamData)->wineD3DVertexBuffer : NULL,
2212 OffsetInBytes, Stride);
2213 wined3d_mutex_unlock();
2214
2215 return hr;
2216}
2217
2218static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, IDirect3DVertexBuffer9 **pStream, UINT* OffsetInBytes, UINT* pStride) {
2219 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2220 IWineD3DBuffer *retStream = NULL;
2221 HRESULT rc = D3D_OK;
2222
2223 TRACE("iface %p, stream_idx %u, buffer %p, offset %p, stride %p.\n",
2224 iface, StreamNumber, pStream, OffsetInBytes, pStride);
2225
2226 if(pStream == NULL){
2227 return D3DERR_INVALIDCALL;
2228 }
2229
2230 wined3d_mutex_lock();
2231 rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, OffsetInBytes, pStride);
2232 if (rc == D3D_OK && NULL != retStream) {
2233 IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
2234 IWineD3DBuffer_Release(retStream);
2235 }else{
2236 if (rc != D3D_OK){
2237 FIXME("Call to GetStreamSource failed %p %p\n", OffsetInBytes, pStride);
2238 }
2239 *pStream = NULL;
2240 }
2241 wined3d_mutex_unlock();
2242
2243 return rc;
2244}
2245
2246static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSourceFreq(IDirect3DDevice9Ex *iface, UINT StreamNumber,
2247 UINT Divider)
2248{
2249 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2250 HRESULT hr;
2251
2252 TRACE("iface %p, stream_idx %u, freq %u.\n", iface, StreamNumber, Divider);
2253
2254 wined3d_mutex_lock();
2255 hr = IWineD3DDevice_SetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
2256 wined3d_mutex_unlock();
2257
2258 return hr;
2259}
2260
2261static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSourceFreq(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, UINT* Divider) {
2262 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2263 HRESULT hr;
2264
2265 TRACE("iface %p, stream_idx %u, freq %p.\n", iface, StreamNumber, Divider);
2266
2267 wined3d_mutex_lock();
2268 hr = IWineD3DDevice_GetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
2269 wined3d_mutex_unlock();
2270
2271 return hr;
2272}
2273
2274static HRESULT WINAPI IDirect3DDevice9Impl_SetIndices(LPDIRECT3DDEVICE9EX iface, IDirect3DIndexBuffer9* pIndexData) {
2275 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2276 HRESULT hr;
2277 IDirect3DIndexBuffer9Impl *ib = (IDirect3DIndexBuffer9Impl *) pIndexData;
2278
2279 TRACE("iface %p, buffer %p.\n", iface, pIndexData);
2280
2281 wined3d_mutex_lock();
2282 hr = IWineD3DDevice_SetIndexBuffer(This->WineD3DDevice,
2283 ib ? ib->wineD3DIndexBuffer : NULL,
2284 ib ? ib->format : WINED3DFMT_UNKNOWN);
2285 wined3d_mutex_unlock();
2286
2287 return hr;
2288}
2289
2290static HRESULT WINAPI IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9EX iface, IDirect3DIndexBuffer9 **ppIndexData) {
2291 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2292 IWineD3DBuffer *retIndexData = NULL;
2293 HRESULT rc = D3D_OK;
2294
2295 TRACE("iface %p, buffer %p.\n", iface, ppIndexData);
2296
2297 if(ppIndexData == NULL){
2298 return D3DERR_INVALIDCALL;
2299 }
2300
2301 wined3d_mutex_lock();
2302 rc = IWineD3DDevice_GetIndexBuffer(This->WineD3DDevice, &retIndexData);
2303 if (SUCCEEDED(rc) && retIndexData) {
2304 IWineD3DBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
2305 IWineD3DBuffer_Release(retIndexData);
2306 } else {
2307 if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
2308 *ppIndexData = NULL;
2309 }
2310 wined3d_mutex_unlock();
2311
2312 return rc;
2313}
2314
2315static HRESULT WINAPI IDirect3DDevice9Impl_CreatePixelShader(IDirect3DDevice9Ex *iface,
2316 const DWORD *byte_code, IDirect3DPixelShader9 **shader)
2317{
2318 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2319 IDirect3DPixelShader9Impl *object;
2320 HRESULT hr;
2321
2322 TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
2323
2324 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2325 if (!object)
2326 {
2327 FIXME("Failed to allocate pixel shader memory.\n");
2328 return E_OUTOFMEMORY;
2329 }
2330
2331 hr = pixelshader_init(object, This, byte_code);
2332 if (FAILED(hr))
2333 {
2334 WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
2335 HeapFree(GetProcessHeap(), 0, object);
2336 return hr;
2337 }
2338
2339 TRACE("Created pixel shader %p.\n", object);
2340 *shader = (IDirect3DPixelShader9 *)object;
2341
2342 return D3D_OK;
2343}
2344
2345static HRESULT WINAPI IDirect3DDevice9Impl_DrawRectPatch(LPDIRECT3DDEVICE9EX iface, UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
2346 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2347 HRESULT hr;
2348
2349 TRACE("iface %p, handle %#x, segment_count %p, patch_info %p.\n",
2350 iface, Handle, pNumSegs, pRectPatchInfo);
2351
2352 wined3d_mutex_lock();
2353 hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
2354 wined3d_mutex_unlock();
2355
2356 return hr;
2357}
2358
2359static HRESULT WINAPI IDirect3DDevice9Impl_DrawTriPatch(LPDIRECT3DDEVICE9EX iface, UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
2360 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2361 HRESULT hr;
2362
2363 TRACE("iface %p, handle %#x, segment_count %p, patch_info %p.\n",
2364 iface, Handle, pNumSegs, pTriPatchInfo);
2365
2366 wined3d_mutex_lock();
2367 hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
2368 wined3d_mutex_unlock();
2369
2370 return hr;
2371}
2372
2373static HRESULT WINAPI IDirect3DDevice9Impl_DeletePatch(LPDIRECT3DDEVICE9EX iface, UINT Handle) {
2374 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2375 HRESULT hr;
2376
2377 TRACE("iface %p, handle %#x.\n", iface, Handle);
2378
2379 wined3d_mutex_lock();
2380 hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
2381 wined3d_mutex_unlock();
2382
2383 return hr;
2384}
2385
2386static HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(IDirect3DDevice9Ex *iface,
2387 D3DQUERYTYPE type, IDirect3DQuery9 **query)
2388{
2389 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2390 IDirect3DQuery9Impl *object;
2391 HRESULT hr;
2392
2393 TRACE("iface %p, type %#x, query %p.\n", iface, type, query);
2394
2395 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2396 if (!object)
2397 {
2398 ERR("Failed to allocate query memory.\n");
2399 return E_OUTOFMEMORY;
2400 }
2401
2402 hr = query_init(object, This, type);
2403 if (FAILED(hr))
2404 {
2405 WARN("Failed to initialize query, hr %#x.\n", hr);
2406 HeapFree(GetProcessHeap(), 0, object);
2407 return hr;
2408 }
2409
2410 TRACE("Created query %p.\n", object);
2411 if (query) *query = (IDirect3DQuery9 *)object;
2412 else IDirect3DQuery9_Release((IDirect3DQuery9 *)object);
2413
2414 return D3D_OK;
2415}
2416
2417static HRESULT WINAPI IDirect3DDevice9ExImpl_SetConvolutionMonoKernel(IDirect3DDevice9Ex *iface,
2418 UINT width, UINT height, float *rows, float *columns)
2419{
2420 FIXME("iface %p, width %u, height %u, rows %p, columns %p stub!\n",
2421 iface, width, height, rows, columns);
2422
2423 return WINED3DERR_INVALIDCALL;
2424}
2425
2426static HRESULT WINAPI IDirect3DDevice9ExImpl_ComposeRects(IDirect3DDevice9Ex *iface,
2427 IDirect3DSurface9 *src_surface, IDirect3DSurface9 *dst_surface, IDirect3DVertexBuffer9 *src_descs,
2428 UINT rect_count, IDirect3DVertexBuffer9 *dst_descs, D3DCOMPOSERECTSOP operation, INT offset_x, INT offset_y)
2429{
2430 FIXME("iface %p, src_surface %p, dst_surface %p, src_descs %p, rect_count %u,\n"
2431 "dst_descs %p, operation %#x, offset_x %u, offset_y %u stub!\n",
2432 iface, src_surface, dst_surface, src_descs, rect_count,
2433 dst_descs, operation, offset_x, offset_y);
2434
2435 return WINED3DERR_INVALIDCALL;
2436}
2437
2438static HRESULT WINAPI IDirect3DDevice9ExImpl_PresentEx(IDirect3DDevice9Ex *iface,
2439 const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
2440 const RGNDATA *dirty_region, DWORD flags)
2441{
2442 FIXME("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p, flags %#x stub!\n",
2443 iface, src_rect, dst_rect, dst_window_override, dirty_region, flags);
2444
2445 return WINED3DERR_INVALIDCALL;
2446}
2447
2448static HRESULT WINAPI IDirect3DDevice9ExImpl_GetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT *priority)
2449{
2450 FIXME("iface %p, priority %p stub!\n", iface, priority);
2451
2452 return WINED3DERR_INVALIDCALL;
2453}
2454
2455static HRESULT WINAPI IDirect3DDevice9ExImpl_SetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT priority)
2456{
2457 FIXME("iface %p, priority %d stub!\n", iface, priority);
2458
2459 return WINED3DERR_INVALIDCALL;
2460}
2461
2462static HRESULT WINAPI IDirect3DDevice9ExImpl_WaitForVBlank(IDirect3DDevice9Ex *iface, UINT swapchain_idx)
2463{
2464 FIXME("iface %p, swapchain_idx %u stub!\n", iface, swapchain_idx);
2465
2466 return WINED3DERR_INVALIDCALL;
2467}
2468
2469static HRESULT WINAPI IDirect3DDevice9ExImpl_CheckResourceResidency(IDirect3DDevice9Ex *iface,
2470 IDirect3DResource9 **resources, UINT32 resource_count)
2471{
2472 FIXME("iface %p, resources %p, resource_count %u stub!\n",
2473 iface, resources, resource_count);
2474
2475 return WINED3DERR_INVALIDCALL;
2476}
2477
2478static HRESULT WINAPI IDirect3DDevice9ExImpl_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT max_latency)
2479{
2480 FIXME("iface %p, max_latency %u stub!\n", iface, max_latency);
2481
2482 return WINED3DERR_INVALIDCALL;
2483}
2484
2485static HRESULT WINAPI IDirect3DDevice9ExImpl_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT *max_latency)
2486{
2487 FIXME("iface %p, max_latency %p stub!\n", iface, max_latency);
2488
2489 *max_latency = 2;
2490
2491 return WINED3DERR_INVALIDCALL;
2492}
2493
2494static HRESULT WINAPI IDirect3DDevice9ExImpl_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND dst_window)
2495{
2496 FIXME("iface %p, dst_window %p stub!\n", iface, dst_window);
2497
2498 return WINED3DERR_INVALIDCALL;
2499}
2500
2501static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateRenderTargetEx(IDirect3DDevice9Ex *iface,
2502 UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
2503 BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage)
2504{
2505 FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n"
2506 "lockable %#x, surface %p, shared_handle %p, usage %#x stub!\n",
2507 iface, width, height, format, multisample_type, multisample_quality,
2508 lockable, surface, shared_handle, usage);
2509
2510 return WINED3DERR_INVALIDCALL;
2511}
2512
2513static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateOffscreenPlainSurfaceEx(IDirect3DDevice9Ex *iface,
2514 UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface,
2515 HANDLE *shared_handle, DWORD usage)
2516{
2517 FIXME("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p, usage %#x stub!\n",
2518 iface, width, height, format, pool, surface, shared_handle, usage);
2519
2520 return WINED3DERR_INVALIDCALL;
2521}
2522
2523static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateDepthStencilSurfaceEx(IDirect3DDevice9Ex *iface,
2524 UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
2525 BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage)
2526{
2527 FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n"
2528 "discard %#x, surface %p, shared_handle %p, usage %#x stub!\n",
2529 iface, width, height, format, multisample_type, multisample_quality,
2530 discard, surface, shared_handle, usage);
2531
2532 return WINED3DERR_INVALIDCALL;
2533}
2534
2535static HRESULT WINAPI IDirect3DDevice9ExImpl_ResetEx(IDirect3DDevice9Ex *iface,
2536 D3DPRESENT_PARAMETERS *present_parameters, D3DDISPLAYMODEEX *mode)
2537{
2538 FIXME("iface %p, present_parameters %p, mode %p stub!\n", iface, present_parameters, mode);
2539
2540 return WINED3DERR_INVALIDCALL;
2541}
2542
2543static HRESULT WINAPI IDirect3DDevice9ExImpl_GetDisplayModeEx(IDirect3DDevice9Ex *iface,
2544 UINT swapchain_idx, D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation)
2545{
2546 FIXME("iface %p, swapchain_idx %u, mode %p, rotation %p stub!\n", iface, swapchain_idx, mode, rotation);
2547
2548 return WINED3DERR_INVALIDCALL;
2549}
2550
2551static const IDirect3DDevice9ExVtbl Direct3DDevice9_Vtbl =
2552{
2553 /* IUnknown */
2554 IDirect3DDevice9Impl_QueryInterface,
2555 IDirect3DDevice9Impl_AddRef,
2556 IDirect3DDevice9Impl_Release,
2557 /* IDirect3DDevice9 */
2558 IDirect3DDevice9Impl_TestCooperativeLevel,
2559 IDirect3DDevice9Impl_GetAvailableTextureMem,
2560 IDirect3DDevice9Impl_EvictManagedResources,
2561 IDirect3DDevice9Impl_GetDirect3D,
2562 IDirect3DDevice9Impl_GetDeviceCaps,
2563 IDirect3DDevice9Impl_GetDisplayMode,
2564 IDirect3DDevice9Impl_GetCreationParameters,
2565 IDirect3DDevice9Impl_SetCursorProperties,
2566 IDirect3DDevice9Impl_SetCursorPosition,
2567 IDirect3DDevice9Impl_ShowCursor,
2568 IDirect3DDevice9Impl_CreateAdditionalSwapChain,
2569 IDirect3DDevice9Impl_GetSwapChain,
2570 IDirect3DDevice9Impl_GetNumberOfSwapChains,
2571 IDirect3DDevice9Impl_Reset,
2572 IDirect3DDevice9Impl_Present,
2573 IDirect3DDevice9Impl_GetBackBuffer,
2574 IDirect3DDevice9Impl_GetRasterStatus,
2575 IDirect3DDevice9Impl_SetDialogBoxMode,
2576 IDirect3DDevice9Impl_SetGammaRamp,
2577 IDirect3DDevice9Impl_GetGammaRamp,
2578 IDirect3DDevice9Impl_CreateTexture,
2579 IDirect3DDevice9Impl_CreateVolumeTexture,
2580 IDirect3DDevice9Impl_CreateCubeTexture,
2581 IDirect3DDevice9Impl_CreateVertexBuffer,
2582 IDirect3DDevice9Impl_CreateIndexBuffer,
2583 IDirect3DDevice9Impl_CreateRenderTarget,
2584 IDirect3DDevice9Impl_CreateDepthStencilSurface,
2585 IDirect3DDevice9Impl_UpdateSurface,
2586 IDirect3DDevice9Impl_UpdateTexture,
2587 IDirect3DDevice9Impl_GetRenderTargetData,
2588 IDirect3DDevice9Impl_GetFrontBufferData,
2589 IDirect3DDevice9Impl_StretchRect,
2590 IDirect3DDevice9Impl_ColorFill,
2591 IDirect3DDevice9Impl_CreateOffscreenPlainSurface,
2592 IDirect3DDevice9Impl_SetRenderTarget,
2593 IDirect3DDevice9Impl_GetRenderTarget,
2594 IDirect3DDevice9Impl_SetDepthStencilSurface,
2595 IDirect3DDevice9Impl_GetDepthStencilSurface,
2596 IDirect3DDevice9Impl_BeginScene,
2597 IDirect3DDevice9Impl_EndScene,
2598 IDirect3DDevice9Impl_Clear,
2599 IDirect3DDevice9Impl_SetTransform,
2600 IDirect3DDevice9Impl_GetTransform,
2601 IDirect3DDevice9Impl_MultiplyTransform,
2602 IDirect3DDevice9Impl_SetViewport,
2603 IDirect3DDevice9Impl_GetViewport,
2604 IDirect3DDevice9Impl_SetMaterial,
2605 IDirect3DDevice9Impl_GetMaterial,
2606 IDirect3DDevice9Impl_SetLight,
2607 IDirect3DDevice9Impl_GetLight,
2608 IDirect3DDevice9Impl_LightEnable,
2609 IDirect3DDevice9Impl_GetLightEnable,
2610 IDirect3DDevice9Impl_SetClipPlane,
2611 IDirect3DDevice9Impl_GetClipPlane,
2612 IDirect3DDevice9Impl_SetRenderState,
2613 IDirect3DDevice9Impl_GetRenderState,
2614 IDirect3DDevice9Impl_CreateStateBlock,
2615 IDirect3DDevice9Impl_BeginStateBlock,
2616 IDirect3DDevice9Impl_EndStateBlock,
2617 IDirect3DDevice9Impl_SetClipStatus,
2618 IDirect3DDevice9Impl_GetClipStatus,
2619 IDirect3DDevice9Impl_GetTexture,
2620 IDirect3DDevice9Impl_SetTexture,
2621 IDirect3DDevice9Impl_GetTextureStageState,
2622 IDirect3DDevice9Impl_SetTextureStageState,
2623 IDirect3DDevice9Impl_GetSamplerState,
2624 IDirect3DDevice9Impl_SetSamplerState,
2625 IDirect3DDevice9Impl_ValidateDevice,
2626 IDirect3DDevice9Impl_SetPaletteEntries,
2627 IDirect3DDevice9Impl_GetPaletteEntries,
2628 IDirect3DDevice9Impl_SetCurrentTexturePalette,
2629 IDirect3DDevice9Impl_GetCurrentTexturePalette,
2630 IDirect3DDevice9Impl_SetScissorRect,
2631 IDirect3DDevice9Impl_GetScissorRect,
2632 IDirect3DDevice9Impl_SetSoftwareVertexProcessing,
2633 IDirect3DDevice9Impl_GetSoftwareVertexProcessing,
2634 IDirect3DDevice9Impl_SetNPatchMode,
2635 IDirect3DDevice9Impl_GetNPatchMode,
2636 IDirect3DDevice9Impl_DrawPrimitive,
2637 IDirect3DDevice9Impl_DrawIndexedPrimitive,
2638 IDirect3DDevice9Impl_DrawPrimitiveUP,
2639 IDirect3DDevice9Impl_DrawIndexedPrimitiveUP,
2640 IDirect3DDevice9Impl_ProcessVertices,
2641 IDirect3DDevice9Impl_CreateVertexDeclaration,
2642 IDirect3DDevice9Impl_SetVertexDeclaration,
2643 IDirect3DDevice9Impl_GetVertexDeclaration,
2644 IDirect3DDevice9Impl_SetFVF,
2645 IDirect3DDevice9Impl_GetFVF,
2646 IDirect3DDevice9Impl_CreateVertexShader,
2647 IDirect3DDevice9Impl_SetVertexShader,
2648 IDirect3DDevice9Impl_GetVertexShader,
2649 IDirect3DDevice9Impl_SetVertexShaderConstantF,
2650 IDirect3DDevice9Impl_GetVertexShaderConstantF,
2651 IDirect3DDevice9Impl_SetVertexShaderConstantI,
2652 IDirect3DDevice9Impl_GetVertexShaderConstantI,
2653 IDirect3DDevice9Impl_SetVertexShaderConstantB,
2654 IDirect3DDevice9Impl_GetVertexShaderConstantB,
2655 IDirect3DDevice9Impl_SetStreamSource,
2656 IDirect3DDevice9Impl_GetStreamSource,
2657 IDirect3DDevice9Impl_SetStreamSourceFreq,
2658 IDirect3DDevice9Impl_GetStreamSourceFreq,
2659 IDirect3DDevice9Impl_SetIndices,
2660 IDirect3DDevice9Impl_GetIndices,
2661 IDirect3DDevice9Impl_CreatePixelShader,
2662 IDirect3DDevice9Impl_SetPixelShader,
2663 IDirect3DDevice9Impl_GetPixelShader,
2664 IDirect3DDevice9Impl_SetPixelShaderConstantF,
2665 IDirect3DDevice9Impl_GetPixelShaderConstantF,
2666 IDirect3DDevice9Impl_SetPixelShaderConstantI,
2667 IDirect3DDevice9Impl_GetPixelShaderConstantI,
2668 IDirect3DDevice9Impl_SetPixelShaderConstantB,
2669 IDirect3DDevice9Impl_GetPixelShaderConstantB,
2670 IDirect3DDevice9Impl_DrawRectPatch,
2671 IDirect3DDevice9Impl_DrawTriPatch,
2672 IDirect3DDevice9Impl_DeletePatch,
2673 IDirect3DDevice9Impl_CreateQuery,
2674 /* IDirect3DDevice9Ex */
2675 IDirect3DDevice9ExImpl_SetConvolutionMonoKernel,
2676 IDirect3DDevice9ExImpl_ComposeRects,
2677 IDirect3DDevice9ExImpl_PresentEx,
2678 IDirect3DDevice9ExImpl_GetGPUThreadPriority,
2679 IDirect3DDevice9ExImpl_SetGPUThreadPriority,
2680 IDirect3DDevice9ExImpl_WaitForVBlank,
2681 IDirect3DDevice9ExImpl_CheckResourceResidency,
2682 IDirect3DDevice9ExImpl_SetMaximumFrameLatency,
2683 IDirect3DDevice9ExImpl_GetMaximumFrameLatency,
2684 IDirect3DDevice9ExImpl_CheckDeviceState,
2685 IDirect3DDevice9ExImpl_CreateRenderTargetEx,
2686 IDirect3DDevice9ExImpl_CreateOffscreenPlainSurfaceEx,
2687 IDirect3DDevice9ExImpl_CreateDepthStencilSurfaceEx,
2688 IDirect3DDevice9ExImpl_ResetEx,
2689 IDirect3DDevice9ExImpl_GetDisplayModeEx
2690};
2691
2692/* IWineD3DDeviceParent IUnknown methods */
2693
2694static inline struct IDirect3DDevice9Impl *device_from_device_parent(IWineD3DDeviceParent *iface)
2695{
2696 return (struct IDirect3DDevice9Impl *)((char*)iface
2697 - FIELD_OFFSET(struct IDirect3DDevice9Impl, device_parent_vtbl));
2698}
2699
2700static HRESULT STDMETHODCALLTYPE device_parent_QueryInterface(IWineD3DDeviceParent *iface, REFIID riid, void **object)
2701{
2702 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2703 return IDirect3DDevice9Impl_QueryInterface((IDirect3DDevice9Ex *)This, riid, object);
2704}
2705
2706static ULONG STDMETHODCALLTYPE device_parent_AddRef(IWineD3DDeviceParent *iface)
2707{
2708 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2709 return IDirect3DDevice9Impl_AddRef((IDirect3DDevice9Ex *)This);
2710}
2711
2712static ULONG STDMETHODCALLTYPE device_parent_Release(IWineD3DDeviceParent *iface)
2713{
2714 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2715 return IDirect3DDevice9Impl_Release((IDirect3DDevice9Ex *)This);
2716}
2717
2718/* IWineD3DDeviceParent methods */
2719
2720static void STDMETHODCALLTYPE device_parent_WineD3DDeviceCreated(IWineD3DDeviceParent *iface, IWineD3DDevice *device)
2721{
2722 TRACE("iface %p, device %p\n", iface, device);
2723}
2724
2725static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParent *iface,
2726 IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, DWORD usage,
2727 WINED3DPOOL pool, UINT level, WINED3DCUBEMAP_FACES face, IWineD3DSurface **surface
2728#ifdef VBOXWDDM
2729 , HANDLE *shared_handle
2730 , void *pvClientMem
2731#endif
2732 )
2733{
2734 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2735 IDirect3DSurface9Impl *d3d_surface;
2736 BOOL lockable = TRUE;
2737 HRESULT hr;
2738
2739 TRACE("iface %p, superior %p, width %u, height %u, format %#x, usage %#x,\n"
2740 "\tpool %#x, level %u, face %u, surface %p\n",
2741 iface, superior, width, height, format, usage, pool, level, face, surface);
2742
2743 if (pool == WINED3DPOOL_DEFAULT && !(usage & D3DUSAGE_DYNAMIC))
2744 lockable = FALSE;
2745
2746 hr = IDirect3DDevice9Impl_CreateSurface((IDirect3DDevice9Ex *)This, width, height,
2747 d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
2748 (IDirect3DSurface9 **)&d3d_surface, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */
2749#ifdef VBOXWDDM
2750 , shared_handle
2751 , pvClientMem
2752#endif
2753 );
2754 if (FAILED(hr))
2755 {
2756 ERR("(%p) CreateSurface failed, returning %#x\n", iface, hr);
2757 return hr;
2758 }
2759
2760 *surface = d3d_surface->wineD3DSurface;
2761 IWineD3DSurface_AddRef(*surface);
2762
2763 d3d_surface->container = superior;
2764 IDirect3DDevice9Ex_Release(d3d_surface->parentDevice);
2765 d3d_surface->parentDevice = NULL;
2766
2767 IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
2768 d3d_surface->forwardReference = superior;
2769
2770 return hr;
2771}
2772
2773static HRESULT STDMETHODCALLTYPE device_parent_CreateRenderTarget(IWineD3DDeviceParent *iface,
2774 IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, WINED3DMULTISAMPLE_TYPE multisample_type,
2775 DWORD multisample_quality, BOOL lockable, IWineD3DSurface **surface)
2776{
2777 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2778 IDirect3DSurface9Impl *d3d_surface;
2779 HRESULT hr;
2780
2781 TRACE("iface %p, superior %p, width %u, height %u, format %#x, multisample_type %#x,\n"
2782 "\tmultisample_quality %u, lockable %u, surface %p\n",
2783 iface, superior, width, height, format, multisample_type, multisample_quality, lockable, surface);
2784
2785 hr = IDirect3DDevice9Impl_CreateRenderTarget((IDirect3DDevice9Ex *)This, width, height,
2786 d3dformat_from_wined3dformat(format), multisample_type, multisample_quality, lockable,
2787 (IDirect3DSurface9 **)&d3d_surface, NULL);
2788 if (FAILED(hr))
2789 {
2790 ERR("(%p) CreateRenderTarget failed, returning %#x\n", iface, hr);
2791 return hr;
2792 }
2793
2794 *surface = d3d_surface->wineD3DSurface;
2795 IWineD3DSurface_AddRef(*surface);
2796
2797 d3d_surface->container = superior;
2798 /* Implicit surfaces are created with an refcount of 0 */
2799 IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
2800
2801 return hr;
2802}
2803
2804static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3DDeviceParent *iface,
2805 IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, WINED3DMULTISAMPLE_TYPE multisample_type,
2806 DWORD multisample_quality, BOOL discard, IWineD3DSurface **surface)
2807{
2808 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2809 IDirect3DSurface9Impl *d3d_surface;
2810 HRESULT hr;
2811
2812 TRACE("iface %p, superior %p, width %u, height %u, format %#x, multisample_type %#x,\n"
2813 "\tmultisample_quality %u, discard %u, surface %p\n",
2814 iface, superior, width, height, format, multisample_type, multisample_quality, discard, surface);
2815
2816 hr = IDirect3DDevice9Impl_CreateDepthStencilSurface((IDirect3DDevice9Ex *)This, width, height,
2817 d3dformat_from_wined3dformat(format), multisample_type, multisample_quality, discard,
2818 (IDirect3DSurface9 **)&d3d_surface, NULL);
2819 if (FAILED(hr))
2820 {
2821 ERR("(%p) CreateDepthStencilSurface failed, returning %#x\n", iface, hr);
2822 return hr;
2823 }
2824
2825 *surface = d3d_surface->wineD3DSurface;
2826 IWineD3DSurface_AddRef(*surface);
2827 d3d_surface->container = (IUnknown *)This;
2828 /* Implicit surfaces are created with an refcount of 0 */
2829 IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
2830
2831 return hr;
2832}
2833
2834static HRESULT STDMETHODCALLTYPE device_parent_CreateVolume(IWineD3DDeviceParent *iface,
2835 IUnknown *superior, UINT width, UINT height, UINT depth, WINED3DFORMAT format,
2836 WINED3DPOOL pool, DWORD usage, IWineD3DVolume **volume)
2837{
2838 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2839 IDirect3DVolume9Impl *object;
2840 HRESULT hr;
2841
2842 TRACE("iface %p, superior %p, width %u, height %u, depth %u, format %#x, pool %#x, usage %#x, volume %p\n",
2843 iface, superior, width, height, depth, format, pool, usage, volume);
2844
2845 /* Allocate the storage for the device */
2846 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2847 if (!object)
2848 {
2849 FIXME("Allocation of memory failed\n");
2850 *volume = NULL;
2851 return D3DERR_OUTOFVIDEOMEMORY;
2852 }
2853
2854 hr = volume_init(object, This, width, height, depth, usage, format, pool);
2855 if (FAILED(hr))
2856 {
2857 WARN("Failed to initialize volume, hr %#x.\n", hr);
2858 HeapFree(GetProcessHeap(), 0, object);
2859 return hr;
2860 }
2861
2862 *volume = object->wineD3DVolume;
2863 IWineD3DVolume_AddRef(*volume);
2864 IDirect3DVolume9_Release((IDirect3DVolume9 *)object);
2865
2866 object->container = superior;
2867 object->forwardReference = superior;
2868
2869 TRACE("(%p) Created volume %p\n", iface, object);
2870
2871 return hr;
2872}
2873
2874static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDeviceParent *iface,
2875 WINED3DPRESENT_PARAMETERS *present_parameters, IWineD3DSwapChain **swapchain)
2876{
2877 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2878 IDirect3DSwapChain9Impl *d3d_swapchain;
2879 D3DPRESENT_PARAMETERS local_parameters;
2880 HRESULT hr;
2881
2882 TRACE("iface %p, present_parameters %p, swapchain %p\n", iface, present_parameters, swapchain);
2883
2884 /* Copy the presentation parameters */
2885 local_parameters.BackBufferWidth = present_parameters->BackBufferWidth;
2886 local_parameters.BackBufferHeight = present_parameters->BackBufferHeight;
2887 local_parameters.BackBufferFormat = d3dformat_from_wined3dformat(present_parameters->BackBufferFormat);
2888 local_parameters.BackBufferCount = present_parameters->BackBufferCount;
2889 local_parameters.MultiSampleType = present_parameters->MultiSampleType;
2890 local_parameters.MultiSampleQuality = present_parameters->MultiSampleQuality;
2891 local_parameters.SwapEffect = present_parameters->SwapEffect;
2892 local_parameters.hDeviceWindow = present_parameters->hDeviceWindow;
2893 local_parameters.Windowed = present_parameters->Windowed;
2894 local_parameters.EnableAutoDepthStencil = present_parameters->EnableAutoDepthStencil;
2895 local_parameters.AutoDepthStencilFormat = d3dformat_from_wined3dformat(present_parameters->AutoDepthStencilFormat);
2896 local_parameters.Flags = present_parameters->Flags;
2897 local_parameters.FullScreen_RefreshRateInHz = present_parameters->FullScreen_RefreshRateInHz;
2898 local_parameters.PresentationInterval = present_parameters->PresentationInterval;
2899
2900 hr = IDirect3DDevice9Impl_CreateAdditionalSwapChain((IDirect3DDevice9Ex *)This,
2901 &local_parameters, (IDirect3DSwapChain9 **)&d3d_swapchain);
2902 if (FAILED(hr))
2903 {
2904 ERR("(%p) CreateAdditionalSwapChain failed, returning %#x\n", iface, hr);
2905 *swapchain = NULL;
2906 return hr;
2907 }
2908
2909 *swapchain = d3d_swapchain->wineD3DSwapChain;
2910 d3d_swapchain->isImplicit = TRUE;
2911 /* Implicit swap chains are created with an refcount of 0 */
2912 IDirect3DSwapChain9_Release((IDirect3DSwapChain9 *)d3d_swapchain);
2913
2914 /* Copy back the presentation parameters */
2915 present_parameters->BackBufferWidth = local_parameters.BackBufferWidth;
2916 present_parameters->BackBufferHeight = local_parameters.BackBufferHeight;
2917 present_parameters->BackBufferFormat = wined3dformat_from_d3dformat(local_parameters.BackBufferFormat);
2918 present_parameters->BackBufferCount = local_parameters.BackBufferCount;
2919 present_parameters->MultiSampleType = local_parameters.MultiSampleType;
2920 present_parameters->MultiSampleQuality = local_parameters.MultiSampleQuality;
2921 present_parameters->SwapEffect = local_parameters.SwapEffect;
2922 present_parameters->hDeviceWindow = local_parameters.hDeviceWindow;
2923 present_parameters->Windowed = local_parameters.Windowed;
2924 present_parameters->EnableAutoDepthStencil = local_parameters.EnableAutoDepthStencil;
2925 present_parameters->AutoDepthStencilFormat = wined3dformat_from_d3dformat(local_parameters.AutoDepthStencilFormat);
2926 present_parameters->Flags = local_parameters.Flags;
2927 present_parameters->FullScreen_RefreshRateInHz = local_parameters.FullScreen_RefreshRateInHz;
2928 present_parameters->PresentationInterval = local_parameters.PresentationInterval;
2929
2930 return hr;
2931}
2932
2933static const IWineD3DDeviceParentVtbl d3d9_wined3d_device_parent_vtbl =
2934{
2935 /* IUnknown methods */
2936 device_parent_QueryInterface,
2937 device_parent_AddRef,
2938 device_parent_Release,
2939 /* IWineD3DDeviceParent methods */
2940 device_parent_WineD3DDeviceCreated,
2941 device_parent_CreateSurface,
2942 device_parent_CreateRenderTarget,
2943 device_parent_CreateDepthStencilSurface,
2944 device_parent_CreateVolume,
2945 device_parent_CreateSwapChain,
2946};
2947
2948HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapter, D3DDEVTYPE device_type,
2949 HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
2950{
2951 WINED3DPRESENT_PARAMETERS *wined3d_parameters;
2952 UINT i, count = 1;
2953 HRESULT hr;
2954
2955 device->lpVtbl = &Direct3DDevice9_Vtbl;
2956 device->device_parent_vtbl = &d3d9_wined3d_device_parent_vtbl;
2957 device->ref = 1;
2958
2959 wined3d_mutex_lock();
2960 hr = IWineD3D_CreateDevice(wined3d, adapter, device_type, focus_window, flags, (IUnknown *)device,
2961 (IWineD3DDeviceParent *)&device->device_parent_vtbl, &device->WineD3DDevice);
2962 if (FAILED(hr))
2963 {
2964 WARN("Failed to create wined3d device, hr %#x.\n", hr);
2965 wined3d_mutex_unlock();
2966 return hr;
2967 }
2968
2969 if (!parameters->Windowed)
2970 {
2971 if (!focus_window) focus_window = parameters->hDeviceWindow;
2972 if (FAILED(hr = IWineD3DDevice_AcquireFocusWindow(device->WineD3DDevice, focus_window)))
2973 {
2974 ERR("Failed to acquire focus window, hr %#x.\n", hr);
2975 IWineD3DDevice_Release(device->WineD3DDevice);
2976 wined3d_mutex_unlock();
2977 return hr;
2978 }
2979 }
2980
2981 if (flags & D3DCREATE_ADAPTERGROUP_DEVICE)
2982 {
2983 WINED3DCAPS caps;
2984
2985 IWineD3D_GetDeviceCaps(wined3d, adapter, device_type, &caps);
2986 count = caps.NumberOfAdaptersInGroup;
2987 }
2988
2989 if (flags & D3DCREATE_MULTITHREADED) IWineD3DDevice_SetMultithreaded(device->WineD3DDevice);
2990
2991 wined3d_parameters = HeapAlloc(GetProcessHeap(), 0, sizeof(*wined3d_parameters) * count);
2992 if (!wined3d_parameters)
2993 {
2994 ERR("Failed to allocate wined3d parameters.\n");
2995 IWineD3DDevice_Release(device->WineD3DDevice);
2996 wined3d_mutex_unlock();
2997 return E_OUTOFMEMORY;
2998 }
2999
3000 for (i = 0; i < count; ++i)
3001 {
3002 wined3d_parameters[i].BackBufferWidth = parameters[i].BackBufferWidth;
3003 wined3d_parameters[i].BackBufferHeight = parameters[i].BackBufferHeight;
3004 wined3d_parameters[i].BackBufferFormat = wined3dformat_from_d3dformat(parameters[i].BackBufferFormat);
3005 wined3d_parameters[i].BackBufferCount = parameters[i].BackBufferCount;
3006 wined3d_parameters[i].MultiSampleType = parameters[i].MultiSampleType;
3007 wined3d_parameters[i].MultiSampleQuality = parameters[i].MultiSampleQuality;
3008 wined3d_parameters[i].SwapEffect = parameters[i].SwapEffect;
3009 wined3d_parameters[i].hDeviceWindow = parameters[i].hDeviceWindow;
3010 wined3d_parameters[i].Windowed = parameters[i].Windowed;
3011 wined3d_parameters[i].EnableAutoDepthStencil = parameters[i].EnableAutoDepthStencil;
3012 wined3d_parameters[i].AutoDepthStencilFormat =
3013 wined3dformat_from_d3dformat(parameters[i].AutoDepthStencilFormat);
3014 wined3d_parameters[i].Flags = parameters[i].Flags;
3015 wined3d_parameters[i].FullScreen_RefreshRateInHz = parameters[i].FullScreen_RefreshRateInHz;
3016 wined3d_parameters[i].PresentationInterval = parameters[i].PresentationInterval;
3017 wined3d_parameters[i].AutoRestoreDisplayMode = TRUE;
3018 }
3019
3020 hr = IWineD3DDevice_Init3D(device->WineD3DDevice, wined3d_parameters);
3021 if (FAILED(hr))
3022 {
3023 WARN("Failed to initialize 3D, hr %#x.\n", hr);
3024 IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice);
3025 HeapFree(GetProcessHeap(), 0, wined3d_parameters);
3026 IWineD3DDevice_Release(device->WineD3DDevice);
3027 wined3d_mutex_unlock();
3028 return hr;
3029 }
3030
3031 wined3d_mutex_unlock();
3032
3033 for (i = 0; i < count; ++i)
3034 {
3035 parameters[i].BackBufferWidth = wined3d_parameters[i].BackBufferWidth;
3036 parameters[i].BackBufferHeight = wined3d_parameters[i].BackBufferHeight;
3037 parameters[i].BackBufferFormat = d3dformat_from_wined3dformat(wined3d_parameters[i].BackBufferFormat);
3038 parameters[i].BackBufferCount = wined3d_parameters[i].BackBufferCount;
3039 parameters[i].MultiSampleType = wined3d_parameters[i].MultiSampleType;
3040 parameters[i].MultiSampleQuality = wined3d_parameters[i].MultiSampleQuality;
3041 parameters[i].SwapEffect = wined3d_parameters[i].SwapEffect;
3042 parameters[i].hDeviceWindow = wined3d_parameters[i].hDeviceWindow;
3043 parameters[i].Windowed = wined3d_parameters[i].Windowed;
3044 parameters[i].EnableAutoDepthStencil = wined3d_parameters[i].EnableAutoDepthStencil;
3045 parameters[i].AutoDepthStencilFormat =
3046 d3dformat_from_wined3dformat(wined3d_parameters[i].AutoDepthStencilFormat);
3047 parameters[i].Flags = wined3d_parameters[i].Flags;
3048 parameters[i].FullScreen_RefreshRateInHz = wined3d_parameters[i].FullScreen_RefreshRateInHz;
3049 parameters[i].PresentationInterval = wined3d_parameters[i].PresentationInterval;
3050 }
3051 HeapFree(GetProcessHeap(), 0, wined3d_parameters);
3052
3053 /* Initialize the converted declaration array. This creates a valid pointer
3054 * and when adding decls HeapReAlloc() can be used without further checking. */
3055 device->convertedDecls = HeapAlloc(GetProcessHeap(), 0, 0);
3056 if (!device->convertedDecls)
3057 {
3058 ERR("Failed to allocate FVF vertex declaration map memory.\n");
3059 wined3d_mutex_lock();
3060 IWineD3DDevice_Uninit3D(device->WineD3DDevice, D3D9CB_DestroySwapChain);
3061 IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice);
3062 IWineD3DDevice_Release(device->WineD3DDevice);
3063 wined3d_mutex_unlock();
3064 return E_OUTOFMEMORY;
3065 }
3066
3067 return D3D_OK;
3068}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette