VirtualBox

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

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

wddm: proper ie rendering under win8 (shared resource open & destroy fixes, zero-init resources on creaate, etc.)

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