VirtualBox

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

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

crOpenGL: update to wine 1.1.43

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

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