VirtualBox

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

最後變更 在這個檔案從39605是 39602,由 vboxsync 提交於 13 年 前

wine/XPDM: 1. Additional swapchain creation fixes 2. De-libwine'ize wined3d 3. Single context per swapchain 4. wine & crOgl current context sync fixes 5. Proper Get/ReleaseDC handling

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

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