VirtualBox

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

Last change on this file since 32184 was 32184, checked in by vboxsync, 15 years ago

wine: shared render target support; wddm/d3d: aero multi-monitor fixes (still buggy)

  • Property svn:eol-style set to native
File size: 114.6 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#endif
771
772static HRESULT WINAPI IDirect3DDevice9Impl_CreateTexture(IDirect3DDevice9Ex *iface,
773 UINT width, UINT height, UINT levels, DWORD usage, D3DFORMAT format,
774 D3DPOOL pool, IDirect3DTexture9 **texture, HANDLE *shared_handle)
775{
776#ifdef VBOXWDDM
777 return VBoxWineExD3DDev9CreateTexture(iface, width, height, levels, usage, format,
778 pool, texture, shared_handle, NULL);
779#else
780 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
781 IDirect3DTexture9Impl *object;
782 HRESULT hr;
783
784 TRACE("iface %p, width %u, height %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
785 iface, width, height, levels, usage, format, pool, texture, shared_handle);
786
787 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
788 if (!object)
789 {
790 ERR("Failed to allocate texture memory.\n");
791 return D3DERR_OUTOFVIDEOMEMORY;
792 }
793
794 hr = texture_init(object, This, width, height, levels, usage, format, pool);
795 if (FAILED(hr))
796 {
797 WARN("Failed to initialize texture, hr %#x.\n", hr);
798 HeapFree(GetProcessHeap(), 0, object);
799 return hr;
800 }
801
802 TRACE("Created texture %p.\n", object);
803 *texture = (IDirect3DTexture9 *)object;
804
805 return D3D_OK;
806#endif
807}
808
809static HRESULT WINAPI IDirect3DDevice9Impl_CreateVolumeTexture(IDirect3DDevice9Ex *iface,
810 UINT width, UINT height, UINT depth, UINT levels, DWORD usage, D3DFORMAT format,
811 D3DPOOL pool, IDirect3DVolumeTexture9 **texture, HANDLE *shared_handle)
812{
813 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
814 IDirect3DVolumeTexture9Impl *object;
815 HRESULT hr;
816
817 TRACE("iface %p, width %u, height %u, depth %u, levels %u\n",
818 iface, width, height, depth, levels);
819 TRACE("usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
820 usage, format, pool, texture, shared_handle);
821
822 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
823 if (!object)
824 {
825 ERR("Failed to allocate volume texture memory.\n");
826 return D3DERR_OUTOFVIDEOMEMORY;
827 }
828
829 hr = volumetexture_init(object, This, width, height, depth, levels, usage, format, pool);
830 if (FAILED(hr))
831 {
832 WARN("Failed to initialize volume texture, hr %#x.\n", hr);
833 HeapFree(GetProcessHeap(), 0, object);
834 return hr;
835 }
836
837 TRACE("Created volume texture %p.\n", object);
838 *texture = (IDirect3DVolumeTexture9 *)object;
839
840 return D3D_OK;
841}
842
843static HRESULT WINAPI IDirect3DDevice9Impl_CreateCubeTexture(IDirect3DDevice9Ex *iface,
844 UINT edge_length, UINT levels, DWORD usage, D3DFORMAT format, D3DPOOL pool,
845 IDirect3DCubeTexture9 **texture, HANDLE *shared_handle)
846{
847 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
848 IDirect3DCubeTexture9Impl *object;
849 HRESULT hr;
850
851 TRACE("iface %p, edge_length %u, levels %u, usage %#x, format %#x, pool %#x, texture %p, shared_handle %p.\n",
852 iface, edge_length, levels, usage, format, pool, texture, shared_handle);
853
854 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
855 if (!object)
856 {
857 ERR("Failed to allocate cube texture memory.\n");
858 return D3DERR_OUTOFVIDEOMEMORY;
859 }
860
861 hr = cubetexture_init(object, This, edge_length, levels, usage, format, pool);
862 if (FAILED(hr))
863 {
864 WARN("Failed to initialize cube texture, hr %#x.\n", hr);
865 HeapFree(GetProcessHeap(), 0, object);
866 return hr;
867 }
868
869 TRACE("Created cube texture %p.\n", object);
870 *texture = (IDirect3DCubeTexture9 *)object;
871
872 return D3D_OK;
873}
874
875static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexBuffer(IDirect3DDevice9Ex *iface, UINT size, DWORD usage,
876 DWORD fvf, D3DPOOL pool, IDirect3DVertexBuffer9 **buffer, HANDLE *shared_handle)
877{
878 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
879 IDirect3DVertexBuffer9Impl *object;
880 HRESULT hr;
881
882 TRACE("iface %p, size %u, usage %#x, fvf %#x, pool %#x, buffer %p, shared_handle %p.\n",
883 iface, size, usage, fvf, pool, buffer, shared_handle);
884
885 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
886 if (!object)
887 {
888 ERR("Failed to allocate buffer memory.\n");
889 return D3DERR_OUTOFVIDEOMEMORY;
890 }
891
892 hr = vertexbuffer_init(object, This, size, usage, fvf, pool);
893 if (FAILED(hr))
894 {
895 WARN("Failed to initialize vertex buffer, hr %#x.\n", hr);
896 HeapFree(GetProcessHeap(), 0, object);
897 return hr;
898 }
899
900 TRACE("Created vertex buffer %p.\n", object);
901 *buffer = (IDirect3DVertexBuffer9 *)object;
902
903 return D3D_OK;
904}
905
906static HRESULT WINAPI IDirect3DDevice9Impl_CreateIndexBuffer(IDirect3DDevice9Ex *iface, UINT size, DWORD usage,
907 D3DFORMAT format, D3DPOOL pool, IDirect3DIndexBuffer9 **buffer, HANDLE *shared_handle)
908{
909 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
910 IDirect3DIndexBuffer9Impl *object;
911 HRESULT hr;
912
913 TRACE("iface %p, size %u, usage %#x, format %#x, pool %#x, buffer %p, shared_handle %p.\n",
914 iface, size, usage, format, pool, buffer, shared_handle);
915
916 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
917 if (!object)
918 {
919 ERR("Failed to allocate buffer memory.\n");
920 return D3DERR_OUTOFVIDEOMEMORY;
921 }
922
923 hr = indexbuffer_init(object, This, size, usage, format, pool);
924 if (FAILED(hr))
925 {
926 WARN("Failed to initialize index buffer, hr %#x.\n", hr);
927 HeapFree(GetProcessHeap(), 0, object);
928 return hr;
929 }
930
931 TRACE("Created index buffer %p.\n", object);
932 *buffer = (IDirect3DIndexBuffer9 *)object;
933
934 return D3D_OK;
935}
936
937static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
938 D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface9 **ppSurface,
939 UINT Usage, D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality
940#ifdef VBOXWDDM
941 , HANDLE *shared_handle
942 , void *pvClientMem
943#endif
944 )
945{
946 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
947 IDirect3DSurface9Impl *object;
948 HRESULT hr;
949
950 TRACE("iface %p, width %u, height %u, format %#x, lockable %#x, discard %#x, level %u, surface %p.\n"
951 "usage %#x, pool %#x, multisample_type %#x, multisample_quality %u.\n",
952 iface, Width, Height, Format, Lockable, Discard, Level, ppSurface,
953 Usage, Pool, MultiSample, MultisampleQuality);
954
955 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface9Impl));
956 if (!object)
957 {
958 FIXME("Failed to allocate surface memory.\n");
959 return D3DERR_OUTOFVIDEOMEMORY;
960 }
961
962 hr = surface_init(object, This, Width, Height, Format, Lockable, Discard,
963 Level, Usage, Pool, MultiSample, MultisampleQuality
964#ifdef VBOXWDDM
965 , shared_handle
966 , pvClientMem
967#endif
968 );
969 if (FAILED(hr))
970 {
971 WARN("Failed to initialize surface, hr %#x.\n", hr);
972 HeapFree(GetProcessHeap(), 0, object);
973 return hr;
974 }
975
976 TRACE("Created surface %p.\n", object);
977 *ppSurface = (IDirect3DSurface9 *)object;
978
979 return D3D_OK;
980}
981
982static HRESULT WINAPI IDirect3DDevice9Impl_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT Width, UINT Height,
983 D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable,
984 IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle)
985{
986 HRESULT hr;
987
988 TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
989 "lockable %#x, surface %p, shared_handle %p.\n",
990 iface, Width, Height, Format, MultiSample, MultisampleQuality,
991 Lockable, ppSurface, pSharedHandle);
992
993 hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */,
994 0 /* Level */, ppSurface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, MultisampleQuality
995#ifdef VBOXWDDM
996 , pSharedHandle
997 , NULL
998#endif
999 );
1000
1001 return hr;
1002}
1003
1004static HRESULT WINAPI IDirect3DDevice9Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
1005 D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
1006 DWORD MultisampleQuality, BOOL Discard,
1007 IDirect3DSurface9 **ppSurface, HANDLE* pSharedHandle) {
1008 HRESULT hr;
1009
1010 TRACE("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u.\n"
1011 "discard %#x, surface %p, shared_handle %p.\n",
1012 iface, Width, Height, Format, MultiSample, MultisampleQuality,
1013 Discard, ppSurface, pSharedHandle);
1014
1015 hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, Discard,
1016 0 /* Level */, ppSurface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, MultiSample, MultisampleQuality
1017#ifdef VBOXWDDM
1018 , pSharedHandle
1019 , NULL
1020#endif
1021 );
1022
1023 return hr;
1024}
1025
1026
1027static HRESULT WINAPI IDirect3DDevice9Impl_UpdateSurface(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) {
1028 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1029 HRESULT hr;
1030
1031 TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_point %p.\n",
1032 iface, pSourceSurface, pSourceRect, pDestinationSurface, pDestPoint);
1033
1034 wined3d_mutex_lock();
1035 hr = IWineD3DDevice_UpdateSurface(This->WineD3DDevice, ((IDirect3DSurface9Impl *)pSourceSurface)->wineD3DSurface, pSourceRect, ((IDirect3DSurface9Impl *)pDestinationSurface)->wineD3DSurface, pDestPoint);
1036 wined3d_mutex_unlock();
1037
1038 return hr;
1039}
1040
1041static HRESULT WINAPI IDirect3DDevice9Impl_UpdateTexture(LPDIRECT3DDEVICE9EX iface, IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) {
1042 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1043 HRESULT hr;
1044
1045 TRACE("iface %p, src_texture %p, dst_texture %p.\n", iface, pSourceTexture, pDestinationTexture);
1046
1047 wined3d_mutex_lock();
1048 hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice, ((IDirect3DBaseTexture9Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture9Impl *)pDestinationTexture)->wineD3DBaseTexture);
1049 wined3d_mutex_unlock();
1050
1051 return hr;
1052}
1053
1054static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderTargetData(IDirect3DDevice9Ex *iface,
1055 IDirect3DSurface9 *pRenderTarget, IDirect3DSurface9 *pDestSurface)
1056{
1057 IDirect3DSurface9Impl *renderTarget = (IDirect3DSurface9Impl *)pRenderTarget;
1058 IDirect3DSurface9Impl *destSurface = (IDirect3DSurface9Impl *)pDestSurface;
1059 HRESULT hr;
1060
1061 TRACE("iface %p, render_target %p, dst_surface %p.\n", iface, pRenderTarget, pDestSurface);
1062
1063 wined3d_mutex_lock();
1064 hr = IWineD3DSurface_BltFast(destSurface->wineD3DSurface, 0, 0, renderTarget->wineD3DSurface, NULL, WINEDDBLTFAST_NOCOLORKEY);
1065 wined3d_mutex_unlock();
1066
1067 return hr;
1068}
1069
1070static HRESULT WINAPI IDirect3DDevice9Impl_GetFrontBufferData(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, IDirect3DSurface9* pDestSurface) {
1071 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1072 IDirect3DSurface9Impl *destSurface = (IDirect3DSurface9Impl *)pDestSurface;
1073 HRESULT hr;
1074
1075 TRACE("iface %p, swapchain %u, dst_surface %p.\n", iface, iSwapChain, pDestSurface);
1076
1077 wined3d_mutex_lock();
1078 hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, iSwapChain, destSurface->wineD3DSurface);
1079 wined3d_mutex_unlock();
1080
1081 return hr;
1082}
1083
1084static HRESULT WINAPI IDirect3DDevice9Impl_StretchRect(IDirect3DDevice9Ex *iface, IDirect3DSurface9 *pSourceSurface,
1085 const RECT *pSourceRect, IDirect3DSurface9 *pDestSurface, const RECT *pDestRect, D3DTEXTUREFILTERTYPE Filter)
1086{
1087 IDirect3DSurface9Impl *src = (IDirect3DSurface9Impl *) pSourceSurface;
1088 IDirect3DSurface9Impl *dst = (IDirect3DSurface9Impl *) pDestSurface;
1089 HRESULT hr;
1090
1091 TRACE("iface %p, src_surface %p, src_rect %p, dst_surface %p, dst_rect %p, filter %#x.\n",
1092 iface, pSourceSurface, pSourceRect, pDestSurface, pDestRect, Filter);
1093
1094 wined3d_mutex_lock();
1095 hr = IWineD3DSurface_Blt(dst->wineD3DSurface, pDestRect, src->wineD3DSurface, pSourceRect, 0, NULL, Filter);
1096 wined3d_mutex_unlock();
1097
1098 return hr;
1099}
1100
1101static HRESULT WINAPI IDirect3DDevice9Impl_ColorFill(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) {
1102 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1103 IDirect3DSurface9Impl *surface = (IDirect3DSurface9Impl *)pSurface;
1104 WINED3DPOOL pool;
1105 WINED3DRESOURCETYPE restype;
1106 DWORD usage;
1107 WINED3DSURFACE_DESC desc;
1108 HRESULT hr;
1109
1110 TRACE("iface %p, surface %p, rect %p, color 0x%08x.\n", iface, pSurface, pRect, color);
1111
1112 wined3d_mutex_lock();
1113
1114 IWineD3DSurface_GetDesc(surface->wineD3DSurface, &desc);
1115 usage = desc.usage;
1116 pool = desc.pool;
1117 restype = desc.resource_type;
1118
1119 /* This method is only allowed with surfaces that are render targets, or offscreen plain surfaces
1120 * in D3DPOOL_DEFAULT
1121 */
1122 if(!(usage & WINED3DUSAGE_RENDERTARGET) && (pool != WINED3DPOOL_DEFAULT || restype != WINED3DRTYPE_SURFACE)) {
1123 wined3d_mutex_unlock();
1124 WARN("Surface is not a render target, or not a stand-alone D3DPOOL_DEFAULT surface\n");
1125 return D3DERR_INVALIDCALL;
1126 }
1127
1128 /* Colorfill can only be used on rendertarget surfaces, or offscreen plain surfaces in D3DPOOL_DEFAULT */
1129 /* Note: D3DRECT is compatible with WINED3DRECT */
1130 hr = IWineD3DDevice_ColorFill(This->WineD3DDevice, surface->wineD3DSurface, (CONST WINED3DRECT*)pRect, color);
1131
1132 wined3d_mutex_unlock();
1133
1134 return hr;
1135}
1136
1137static HRESULT WINAPI IDirect3DDevice9Impl_CreateOffscreenPlainSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9 **ppSurface, HANDLE* pSharedHandle) {
1138 HRESULT hr;
1139
1140 TRACE("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p.\n",
1141 iface, Width, Height, Format, Pool, ppSurface, pSharedHandle);
1142
1143 if(Pool == D3DPOOL_MANAGED ){
1144 FIXME("Attempting to create a managed offscreen plain surface\n");
1145 return D3DERR_INVALIDCALL;
1146 }
1147 /*
1148 'Off-screen plain surfaces are always lockable, regardless of their pool types.'
1149 but then...
1150 D3DPOOL_DEFAULT is the appropriate pool for use with the IDirect3DDevice9::StretchRect and IDirect3DDevice9::ColorFill.
1151 Why, their always lockable?
1152 should I change the usage to dynamic?
1153 */
1154 hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE /* Discard */,
1155 0 /* Level */, ppSurface, 0 /* Usage (undefined/none) */, (WINED3DPOOL)Pool, D3DMULTISAMPLE_NONE,
1156 0 /* MultisampleQuality */
1157#ifdef VBOXWDDM
1158 , pSharedHandle
1159 , NULL
1160#endif
1161 );
1162
1163 return hr;
1164}
1165
1166/* TODO: move to wineD3D */
1167static HRESULT WINAPI IDirect3DDevice9Impl_SetRenderTarget(LPDIRECT3DDEVICE9EX iface, DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) {
1168 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1169 IDirect3DSurface9Impl *pSurface = (IDirect3DSurface9Impl*)pRenderTarget;
1170 HRESULT hr;
1171
1172 TRACE("iface %p, idx %u, surface %p.\n", iface, RenderTargetIndex, pRenderTarget);
1173
1174 if (RenderTargetIndex >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
1175 {
1176 WARN("Invalid index %u specified.\n", RenderTargetIndex);
1177 return D3DERR_INVALIDCALL;
1178 }
1179
1180 wined3d_mutex_lock();
1181 hr = IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, RenderTargetIndex, pSurface ? pSurface->wineD3DSurface : NULL, TRUE);
1182 wined3d_mutex_unlock();
1183
1184 return hr;
1185}
1186
1187static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9EX iface, DWORD RenderTargetIndex, IDirect3DSurface9 **ppRenderTarget) {
1188 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1189 IWineD3DSurface *pRenderTarget;
1190 HRESULT hr;
1191
1192 TRACE("iface %p, idx %u, surface %p.\n", iface, RenderTargetIndex, ppRenderTarget);
1193
1194 if (ppRenderTarget == NULL) {
1195 return D3DERR_INVALIDCALL;
1196 }
1197
1198 if (RenderTargetIndex >= D3D9_MAX_SIMULTANEOUS_RENDERTARGETS)
1199 {
1200 WARN("Invalid index %u specified.\n", RenderTargetIndex);
1201 return D3DERR_INVALIDCALL;
1202 }
1203
1204 wined3d_mutex_lock();
1205
1206 hr=IWineD3DDevice_GetRenderTarget(This->WineD3DDevice,RenderTargetIndex,&pRenderTarget);
1207
1208 if (FAILED(hr))
1209 {
1210 FIXME("Call to IWineD3DDevice_GetRenderTarget failed, hr %#x\n", hr);
1211 }
1212 else if (!pRenderTarget)
1213 {
1214 *ppRenderTarget = NULL;
1215 }
1216 else
1217 {
1218 IWineD3DSurface_GetParent(pRenderTarget, (IUnknown **)ppRenderTarget);
1219 IWineD3DSurface_Release(pRenderTarget);
1220 }
1221
1222 wined3d_mutex_unlock();
1223
1224 return hr;
1225}
1226
1227static HRESULT WINAPI IDirect3DDevice9Impl_SetDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pZStencilSurface) {
1228 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1229 IDirect3DSurface9Impl *pSurface;
1230 IDirect3DSurface9 *pOldSurface;
1231 HRESULT hr;
1232
1233 TRACE("iface %p, depth_stencil %p.\n", iface, pZStencilSurface);
1234
1235 pSurface = (IDirect3DSurface9Impl*)pZStencilSurface;
1236
1237 wined3d_mutex_lock();
1238 hr = IDirect3DDevice9_GetDepthStencilSurface(iface, &pOldSurface);
1239 if (D3D_OK==hr) {
1240 IDirect3DSurface9_Release(pOldSurface);
1241 IDirect3DSurface9_Release(pOldSurface);
1242 }
1243 hr = IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL==pSurface ? NULL : pSurface->wineD3DSurface);
1244 if (pZStencilSurface) {
1245 IDirect3DSurface9_AddRef(pZStencilSurface);
1246 }
1247 wined3d_mutex_unlock();
1248
1249 return hr;
1250}
1251
1252static HRESULT WINAPI IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9 **ppZStencilSurface) {
1253 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1254 HRESULT hr = D3D_OK;
1255 IWineD3DSurface *pZStencilSurface;
1256
1257 TRACE("iface %p, depth_stencil %p.\n", iface, ppZStencilSurface);
1258
1259 if(ppZStencilSurface == NULL){
1260 return D3DERR_INVALIDCALL;
1261 }
1262
1263 wined3d_mutex_lock();
1264 hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
1265 if (hr == WINED3D_OK) {
1266 IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface);
1267 IWineD3DSurface_Release(pZStencilSurface);
1268 } else {
1269 if (hr != WINED3DERR_NOTFOUND)
1270 WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
1271 *ppZStencilSurface = NULL;
1272 }
1273 wined3d_mutex_unlock();
1274
1275 return hr;
1276}
1277
1278static HRESULT WINAPI IDirect3DDevice9Impl_BeginScene(LPDIRECT3DDEVICE9EX iface) {
1279 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1280 HRESULT hr;
1281
1282 TRACE("iface %p.\n", iface);
1283
1284 wined3d_mutex_lock();
1285 hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
1286 wined3d_mutex_unlock();
1287
1288 return hr;
1289}
1290
1291static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_EndScene(LPDIRECT3DDEVICE9EX iface) {
1292 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1293 HRESULT hr;
1294
1295 TRACE("iface %p.\n", iface);
1296
1297 wined3d_mutex_lock();
1298 hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
1299 wined3d_mutex_unlock();
1300
1301 return hr;
1302}
1303
1304static HRESULT WINAPI IDirect3DDevice9Impl_Clear(LPDIRECT3DDEVICE9EX iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
1305 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1306 HRESULT hr;
1307
1308 TRACE("iface %p, rect_count %u, rects %p, flags %#x, color 0x%08x, z %.8e, stencil %u.\n",
1309 iface, Count, pRects, Flags, Color, Z, Stencil);
1310
1311 /* Note: D3DRECT is compatible with WINED3DRECT */
1312 wined3d_mutex_lock();
1313 hr = IWineD3DDevice_Clear(This->WineD3DDevice, Count, (CONST WINED3DRECT*) pRects, Flags, Color, Z, Stencil);
1314 wined3d_mutex_unlock();
1315
1316 return hr;
1317}
1318
1319static HRESULT WINAPI IDirect3DDevice9Impl_SetTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* lpMatrix) {
1320 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1321 HRESULT hr;
1322
1323 TRACE("iface %p, state %#x, matrix %p.\n", iface, State, lpMatrix);
1324
1325 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
1326 wined3d_mutex_lock();
1327 hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
1328 wined3d_mutex_unlock();
1329
1330 return hr;
1331}
1332
1333static HRESULT WINAPI IDirect3DDevice9Impl_GetTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) {
1334 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1335 HRESULT hr;
1336
1337 TRACE("iface %p, state %#x, matrix %p.\n", iface, State, pMatrix);
1338
1339 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
1340 wined3d_mutex_lock();
1341 hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
1342 wined3d_mutex_unlock();
1343
1344 return hr;
1345}
1346
1347static HRESULT WINAPI IDirect3DDevice9Impl_MultiplyTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
1348 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1349 HRESULT hr;
1350
1351 TRACE("iface %p, state %#x, matrix %p.\n", iface, State, pMatrix);
1352
1353 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
1354 wined3d_mutex_lock();
1355 hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
1356 wined3d_mutex_unlock();
1357
1358 return hr;
1359}
1360
1361static HRESULT WINAPI IDirect3DDevice9Impl_SetViewport(LPDIRECT3DDEVICE9EX iface, CONST D3DVIEWPORT9* pViewport) {
1362 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1363 HRESULT hr;
1364
1365 TRACE("iface %p, viewport %p.\n", iface, pViewport);
1366
1367 /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
1368 wined3d_mutex_lock();
1369 hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
1370 wined3d_mutex_unlock();
1371
1372 return hr;
1373}
1374
1375static HRESULT WINAPI IDirect3DDevice9Impl_GetViewport(LPDIRECT3DDEVICE9EX iface, D3DVIEWPORT9* pViewport) {
1376 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1377 HRESULT hr;
1378
1379 TRACE("iface %p, viewport %p.\n", iface, pViewport);
1380
1381 /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
1382 wined3d_mutex_lock();
1383 hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
1384 wined3d_mutex_unlock();
1385
1386 return hr;
1387}
1388
1389static HRESULT WINAPI IDirect3DDevice9Impl_SetMaterial(LPDIRECT3DDEVICE9EX iface, CONST D3DMATERIAL9* pMaterial) {
1390 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1391 HRESULT hr;
1392
1393 TRACE("iface %p, material %p.\n", iface, pMaterial);
1394
1395 /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
1396 wined3d_mutex_lock();
1397 hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
1398 wined3d_mutex_unlock();
1399
1400 return hr;
1401}
1402
1403static HRESULT WINAPI IDirect3DDevice9Impl_GetMaterial(LPDIRECT3DDEVICE9EX iface, D3DMATERIAL9* pMaterial) {
1404 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1405 HRESULT hr;
1406
1407 TRACE("iface %p, material %p.\n", iface, pMaterial);
1408
1409 /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
1410 wined3d_mutex_lock();
1411 hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
1412 wined3d_mutex_unlock();
1413
1414 return hr;
1415}
1416
1417static HRESULT WINAPI IDirect3DDevice9Impl_SetLight(LPDIRECT3DDEVICE9EX iface, DWORD Index, CONST D3DLIGHT9* pLight) {
1418 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1419 HRESULT hr;
1420
1421 TRACE("iface %p, index %u, light %p.\n", iface, Index, pLight);
1422
1423 /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
1424 wined3d_mutex_lock();
1425 hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
1426 wined3d_mutex_unlock();
1427
1428 return hr;
1429}
1430
1431static HRESULT WINAPI IDirect3DDevice9Impl_GetLight(LPDIRECT3DDEVICE9EX iface, DWORD Index, D3DLIGHT9* pLight) {
1432 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1433 HRESULT hr;
1434
1435 TRACE("iface %p, index %u, light %p.\n", iface, Index, pLight);
1436
1437 /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
1438 wined3d_mutex_lock();
1439 hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
1440 wined3d_mutex_unlock();
1441
1442 return hr;
1443}
1444
1445static HRESULT WINAPI IDirect3DDevice9Impl_LightEnable(LPDIRECT3DDEVICE9EX iface, DWORD Index, BOOL Enable) {
1446 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1447 HRESULT hr;
1448
1449 TRACE("iface %p, index %u, enable %#x.\n", iface, Index, Enable);
1450
1451 wined3d_mutex_lock();
1452 hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
1453 wined3d_mutex_unlock();
1454
1455 return hr;
1456}
1457
1458static HRESULT WINAPI IDirect3DDevice9Impl_GetLightEnable(LPDIRECT3DDEVICE9EX iface, DWORD Index, BOOL* pEnable) {
1459 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1460 HRESULT hr;
1461
1462 TRACE("iface %p, index %u, enable %p.\n", iface, Index, pEnable);
1463
1464 wined3d_mutex_lock();
1465 hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
1466 wined3d_mutex_unlock();
1467
1468 return hr;
1469}
1470
1471static HRESULT WINAPI IDirect3DDevice9Impl_SetClipPlane(LPDIRECT3DDEVICE9EX iface, DWORD Index, CONST float* pPlane) {
1472 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1473 HRESULT hr;
1474
1475 TRACE("iface %p, index %u, plane %p.\n", iface, Index, pPlane);
1476
1477 wined3d_mutex_lock();
1478 hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
1479 wined3d_mutex_unlock();
1480
1481 return hr;
1482}
1483
1484static HRESULT WINAPI IDirect3DDevice9Impl_GetClipPlane(LPDIRECT3DDEVICE9EX iface, DWORD Index, float* pPlane) {
1485 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1486 HRESULT hr;
1487
1488 TRACE("iface %p, index %u, plane %p.\n", iface, Index, pPlane);
1489
1490 wined3d_mutex_lock();
1491 hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
1492 wined3d_mutex_unlock();
1493
1494 return hr;
1495}
1496
1497static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_SetRenderState(LPDIRECT3DDEVICE9EX iface, D3DRENDERSTATETYPE State, DWORD Value) {
1498 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1499 HRESULT hr;
1500
1501 TRACE("iface %p, state %#x, value %#x.\n", iface, State, Value);
1502
1503 wined3d_mutex_lock();
1504 hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
1505 wined3d_mutex_unlock();
1506
1507 return hr;
1508}
1509
1510static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderState(LPDIRECT3DDEVICE9EX iface, D3DRENDERSTATETYPE State, DWORD* pValue) {
1511 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1512 HRESULT hr;
1513
1514 TRACE("iface %p, state %#x, value %p.\n", iface, State, pValue);
1515
1516 wined3d_mutex_lock();
1517 hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
1518 wined3d_mutex_unlock();
1519
1520 return hr;
1521}
1522
1523static HRESULT WINAPI IDirect3DDevice9Impl_CreateStateBlock(IDirect3DDevice9Ex *iface,
1524 D3DSTATEBLOCKTYPE type, IDirect3DStateBlock9 **stateblock)
1525{
1526 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1527 IDirect3DStateBlock9Impl *object;
1528 HRESULT hr;
1529
1530 TRACE("iface %p, type %#x, stateblock %p.\n", iface, type, stateblock);
1531
1532 if (type != D3DSBT_ALL && type != D3DSBT_PIXELSTATE && type != D3DSBT_VERTEXSTATE)
1533 {
1534 WARN("Unexpected stateblock type, returning D3DERR_INVALIDCALL.\n");
1535 return D3DERR_INVALIDCALL;
1536 }
1537
1538 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1539 if (!object)
1540 {
1541 ERR("Failed to allocate stateblock memory.\n");
1542 return E_OUTOFMEMORY;
1543 }
1544
1545 hr = stateblock_init(object, This, type, NULL);
1546 if (FAILED(hr))
1547 {
1548 WARN("Failed to initialize stateblock, hr %#x.\n", hr);
1549 HeapFree(GetProcessHeap(), 0, object);
1550 return hr;
1551 }
1552
1553 TRACE("Created stateblock %p.\n", object);
1554 *stateblock = (IDirect3DStateBlock9 *)object;
1555
1556 return D3D_OK;
1557}
1558
1559static HRESULT WINAPI IDirect3DDevice9Impl_BeginStateBlock(IDirect3DDevice9Ex *iface)
1560{
1561 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1562 HRESULT hr;
1563
1564 TRACE("iface %p.\n", iface);
1565
1566 wined3d_mutex_lock();
1567 hr = IWineD3DDevice_BeginStateBlock(This->WineD3DDevice);
1568 wined3d_mutex_unlock();
1569
1570 return hr;
1571}
1572
1573static HRESULT WINAPI IDirect3DDevice9Impl_EndStateBlock(IDirect3DDevice9Ex *iface, IDirect3DStateBlock9 **stateblock)
1574{
1575 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1576 IWineD3DStateBlock *wined3d_stateblock;
1577 IDirect3DStateBlock9Impl *object;
1578 HRESULT hr;
1579
1580 TRACE("iface %p, stateblock %p.\n", iface, stateblock);
1581
1582 wined3d_mutex_lock();
1583 hr = IWineD3DDevice_EndStateBlock(This->WineD3DDevice, &wined3d_stateblock);
1584 wined3d_mutex_unlock();
1585 if (FAILED(hr))
1586 {
1587 WARN("IWineD3DDevice_EndStateBlock() failed, hr %#x.\n", hr);
1588 return hr;
1589 }
1590
1591 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
1592 if (!object)
1593 {
1594 ERR("Failed to allocate stateblock memory.\n");
1595 IWineD3DStateBlock_Release(wined3d_stateblock);
1596 return E_OUTOFMEMORY;
1597 }
1598
1599 hr = stateblock_init(object, This, 0, wined3d_stateblock);
1600 if (FAILED(hr))
1601 {
1602 WARN("Failed to initialize stateblock, hr %#x.\n", hr);
1603 IWineD3DStateBlock_Release(wined3d_stateblock);
1604 HeapFree(GetProcessHeap(), 0, object);
1605 return hr;
1606 }
1607
1608 TRACE("Created stateblock %p.\n", object);
1609 *stateblock = (IDirect3DStateBlock9 *)object;
1610
1611 return D3D_OK;
1612}
1613
1614static HRESULT WINAPI IDirect3DDevice9Impl_SetClipStatus(LPDIRECT3DDEVICE9EX iface, CONST D3DCLIPSTATUS9* pClipStatus) {
1615 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1616 HRESULT hr;
1617
1618 TRACE("iface %p, clip_status %p.\n", iface, pClipStatus);
1619
1620 wined3d_mutex_lock();
1621 hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
1622 wined3d_mutex_unlock();
1623
1624 return hr;
1625}
1626
1627static HRESULT WINAPI IDirect3DDevice9Impl_GetClipStatus(LPDIRECT3DDEVICE9EX iface, D3DCLIPSTATUS9* pClipStatus) {
1628 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1629 HRESULT hr;
1630
1631 TRACE("iface %p, clip_status %p.\n", iface, pClipStatus);
1632
1633 wined3d_mutex_lock();
1634 hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
1635 wined3d_mutex_unlock();
1636
1637 return hr;
1638}
1639
1640static HRESULT WINAPI IDirect3DDevice9Impl_GetTexture(LPDIRECT3DDEVICE9EX iface, DWORD Stage, IDirect3DBaseTexture9 **ppTexture) {
1641 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1642 IWineD3DBaseTexture *retTexture = NULL;
1643 HRESULT rc = D3D_OK;
1644
1645 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, ppTexture);
1646
1647 if(ppTexture == NULL){
1648 return D3DERR_INVALIDCALL;
1649 }
1650
1651 wined3d_mutex_lock();
1652 rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, &retTexture);
1653 if (SUCCEEDED(rc) && NULL != retTexture) {
1654 IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture);
1655 IWineD3DBaseTexture_Release(retTexture);
1656 } else {
1657 if(FAILED(rc)) {
1658 WARN("Call to get texture (%d) failed (%p)\n", Stage, retTexture);
1659 }
1660 *ppTexture = NULL;
1661 }
1662 wined3d_mutex_unlock();
1663
1664 return rc;
1665}
1666
1667static HRESULT WINAPI IDirect3DDevice9Impl_SetTexture(LPDIRECT3DDEVICE9EX iface, DWORD Stage, IDirect3DBaseTexture9* pTexture) {
1668 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1669 HRESULT hr;
1670
1671 TRACE("iface %p, stage %u, texture %p.\n", iface, Stage, pTexture);
1672
1673 wined3d_mutex_lock();
1674 hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
1675 pTexture==NULL ? NULL:((IDirect3DBaseTexture9Impl *)pTexture)->wineD3DBaseTexture);
1676 wined3d_mutex_unlock();
1677
1678 return hr;
1679}
1680
1681static const WINED3DTEXTURESTAGESTATETYPE tss_lookup[] =
1682{
1683 WINED3DTSS_FORCE_DWORD, /* 0, unused */
1684 WINED3DTSS_COLOROP, /* 1, D3DTSS_COLOROP */
1685 WINED3DTSS_COLORARG1, /* 2, D3DTSS_COLORARG1 */
1686 WINED3DTSS_COLORARG2, /* 3, D3DTSS_COLORARG2 */
1687 WINED3DTSS_ALPHAOP, /* 4, D3DTSS_ALPHAOP */
1688 WINED3DTSS_ALPHAARG1, /* 5, D3DTSS_ALPHAARG1 */
1689 WINED3DTSS_ALPHAARG2, /* 6, D3DTSS_ALPHAARG2 */
1690 WINED3DTSS_BUMPENVMAT00, /* 7, D3DTSS_BUMPENVMAT00 */
1691 WINED3DTSS_BUMPENVMAT01, /* 8, D3DTSS_BUMPENVMAT01 */
1692 WINED3DTSS_BUMPENVMAT10, /* 9, D3DTSS_BUMPENVMAT10 */
1693 WINED3DTSS_BUMPENVMAT11, /* 10, D3DTSS_BUMPENVMAT11 */
1694 WINED3DTSS_TEXCOORDINDEX, /* 11, D3DTSS_TEXCOORDINDEX */
1695 WINED3DTSS_FORCE_DWORD, /* 12, unused */
1696 WINED3DTSS_FORCE_DWORD, /* 13, unused */
1697 WINED3DTSS_FORCE_DWORD, /* 14, unused */
1698 WINED3DTSS_FORCE_DWORD, /* 15, unused */
1699 WINED3DTSS_FORCE_DWORD, /* 16, unused */
1700 WINED3DTSS_FORCE_DWORD, /* 17, unused */
1701 WINED3DTSS_FORCE_DWORD, /* 18, unused */
1702 WINED3DTSS_FORCE_DWORD, /* 19, unused */
1703 WINED3DTSS_FORCE_DWORD, /* 20, unused */
1704 WINED3DTSS_FORCE_DWORD, /* 21, unused */
1705 WINED3DTSS_BUMPENVLSCALE, /* 22, D3DTSS_BUMPENVLSCALE */
1706 WINED3DTSS_BUMPENVLOFFSET, /* 23, D3DTSS_BUMPENVLOFFSET */
1707 WINED3DTSS_TEXTURETRANSFORMFLAGS, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
1708 WINED3DTSS_FORCE_DWORD, /* 25, unused */
1709 WINED3DTSS_COLORARG0, /* 26, D3DTSS_COLORARG0 */
1710 WINED3DTSS_ALPHAARG0, /* 27, D3DTSS_ALPHAARG0 */
1711 WINED3DTSS_RESULTARG, /* 28, D3DTSS_RESULTARG */
1712 WINED3DTSS_FORCE_DWORD, /* 29, unused */
1713 WINED3DTSS_FORCE_DWORD, /* 30, unused */
1714 WINED3DTSS_FORCE_DWORD, /* 31, unused */
1715 WINED3DTSS_CONSTANT, /* 32, D3DTSS_CONSTANT */
1716};
1717
1718static HRESULT WINAPI IDirect3DDevice9Impl_GetTextureStageState(LPDIRECT3DDEVICE9EX iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) {
1719 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1720 HRESULT hr;
1721
1722 TRACE("iface %p, stage %u, state %#x, value %p.\n", iface, Stage, Type, pValue);
1723
1724 wined3d_mutex_lock();
1725 hr = IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], pValue);
1726 wined3d_mutex_unlock();
1727
1728 return hr;
1729}
1730
1731static HRESULT WINAPI IDirect3DDevice9Impl_SetTextureStageState(LPDIRECT3DDEVICE9EX iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
1732 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1733 HRESULT hr;
1734
1735 TRACE("iface %p, stage %u, state %#x, value %#x.\n", iface, Stage, Type, Value);
1736
1737 wined3d_mutex_lock();
1738 hr = IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], Value);
1739 wined3d_mutex_unlock();
1740
1741 return hr;
1742}
1743
1744static HRESULT WINAPI IDirect3DDevice9Impl_GetSamplerState(IDirect3DDevice9Ex *iface, DWORD Sampler,
1745 D3DSAMPLERSTATETYPE Type, DWORD *pValue)
1746{
1747 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1748 HRESULT hr;
1749
1750 TRACE("iface %p, sampler %u, state %#x, value %p.\n", iface, Sampler, Type, pValue);
1751
1752 wined3d_mutex_lock();
1753 hr = IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Sampler, Type, pValue);
1754 wined3d_mutex_unlock();
1755
1756 return hr;
1757}
1758
1759static HRESULT WINAPI DECLSPEC_HOTPATCH IDirect3DDevice9Impl_SetSamplerState(LPDIRECT3DDEVICE9EX iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) {
1760 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1761 HRESULT hr;
1762
1763 TRACE("iface %p, sampler %u, state %#x, value %#x.\n", iface, Sampler, Type, Value);
1764
1765 wined3d_mutex_lock();
1766 hr = IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Sampler, Type, Value);
1767 wined3d_mutex_unlock();
1768
1769 return hr;
1770}
1771
1772static HRESULT WINAPI IDirect3DDevice9Impl_ValidateDevice(LPDIRECT3DDEVICE9EX iface, DWORD* pNumPasses) {
1773 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1774 HRESULT hr;
1775
1776 TRACE("iface %p, pass_count %p.\n", iface, pNumPasses);
1777
1778 wined3d_mutex_lock();
1779 hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
1780 wined3d_mutex_unlock();
1781
1782 return hr;
1783}
1784
1785static HRESULT WINAPI IDirect3DDevice9Impl_SetPaletteEntries(IDirect3DDevice9Ex *iface, UINT PaletteNumber,
1786 const PALETTEENTRY *pEntries)
1787{
1788 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1789 HRESULT hr;
1790
1791 TRACE("iface %p, palette_idx %u, entries %p.\n", iface, PaletteNumber, pEntries);
1792
1793 wined3d_mutex_lock();
1794 hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
1795 wined3d_mutex_unlock();
1796
1797 return hr;
1798}
1799
1800static HRESULT WINAPI IDirect3DDevice9Impl_GetPaletteEntries(LPDIRECT3DDEVICE9EX iface, UINT PaletteNumber, PALETTEENTRY* pEntries) {
1801 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1802 HRESULT hr;
1803
1804 TRACE("iface %p, palette_idx %u, entries %p.\n", iface, PaletteNumber, pEntries);
1805
1806 wined3d_mutex_lock();
1807 hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
1808 wined3d_mutex_unlock();
1809
1810 return hr;
1811}
1812
1813static HRESULT WINAPI IDirect3DDevice9Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE9EX iface, UINT PaletteNumber) {
1814 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1815 HRESULT hr;
1816
1817 TRACE("iface %p, palette_idx %u.\n", iface, PaletteNumber);
1818
1819 wined3d_mutex_lock();
1820 hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
1821 wined3d_mutex_unlock();
1822
1823 return hr;
1824}
1825
1826static HRESULT WINAPI IDirect3DDevice9Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE9EX iface, UINT* PaletteNumber) {
1827 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1828 HRESULT hr;
1829
1830 TRACE("iface %p, palette_idx %p.\n", iface, PaletteNumber);
1831
1832 wined3d_mutex_lock();
1833 hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
1834 wined3d_mutex_unlock();
1835
1836 return hr;
1837}
1838
1839static HRESULT WINAPI IDirect3DDevice9Impl_SetScissorRect(LPDIRECT3DDEVICE9EX iface, CONST RECT* pRect) {
1840 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1841 HRESULT hr;
1842
1843 TRACE("iface %p, rect %p.\n", iface, pRect);
1844
1845 wined3d_mutex_lock();
1846 hr = IWineD3DDevice_SetScissorRect(This->WineD3DDevice, pRect);
1847 wined3d_mutex_unlock();
1848
1849 return hr;
1850}
1851
1852static HRESULT WINAPI IDirect3DDevice9Impl_GetScissorRect(LPDIRECT3DDEVICE9EX iface, RECT* pRect) {
1853 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1854 HRESULT hr;
1855
1856 TRACE("iface %p, rect %p.\n", iface, pRect);
1857
1858 wined3d_mutex_lock();
1859 hr = IWineD3DDevice_GetScissorRect(This->WineD3DDevice, pRect);
1860 wined3d_mutex_unlock();
1861
1862 return hr;
1863}
1864
1865static HRESULT WINAPI IDirect3DDevice9Impl_SetSoftwareVertexProcessing(LPDIRECT3DDEVICE9EX iface, BOOL bSoftware) {
1866 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1867 HRESULT hr;
1868
1869 TRACE("iface %p, software %#x.\n", iface, bSoftware);
1870
1871 wined3d_mutex_lock();
1872 hr = IWineD3DDevice_SetSoftwareVertexProcessing(This->WineD3DDevice, bSoftware);
1873 wined3d_mutex_unlock();
1874
1875 return hr;
1876}
1877
1878static BOOL WINAPI IDirect3DDevice9Impl_GetSoftwareVertexProcessing(LPDIRECT3DDEVICE9EX iface) {
1879 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1880 BOOL ret;
1881
1882 TRACE("iface %p.\n", iface);
1883
1884 wined3d_mutex_lock();
1885 ret = IWineD3DDevice_GetSoftwareVertexProcessing(This->WineD3DDevice);
1886 wined3d_mutex_unlock();
1887
1888 return ret;
1889}
1890
1891static HRESULT WINAPI IDirect3DDevice9Impl_SetNPatchMode(LPDIRECT3DDEVICE9EX iface, float nSegments) {
1892 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1893 HRESULT hr;
1894
1895 TRACE("iface %p, segment_count %.8e.\n", iface, nSegments);
1896
1897 wined3d_mutex_lock();
1898 hr = IWineD3DDevice_SetNPatchMode(This->WineD3DDevice, nSegments);
1899 wined3d_mutex_unlock();
1900
1901 return hr;
1902}
1903
1904static float WINAPI IDirect3DDevice9Impl_GetNPatchMode(LPDIRECT3DDEVICE9EX iface) {
1905 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1906 float ret;
1907
1908 TRACE("iface %p.\n", iface);
1909
1910 wined3d_mutex_lock();
1911 ret = IWineD3DDevice_GetNPatchMode(This->WineD3DDevice);
1912 wined3d_mutex_unlock();
1913
1914 return ret;
1915}
1916
1917static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE PrimitiveType,
1918 UINT StartVertex, UINT PrimitiveCount)
1919{
1920 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1921 HRESULT hr;
1922
1923 TRACE("iface %p, primitive_type %#x, start_vertex %u, primitive_count %u.\n",
1924 iface, PrimitiveType, StartVertex, PrimitiveCount);
1925
1926 wined3d_mutex_lock();
1927 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1928 hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex,
1929 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
1930 wined3d_mutex_unlock();
1931
1932 return hr;
1933}
1934
1935static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE9EX iface, D3DPRIMITIVETYPE PrimitiveType,
1936 INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) {
1937 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1938 HRESULT hr;
1939
1940 TRACE("iface %p, primitive_type %#x, base_vertex_idx %u, min_vertex_idx %u,\n"
1941 "vertex_count %u, start_idx %u, primitive_count %u.\n",
1942 iface, PrimitiveType, BaseVertexIndex, MinVertexIndex,
1943 NumVertices, startIndex, primCount);
1944
1945 wined3d_mutex_lock();
1946 IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, BaseVertexIndex);
1947 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1948 hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, startIndex,
1949 vertex_count_from_primitive_count(PrimitiveType, primCount));
1950 wined3d_mutex_unlock();
1951
1952 return hr;
1953}
1954
1955static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE PrimitiveType,
1956 UINT PrimitiveCount, const void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
1957{
1958 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1959 HRESULT hr;
1960
1961 TRACE("iface %p, primitive_type %#x, primitive_count %u, data %p, stride %u.\n",
1962 iface, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
1963
1964 wined3d_mutex_lock();
1965 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1966 hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice,
1967 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
1968 pVertexStreamZeroData, VertexStreamZeroStride);
1969 wined3d_mutex_unlock();
1970
1971 return hr;
1972}
1973
1974static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE9EX iface, D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex,
1975 UINT NumVertexIndices, UINT PrimitiveCount, CONST void* pIndexData,
1976 D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) {
1977 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1978 HRESULT hr;
1979
1980 TRACE("iface %p, primitive_type %#x, min_vertex_idx %u, index_count %u, primitive_count %u,\n"
1981 "index_data %p, index_format %#x, vertex_data %p, vertex_stride %u.\n",
1982 iface, PrimitiveType, MinVertexIndex, NumVertexIndices, PrimitiveCount,
1983 pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
1984
1985 wined3d_mutex_lock();
1986 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1987 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice,
1988 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
1989 wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
1990 wined3d_mutex_unlock();
1991
1992 return hr;
1993}
1994
1995static HRESULT WINAPI IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9EX iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) {
1996 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1997 IDirect3DVertexDeclaration9Impl *Decl = (IDirect3DVertexDeclaration9Impl *) pVertexDecl;
1998 HRESULT hr;
1999 IDirect3DVertexBuffer9Impl *dest = (IDirect3DVertexBuffer9Impl *) pDestBuffer;
2000
2001 TRACE("iface %p, src_start_idx %u, dst_idx %u, vertex_count %u, dst_buffer %p, declaration %p, flags %#x.\n",
2002 iface, SrcStartIndex, DestIndex, VertexCount, pDestBuffer, pVertexDecl, Flags);
2003
2004 wined3d_mutex_lock();
2005 hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags, dest->fvf);
2006 wined3d_mutex_unlock();
2007
2008 return hr;
2009}
2010
2011static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexDeclaration(IDirect3DDevice9Ex *iface,
2012 const D3DVERTEXELEMENT9 *elements, IDirect3DVertexDeclaration9 **declaration)
2013{
2014 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2015 IDirect3DVertexDeclaration9Impl *object;
2016 HRESULT hr;
2017
2018 TRACE("iface %p, elements %p, declaration %p.\n", iface, elements, declaration);
2019
2020 if (!declaration)
2021 {
2022 WARN("Caller passed a NULL declaration, returning D3DERR_INVALIDCALL.\n");
2023 return D3DERR_INVALIDCALL;
2024 }
2025
2026 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2027 if (!object)
2028 {
2029 ERR("Failed to allocate vertex declaration memory.\n");
2030 return E_OUTOFMEMORY;
2031 }
2032
2033 hr = vertexdeclaration_init(object, This, elements);
2034 if (FAILED(hr))
2035 {
2036 WARN("Failed to initialize vertex declaration, hr %#x.\n", hr);
2037 HeapFree(GetProcessHeap(), 0, object);
2038 return hr;
2039 }
2040
2041 TRACE("Created vertex declaration %p.\n", object);
2042 *declaration = (IDirect3DVertexDeclaration9 *)object;
2043
2044 return D3D_OK;
2045}
2046
2047static IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, DWORD fvf) {
2048 HRESULT hr;
2049 D3DVERTEXELEMENT9* elements = NULL;
2050 IDirect3DVertexDeclaration9* pDecl = NULL;
2051 int p, low, high; /* deliberately signed */
2052 IDirect3DVertexDeclaration9 **convertedDecls = This->convertedDecls;
2053
2054 TRACE("Searching for declaration for fvf %08x... ", fvf);
2055
2056 low = 0;
2057 high = This->numConvertedDecls - 1;
2058 while(low <= high) {
2059 p = (low + high) >> 1;
2060 TRACE("%d ", p);
2061 if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF == fvf) {
2062 TRACE("found %p\n", convertedDecls[p]);
2063 return convertedDecls[p];
2064 } else if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF < fvf) {
2065 low = p + 1;
2066 } else {
2067 high = p - 1;
2068 }
2069 }
2070 TRACE("not found. Creating and inserting at position %d.\n", low);
2071
2072 hr = vdecl_convert_fvf(fvf, &elements);
2073 if (hr != S_OK) return NULL;
2074
2075 hr = IDirect3DDevice9Impl_CreateVertexDeclaration((IDirect3DDevice9Ex *) This, elements, &pDecl);
2076 HeapFree(GetProcessHeap(), 0, elements); /* CreateVertexDeclaration makes a copy */
2077 if (hr != S_OK) return NULL;
2078
2079 if(This->declArraySize == This->numConvertedDecls) {
2080 int grow = max(This->declArraySize / 2, 8);
2081 convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
2082 sizeof(convertedDecls[0]) * (This->numConvertedDecls + grow));
2083 if(!convertedDecls) {
2084 /* This will destroy it */
2085 IDirect3DVertexDeclaration9_Release(pDecl);
2086 return NULL;
2087 }
2088 This->convertedDecls = convertedDecls;
2089 This->declArraySize += grow;
2090 }
2091
2092 memmove(convertedDecls + low + 1, convertedDecls + low, sizeof(IDirect3DVertexDeclaration9Impl *) * (This->numConvertedDecls - low));
2093 convertedDecls[low] = pDecl;
2094 This->numConvertedDecls++;
2095
2096 /* Will prevent the decl from being destroyed */
2097 ((IDirect3DVertexDeclaration9Impl *) pDecl)->convFVF = fvf;
2098 IDirect3DVertexDeclaration9_Release(pDecl); /* Does not destroy now */
2099
2100 TRACE("Returning %p. %d decls in array\n", pDecl, This->numConvertedDecls);
2101 return pDecl;
2102}
2103
2104static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWORD FVF) {
2105 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2106 IDirect3DVertexDeclaration9 *decl;
2107 HRESULT hr;
2108
2109 TRACE("iface %p, fvf %#x.\n", iface, FVF);
2110
2111 if (!FVF)
2112 {
2113 WARN("%#x is not a valid FVF\n", FVF);
2114 return D3D_OK;
2115 }
2116
2117 wined3d_mutex_lock();
2118 decl = getConvertedDecl(This, FVF);
2119 wined3d_mutex_unlock();
2120
2121 if (!decl)
2122 {
2123 /* Any situation when this should happen, except out of memory? */
2124 ERR("Failed to create a converted vertex declaration\n");
2125 return D3DERR_DRIVERINTERNALERROR;
2126 }
2127
2128 hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, decl);
2129 if (FAILED(hr)) ERR("Failed to set vertex declaration\n");
2130
2131 return hr;
2132}
2133
2134static HRESULT WINAPI IDirect3DDevice9Impl_GetFVF(IDirect3DDevice9Ex *iface, DWORD *pFVF)
2135{
2136 IDirect3DVertexDeclaration9 *decl;
2137 HRESULT hr;
2138
2139 TRACE("iface %p, fvf %p.\n", iface, pFVF);
2140
2141 hr = IDirect3DDevice9_GetVertexDeclaration(iface, &decl);
2142 if (FAILED(hr))
2143 {
2144 WARN("Failed to get vertex declaration, %#x\n", hr);
2145 *pFVF = 0;
2146 return hr;
2147 }
2148
2149 if (decl)
2150 {
2151 *pFVF = ((IDirect3DVertexDeclaration9Impl *)decl)->convFVF;
2152 IDirect3DVertexDeclaration9_Release(decl);
2153 }
2154 else
2155 {
2156 *pFVF = 0;
2157 }
2158
2159 TRACE("Returning FVF %#x\n", *pFVF);
2160
2161 return hr;
2162}
2163
2164static HRESULT WINAPI IDirect3DDevice9Impl_CreateVertexShader(IDirect3DDevice9Ex *iface,
2165 const DWORD *byte_code, IDirect3DVertexShader9 **shader)
2166{
2167 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2168 IDirect3DVertexShader9Impl *object;
2169 HRESULT hr;
2170
2171 TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
2172
2173 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2174 if (!object)
2175 {
2176 ERR("Failed to allocate vertex shader memory.\n");
2177 return E_OUTOFMEMORY;
2178 }
2179
2180 hr = vertexshader_init(object, This, byte_code);
2181 if (FAILED(hr))
2182 {
2183 WARN("Failed to initialize vertex shader, hr %#x.\n", hr);
2184 HeapFree(GetProcessHeap(), 0, object);
2185 return hr;
2186 }
2187
2188 TRACE("Created vertex shader %p.\n", object);
2189 *shader = (IDirect3DVertexShader9 *)object;
2190
2191 return D3D_OK;
2192}
2193
2194static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSource(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) {
2195 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2196 HRESULT hr;
2197
2198 TRACE("iface %p, stream_idx %u, buffer %p, offset %u, stride %u.\n",
2199 iface, StreamNumber, pStreamData, OffsetInBytes, Stride);
2200
2201 wined3d_mutex_lock();
2202 hr = IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
2203 pStreamData ? ((IDirect3DVertexBuffer9Impl *)pStreamData)->wineD3DVertexBuffer : NULL,
2204 OffsetInBytes, Stride);
2205 wined3d_mutex_unlock();
2206
2207 return hr;
2208}
2209
2210static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, IDirect3DVertexBuffer9 **pStream, UINT* OffsetInBytes, UINT* pStride) {
2211 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2212 IWineD3DBuffer *retStream = NULL;
2213 HRESULT rc = D3D_OK;
2214
2215 TRACE("iface %p, stream_idx %u, buffer %p, offset %p, stride %p.\n",
2216 iface, StreamNumber, pStream, OffsetInBytes, pStride);
2217
2218 if(pStream == NULL){
2219 return D3DERR_INVALIDCALL;
2220 }
2221
2222 wined3d_mutex_lock();
2223 rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, OffsetInBytes, pStride);
2224 if (rc == D3D_OK && NULL != retStream) {
2225 IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
2226 IWineD3DBuffer_Release(retStream);
2227 }else{
2228 if (rc != D3D_OK){
2229 FIXME("Call to GetStreamSource failed %p %p\n", OffsetInBytes, pStride);
2230 }
2231 *pStream = NULL;
2232 }
2233 wined3d_mutex_unlock();
2234
2235 return rc;
2236}
2237
2238static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSourceFreq(IDirect3DDevice9Ex *iface, UINT StreamNumber,
2239 UINT Divider)
2240{
2241 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2242 HRESULT hr;
2243
2244 TRACE("iface %p, stream_idx %u, freq %u.\n", iface, StreamNumber, Divider);
2245
2246 wined3d_mutex_lock();
2247 hr = IWineD3DDevice_SetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
2248 wined3d_mutex_unlock();
2249
2250 return hr;
2251}
2252
2253static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSourceFreq(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, UINT* Divider) {
2254 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2255 HRESULT hr;
2256
2257 TRACE("iface %p, stream_idx %u, freq %p.\n", iface, StreamNumber, Divider);
2258
2259 wined3d_mutex_lock();
2260 hr = IWineD3DDevice_GetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
2261 wined3d_mutex_unlock();
2262
2263 return hr;
2264}
2265
2266static HRESULT WINAPI IDirect3DDevice9Impl_SetIndices(LPDIRECT3DDEVICE9EX iface, IDirect3DIndexBuffer9* pIndexData) {
2267 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2268 HRESULT hr;
2269 IDirect3DIndexBuffer9Impl *ib = (IDirect3DIndexBuffer9Impl *) pIndexData;
2270
2271 TRACE("iface %p, buffer %p.\n", iface, pIndexData);
2272
2273 wined3d_mutex_lock();
2274 hr = IWineD3DDevice_SetIndexBuffer(This->WineD3DDevice,
2275 ib ? ib->wineD3DIndexBuffer : NULL,
2276 ib ? ib->format : WINED3DFMT_UNKNOWN);
2277 wined3d_mutex_unlock();
2278
2279 return hr;
2280}
2281
2282static HRESULT WINAPI IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9EX iface, IDirect3DIndexBuffer9 **ppIndexData) {
2283 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2284 IWineD3DBuffer *retIndexData = NULL;
2285 HRESULT rc = D3D_OK;
2286
2287 TRACE("iface %p, buffer %p.\n", iface, ppIndexData);
2288
2289 if(ppIndexData == NULL){
2290 return D3DERR_INVALIDCALL;
2291 }
2292
2293 wined3d_mutex_lock();
2294 rc = IWineD3DDevice_GetIndexBuffer(This->WineD3DDevice, &retIndexData);
2295 if (SUCCEEDED(rc) && retIndexData) {
2296 IWineD3DBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
2297 IWineD3DBuffer_Release(retIndexData);
2298 } else {
2299 if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
2300 *ppIndexData = NULL;
2301 }
2302 wined3d_mutex_unlock();
2303
2304 return rc;
2305}
2306
2307static HRESULT WINAPI IDirect3DDevice9Impl_CreatePixelShader(IDirect3DDevice9Ex *iface,
2308 const DWORD *byte_code, IDirect3DPixelShader9 **shader)
2309{
2310 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2311 IDirect3DPixelShader9Impl *object;
2312 HRESULT hr;
2313
2314 TRACE("iface %p, byte_code %p, shader %p.\n", iface, byte_code, shader);
2315
2316 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2317 if (!object)
2318 {
2319 FIXME("Failed to allocate pixel shader memory.\n");
2320 return E_OUTOFMEMORY;
2321 }
2322
2323 hr = pixelshader_init(object, This, byte_code);
2324 if (FAILED(hr))
2325 {
2326 WARN("Failed to initialize pixel shader, hr %#x.\n", hr);
2327 HeapFree(GetProcessHeap(), 0, object);
2328 return hr;
2329 }
2330
2331 TRACE("Created pixel shader %p.\n", object);
2332 *shader = (IDirect3DPixelShader9 *)object;
2333
2334 return D3D_OK;
2335}
2336
2337static HRESULT WINAPI IDirect3DDevice9Impl_DrawRectPatch(LPDIRECT3DDEVICE9EX iface, UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
2338 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2339 HRESULT hr;
2340
2341 TRACE("iface %p, handle %#x, segment_count %p, patch_info %p.\n",
2342 iface, Handle, pNumSegs, pRectPatchInfo);
2343
2344 wined3d_mutex_lock();
2345 hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
2346 wined3d_mutex_unlock();
2347
2348 return hr;
2349}
2350
2351static HRESULT WINAPI IDirect3DDevice9Impl_DrawTriPatch(LPDIRECT3DDEVICE9EX iface, UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
2352 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2353 HRESULT hr;
2354
2355 TRACE("iface %p, handle %#x, segment_count %p, patch_info %p.\n",
2356 iface, Handle, pNumSegs, pTriPatchInfo);
2357
2358 wined3d_mutex_lock();
2359 hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
2360 wined3d_mutex_unlock();
2361
2362 return hr;
2363}
2364
2365static HRESULT WINAPI IDirect3DDevice9Impl_DeletePatch(LPDIRECT3DDEVICE9EX iface, UINT Handle) {
2366 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2367 HRESULT hr;
2368
2369 TRACE("iface %p, handle %#x.\n", iface, Handle);
2370
2371 wined3d_mutex_lock();
2372 hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
2373 wined3d_mutex_unlock();
2374
2375 return hr;
2376}
2377
2378static HRESULT WINAPI IDirect3DDevice9Impl_CreateQuery(IDirect3DDevice9Ex *iface,
2379 D3DQUERYTYPE type, IDirect3DQuery9 **query)
2380{
2381 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
2382 IDirect3DQuery9Impl *object;
2383 HRESULT hr;
2384
2385 TRACE("iface %p, type %#x, query %p.\n", iface, type, query);
2386
2387 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2388 if (!object)
2389 {
2390 ERR("Failed to allocate query memory.\n");
2391 return E_OUTOFMEMORY;
2392 }
2393
2394 hr = query_init(object, This, type);
2395 if (FAILED(hr))
2396 {
2397 WARN("Failed to initialize query, hr %#x.\n", hr);
2398 HeapFree(GetProcessHeap(), 0, object);
2399 return hr;
2400 }
2401
2402 TRACE("Created query %p.\n", object);
2403 if (query) *query = (IDirect3DQuery9 *)object;
2404 else IDirect3DQuery9_Release((IDirect3DQuery9 *)object);
2405
2406 return D3D_OK;
2407}
2408
2409static HRESULT WINAPI IDirect3DDevice9ExImpl_SetConvolutionMonoKernel(IDirect3DDevice9Ex *iface,
2410 UINT width, UINT height, float *rows, float *columns)
2411{
2412 FIXME("iface %p, width %u, height %u, rows %p, columns %p stub!\n",
2413 iface, width, height, rows, columns);
2414
2415 return WINED3DERR_INVALIDCALL;
2416}
2417
2418static HRESULT WINAPI IDirect3DDevice9ExImpl_ComposeRects(IDirect3DDevice9Ex *iface,
2419 IDirect3DSurface9 *src_surface, IDirect3DSurface9 *dst_surface, IDirect3DVertexBuffer9 *src_descs,
2420 UINT rect_count, IDirect3DVertexBuffer9 *dst_descs, D3DCOMPOSERECTSOP operation, INT offset_x, INT offset_y)
2421{
2422 FIXME("iface %p, src_surface %p, dst_surface %p, src_descs %p, rect_count %u,\n"
2423 "dst_descs %p, operation %#x, offset_x %u, offset_y %u stub!\n",
2424 iface, src_surface, dst_surface, src_descs, rect_count,
2425 dst_descs, operation, offset_x, offset_y);
2426
2427 return WINED3DERR_INVALIDCALL;
2428}
2429
2430static HRESULT WINAPI IDirect3DDevice9ExImpl_PresentEx(IDirect3DDevice9Ex *iface,
2431 const RECT *src_rect, const RECT *dst_rect, HWND dst_window_override,
2432 const RGNDATA *dirty_region, DWORD flags)
2433{
2434 FIXME("iface %p, src_rect %p, dst_rect %p, dst_window_override %p, dirty_region %p, flags %#x stub!\n",
2435 iface, src_rect, dst_rect, dst_window_override, dirty_region, flags);
2436
2437 return WINED3DERR_INVALIDCALL;
2438}
2439
2440static HRESULT WINAPI IDirect3DDevice9ExImpl_GetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT *priority)
2441{
2442 FIXME("iface %p, priority %p stub!\n", iface, priority);
2443
2444 return WINED3DERR_INVALIDCALL;
2445}
2446
2447static HRESULT WINAPI IDirect3DDevice9ExImpl_SetGPUThreadPriority(IDirect3DDevice9Ex *iface, INT priority)
2448{
2449 FIXME("iface %p, priority %d stub!\n", iface, priority);
2450
2451 return WINED3DERR_INVALIDCALL;
2452}
2453
2454static HRESULT WINAPI IDirect3DDevice9ExImpl_WaitForVBlank(IDirect3DDevice9Ex *iface, UINT swapchain_idx)
2455{
2456 FIXME("iface %p, swapchain_idx %u stub!\n", iface, swapchain_idx);
2457
2458 return WINED3DERR_INVALIDCALL;
2459}
2460
2461static HRESULT WINAPI IDirect3DDevice9ExImpl_CheckResourceResidency(IDirect3DDevice9Ex *iface,
2462 IDirect3DResource9 **resources, UINT32 resource_count)
2463{
2464 FIXME("iface %p, resources %p, resource_count %u stub!\n",
2465 iface, resources, resource_count);
2466
2467 return WINED3DERR_INVALIDCALL;
2468}
2469
2470static HRESULT WINAPI IDirect3DDevice9ExImpl_SetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT max_latency)
2471{
2472 FIXME("iface %p, max_latency %u stub!\n", iface, max_latency);
2473
2474 return WINED3DERR_INVALIDCALL;
2475}
2476
2477static HRESULT WINAPI IDirect3DDevice9ExImpl_GetMaximumFrameLatency(IDirect3DDevice9Ex *iface, UINT *max_latency)
2478{
2479 FIXME("iface %p, max_latency %p stub!\n", iface, max_latency);
2480
2481 *max_latency = 2;
2482
2483 return WINED3DERR_INVALIDCALL;
2484}
2485
2486static HRESULT WINAPI IDirect3DDevice9ExImpl_CheckDeviceState(IDirect3DDevice9Ex *iface, HWND dst_window)
2487{
2488 FIXME("iface %p, dst_window %p stub!\n", iface, dst_window);
2489
2490 return WINED3DERR_INVALIDCALL;
2491}
2492
2493static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateRenderTargetEx(IDirect3DDevice9Ex *iface,
2494 UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
2495 BOOL lockable, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage)
2496{
2497 FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n"
2498 "lockable %#x, surface %p, shared_handle %p, usage %#x stub!\n",
2499 iface, width, height, format, multisample_type, multisample_quality,
2500 lockable, surface, shared_handle, usage);
2501
2502 return WINED3DERR_INVALIDCALL;
2503}
2504
2505static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateOffscreenPlainSurfaceEx(IDirect3DDevice9Ex *iface,
2506 UINT width, UINT height, D3DFORMAT format, D3DPOOL pool, IDirect3DSurface9 **surface,
2507 HANDLE *shared_handle, DWORD usage)
2508{
2509 FIXME("iface %p, width %u, height %u, format %#x, pool %#x, surface %p, shared_handle %p, usage %#x stub!\n",
2510 iface, width, height, format, pool, surface, shared_handle, usage);
2511
2512 return WINED3DERR_INVALIDCALL;
2513}
2514
2515static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateDepthStencilSurfaceEx(IDirect3DDevice9Ex *iface,
2516 UINT width, UINT height, D3DFORMAT format, D3DMULTISAMPLE_TYPE multisample_type, DWORD multisample_quality,
2517 BOOL discard, IDirect3DSurface9 **surface, HANDLE *shared_handle, DWORD usage)
2518{
2519 FIXME("iface %p, width %u, height %u, format %#x, multisample_type %#x, multisample_quality %u,\n"
2520 "discard %#x, surface %p, shared_handle %p, usage %#x stub!\n",
2521 iface, width, height, format, multisample_type, multisample_quality,
2522 discard, surface, shared_handle, usage);
2523
2524 return WINED3DERR_INVALIDCALL;
2525}
2526
2527static HRESULT WINAPI IDirect3DDevice9ExImpl_ResetEx(IDirect3DDevice9Ex *iface,
2528 D3DPRESENT_PARAMETERS *present_parameters, D3DDISPLAYMODEEX *mode)
2529{
2530 FIXME("iface %p, present_parameters %p, mode %p stub!\n", iface, present_parameters, mode);
2531
2532 return WINED3DERR_INVALIDCALL;
2533}
2534
2535static HRESULT WINAPI IDirect3DDevice9ExImpl_GetDisplayModeEx(IDirect3DDevice9Ex *iface,
2536 UINT swapchain_idx, D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation)
2537{
2538 FIXME("iface %p, swapchain_idx %u, mode %p, rotation %p stub!\n", iface, swapchain_idx, mode, rotation);
2539
2540 return WINED3DERR_INVALIDCALL;
2541}
2542
2543static const IDirect3DDevice9ExVtbl Direct3DDevice9_Vtbl =
2544{
2545 /* IUnknown */
2546 IDirect3DDevice9Impl_QueryInterface,
2547 IDirect3DDevice9Impl_AddRef,
2548 IDirect3DDevice9Impl_Release,
2549 /* IDirect3DDevice9 */
2550 IDirect3DDevice9Impl_TestCooperativeLevel,
2551 IDirect3DDevice9Impl_GetAvailableTextureMem,
2552 IDirect3DDevice9Impl_EvictManagedResources,
2553 IDirect3DDevice9Impl_GetDirect3D,
2554 IDirect3DDevice9Impl_GetDeviceCaps,
2555 IDirect3DDevice9Impl_GetDisplayMode,
2556 IDirect3DDevice9Impl_GetCreationParameters,
2557 IDirect3DDevice9Impl_SetCursorProperties,
2558 IDirect3DDevice9Impl_SetCursorPosition,
2559 IDirect3DDevice9Impl_ShowCursor,
2560 IDirect3DDevice9Impl_CreateAdditionalSwapChain,
2561 IDirect3DDevice9Impl_GetSwapChain,
2562 IDirect3DDevice9Impl_GetNumberOfSwapChains,
2563 IDirect3DDevice9Impl_Reset,
2564 IDirect3DDevice9Impl_Present,
2565 IDirect3DDevice9Impl_GetBackBuffer,
2566 IDirect3DDevice9Impl_GetRasterStatus,
2567 IDirect3DDevice9Impl_SetDialogBoxMode,
2568 IDirect3DDevice9Impl_SetGammaRamp,
2569 IDirect3DDevice9Impl_GetGammaRamp,
2570 IDirect3DDevice9Impl_CreateTexture,
2571 IDirect3DDevice9Impl_CreateVolumeTexture,
2572 IDirect3DDevice9Impl_CreateCubeTexture,
2573 IDirect3DDevice9Impl_CreateVertexBuffer,
2574 IDirect3DDevice9Impl_CreateIndexBuffer,
2575 IDirect3DDevice9Impl_CreateRenderTarget,
2576 IDirect3DDevice9Impl_CreateDepthStencilSurface,
2577 IDirect3DDevice9Impl_UpdateSurface,
2578 IDirect3DDevice9Impl_UpdateTexture,
2579 IDirect3DDevice9Impl_GetRenderTargetData,
2580 IDirect3DDevice9Impl_GetFrontBufferData,
2581 IDirect3DDevice9Impl_StretchRect,
2582 IDirect3DDevice9Impl_ColorFill,
2583 IDirect3DDevice9Impl_CreateOffscreenPlainSurface,
2584 IDirect3DDevice9Impl_SetRenderTarget,
2585 IDirect3DDevice9Impl_GetRenderTarget,
2586 IDirect3DDevice9Impl_SetDepthStencilSurface,
2587 IDirect3DDevice9Impl_GetDepthStencilSurface,
2588 IDirect3DDevice9Impl_BeginScene,
2589 IDirect3DDevice9Impl_EndScene,
2590 IDirect3DDevice9Impl_Clear,
2591 IDirect3DDevice9Impl_SetTransform,
2592 IDirect3DDevice9Impl_GetTransform,
2593 IDirect3DDevice9Impl_MultiplyTransform,
2594 IDirect3DDevice9Impl_SetViewport,
2595 IDirect3DDevice9Impl_GetViewport,
2596 IDirect3DDevice9Impl_SetMaterial,
2597 IDirect3DDevice9Impl_GetMaterial,
2598 IDirect3DDevice9Impl_SetLight,
2599 IDirect3DDevice9Impl_GetLight,
2600 IDirect3DDevice9Impl_LightEnable,
2601 IDirect3DDevice9Impl_GetLightEnable,
2602 IDirect3DDevice9Impl_SetClipPlane,
2603 IDirect3DDevice9Impl_GetClipPlane,
2604 IDirect3DDevice9Impl_SetRenderState,
2605 IDirect3DDevice9Impl_GetRenderState,
2606 IDirect3DDevice9Impl_CreateStateBlock,
2607 IDirect3DDevice9Impl_BeginStateBlock,
2608 IDirect3DDevice9Impl_EndStateBlock,
2609 IDirect3DDevice9Impl_SetClipStatus,
2610 IDirect3DDevice9Impl_GetClipStatus,
2611 IDirect3DDevice9Impl_GetTexture,
2612 IDirect3DDevice9Impl_SetTexture,
2613 IDirect3DDevice9Impl_GetTextureStageState,
2614 IDirect3DDevice9Impl_SetTextureStageState,
2615 IDirect3DDevice9Impl_GetSamplerState,
2616 IDirect3DDevice9Impl_SetSamplerState,
2617 IDirect3DDevice9Impl_ValidateDevice,
2618 IDirect3DDevice9Impl_SetPaletteEntries,
2619 IDirect3DDevice9Impl_GetPaletteEntries,
2620 IDirect3DDevice9Impl_SetCurrentTexturePalette,
2621 IDirect3DDevice9Impl_GetCurrentTexturePalette,
2622 IDirect3DDevice9Impl_SetScissorRect,
2623 IDirect3DDevice9Impl_GetScissorRect,
2624 IDirect3DDevice9Impl_SetSoftwareVertexProcessing,
2625 IDirect3DDevice9Impl_GetSoftwareVertexProcessing,
2626 IDirect3DDevice9Impl_SetNPatchMode,
2627 IDirect3DDevice9Impl_GetNPatchMode,
2628 IDirect3DDevice9Impl_DrawPrimitive,
2629 IDirect3DDevice9Impl_DrawIndexedPrimitive,
2630 IDirect3DDevice9Impl_DrawPrimitiveUP,
2631 IDirect3DDevice9Impl_DrawIndexedPrimitiveUP,
2632 IDirect3DDevice9Impl_ProcessVertices,
2633 IDirect3DDevice9Impl_CreateVertexDeclaration,
2634 IDirect3DDevice9Impl_SetVertexDeclaration,
2635 IDirect3DDevice9Impl_GetVertexDeclaration,
2636 IDirect3DDevice9Impl_SetFVF,
2637 IDirect3DDevice9Impl_GetFVF,
2638 IDirect3DDevice9Impl_CreateVertexShader,
2639 IDirect3DDevice9Impl_SetVertexShader,
2640 IDirect3DDevice9Impl_GetVertexShader,
2641 IDirect3DDevice9Impl_SetVertexShaderConstantF,
2642 IDirect3DDevice9Impl_GetVertexShaderConstantF,
2643 IDirect3DDevice9Impl_SetVertexShaderConstantI,
2644 IDirect3DDevice9Impl_GetVertexShaderConstantI,
2645 IDirect3DDevice9Impl_SetVertexShaderConstantB,
2646 IDirect3DDevice9Impl_GetVertexShaderConstantB,
2647 IDirect3DDevice9Impl_SetStreamSource,
2648 IDirect3DDevice9Impl_GetStreamSource,
2649 IDirect3DDevice9Impl_SetStreamSourceFreq,
2650 IDirect3DDevice9Impl_GetStreamSourceFreq,
2651 IDirect3DDevice9Impl_SetIndices,
2652 IDirect3DDevice9Impl_GetIndices,
2653 IDirect3DDevice9Impl_CreatePixelShader,
2654 IDirect3DDevice9Impl_SetPixelShader,
2655 IDirect3DDevice9Impl_GetPixelShader,
2656 IDirect3DDevice9Impl_SetPixelShaderConstantF,
2657 IDirect3DDevice9Impl_GetPixelShaderConstantF,
2658 IDirect3DDevice9Impl_SetPixelShaderConstantI,
2659 IDirect3DDevice9Impl_GetPixelShaderConstantI,
2660 IDirect3DDevice9Impl_SetPixelShaderConstantB,
2661 IDirect3DDevice9Impl_GetPixelShaderConstantB,
2662 IDirect3DDevice9Impl_DrawRectPatch,
2663 IDirect3DDevice9Impl_DrawTriPatch,
2664 IDirect3DDevice9Impl_DeletePatch,
2665 IDirect3DDevice9Impl_CreateQuery,
2666 /* IDirect3DDevice9Ex */
2667 IDirect3DDevice9ExImpl_SetConvolutionMonoKernel,
2668 IDirect3DDevice9ExImpl_ComposeRects,
2669 IDirect3DDevice9ExImpl_PresentEx,
2670 IDirect3DDevice9ExImpl_GetGPUThreadPriority,
2671 IDirect3DDevice9ExImpl_SetGPUThreadPriority,
2672 IDirect3DDevice9ExImpl_WaitForVBlank,
2673 IDirect3DDevice9ExImpl_CheckResourceResidency,
2674 IDirect3DDevice9ExImpl_SetMaximumFrameLatency,
2675 IDirect3DDevice9ExImpl_GetMaximumFrameLatency,
2676 IDirect3DDevice9ExImpl_CheckDeviceState,
2677 IDirect3DDevice9ExImpl_CreateRenderTargetEx,
2678 IDirect3DDevice9ExImpl_CreateOffscreenPlainSurfaceEx,
2679 IDirect3DDevice9ExImpl_CreateDepthStencilSurfaceEx,
2680 IDirect3DDevice9ExImpl_ResetEx,
2681 IDirect3DDevice9ExImpl_GetDisplayModeEx
2682};
2683
2684/* IWineD3DDeviceParent IUnknown methods */
2685
2686static inline struct IDirect3DDevice9Impl *device_from_device_parent(IWineD3DDeviceParent *iface)
2687{
2688 return (struct IDirect3DDevice9Impl *)((char*)iface
2689 - FIELD_OFFSET(struct IDirect3DDevice9Impl, device_parent_vtbl));
2690}
2691
2692static HRESULT STDMETHODCALLTYPE device_parent_QueryInterface(IWineD3DDeviceParent *iface, REFIID riid, void **object)
2693{
2694 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2695 return IDirect3DDevice9Impl_QueryInterface((IDirect3DDevice9Ex *)This, riid, object);
2696}
2697
2698static ULONG STDMETHODCALLTYPE device_parent_AddRef(IWineD3DDeviceParent *iface)
2699{
2700 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2701 return IDirect3DDevice9Impl_AddRef((IDirect3DDevice9Ex *)This);
2702}
2703
2704static ULONG STDMETHODCALLTYPE device_parent_Release(IWineD3DDeviceParent *iface)
2705{
2706 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2707 return IDirect3DDevice9Impl_Release((IDirect3DDevice9Ex *)This);
2708}
2709
2710/* IWineD3DDeviceParent methods */
2711
2712static void STDMETHODCALLTYPE device_parent_WineD3DDeviceCreated(IWineD3DDeviceParent *iface, IWineD3DDevice *device)
2713{
2714 TRACE("iface %p, device %p\n", iface, device);
2715}
2716
2717static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParent *iface,
2718 IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, DWORD usage,
2719 WINED3DPOOL pool, UINT level, WINED3DCUBEMAP_FACES face, IWineD3DSurface **surface
2720#ifdef VBOXWDDM
2721 , HANDLE *shared_handle
2722 , void *pvClientMem
2723#endif
2724 )
2725{
2726 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2727 IDirect3DSurface9Impl *d3d_surface;
2728 BOOL lockable = TRUE;
2729 HRESULT hr;
2730
2731 TRACE("iface %p, superior %p, width %u, height %u, format %#x, usage %#x,\n"
2732 "\tpool %#x, level %u, face %u, surface %p\n",
2733 iface, superior, width, height, format, usage, pool, level, face, surface);
2734
2735 if (pool == WINED3DPOOL_DEFAULT && !(usage & D3DUSAGE_DYNAMIC))
2736 lockable = FALSE;
2737
2738 hr = IDirect3DDevice9Impl_CreateSurface((IDirect3DDevice9Ex *)This, width, height,
2739 d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
2740 (IDirect3DSurface9 **)&d3d_surface, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */
2741#ifdef VBOXWDDM
2742 , shared_handle
2743 , pvClientMem
2744#endif
2745 );
2746 if (FAILED(hr))
2747 {
2748 ERR("(%p) CreateSurface failed, returning %#x\n", iface, hr);
2749 return hr;
2750 }
2751
2752 *surface = d3d_surface->wineD3DSurface;
2753 IWineD3DSurface_AddRef(*surface);
2754
2755 d3d_surface->container = superior;
2756 IDirect3DDevice9Ex_Release(d3d_surface->parentDevice);
2757 d3d_surface->parentDevice = NULL;
2758
2759 IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
2760 d3d_surface->forwardReference = superior;
2761
2762 return hr;
2763}
2764
2765static HRESULT STDMETHODCALLTYPE device_parent_CreateRenderTarget(IWineD3DDeviceParent *iface,
2766 IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, WINED3DMULTISAMPLE_TYPE multisample_type,
2767 DWORD multisample_quality, BOOL lockable, IWineD3DSurface **surface)
2768{
2769 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2770 IDirect3DSurface9Impl *d3d_surface;
2771 HRESULT hr;
2772
2773 TRACE("iface %p, superior %p, width %u, height %u, format %#x, multisample_type %#x,\n"
2774 "\tmultisample_quality %u, lockable %u, surface %p\n",
2775 iface, superior, width, height, format, multisample_type, multisample_quality, lockable, surface);
2776
2777 hr = IDirect3DDevice9Impl_CreateRenderTarget((IDirect3DDevice9Ex *)This, width, height,
2778 d3dformat_from_wined3dformat(format), multisample_type, multisample_quality, lockable,
2779 (IDirect3DSurface9 **)&d3d_surface, NULL);
2780 if (FAILED(hr))
2781 {
2782 ERR("(%p) CreateRenderTarget failed, returning %#x\n", iface, hr);
2783 return hr;
2784 }
2785
2786 *surface = d3d_surface->wineD3DSurface;
2787 IWineD3DSurface_AddRef(*surface);
2788
2789 d3d_surface->container = superior;
2790 /* Implicit surfaces are created with an refcount of 0 */
2791 IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
2792
2793 return hr;
2794}
2795
2796static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3DDeviceParent *iface,
2797 IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, WINED3DMULTISAMPLE_TYPE multisample_type,
2798 DWORD multisample_quality, BOOL discard, IWineD3DSurface **surface)
2799{
2800 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2801 IDirect3DSurface9Impl *d3d_surface;
2802 HRESULT hr;
2803
2804 TRACE("iface %p, superior %p, width %u, height %u, format %#x, multisample_type %#x,\n"
2805 "\tmultisample_quality %u, discard %u, surface %p\n",
2806 iface, superior, width, height, format, multisample_type, multisample_quality, discard, surface);
2807
2808 hr = IDirect3DDevice9Impl_CreateDepthStencilSurface((IDirect3DDevice9Ex *)This, width, height,
2809 d3dformat_from_wined3dformat(format), multisample_type, multisample_quality, discard,
2810 (IDirect3DSurface9 **)&d3d_surface, NULL);
2811 if (FAILED(hr))
2812 {
2813 ERR("(%p) CreateDepthStencilSurface failed, returning %#x\n", iface, hr);
2814 return hr;
2815 }
2816
2817 *surface = d3d_surface->wineD3DSurface;
2818 IWineD3DSurface_AddRef(*surface);
2819 d3d_surface->container = (IUnknown *)This;
2820 /* Implicit surfaces are created with an refcount of 0 */
2821 IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
2822
2823 return hr;
2824}
2825
2826static HRESULT STDMETHODCALLTYPE device_parent_CreateVolume(IWineD3DDeviceParent *iface,
2827 IUnknown *superior, UINT width, UINT height, UINT depth, WINED3DFORMAT format,
2828 WINED3DPOOL pool, DWORD usage, IWineD3DVolume **volume)
2829{
2830 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2831 IDirect3DVolume9Impl *object;
2832 HRESULT hr;
2833
2834 TRACE("iface %p, superior %p, width %u, height %u, depth %u, format %#x, pool %#x, usage %#x, volume %p\n",
2835 iface, superior, width, height, depth, format, pool, usage, volume);
2836
2837 /* Allocate the storage for the device */
2838 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2839 if (!object)
2840 {
2841 FIXME("Allocation of memory failed\n");
2842 *volume = NULL;
2843 return D3DERR_OUTOFVIDEOMEMORY;
2844 }
2845
2846 hr = volume_init(object, This, width, height, depth, usage, format, pool);
2847 if (FAILED(hr))
2848 {
2849 WARN("Failed to initialize volume, hr %#x.\n", hr);
2850 HeapFree(GetProcessHeap(), 0, object);
2851 return hr;
2852 }
2853
2854 *volume = object->wineD3DVolume;
2855 IWineD3DVolume_AddRef(*volume);
2856 IDirect3DVolume9_Release((IDirect3DVolume9 *)object);
2857
2858 object->container = superior;
2859 object->forwardReference = superior;
2860
2861 TRACE("(%p) Created volume %p\n", iface, object);
2862
2863 return hr;
2864}
2865
2866static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDeviceParent *iface,
2867 WINED3DPRESENT_PARAMETERS *present_parameters, IWineD3DSwapChain **swapchain)
2868{
2869 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2870 IDirect3DSwapChain9Impl *d3d_swapchain;
2871 D3DPRESENT_PARAMETERS local_parameters;
2872 HRESULT hr;
2873
2874 TRACE("iface %p, present_parameters %p, swapchain %p\n", iface, present_parameters, swapchain);
2875
2876 /* Copy the presentation parameters */
2877 local_parameters.BackBufferWidth = present_parameters->BackBufferWidth;
2878 local_parameters.BackBufferHeight = present_parameters->BackBufferHeight;
2879 local_parameters.BackBufferFormat = d3dformat_from_wined3dformat(present_parameters->BackBufferFormat);
2880 local_parameters.BackBufferCount = present_parameters->BackBufferCount;
2881 local_parameters.MultiSampleType = present_parameters->MultiSampleType;
2882 local_parameters.MultiSampleQuality = present_parameters->MultiSampleQuality;
2883 local_parameters.SwapEffect = present_parameters->SwapEffect;
2884 local_parameters.hDeviceWindow = present_parameters->hDeviceWindow;
2885 local_parameters.Windowed = present_parameters->Windowed;
2886 local_parameters.EnableAutoDepthStencil = present_parameters->EnableAutoDepthStencil;
2887 local_parameters.AutoDepthStencilFormat = d3dformat_from_wined3dformat(present_parameters->AutoDepthStencilFormat);
2888 local_parameters.Flags = present_parameters->Flags;
2889 local_parameters.FullScreen_RefreshRateInHz = present_parameters->FullScreen_RefreshRateInHz;
2890 local_parameters.PresentationInterval = present_parameters->PresentationInterval;
2891
2892 hr = IDirect3DDevice9Impl_CreateAdditionalSwapChain((IDirect3DDevice9Ex *)This,
2893 &local_parameters, (IDirect3DSwapChain9 **)&d3d_swapchain);
2894 if (FAILED(hr))
2895 {
2896 ERR("(%p) CreateAdditionalSwapChain failed, returning %#x\n", iface, hr);
2897 *swapchain = NULL;
2898 return hr;
2899 }
2900
2901 *swapchain = d3d_swapchain->wineD3DSwapChain;
2902 d3d_swapchain->isImplicit = TRUE;
2903 /* Implicit swap chains are created with an refcount of 0 */
2904 IDirect3DSwapChain9_Release((IDirect3DSwapChain9 *)d3d_swapchain);
2905
2906 /* Copy back the presentation parameters */
2907 present_parameters->BackBufferWidth = local_parameters.BackBufferWidth;
2908 present_parameters->BackBufferHeight = local_parameters.BackBufferHeight;
2909 present_parameters->BackBufferFormat = wined3dformat_from_d3dformat(local_parameters.BackBufferFormat);
2910 present_parameters->BackBufferCount = local_parameters.BackBufferCount;
2911 present_parameters->MultiSampleType = local_parameters.MultiSampleType;
2912 present_parameters->MultiSampleQuality = local_parameters.MultiSampleQuality;
2913 present_parameters->SwapEffect = local_parameters.SwapEffect;
2914 present_parameters->hDeviceWindow = local_parameters.hDeviceWindow;
2915 present_parameters->Windowed = local_parameters.Windowed;
2916 present_parameters->EnableAutoDepthStencil = local_parameters.EnableAutoDepthStencil;
2917 present_parameters->AutoDepthStencilFormat = wined3dformat_from_d3dformat(local_parameters.AutoDepthStencilFormat);
2918 present_parameters->Flags = local_parameters.Flags;
2919 present_parameters->FullScreen_RefreshRateInHz = local_parameters.FullScreen_RefreshRateInHz;
2920 present_parameters->PresentationInterval = local_parameters.PresentationInterval;
2921
2922 return hr;
2923}
2924
2925static const IWineD3DDeviceParentVtbl d3d9_wined3d_device_parent_vtbl =
2926{
2927 /* IUnknown methods */
2928 device_parent_QueryInterface,
2929 device_parent_AddRef,
2930 device_parent_Release,
2931 /* IWineD3DDeviceParent methods */
2932 device_parent_WineD3DDeviceCreated,
2933 device_parent_CreateSurface,
2934 device_parent_CreateRenderTarget,
2935 device_parent_CreateDepthStencilSurface,
2936 device_parent_CreateVolume,
2937 device_parent_CreateSwapChain,
2938};
2939
2940HRESULT device_init(IDirect3DDevice9Impl *device, IWineD3D *wined3d, UINT adapter, D3DDEVTYPE device_type,
2941 HWND focus_window, DWORD flags, D3DPRESENT_PARAMETERS *parameters)
2942{
2943 WINED3DPRESENT_PARAMETERS *wined3d_parameters;
2944 UINT i, count = 1;
2945 HRESULT hr;
2946
2947 device->lpVtbl = &Direct3DDevice9_Vtbl;
2948 device->device_parent_vtbl = &d3d9_wined3d_device_parent_vtbl;
2949 device->ref = 1;
2950
2951 wined3d_mutex_lock();
2952 hr = IWineD3D_CreateDevice(wined3d, adapter, device_type, focus_window, flags, (IUnknown *)device,
2953 (IWineD3DDeviceParent *)&device->device_parent_vtbl, &device->WineD3DDevice);
2954 if (FAILED(hr))
2955 {
2956 WARN("Failed to create wined3d device, hr %#x.\n", hr);
2957 wined3d_mutex_unlock();
2958 return hr;
2959 }
2960
2961 if (!parameters->Windowed)
2962 {
2963 if (!focus_window) focus_window = parameters->hDeviceWindow;
2964 if (FAILED(hr = IWineD3DDevice_AcquireFocusWindow(device->WineD3DDevice, focus_window)))
2965 {
2966 ERR("Failed to acquire focus window, hr %#x.\n", hr);
2967 IWineD3DDevice_Release(device->WineD3DDevice);
2968 wined3d_mutex_unlock();
2969 return hr;
2970 }
2971 }
2972
2973 if (flags & D3DCREATE_ADAPTERGROUP_DEVICE)
2974 {
2975 WINED3DCAPS caps;
2976
2977 IWineD3D_GetDeviceCaps(wined3d, adapter, device_type, &caps);
2978 count = caps.NumberOfAdaptersInGroup;
2979 }
2980
2981 if (flags & D3DCREATE_MULTITHREADED) IWineD3DDevice_SetMultithreaded(device->WineD3DDevice);
2982
2983 wined3d_parameters = HeapAlloc(GetProcessHeap(), 0, sizeof(*wined3d_parameters) * count);
2984 if (!wined3d_parameters)
2985 {
2986 ERR("Failed to allocate wined3d parameters.\n");
2987 IWineD3DDevice_Release(device->WineD3DDevice);
2988 wined3d_mutex_unlock();
2989 return E_OUTOFMEMORY;
2990 }
2991
2992 for (i = 0; i < count; ++i)
2993 {
2994 wined3d_parameters[i].BackBufferWidth = parameters[i].BackBufferWidth;
2995 wined3d_parameters[i].BackBufferHeight = parameters[i].BackBufferHeight;
2996 wined3d_parameters[i].BackBufferFormat = wined3dformat_from_d3dformat(parameters[i].BackBufferFormat);
2997 wined3d_parameters[i].BackBufferCount = parameters[i].BackBufferCount;
2998 wined3d_parameters[i].MultiSampleType = parameters[i].MultiSampleType;
2999 wined3d_parameters[i].MultiSampleQuality = parameters[i].MultiSampleQuality;
3000 wined3d_parameters[i].SwapEffect = parameters[i].SwapEffect;
3001 wined3d_parameters[i].hDeviceWindow = parameters[i].hDeviceWindow;
3002 wined3d_parameters[i].Windowed = parameters[i].Windowed;
3003 wined3d_parameters[i].EnableAutoDepthStencil = parameters[i].EnableAutoDepthStencil;
3004 wined3d_parameters[i].AutoDepthStencilFormat =
3005 wined3dformat_from_d3dformat(parameters[i].AutoDepthStencilFormat);
3006 wined3d_parameters[i].Flags = parameters[i].Flags;
3007 wined3d_parameters[i].FullScreen_RefreshRateInHz = parameters[i].FullScreen_RefreshRateInHz;
3008 wined3d_parameters[i].PresentationInterval = parameters[i].PresentationInterval;
3009 wined3d_parameters[i].AutoRestoreDisplayMode = TRUE;
3010 }
3011
3012 hr = IWineD3DDevice_Init3D(device->WineD3DDevice, wined3d_parameters);
3013 if (FAILED(hr))
3014 {
3015 WARN("Failed to initialize 3D, hr %#x.\n", hr);
3016 IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice);
3017 HeapFree(GetProcessHeap(), 0, wined3d_parameters);
3018 IWineD3DDevice_Release(device->WineD3DDevice);
3019 wined3d_mutex_unlock();
3020 return hr;
3021 }
3022
3023 wined3d_mutex_unlock();
3024
3025 for (i = 0; i < count; ++i)
3026 {
3027 parameters[i].BackBufferWidth = wined3d_parameters[i].BackBufferWidth;
3028 parameters[i].BackBufferHeight = wined3d_parameters[i].BackBufferHeight;
3029 parameters[i].BackBufferFormat = d3dformat_from_wined3dformat(wined3d_parameters[i].BackBufferFormat);
3030 parameters[i].BackBufferCount = wined3d_parameters[i].BackBufferCount;
3031 parameters[i].MultiSampleType = wined3d_parameters[i].MultiSampleType;
3032 parameters[i].MultiSampleQuality = wined3d_parameters[i].MultiSampleQuality;
3033 parameters[i].SwapEffect = wined3d_parameters[i].SwapEffect;
3034 parameters[i].hDeviceWindow = wined3d_parameters[i].hDeviceWindow;
3035 parameters[i].Windowed = wined3d_parameters[i].Windowed;
3036 parameters[i].EnableAutoDepthStencil = wined3d_parameters[i].EnableAutoDepthStencil;
3037 parameters[i].AutoDepthStencilFormat =
3038 d3dformat_from_wined3dformat(wined3d_parameters[i].AutoDepthStencilFormat);
3039 parameters[i].Flags = wined3d_parameters[i].Flags;
3040 parameters[i].FullScreen_RefreshRateInHz = wined3d_parameters[i].FullScreen_RefreshRateInHz;
3041 parameters[i].PresentationInterval = wined3d_parameters[i].PresentationInterval;
3042 }
3043 HeapFree(GetProcessHeap(), 0, wined3d_parameters);
3044
3045 /* Initialize the converted declaration array. This creates a valid pointer
3046 * and when adding decls HeapReAlloc() can be used without further checking. */
3047 device->convertedDecls = HeapAlloc(GetProcessHeap(), 0, 0);
3048 if (!device->convertedDecls)
3049 {
3050 ERR("Failed to allocate FVF vertex declaration map memory.\n");
3051 wined3d_mutex_lock();
3052 IWineD3DDevice_Uninit3D(device->WineD3DDevice, D3D9CB_DestroySwapChain);
3053 IWineD3DDevice_ReleaseFocusWindow(device->WineD3DDevice);
3054 IWineD3DDevice_Release(device->WineD3DDevice);
3055 wined3d_mutex_unlock();
3056 return E_OUTOFMEMORY;
3057 }
3058
3059 return D3D_OK;
3060}
Note: See TracBrowser for help on using the repository browser.

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