Sync ddraw, d3d8 and d3d9 + wined3d to wine 1.1.28
[reactos.git] / reactos / dll / directx / wine / d3d9 / device.c
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 #include "config.h"
24 #include "d3d9_private.h"
25
26 WINE_DEFAULT_DEBUG_CHANNEL(d3d9);
27
28 D3DFORMAT d3dformat_from_wined3dformat(WINED3DFORMAT format)
29 {
30 BYTE *c = (BYTE *)&format;
31
32 /* Don't translate FOURCC formats */
33 if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
34
35 switch(format)
36 {
37 case WINED3DFMT_UNKNOWN: return D3DFMT_UNKNOWN;
38 case WINED3DFMT_R8G8B8: return D3DFMT_R8G8B8;
39 case WINED3DFMT_A8R8G8B8: return D3DFMT_A8R8G8B8;
40 case WINED3DFMT_X8R8G8B8: return D3DFMT_X8R8G8B8;
41 case WINED3DFMT_R5G6B5: return D3DFMT_R5G6B5;
42 case WINED3DFMT_X1R5G5B5: return D3DFMT_X1R5G5B5;
43 case WINED3DFMT_A1R5G5B5: return D3DFMT_A1R5G5B5;
44 case WINED3DFMT_A4R4G4B4: return D3DFMT_A4R4G4B4;
45 case WINED3DFMT_R3G3B2: return D3DFMT_R3G3B2;
46 case WINED3DFMT_A8_UNORM: return D3DFMT_A8;
47 case WINED3DFMT_A8R3G3B2: return D3DFMT_A8R3G3B2;
48 case WINED3DFMT_X4R4G4B4: return D3DFMT_X4R4G4B4;
49 case WINED3DFMT_R10G10B10A2_UNORM: return D3DFMT_A2B10G10R10;
50 case WINED3DFMT_R8G8B8A8_UNORM: return D3DFMT_A8B8G8R8;
51 case WINED3DFMT_X8B8G8R8: return D3DFMT_X8B8G8R8;
52 case WINED3DFMT_R16G16_UNORM: return D3DFMT_G16R16;
53 case WINED3DFMT_A2R10G10B10: return D3DFMT_A2R10G10B10;
54 case WINED3DFMT_R16G16B16A16_UNORM: return D3DFMT_A16B16G16R16;
55 case WINED3DFMT_A8P8: return D3DFMT_A8P8;
56 case WINED3DFMT_P8: return D3DFMT_P8;
57 case WINED3DFMT_L8: return D3DFMT_L8;
58 case WINED3DFMT_A8L8: return D3DFMT_A8L8;
59 case WINED3DFMT_A4L4: return D3DFMT_A4L4;
60 case WINED3DFMT_R8G8_SNORM: return D3DFMT_V8U8;
61 case WINED3DFMT_L6V5U5: return D3DFMT_L6V5U5;
62 case WINED3DFMT_X8L8V8U8: return D3DFMT_X8L8V8U8;
63 case WINED3DFMT_R8G8B8A8_SNORM: return D3DFMT_Q8W8V8U8;
64 case WINED3DFMT_R16G16_SNORM: return D3DFMT_V16U16;
65 case WINED3DFMT_A2W10V10U10: return D3DFMT_A2W10V10U10;
66 case WINED3DFMT_D16_LOCKABLE: return D3DFMT_D16_LOCKABLE;
67 case WINED3DFMT_D32: return D3DFMT_D32;
68 case WINED3DFMT_D15S1: return D3DFMT_D15S1;
69 case WINED3DFMT_D24S8: return D3DFMT_D24S8;
70 case WINED3DFMT_D24X8: return D3DFMT_D24X8;
71 case WINED3DFMT_D24X4S4: return D3DFMT_D24X4S4;
72 case WINED3DFMT_D16_UNORM: return D3DFMT_D16;
73 case WINED3DFMT_L16: return D3DFMT_L16;
74 case WINED3DFMT_D32F_LOCKABLE: return D3DFMT_D32F_LOCKABLE;
75 case WINED3DFMT_D24FS8: return D3DFMT_D24FS8;
76 case WINED3DFMT_VERTEXDATA: return D3DFMT_VERTEXDATA;
77 case WINED3DFMT_R16_UINT: return D3DFMT_INDEX16;
78 case WINED3DFMT_R32_UINT: return D3DFMT_INDEX32;
79 case WINED3DFMT_R16G16B16A16_SNORM: return D3DFMT_Q16W16V16U16;
80 case WINED3DFMT_R16_FLOAT: return D3DFMT_R16F;
81 case WINED3DFMT_R16G16_FLOAT: return D3DFMT_G16R16F;
82 case WINED3DFMT_R16G16B16A16_FLOAT: return D3DFMT_A16B16G16R16F;
83 case WINED3DFMT_R32_FLOAT: return D3DFMT_R32F;
84 case WINED3DFMT_R32G32_FLOAT: return D3DFMT_G32R32F;
85 case WINED3DFMT_R32G32B32A32_FLOAT: return D3DFMT_A32B32G32R32F;
86 case WINED3DFMT_CxV8U8: return D3DFMT_CxV8U8;
87 default:
88 FIXME("Unhandled WINED3DFORMAT %#x\n", format);
89 return D3DFMT_UNKNOWN;
90 }
91 }
92
93 WINED3DFORMAT wined3dformat_from_d3dformat(D3DFORMAT format)
94 {
95 BYTE *c = (BYTE *)&format;
96
97 /* Don't translate FOURCC formats */
98 if (isprint(c[0]) && isprint(c[1]) && isprint(c[2]) && isprint(c[3])) return format;
99
100 switch(format)
101 {
102 case D3DFMT_UNKNOWN: return WINED3DFMT_UNKNOWN;
103 case D3DFMT_R8G8B8: return WINED3DFMT_R8G8B8;
104 case D3DFMT_A8R8G8B8: return WINED3DFMT_A8R8G8B8;
105 case D3DFMT_X8R8G8B8: return WINED3DFMT_X8R8G8B8;
106 case D3DFMT_R5G6B5: return WINED3DFMT_R5G6B5;
107 case D3DFMT_X1R5G5B5: return WINED3DFMT_X1R5G5B5;
108 case D3DFMT_A1R5G5B5: return WINED3DFMT_A1R5G5B5;
109 case D3DFMT_A4R4G4B4: return WINED3DFMT_A4R4G4B4;
110 case D3DFMT_R3G3B2: return WINED3DFMT_R3G3B2;
111 case D3DFMT_A8: return WINED3DFMT_A8_UNORM;
112 case D3DFMT_A8R3G3B2: return WINED3DFMT_A8R3G3B2;
113 case D3DFMT_X4R4G4B4: return WINED3DFMT_X4R4G4B4;
114 case D3DFMT_A2B10G10R10: return WINED3DFMT_R10G10B10A2_UNORM;
115 case D3DFMT_A8B8G8R8: return WINED3DFMT_R8G8B8A8_UNORM;
116 case D3DFMT_X8B8G8R8: return WINED3DFMT_X8B8G8R8;
117 case D3DFMT_G16R16: return WINED3DFMT_R16G16_UNORM;
118 case D3DFMT_A2R10G10B10: return WINED3DFMT_A2R10G10B10;
119 case D3DFMT_A16B16G16R16: return WINED3DFMT_R16G16B16A16_UNORM;
120 case D3DFMT_A8P8: return WINED3DFMT_A8P8;
121 case D3DFMT_P8: return WINED3DFMT_P8;
122 case D3DFMT_L8: return WINED3DFMT_L8;
123 case D3DFMT_A8L8: return WINED3DFMT_A8L8;
124 case D3DFMT_A4L4: return WINED3DFMT_A4L4;
125 case D3DFMT_V8U8: return WINED3DFMT_R8G8_SNORM;
126 case D3DFMT_L6V5U5: return WINED3DFMT_L6V5U5;
127 case D3DFMT_X8L8V8U8: return WINED3DFMT_X8L8V8U8;
128 case D3DFMT_Q8W8V8U8: return WINED3DFMT_R8G8B8A8_SNORM;
129 case D3DFMT_V16U16: return WINED3DFMT_R16G16_SNORM;
130 case D3DFMT_A2W10V10U10: return WINED3DFMT_A2W10V10U10;
131 case D3DFMT_D16_LOCKABLE: return WINED3DFMT_D16_LOCKABLE;
132 case D3DFMT_D32: return WINED3DFMT_D32;
133 case D3DFMT_D15S1: return WINED3DFMT_D15S1;
134 case D3DFMT_D24S8: return WINED3DFMT_D24S8;
135 case D3DFMT_D24X8: return WINED3DFMT_D24X8;
136 case D3DFMT_D24X4S4: return WINED3DFMT_D24X4S4;
137 case D3DFMT_D16: return WINED3DFMT_D16_UNORM;
138 case D3DFMT_L16: return WINED3DFMT_L16;
139 case D3DFMT_D32F_LOCKABLE: return WINED3DFMT_D32F_LOCKABLE;
140 case D3DFMT_D24FS8: return WINED3DFMT_D24FS8;
141 case D3DFMT_VERTEXDATA: return WINED3DFMT_VERTEXDATA;
142 case D3DFMT_INDEX16: return WINED3DFMT_R16_UINT;
143 case D3DFMT_INDEX32: return WINED3DFMT_R32_UINT;
144 case D3DFMT_Q16W16V16U16: return WINED3DFMT_R16G16B16A16_SNORM;
145 case D3DFMT_R16F: return WINED3DFMT_R16_FLOAT;
146 case D3DFMT_G16R16F: return WINED3DFMT_R16G16_FLOAT;
147 case D3DFMT_A16B16G16R16F: return WINED3DFMT_R16G16B16A16_FLOAT;
148 case D3DFMT_R32F: return WINED3DFMT_R32_FLOAT;
149 case D3DFMT_G32R32F: return WINED3DFMT_R32G32_FLOAT;
150 case D3DFMT_A32B32G32R32F: return WINED3DFMT_R32G32B32A32_FLOAT;
151 case D3DFMT_CxV8U8: return WINED3DFMT_CxV8U8;
152 default:
153 FIXME("Unhandled D3DFORMAT %#x\n", format);
154 return WINED3DFMT_UNKNOWN;
155 }
156 }
157
158 static UINT vertex_count_from_primitive_count(D3DPRIMITIVETYPE primitive_type, UINT primitive_count)
159 {
160 switch(primitive_type)
161 {
162 case D3DPT_POINTLIST:
163 return primitive_count;
164
165 case D3DPT_LINELIST:
166 return primitive_count * 2;
167
168 case D3DPT_LINESTRIP:
169 return primitive_count + 1;
170
171 case D3DPT_TRIANGLELIST:
172 return primitive_count * 3;
173
174 case D3DPT_TRIANGLESTRIP:
175 case D3DPT_TRIANGLEFAN:
176 return primitive_count + 2;
177
178 default:
179 FIXME("Unhandled primitive type %#x\n", primitive_type);
180 return 0;
181 }
182 }
183
184 /* IDirect3D IUnknown parts follow: */
185 static HRESULT WINAPI IDirect3DDevice9Impl_QueryInterface(LPDIRECT3DDEVICE9EX iface, REFIID riid, LPVOID* ppobj) {
186 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
187 IDirect3D9 *d3d;
188 IDirect3D9Impl *d3dimpl;
189
190 if (IsEqualGUID(riid, &IID_IUnknown)
191 || IsEqualGUID(riid, &IID_IDirect3DDevice9)) {
192 IDirect3DDevice9Ex_AddRef(iface);
193 *ppobj = This;
194 TRACE("Returning IDirect3DDevice9 interface at %p\n", *ppobj);
195 return S_OK;
196 } else if(IsEqualGUID(riid, &IID_IDirect3DDevice9Ex)) {
197 /* Find out if the creating d3d9 interface was created with Direct3DCreate9Ex.
198 * It doesn't matter with which function the device was created.
199 */
200 IDirect3DDevice9_GetDirect3D(iface, &d3d);
201 d3dimpl = (IDirect3D9Impl *) d3d;
202
203 if(d3dimpl->extended) {
204 *ppobj = iface;
205 IDirect3DDevice9Ex_AddRef((IDirect3DDevice9Ex *) *ppobj);
206 IDirect3D9_Release(d3d);
207 TRACE("Returning IDirect3DDevice9Ex interface at %p\n", *ppobj);
208 return S_OK;
209 } else {
210 WARN("IDirect3D9 instance wasn't created with CreateDirect3D9Ex, returning E_NOINTERFACE\n");
211 IDirect3D9_Release(d3d);
212 *ppobj = NULL;
213 return E_NOINTERFACE;
214 }
215 }
216
217 if (IsEqualGUID(riid, &IID_IWineD3DDeviceParent))
218 {
219 IUnknown_AddRef((IUnknown *)&This->device_parent_vtbl);
220 *ppobj = &This->device_parent_vtbl;
221 return S_OK;
222 }
223
224 WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
225 *ppobj = NULL;
226 return E_NOINTERFACE;
227 }
228
229 static ULONG WINAPI IDirect3DDevice9Impl_AddRef(LPDIRECT3DDEVICE9EX iface) {
230 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
231 ULONG ref = InterlockedIncrement(&This->ref);
232
233 TRACE("(%p) : AddRef from %d\n", This, ref - 1);
234
235 return ref;
236 }
237
238 static ULONG WINAPI IDirect3DDevice9Impl_Release(LPDIRECT3DDEVICE9EX iface) {
239 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
240 ULONG ref;
241
242 if (This->inDestruction) return 0;
243 ref = InterlockedDecrement(&This->ref);
244
245 TRACE("(%p) : ReleaseRef to %d\n", This, ref);
246
247 if (ref == 0) {
248 unsigned i;
249 This->inDestruction = TRUE;
250
251 wined3d_mutex_lock();
252 for(i = 0; i < This->numConvertedDecls; i++) {
253 /* Unless Wine is buggy or the app has a bug the refcount will be 0, because decls hold a reference to the
254 * device
255 */
256 IDirect3DVertexDeclaration9Impl_Destroy(This->convertedDecls[i]);
257 }
258 HeapFree(GetProcessHeap(), 0, This->convertedDecls);
259
260 IWineD3DDevice_Uninit3D(This->WineD3DDevice, D3D9CB_DestroyDepthStencilSurface, D3D9CB_DestroySwapChain);
261 IWineD3DDevice_Release(This->WineD3DDevice);
262 wined3d_mutex_unlock();
263
264 HeapFree(GetProcessHeap(), 0, This);
265 }
266 return ref;
267 }
268
269 /* IDirect3DDevice Interface follow: */
270 static HRESULT WINAPI IDirect3DDevice9Impl_TestCooperativeLevel(LPDIRECT3DDEVICE9EX iface) {
271 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
272 HRESULT hr;
273 TRACE("(%p)\n", This);
274
275 wined3d_mutex_lock();
276 hr = IWineD3DDevice_TestCooperativeLevel(This->WineD3DDevice);
277 wined3d_mutex_unlock();
278
279 if(hr == WINED3D_OK && This->notreset) {
280 TRACE("D3D9 Device is marked not reset\n");
281 hr = D3DERR_DEVICENOTRESET;
282 }
283
284 return hr;
285 }
286
287 static UINT WINAPI IDirect3DDevice9Impl_GetAvailableTextureMem(LPDIRECT3DDEVICE9EX iface) {
288 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
289 HRESULT hr;
290 TRACE("(%p) Relay\n", This);
291
292 wined3d_mutex_lock();
293 hr = IWineD3DDevice_GetAvailableTextureMem(This->WineD3DDevice);
294 wined3d_mutex_unlock();
295
296 return hr;
297 }
298
299 static HRESULT WINAPI IDirect3DDevice9Impl_EvictManagedResources(LPDIRECT3DDEVICE9EX iface) {
300 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
301 HRESULT hr;
302 TRACE("(%p) : Relay\n", This);
303
304 wined3d_mutex_lock();
305 hr = IWineD3DDevice_EvictManagedResources(This->WineD3DDevice);
306 wined3d_mutex_unlock();
307
308 return hr;
309 }
310
311 static HRESULT WINAPI IDirect3DDevice9Impl_GetDirect3D(LPDIRECT3DDEVICE9EX iface, IDirect3D9** ppD3D9) {
312 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
313 HRESULT hr = D3D_OK;
314 IWineD3D* pWineD3D;
315
316 TRACE("(%p) Relay\n", This);
317
318 if (NULL == ppD3D9) {
319 return D3DERR_INVALIDCALL;
320 }
321
322 wined3d_mutex_lock();
323 hr = IWineD3DDevice_GetDirect3D(This->WineD3DDevice, &pWineD3D);
324 if (hr == D3D_OK && pWineD3D != NULL)
325 {
326 IWineD3D_GetParent(pWineD3D,(IUnknown **)ppD3D9);
327 IWineD3D_Release(pWineD3D);
328 } else {
329 FIXME("Call to IWineD3DDevice_GetDirect3D failed\n");
330 *ppD3D9 = NULL;
331 }
332 TRACE("(%p) returning %p\n", This, *ppD3D9);
333 wined3d_mutex_unlock();
334
335 return hr;
336 }
337
338 static HRESULT WINAPI IDirect3DDevice9Impl_GetDeviceCaps(LPDIRECT3DDEVICE9EX iface, D3DCAPS9* pCaps) {
339 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
340 HRESULT hrc = D3D_OK;
341 WINED3DCAPS *pWineCaps;
342
343 TRACE("(%p) : Relay pCaps %p\n", This, pCaps);
344 if(NULL == pCaps){
345 return D3DERR_INVALIDCALL;
346 }
347 pWineCaps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINED3DCAPS));
348 if(pWineCaps == NULL){
349 return D3DERR_INVALIDCALL; /* well this is what MSDN says to return */
350 }
351
352 memset(pCaps, 0, sizeof(*pCaps));
353
354 wined3d_mutex_lock();
355 hrc = IWineD3DDevice_GetDeviceCaps(This->WineD3DDevice, pWineCaps);
356 wined3d_mutex_unlock();
357
358 WINECAPSTOD3D9CAPS(pCaps, pWineCaps)
359 HeapFree(GetProcessHeap(), 0, pWineCaps);
360
361 /* Some functionality is implemented in d3d9.dll, not wined3d.dll. Add the needed caps */
362 pCaps->DevCaps2 |= D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES;
363
364 filter_caps(pCaps);
365
366 TRACE("Returning %p %p\n", This, pCaps);
367 return hrc;
368 }
369
370 static HRESULT WINAPI IDirect3DDevice9Impl_GetDisplayMode(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DDISPLAYMODE* pMode) {
371 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
372 HRESULT hr;
373 TRACE("(%p) Relay\n", This);
374
375 wined3d_mutex_lock();
376 hr = IWineD3DDevice_GetDisplayMode(This->WineD3DDevice, iSwapChain, (WINED3DDISPLAYMODE *) pMode);
377 wined3d_mutex_unlock();
378
379 if (SUCCEEDED(hr)) pMode->Format = d3dformat_from_wined3dformat(pMode->Format);
380
381 return hr;
382 }
383
384 static HRESULT WINAPI IDirect3DDevice9Impl_GetCreationParameters(LPDIRECT3DDEVICE9EX iface, D3DDEVICE_CREATION_PARAMETERS *pParameters) {
385 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
386 HRESULT hr;
387 TRACE("(%p) Relay\n", This);
388
389 wined3d_mutex_lock();
390 hr = IWineD3DDevice_GetCreationParameters(This->WineD3DDevice, (WINED3DDEVICE_CREATION_PARAMETERS *) pParameters);
391 wined3d_mutex_unlock();
392
393 return hr;
394 }
395
396 static HRESULT WINAPI IDirect3DDevice9Impl_SetCursorProperties(LPDIRECT3DDEVICE9EX iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap) {
397 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
398 IDirect3DSurface9Impl *pSurface = (IDirect3DSurface9Impl*)pCursorBitmap;
399 HRESULT hr;
400
401 TRACE("(%p) Relay\n", This);
402 if(!pCursorBitmap) {
403 WARN("No cursor bitmap, returning WINED3DERR_INVALIDCALL\n");
404 return WINED3DERR_INVALIDCALL;
405 }
406
407 wined3d_mutex_lock();
408 hr = IWineD3DDevice_SetCursorProperties(This->WineD3DDevice, XHotSpot, YHotSpot, pSurface->wineD3DSurface);
409 wined3d_mutex_unlock();
410
411 return hr;
412 }
413
414 static void WINAPI IDirect3DDevice9Impl_SetCursorPosition(LPDIRECT3DDEVICE9EX iface, int XScreenSpace, int YScreenSpace, DWORD Flags) {
415 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
416 TRACE("(%p) Relay\n", This);
417
418 wined3d_mutex_lock();
419 IWineD3DDevice_SetCursorPosition(This->WineD3DDevice, XScreenSpace, YScreenSpace, Flags);
420 wined3d_mutex_unlock();
421 }
422
423 static BOOL WINAPI IDirect3DDevice9Impl_ShowCursor(LPDIRECT3DDEVICE9EX iface, BOOL bShow) {
424 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
425 BOOL ret;
426 TRACE("(%p) Relay\n", This);
427
428 wined3d_mutex_lock();
429 ret = IWineD3DDevice_ShowCursor(This->WineD3DDevice, bShow);
430 wined3d_mutex_unlock();
431
432 return ret;
433 }
434
435 static HRESULT WINAPI reset_enum_callback(IWineD3DResource *resource, void *data) {
436 BOOL *resources_ok = data;
437 D3DRESOURCETYPE type;
438 HRESULT ret = S_OK;
439 WINED3DSURFACE_DESC surface_desc;
440 WINED3DVOLUME_DESC volume_desc;
441 D3DINDEXBUFFER_DESC index_desc;
442 D3DVERTEXBUFFER_DESC vertex_desc;
443 WINED3DPOOL pool;
444 IDirect3DResource9 *parent;
445
446 IWineD3DResource_GetParent(resource, (IUnknown **) &parent);
447 type = IDirect3DResource9_GetType(parent);
448 switch(type) {
449 case D3DRTYPE_SURFACE:
450 IWineD3DSurface_GetDesc((IWineD3DSurface *) resource, &surface_desc);
451 pool = surface_desc.pool;
452 break;
453
454 case D3DRTYPE_VOLUME:
455 IWineD3DVolume_GetDesc((IWineD3DVolume *) resource, &volume_desc);
456 pool = volume_desc.Pool;
457 break;
458
459 case D3DRTYPE_INDEXBUFFER:
460 IDirect3DIndexBuffer9_GetDesc((IDirect3DIndexBuffer9 *) parent, &index_desc);
461 pool = index_desc.Pool;
462 break;
463
464 case D3DRTYPE_VERTEXBUFFER:
465 IDirect3DVertexBuffer9_GetDesc((IDirect3DVertexBuffer9 *)parent, &vertex_desc);
466 pool = vertex_desc.Pool;
467 break;
468
469 /* No need to check for textures. If there is a D3DPOOL_DEFAULT texture, there
470 * is a D3DPOOL_DEFAULT surface or volume as well
471 */
472 default:
473 pool = WINED3DPOOL_SCRATCH; /* a harmless pool */
474 break;
475 }
476
477 if(pool == WINED3DPOOL_DEFAULT) {
478 if(IUnknown_Release(parent) == 0) {
479 TRACE("Parent %p is an implicit resource with ref 0\n", parent);
480 } else {
481 WARN("Resource %p(wineD3D %p) with pool D3DPOOL_DEFAULT blocks the Reset call\n", parent, resource);
482 ret = S_FALSE;
483 *resources_ok = FALSE;
484 }
485 } else {
486 IUnknown_Release(parent);
487 }
488 IWineD3DResource_Release(resource);
489
490 return ret;
491 }
492
493 static HRESULT WINAPI IDirect3DDevice9Impl_Reset(LPDIRECT3DDEVICE9EX iface, D3DPRESENT_PARAMETERS* pPresentationParameters) {
494 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
495 WINED3DPRESENT_PARAMETERS localParameters;
496 HRESULT hr;
497 BOOL resources_ok = TRUE;
498 UINT i;
499
500 TRACE("(%p) Relay pPresentationParameters(%p)\n", This, pPresentationParameters);
501
502 /* Reset states that hold a COM object. WineD3D holds an internal reference to set objects, because
503 * such objects can still be used for rendering after their external d3d9 object has been destroyed.
504 * These objects must not be enumerated. Unsetting them tells WineD3D that the application will not
505 * make use of the hidden reference and destroys the objects.
506 *
507 * Unsetting them is no problem, because the states are supposed to be reset anyway. If the validation
508 * below fails, the device is considered "lost", and _Reset and _Release are the only allowed calls
509 */
510 wined3d_mutex_lock();
511 IWineD3DDevice_SetIndices(This->WineD3DDevice, NULL, WINED3DFMT_UNKNOWN);
512 for(i = 0; i < 16; i++) {
513 IWineD3DDevice_SetStreamSource(This->WineD3DDevice, i, NULL, 0, 0);
514 }
515 for(i = 0; i < 16; i++) {
516 IWineD3DDevice_SetTexture(This->WineD3DDevice, i, NULL);
517 }
518
519 IWineD3DDevice_EnumResources(This->WineD3DDevice, reset_enum_callback, &resources_ok);
520 if(!resources_ok) {
521 WARN("The application is holding D3DPOOL_DEFAULT resources, rejecting reset\n");
522 This->notreset = TRUE;
523 wined3d_mutex_unlock();
524
525 return WINED3DERR_INVALIDCALL;
526 }
527
528 localParameters.BackBufferWidth = pPresentationParameters->BackBufferWidth;
529 localParameters.BackBufferHeight = pPresentationParameters->BackBufferHeight;
530 localParameters.BackBufferFormat = wined3dformat_from_d3dformat(pPresentationParameters->BackBufferFormat);
531 localParameters.BackBufferCount = pPresentationParameters->BackBufferCount;
532 localParameters.MultiSampleType = pPresentationParameters->MultiSampleType;
533 localParameters.MultiSampleQuality = pPresentationParameters->MultiSampleQuality;
534 localParameters.SwapEffect = pPresentationParameters->SwapEffect;
535 localParameters.hDeviceWindow = pPresentationParameters->hDeviceWindow;
536 localParameters.Windowed = pPresentationParameters->Windowed;
537 localParameters.EnableAutoDepthStencil = pPresentationParameters->EnableAutoDepthStencil;
538 localParameters.AutoDepthStencilFormat = wined3dformat_from_d3dformat(pPresentationParameters->AutoDepthStencilFormat);
539 localParameters.Flags = pPresentationParameters->Flags;
540 localParameters.FullScreen_RefreshRateInHz = pPresentationParameters->FullScreen_RefreshRateInHz;
541 localParameters.PresentationInterval = pPresentationParameters->PresentationInterval;
542 localParameters.AutoRestoreDisplayMode = TRUE;
543
544 hr = IWineD3DDevice_Reset(This->WineD3DDevice, &localParameters);
545 if(FAILED(hr)) {
546 This->notreset = TRUE;
547
548 pPresentationParameters->BackBufferWidth = localParameters.BackBufferWidth;
549 pPresentationParameters->BackBufferHeight = localParameters.BackBufferHeight;
550 pPresentationParameters->BackBufferFormat = d3dformat_from_wined3dformat(localParameters.BackBufferFormat);
551 pPresentationParameters->BackBufferCount = localParameters.BackBufferCount;
552 pPresentationParameters->MultiSampleType = localParameters.MultiSampleType;
553 pPresentationParameters->MultiSampleQuality = localParameters.MultiSampleQuality;
554 pPresentationParameters->SwapEffect = localParameters.SwapEffect;
555 pPresentationParameters->hDeviceWindow = localParameters.hDeviceWindow;
556 pPresentationParameters->Windowed = localParameters.Windowed;
557 pPresentationParameters->EnableAutoDepthStencil = localParameters.EnableAutoDepthStencil;
558 pPresentationParameters->AutoDepthStencilFormat = d3dformat_from_wined3dformat(localParameters.AutoDepthStencilFormat);
559 pPresentationParameters->Flags = localParameters.Flags;
560 pPresentationParameters->FullScreen_RefreshRateInHz = localParameters.FullScreen_RefreshRateInHz;
561 pPresentationParameters->PresentationInterval = localParameters.PresentationInterval;
562 } else {
563 This->notreset = FALSE;
564 }
565
566 wined3d_mutex_unlock();
567
568 return hr;
569 }
570
571 static HRESULT WINAPI IDirect3DDevice9Impl_Present(LPDIRECT3DDEVICE9EX iface, CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA*
572 pDirtyRegion) {
573 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
574 HRESULT hr;
575 TRACE("(%p) Relay\n", This);
576
577 wined3d_mutex_lock();
578 hr = IWineD3DDevice_Present(This->WineD3DDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
579 wined3d_mutex_unlock();
580
581 return hr;
582 }
583
584 static HRESULT WINAPI IDirect3DDevice9Impl_GetBackBuffer(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, UINT BackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 ** ppBackBuffer) {
585 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
586 IWineD3DSurface *retSurface = NULL;
587 HRESULT rc = D3D_OK;
588
589 TRACE("(%p) Relay\n", This);
590
591 wined3d_mutex_lock();
592 rc = IWineD3DDevice_GetBackBuffer(This->WineD3DDevice, iSwapChain, BackBuffer, (WINED3DBACKBUFFER_TYPE) Type, &retSurface);
593 if (rc == D3D_OK && NULL != retSurface && NULL != ppBackBuffer) {
594 IWineD3DSurface_GetParent(retSurface, (IUnknown **)ppBackBuffer);
595 IWineD3DSurface_Release(retSurface);
596 }
597 wined3d_mutex_unlock();
598
599 return rc;
600 }
601 static HRESULT WINAPI IDirect3DDevice9Impl_GetRasterStatus(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus) {
602 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
603 HRESULT hr;
604 TRACE("(%p) Relay\n", This);
605
606 wined3d_mutex_lock();
607 hr = IWineD3DDevice_GetRasterStatus(This->WineD3DDevice, iSwapChain, (WINED3DRASTER_STATUS *) pRasterStatus);
608 wined3d_mutex_unlock();
609
610 return hr;
611 }
612
613 static HRESULT WINAPI IDirect3DDevice9Impl_SetDialogBoxMode(LPDIRECT3DDEVICE9EX iface, BOOL bEnableDialogs) {
614 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
615 HRESULT hr;
616 TRACE("(%p) Relay\n", This);
617
618 wined3d_mutex_lock();
619 hr = IWineD3DDevice_SetDialogBoxMode(This->WineD3DDevice, bEnableDialogs);
620 wined3d_mutex_unlock();
621
622 return hr;
623 }
624
625 static void WINAPI IDirect3DDevice9Impl_SetGammaRamp(IDirect3DDevice9Ex *iface, UINT iSwapChain,
626 DWORD Flags, const D3DGAMMARAMP *pRamp)
627 {
628 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
629 TRACE("(%p) Relay\n", This);
630
631 /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
632 wined3d_mutex_lock();
633 IWineD3DDevice_SetGammaRamp(This->WineD3DDevice, iSwapChain, Flags, (CONST WINED3DGAMMARAMP *)pRamp);
634 wined3d_mutex_unlock();
635 }
636
637 static void WINAPI IDirect3DDevice9Impl_GetGammaRamp(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DGAMMARAMP* pRamp) {
638 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
639 TRACE("(%p) Relay\n", This);
640
641 /* Note: D3DGAMMARAMP is compatible with WINED3DGAMMARAMP */
642 wined3d_mutex_lock();
643 IWineD3DDevice_GetGammaRamp(This->WineD3DDevice, iSwapChain, (WINED3DGAMMARAMP *) pRamp);
644 wined3d_mutex_unlock();
645 }
646
647
648 static HRESULT IDirect3DDevice9Impl_CreateSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
649 D3DFORMAT Format, BOOL Lockable, BOOL Discard, UINT Level, IDirect3DSurface9 **ppSurface,
650 UINT Usage, D3DPOOL Pool, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality)
651 {
652 HRESULT hrc;
653 IDirect3DSurface9Impl *object;
654 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
655 TRACE("(%p) Relay\n", This);
656
657 if (MultisampleQuality > 0)
658 {
659 FIXME("MultisampleQuality set to %d, bstituting 0\n", MultisampleQuality);
660 MultisampleQuality = 0;
661 }
662 /*FIXME: Check MAX bounds of MultisampleQuality*/
663
664 /* Allocate the storage for the device */
665 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DSurface9Impl));
666 if (NULL == object) {
667 FIXME("Allocation of memory failed\n");
668 return D3DERR_OUTOFVIDEOMEMORY;
669 }
670
671 object->lpVtbl = &Direct3DSurface9_Vtbl;
672 object->ref = 1;
673
674 TRACE("(%p) : w(%d) h(%d) fmt(%d) surf@%p\n", This, Width, Height, Format, *ppSurface);
675
676 wined3d_mutex_lock();
677 hrc = IWineD3DDevice_CreateSurface(This->WineD3DDevice, Width, Height, wined3dformat_from_d3dformat(Format),
678 Lockable, Discard, Level, &object->wineD3DSurface, Usage & WINED3DUSAGE_MASK, (WINED3DPOOL)Pool,
679 MultiSample, MultisampleQuality, SURFACE_OPENGL, (IUnknown *)object);
680 wined3d_mutex_unlock();
681
682 if (hrc != D3D_OK || NULL == object->wineD3DSurface) {
683
684 /* free up object */
685 FIXME("(%p) call to IWineD3DDevice_CreateSurface failed\n", This);
686 HeapFree(GetProcessHeap(), 0, object);
687 } else {
688 IDirect3DDevice9Ex_AddRef(iface);
689 object->parentDevice = iface;
690 TRACE("(%p) : Created surface %p\n", This, object);
691 *ppSurface = (LPDIRECT3DSURFACE9) object;
692 }
693 return hrc;
694 }
695
696 static HRESULT WINAPI IDirect3DDevice9Impl_CreateRenderTarget(IDirect3DDevice9Ex *iface, UINT Width, UINT Height,
697 D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable,
698 IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle)
699 {
700 HRESULT hr;
701 TRACE("Relay\n");
702
703 hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, Lockable, FALSE /* Discard */,
704 0 /* Level */, ppSurface, D3DUSAGE_RENDERTARGET, D3DPOOL_DEFAULT, MultiSample, MultisampleQuality);
705
706 return hr;
707 }
708
709 static HRESULT WINAPI IDirect3DDevice9Impl_CreateDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height,
710 D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample,
711 DWORD MultisampleQuality, BOOL Discard,
712 IDirect3DSurface9 **ppSurface, HANDLE* pSharedHandle) {
713 HRESULT hr;
714 TRACE("Relay\n");
715
716 hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, Discard,
717 0 /* Level */, ppSurface, D3DUSAGE_DEPTHSTENCIL, D3DPOOL_DEFAULT, MultiSample, MultisampleQuality);
718
719 return hr;
720 }
721
722
723 static HRESULT WINAPI IDirect3DDevice9Impl_UpdateSurface(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint) {
724 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
725 HRESULT hr;
726 TRACE("(%p) Relay\n" , This);
727
728 wined3d_mutex_lock();
729 hr = IWineD3DDevice_UpdateSurface(This->WineD3DDevice, ((IDirect3DSurface9Impl *)pSourceSurface)->wineD3DSurface, pSourceRect, ((IDirect3DSurface9Impl *)pDestinationSurface)->wineD3DSurface, pDestPoint);
730 wined3d_mutex_unlock();
731
732 return hr;
733 }
734
735 static HRESULT WINAPI IDirect3DDevice9Impl_UpdateTexture(LPDIRECT3DDEVICE9EX iface, IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture) {
736 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
737 HRESULT hr;
738 TRACE("(%p) Relay\n" , This);
739
740 wined3d_mutex_lock();
741 hr = IWineD3DDevice_UpdateTexture(This->WineD3DDevice, ((IDirect3DBaseTexture9Impl *)pSourceTexture)->wineD3DBaseTexture, ((IDirect3DBaseTexture9Impl *)pDestinationTexture)->wineD3DBaseTexture);
742 wined3d_mutex_unlock();
743
744 return hr;
745 }
746
747 static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderTargetData(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface) {
748 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
749 IDirect3DSurface9Impl *renderTarget = (IDirect3DSurface9Impl *)pRenderTarget;
750 IDirect3DSurface9Impl *destSurface = (IDirect3DSurface9Impl *)pDestSurface;
751 HRESULT hr;
752 TRACE("(%p)->(%p,%p)\n" , This, renderTarget, destSurface);
753
754 wined3d_mutex_lock();
755 hr = IWineD3DSurface_BltFast(destSurface->wineD3DSurface, 0, 0, renderTarget->wineD3DSurface, NULL, WINEDDBLTFAST_NOCOLORKEY);
756 wined3d_mutex_unlock();
757
758 return hr;
759 }
760
761 static HRESULT WINAPI IDirect3DDevice9Impl_GetFrontBufferData(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, IDirect3DSurface9* pDestSurface) {
762 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
763 IDirect3DSurface9Impl *destSurface = (IDirect3DSurface9Impl *)pDestSurface;
764 HRESULT hr;
765 TRACE("(%p) Relay\n" , This);
766
767 wined3d_mutex_lock();
768 hr = IWineD3DDevice_GetFrontBufferData(This->WineD3DDevice, iSwapChain, destSurface->wineD3DSurface);
769 wined3d_mutex_unlock();
770
771 return hr;
772 }
773
774 static HRESULT WINAPI IDirect3DDevice9Impl_StretchRect(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter) {
775 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
776 IDirect3DSurface9Impl *src = (IDirect3DSurface9Impl *) pSourceSurface;
777 IDirect3DSurface9Impl *dst = (IDirect3DSurface9Impl *) pDestSurface;
778 HRESULT hr;
779
780 TRACE("(%p)->(%p,%p,%p,%p,%d)\n" , This, src, pSourceRect, dst, pDestRect, Filter);
781
782 wined3d_mutex_lock();
783 hr = IWineD3DSurface_Blt(dst->wineD3DSurface, pDestRect, src->wineD3DSurface, pSourceRect, 0, NULL, Filter);
784 wined3d_mutex_unlock();
785
786 return hr;
787 }
788
789 static HRESULT WINAPI IDirect3DDevice9Impl_ColorFill(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color) {
790 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
791 IDirect3DSurface9Impl *surface = (IDirect3DSurface9Impl *)pSurface;
792 WINED3DPOOL pool;
793 WINED3DRESOURCETYPE restype;
794 DWORD usage;
795 WINED3DSURFACE_DESC desc;
796 HRESULT hr;
797 TRACE("(%p) Relay\n" , This);
798
799 wined3d_mutex_lock();
800
801 IWineD3DSurface_GetDesc(surface->wineD3DSurface, &desc);
802 usage = desc.usage;
803 pool = desc.pool;
804 restype = desc.resource_type;
805
806 /* This method is only allowed with surfaces that are render targets, or offscreen plain surfaces
807 * in D3DPOOL_DEFAULT
808 */
809 if(!(usage & WINED3DUSAGE_RENDERTARGET) && (pool != WINED3DPOOL_DEFAULT || restype != WINED3DRTYPE_SURFACE)) {
810 wined3d_mutex_unlock();
811 WARN("Surface is not a render target, or not a stand-alone D3DPOOL_DEFAULT surface\n");
812 return D3DERR_INVALIDCALL;
813 }
814
815 /* Colorfill can only be used on rendertarget surfaces, or offscreen plain surfaces in D3DPOOL_DEFAULT */
816 /* Note: D3DRECT is compatible with WINED3DRECT */
817 hr = IWineD3DDevice_ColorFill(This->WineD3DDevice, surface->wineD3DSurface, (CONST WINED3DRECT*)pRect, color);
818
819 wined3d_mutex_unlock();
820
821 return hr;
822 }
823
824 static HRESULT WINAPI IDirect3DDevice9Impl_CreateOffscreenPlainSurface(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9 **ppSurface, HANDLE* pSharedHandle) {
825 HRESULT hr;
826 TRACE("Relay\n");
827 if(Pool == D3DPOOL_MANAGED ){
828 FIXME("Attempting to create a managed offscreen plain surface\n");
829 return D3DERR_INVALIDCALL;
830 }
831 /*
832 'Off-screen plain surfaces are always lockable, regardless of their pool types.'
833 but then...
834 D3DPOOL_DEFAULT is the appropriate pool for use with the IDirect3DDevice9::StretchRect and IDirect3DDevice9::ColorFill.
835 Why, their always lockable?
836 should I change the usage to dynamic?
837 */
838 hr = IDirect3DDevice9Impl_CreateSurface(iface, Width, Height, Format, TRUE /* Lockable */, FALSE /* Discard */,
839 0 /* Level */, ppSurface, 0 /* Usage (undefined/none) */, (WINED3DPOOL)Pool, D3DMULTISAMPLE_NONE,
840 0 /* MultisampleQuality */);
841
842 return hr;
843 }
844
845 /* TODO: move to wineD3D */
846 static HRESULT WINAPI IDirect3DDevice9Impl_SetRenderTarget(LPDIRECT3DDEVICE9EX iface, DWORD RenderTargetIndex, IDirect3DSurface9* pRenderTarget) {
847 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
848 IDirect3DSurface9Impl *pSurface = (IDirect3DSurface9Impl*)pRenderTarget;
849 HRESULT hr;
850 TRACE("(%p) Relay\n" , This);
851
852 wined3d_mutex_lock();
853 hr = IWineD3DDevice_SetRenderTarget(This->WineD3DDevice, RenderTargetIndex, pSurface ? pSurface->wineD3DSurface : NULL);
854 wined3d_mutex_unlock();
855
856 return hr;
857 }
858
859 static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderTarget(LPDIRECT3DDEVICE9EX iface, DWORD RenderTargetIndex, IDirect3DSurface9 **ppRenderTarget) {
860 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
861 IWineD3DSurface *pRenderTarget;
862 HRESULT hr;
863
864 TRACE("(%p) Relay\n" , This);
865
866 if (ppRenderTarget == NULL) {
867 return D3DERR_INVALIDCALL;
868 }
869
870 wined3d_mutex_lock();
871
872 hr=IWineD3DDevice_GetRenderTarget(This->WineD3DDevice,RenderTargetIndex,&pRenderTarget);
873
874 if (FAILED(hr))
875 {
876 FIXME("Call to IWineD3DDevice_GetRenderTarget failed, hr %#x\n", hr);
877 }
878 else if (!pRenderTarget)
879 {
880 *ppRenderTarget = NULL;
881 }
882 else
883 {
884 IWineD3DSurface_GetParent(pRenderTarget, (IUnknown **)ppRenderTarget);
885 IWineD3DSurface_Release(pRenderTarget);
886 }
887
888 wined3d_mutex_unlock();
889
890 return hr;
891 }
892
893 static HRESULT WINAPI IDirect3DDevice9Impl_SetDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9* pZStencilSurface) {
894 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
895 IDirect3DSurface9Impl *pSurface;
896 HRESULT hr;
897 TRACE("(%p) Relay\n" , This);
898
899 pSurface = (IDirect3DSurface9Impl*)pZStencilSurface;
900
901 wined3d_mutex_lock();
902 hr = IWineD3DDevice_SetDepthStencilSurface(This->WineD3DDevice, NULL==pSurface ? NULL : pSurface->wineD3DSurface);
903 wined3d_mutex_unlock();
904
905 return hr;
906 }
907
908 static HRESULT WINAPI IDirect3DDevice9Impl_GetDepthStencilSurface(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9 **ppZStencilSurface) {
909 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
910 HRESULT hr = D3D_OK;
911 IWineD3DSurface *pZStencilSurface;
912
913 TRACE("(%p) Relay\n" , This);
914 if(ppZStencilSurface == NULL){
915 return D3DERR_INVALIDCALL;
916 }
917
918 wined3d_mutex_lock();
919 hr = IWineD3DDevice_GetDepthStencilSurface(This->WineD3DDevice,&pZStencilSurface);
920 if (hr == WINED3D_OK) {
921 IWineD3DSurface_GetParent(pZStencilSurface,(IUnknown**)ppZStencilSurface);
922 IWineD3DSurface_Release(pZStencilSurface);
923 } else {
924 if (hr != WINED3DERR_NOTFOUND)
925 WARN("Call to IWineD3DDevice_GetDepthStencilSurface failed with 0x%08x\n", hr);
926 *ppZStencilSurface = NULL;
927 }
928 wined3d_mutex_unlock();
929
930 return hr;
931 }
932
933 static HRESULT WINAPI IDirect3DDevice9Impl_BeginScene(LPDIRECT3DDEVICE9EX iface) {
934 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
935 HRESULT hr;
936 TRACE("(%p) Relay\n" , This);
937
938 wined3d_mutex_lock();
939 hr = IWineD3DDevice_BeginScene(This->WineD3DDevice);
940 wined3d_mutex_unlock();
941
942 return hr;
943 }
944
945 static HRESULT WINAPI IDirect3DDevice9Impl_EndScene(LPDIRECT3DDEVICE9EX iface) {
946 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
947 HRESULT hr;
948 TRACE("(%p) Relay\n" , This);
949
950 wined3d_mutex_lock();
951 hr = IWineD3DDevice_EndScene(This->WineD3DDevice);
952 wined3d_mutex_unlock();
953
954 return hr;
955 }
956
957 static HRESULT WINAPI IDirect3DDevice9Impl_Clear(LPDIRECT3DDEVICE9EX iface, DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) {
958 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
959 HRESULT hr;
960 TRACE("(%p) Relay\n" , This);
961
962 /* Note: D3DRECT is compatible with WINED3DRECT */
963 wined3d_mutex_lock();
964 hr = IWineD3DDevice_Clear(This->WineD3DDevice, Count, (CONST WINED3DRECT*) pRects, Flags, Color, Z, Stencil);
965 wined3d_mutex_unlock();
966
967 return hr;
968 }
969
970 static HRESULT WINAPI IDirect3DDevice9Impl_SetTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* lpMatrix) {
971 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
972 HRESULT hr;
973 TRACE("(%p) Relay\n" , This);
974
975 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
976 wined3d_mutex_lock();
977 hr = IWineD3DDevice_SetTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) lpMatrix);
978 wined3d_mutex_unlock();
979
980 return hr;
981 }
982
983 static HRESULT WINAPI IDirect3DDevice9Impl_GetTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, D3DMATRIX* pMatrix) {
984 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
985 HRESULT hr;
986
987 TRACE("(%p) Relay\n" , This);
988
989 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
990 wined3d_mutex_lock();
991 hr = IWineD3DDevice_GetTransform(This->WineD3DDevice, State, (WINED3DMATRIX*) pMatrix);
992 wined3d_mutex_unlock();
993
994 return hr;
995 }
996
997 static HRESULT WINAPI IDirect3DDevice9Impl_MultiplyTransform(LPDIRECT3DDEVICE9EX iface, D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX* pMatrix) {
998 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
999 HRESULT hr;
1000 TRACE("(%p) Relay\n" , This);
1001
1002 /* Note: D3DMATRIX is compatible with WINED3DMATRIX */
1003 wined3d_mutex_lock();
1004 hr = IWineD3DDevice_MultiplyTransform(This->WineD3DDevice, State, (CONST WINED3DMATRIX*) pMatrix);
1005 wined3d_mutex_unlock();
1006
1007 return hr;
1008 }
1009
1010 static HRESULT WINAPI IDirect3DDevice9Impl_SetViewport(LPDIRECT3DDEVICE9EX iface, CONST D3DVIEWPORT9* pViewport) {
1011 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1012 HRESULT hr;
1013 TRACE("(%p) Relay\n" , This);
1014
1015 /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
1016 wined3d_mutex_lock();
1017 hr = IWineD3DDevice_SetViewport(This->WineD3DDevice, (const WINED3DVIEWPORT *)pViewport);
1018 wined3d_mutex_unlock();
1019
1020 return hr;
1021 }
1022
1023 static HRESULT WINAPI IDirect3DDevice9Impl_GetViewport(LPDIRECT3DDEVICE9EX iface, D3DVIEWPORT9* pViewport) {
1024 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1025 HRESULT hr;
1026 TRACE("(%p) Relay\n" , This);
1027
1028 /* Note: D3DVIEWPORT9 is compatible with WINED3DVIEWPORT */
1029 wined3d_mutex_lock();
1030 hr = IWineD3DDevice_GetViewport(This->WineD3DDevice, (WINED3DVIEWPORT *)pViewport);
1031 wined3d_mutex_unlock();
1032
1033 return hr;
1034 }
1035
1036 static HRESULT WINAPI IDirect3DDevice9Impl_SetMaterial(LPDIRECT3DDEVICE9EX iface, CONST D3DMATERIAL9* pMaterial) {
1037 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1038 HRESULT hr;
1039 TRACE("(%p) Relay\n" , This);
1040
1041 /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
1042 wined3d_mutex_lock();
1043 hr = IWineD3DDevice_SetMaterial(This->WineD3DDevice, (const WINED3DMATERIAL *)pMaterial);
1044 wined3d_mutex_unlock();
1045
1046 return hr;
1047 }
1048
1049 static HRESULT WINAPI IDirect3DDevice9Impl_GetMaterial(LPDIRECT3DDEVICE9EX iface, D3DMATERIAL9* pMaterial) {
1050 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1051 HRESULT hr;
1052 TRACE("(%p) Relay\n" , This);
1053
1054 /* Note: D3DMATERIAL9 is compatible with WINED3DMATERIAL */
1055 wined3d_mutex_lock();
1056 hr = IWineD3DDevice_GetMaterial(This->WineD3DDevice, (WINED3DMATERIAL *)pMaterial);
1057 wined3d_mutex_unlock();
1058
1059 return hr;
1060 }
1061
1062 static HRESULT WINAPI IDirect3DDevice9Impl_SetLight(LPDIRECT3DDEVICE9EX iface, DWORD Index, CONST D3DLIGHT9* pLight) {
1063 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1064 HRESULT hr;
1065 TRACE("(%p) Relay\n" , This);
1066
1067 /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
1068 wined3d_mutex_lock();
1069 hr = IWineD3DDevice_SetLight(This->WineD3DDevice, Index, (const WINED3DLIGHT *)pLight);
1070 wined3d_mutex_unlock();
1071
1072 return hr;
1073 }
1074
1075 static HRESULT WINAPI IDirect3DDevice9Impl_GetLight(LPDIRECT3DDEVICE9EX iface, DWORD Index, D3DLIGHT9* pLight) {
1076 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1077 HRESULT hr;
1078 TRACE("(%p) Relay\n" , This);
1079
1080 /* Note: D3DLIGHT9 is compatible with WINED3DLIGHT */
1081 wined3d_mutex_lock();
1082 hr = IWineD3DDevice_GetLight(This->WineD3DDevice, Index, (WINED3DLIGHT *)pLight);
1083 wined3d_mutex_unlock();
1084
1085 return hr;
1086 }
1087
1088 static HRESULT WINAPI IDirect3DDevice9Impl_LightEnable(LPDIRECT3DDEVICE9EX iface, DWORD Index, BOOL Enable) {
1089 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1090 HRESULT hr;
1091 TRACE("(%p) Relay\n" , This);
1092
1093 wined3d_mutex_lock();
1094 hr = IWineD3DDevice_SetLightEnable(This->WineD3DDevice, Index, Enable);
1095 wined3d_mutex_unlock();
1096
1097 return hr;
1098 }
1099
1100 static HRESULT WINAPI IDirect3DDevice9Impl_GetLightEnable(LPDIRECT3DDEVICE9EX iface, DWORD Index, BOOL* pEnable) {
1101 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1102 HRESULT hr;
1103 TRACE("(%p) Relay\n" , This);
1104
1105 wined3d_mutex_lock();
1106 hr = IWineD3DDevice_GetLightEnable(This->WineD3DDevice, Index, pEnable);
1107 wined3d_mutex_unlock();
1108
1109 return hr;
1110 }
1111
1112 static HRESULT WINAPI IDirect3DDevice9Impl_SetClipPlane(LPDIRECT3DDEVICE9EX iface, DWORD Index, CONST float* pPlane) {
1113 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1114 HRESULT hr;
1115 TRACE("(%p) Relay\n" , This);
1116
1117 wined3d_mutex_lock();
1118 hr = IWineD3DDevice_SetClipPlane(This->WineD3DDevice, Index, pPlane);
1119 wined3d_mutex_unlock();
1120
1121 return hr;
1122 }
1123
1124 static HRESULT WINAPI IDirect3DDevice9Impl_GetClipPlane(LPDIRECT3DDEVICE9EX iface, DWORD Index, float* pPlane) {
1125 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1126 HRESULT hr;
1127 TRACE("(%p) Relay\n" , This);
1128
1129 wined3d_mutex_lock();
1130 hr = IWineD3DDevice_GetClipPlane(This->WineD3DDevice, Index, pPlane);
1131 wined3d_mutex_unlock();
1132
1133 return hr;
1134 }
1135
1136 static HRESULT WINAPI IDirect3DDevice9Impl_SetRenderState(LPDIRECT3DDEVICE9EX iface, D3DRENDERSTATETYPE State, DWORD Value) {
1137 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1138 HRESULT hr;
1139 TRACE("(%p) Relay\n" , This);
1140
1141 wined3d_mutex_lock();
1142 hr = IWineD3DDevice_SetRenderState(This->WineD3DDevice, State, Value);
1143 wined3d_mutex_unlock();
1144
1145 return hr;
1146 }
1147
1148 static HRESULT WINAPI IDirect3DDevice9Impl_GetRenderState(LPDIRECT3DDEVICE9EX iface, D3DRENDERSTATETYPE State, DWORD* pValue) {
1149 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1150 HRESULT hr;
1151 TRACE("(%p) Relay\n" , This);
1152
1153 wined3d_mutex_lock();
1154 hr = IWineD3DDevice_GetRenderState(This->WineD3DDevice, State, pValue);
1155 wined3d_mutex_unlock();
1156
1157 return hr;
1158 }
1159
1160 static HRESULT WINAPI IDirect3DDevice9Impl_SetClipStatus(LPDIRECT3DDEVICE9EX iface, CONST D3DCLIPSTATUS9* pClipStatus) {
1161 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1162 HRESULT hr;
1163 TRACE("(%p) Relay\n" , This);
1164
1165 wined3d_mutex_lock();
1166 hr = IWineD3DDevice_SetClipStatus(This->WineD3DDevice, (const WINED3DCLIPSTATUS *)pClipStatus);
1167 wined3d_mutex_unlock();
1168
1169 return hr;
1170 }
1171
1172 static HRESULT WINAPI IDirect3DDevice9Impl_GetClipStatus(LPDIRECT3DDEVICE9EX iface, D3DCLIPSTATUS9* pClipStatus) {
1173 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1174 HRESULT hr;
1175 TRACE("(%p) Relay\n" , This);
1176
1177 wined3d_mutex_lock();
1178 hr = IWineD3DDevice_GetClipStatus(This->WineD3DDevice, (WINED3DCLIPSTATUS *)pClipStatus);
1179 wined3d_mutex_unlock();
1180
1181 return hr;
1182 }
1183
1184 static HRESULT WINAPI IDirect3DDevice9Impl_GetTexture(LPDIRECT3DDEVICE9EX iface, DWORD Stage, IDirect3DBaseTexture9 **ppTexture) {
1185 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1186 IWineD3DBaseTexture *retTexture = NULL;
1187 HRESULT rc = D3D_OK;
1188
1189 TRACE("(%p) Relay\n" , This);
1190
1191 if(ppTexture == NULL){
1192 return D3DERR_INVALIDCALL;
1193 }
1194
1195 wined3d_mutex_lock();
1196 rc = IWineD3DDevice_GetTexture(This->WineD3DDevice, Stage, &retTexture);
1197 if (SUCCEEDED(rc) && NULL != retTexture) {
1198 IWineD3DBaseTexture_GetParent(retTexture, (IUnknown **)ppTexture);
1199 IWineD3DBaseTexture_Release(retTexture);
1200 } else {
1201 if(FAILED(rc)) {
1202 WARN("Call to get texture (%d) failed (%p)\n", Stage, retTexture);
1203 }
1204 *ppTexture = NULL;
1205 }
1206 wined3d_mutex_unlock();
1207
1208 return rc;
1209 }
1210
1211 static HRESULT WINAPI IDirect3DDevice9Impl_SetTexture(LPDIRECT3DDEVICE9EX iface, DWORD Stage, IDirect3DBaseTexture9* pTexture) {
1212 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1213 HRESULT hr;
1214 TRACE("(%p) Relay %d %p\n" , This, Stage, pTexture);
1215
1216 wined3d_mutex_lock();
1217 hr = IWineD3DDevice_SetTexture(This->WineD3DDevice, Stage,
1218 pTexture==NULL ? NULL:((IDirect3DBaseTexture9Impl *)pTexture)->wineD3DBaseTexture);
1219 wined3d_mutex_unlock();
1220
1221 return hr;
1222 }
1223
1224 static const WINED3DTEXTURESTAGESTATETYPE tss_lookup[] =
1225 {
1226 WINED3DTSS_FORCE_DWORD, /* 0, unused */
1227 WINED3DTSS_COLOROP, /* 1, D3DTSS_COLOROP */
1228 WINED3DTSS_COLORARG1, /* 2, D3DTSS_COLORARG1 */
1229 WINED3DTSS_COLORARG2, /* 3, D3DTSS_COLORARG2 */
1230 WINED3DTSS_ALPHAOP, /* 4, D3DTSS_ALPHAOP */
1231 WINED3DTSS_ALPHAARG1, /* 5, D3DTSS_ALPHAARG1 */
1232 WINED3DTSS_ALPHAARG2, /* 6, D3DTSS_ALPHAARG2 */
1233 WINED3DTSS_BUMPENVMAT00, /* 7, D3DTSS_BUMPENVMAT00 */
1234 WINED3DTSS_BUMPENVMAT01, /* 8, D3DTSS_BUMPENVMAT01 */
1235 WINED3DTSS_BUMPENVMAT10, /* 9, D3DTSS_BUMPENVMAT10 */
1236 WINED3DTSS_BUMPENVMAT11, /* 10, D3DTSS_BUMPENVMAT11 */
1237 WINED3DTSS_TEXCOORDINDEX, /* 11, D3DTSS_TEXCOORDINDEX */
1238 WINED3DTSS_FORCE_DWORD, /* 12, unused */
1239 WINED3DTSS_FORCE_DWORD, /* 13, unused */
1240 WINED3DTSS_FORCE_DWORD, /* 14, unused */
1241 WINED3DTSS_FORCE_DWORD, /* 15, unused */
1242 WINED3DTSS_FORCE_DWORD, /* 16, unused */
1243 WINED3DTSS_FORCE_DWORD, /* 17, unused */
1244 WINED3DTSS_FORCE_DWORD, /* 18, unused */
1245 WINED3DTSS_FORCE_DWORD, /* 19, unused */
1246 WINED3DTSS_FORCE_DWORD, /* 20, unused */
1247 WINED3DTSS_FORCE_DWORD, /* 21, unused */
1248 WINED3DTSS_BUMPENVLSCALE, /* 22, D3DTSS_BUMPENVLSCALE */
1249 WINED3DTSS_BUMPENVLOFFSET, /* 23, D3DTSS_BUMPENVLOFFSET */
1250 WINED3DTSS_TEXTURETRANSFORMFLAGS, /* 24, D3DTSS_TEXTURETRANSFORMFLAGS */
1251 WINED3DTSS_FORCE_DWORD, /* 25, unused */
1252 WINED3DTSS_COLORARG0, /* 26, D3DTSS_COLORARG0 */
1253 WINED3DTSS_ALPHAARG0, /* 27, D3DTSS_ALPHAARG0 */
1254 WINED3DTSS_RESULTARG, /* 28, D3DTSS_RESULTARG */
1255 WINED3DTSS_FORCE_DWORD, /* 29, unused */
1256 WINED3DTSS_FORCE_DWORD, /* 30, unused */
1257 WINED3DTSS_FORCE_DWORD, /* 31, unused */
1258 WINED3DTSS_CONSTANT, /* 32, D3DTSS_CONSTANT */
1259 };
1260
1261 static HRESULT WINAPI IDirect3DDevice9Impl_GetTextureStageState(LPDIRECT3DDEVICE9EX iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD* pValue) {
1262 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1263 HRESULT hr;
1264 TRACE("(%p) Relay\n" , This);
1265
1266 wined3d_mutex_lock();
1267 hr = IWineD3DDevice_GetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], pValue);
1268 wined3d_mutex_unlock();
1269
1270 return hr;
1271 }
1272
1273 static HRESULT WINAPI IDirect3DDevice9Impl_SetTextureStageState(LPDIRECT3DDEVICE9EX iface, DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value) {
1274 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1275 HRESULT hr;
1276 TRACE("(%p) Relay\n" , This);
1277
1278 wined3d_mutex_lock();
1279 hr = IWineD3DDevice_SetTextureStageState(This->WineD3DDevice, Stage, tss_lookup[Type], Value);
1280 wined3d_mutex_unlock();
1281
1282 return hr;
1283 }
1284
1285 static HRESULT WINAPI IDirect3DDevice9Impl_GetSamplerState(IDirect3DDevice9Ex *iface, DWORD Sampler,
1286 D3DSAMPLERSTATETYPE Type, DWORD *pValue)
1287 {
1288 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1289 HRESULT hr;
1290 TRACE("(%p) Relay\n" , This);
1291
1292 wined3d_mutex_lock();
1293 hr = IWineD3DDevice_GetSamplerState(This->WineD3DDevice, Sampler, Type, pValue);
1294 wined3d_mutex_unlock();
1295
1296 return hr;
1297 }
1298
1299 static HRESULT WINAPI IDirect3DDevice9Impl_SetSamplerState(LPDIRECT3DDEVICE9EX iface, DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value) {
1300 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1301 HRESULT hr;
1302 TRACE("(%p) Relay\n" , This);
1303
1304 wined3d_mutex_lock();
1305 hr = IWineD3DDevice_SetSamplerState(This->WineD3DDevice, Sampler, Type, Value);
1306 wined3d_mutex_unlock();
1307
1308 return hr;
1309 }
1310
1311 static HRESULT WINAPI IDirect3DDevice9Impl_ValidateDevice(LPDIRECT3DDEVICE9EX iface, DWORD* pNumPasses) {
1312 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1313 HRESULT hr;
1314 TRACE("(%p) Relay\n" , This);
1315
1316 wined3d_mutex_lock();
1317 hr = IWineD3DDevice_ValidateDevice(This->WineD3DDevice, pNumPasses);
1318 wined3d_mutex_unlock();
1319
1320 return hr;
1321 }
1322
1323 static HRESULT WINAPI IDirect3DDevice9Impl_SetPaletteEntries(IDirect3DDevice9Ex *iface, UINT PaletteNumber,
1324 const PALETTEENTRY *pEntries)
1325 {
1326 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1327 HRESULT hr;
1328 TRACE("(%p) Relay\n" , This);
1329
1330 wined3d_mutex_lock();
1331 hr = IWineD3DDevice_SetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
1332 wined3d_mutex_unlock();
1333
1334 return hr;
1335 }
1336
1337 static HRESULT WINAPI IDirect3DDevice9Impl_GetPaletteEntries(LPDIRECT3DDEVICE9EX iface, UINT PaletteNumber, PALETTEENTRY* pEntries) {
1338 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1339 HRESULT hr;
1340 TRACE("(%p) Relay\n" , This);
1341
1342 wined3d_mutex_lock();
1343 hr = IWineD3DDevice_GetPaletteEntries(This->WineD3DDevice, PaletteNumber, pEntries);
1344 wined3d_mutex_unlock();
1345
1346 return hr;
1347 }
1348
1349 static HRESULT WINAPI IDirect3DDevice9Impl_SetCurrentTexturePalette(LPDIRECT3DDEVICE9EX iface, UINT PaletteNumber) {
1350 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1351 HRESULT hr;
1352 TRACE("(%p) Relay\n" , This);
1353
1354 wined3d_mutex_lock();
1355 hr = IWineD3DDevice_SetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
1356 wined3d_mutex_unlock();
1357
1358 return hr;
1359 }
1360
1361 static HRESULT WINAPI IDirect3DDevice9Impl_GetCurrentTexturePalette(LPDIRECT3DDEVICE9EX iface, UINT* PaletteNumber) {
1362 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1363 HRESULT hr;
1364 TRACE("(%p) Relay\n" , This);
1365
1366 wined3d_mutex_lock();
1367 hr = IWineD3DDevice_GetCurrentTexturePalette(This->WineD3DDevice, PaletteNumber);
1368 wined3d_mutex_unlock();
1369
1370 return hr;
1371 }
1372
1373 static HRESULT WINAPI IDirect3DDevice9Impl_SetScissorRect(LPDIRECT3DDEVICE9EX iface, CONST RECT* pRect) {
1374 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1375 HRESULT hr;
1376 TRACE("(%p) Relay\n" , This);
1377
1378 wined3d_mutex_lock();
1379 hr = IWineD3DDevice_SetScissorRect(This->WineD3DDevice, pRect);
1380 wined3d_mutex_unlock();
1381
1382 return hr;
1383 }
1384
1385 static HRESULT WINAPI IDirect3DDevice9Impl_GetScissorRect(LPDIRECT3DDEVICE9EX iface, RECT* pRect) {
1386 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1387 HRESULT hr;
1388 TRACE("(%p) Relay\n" , This);
1389
1390 wined3d_mutex_lock();
1391 hr = IWineD3DDevice_GetScissorRect(This->WineD3DDevice, pRect);
1392 wined3d_mutex_unlock();
1393
1394 return hr;
1395 }
1396
1397 static HRESULT WINAPI IDirect3DDevice9Impl_SetSoftwareVertexProcessing(LPDIRECT3DDEVICE9EX iface, BOOL bSoftware) {
1398 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1399 HRESULT hr;
1400 TRACE("(%p) Relay\n" , This);
1401
1402 wined3d_mutex_lock();
1403 hr = IWineD3DDevice_SetSoftwareVertexProcessing(This->WineD3DDevice, bSoftware);
1404 wined3d_mutex_unlock();
1405
1406 return hr;
1407 }
1408
1409 static BOOL WINAPI IDirect3DDevice9Impl_GetSoftwareVertexProcessing(LPDIRECT3DDEVICE9EX iface) {
1410 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1411 BOOL ret;
1412 TRACE("(%p) Relay\n" , This);
1413
1414 wined3d_mutex_lock();
1415 ret = IWineD3DDevice_GetSoftwareVertexProcessing(This->WineD3DDevice);
1416 wined3d_mutex_unlock();
1417
1418 return ret;
1419 }
1420
1421 static HRESULT WINAPI IDirect3DDevice9Impl_SetNPatchMode(LPDIRECT3DDEVICE9EX iface, float nSegments) {
1422 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1423 HRESULT hr;
1424 TRACE("(%p) Relay\n" , This);
1425
1426 wined3d_mutex_lock();
1427 hr = IWineD3DDevice_SetNPatchMode(This->WineD3DDevice, nSegments);
1428 wined3d_mutex_unlock();
1429
1430 return hr;
1431 }
1432
1433 static float WINAPI IDirect3DDevice9Impl_GetNPatchMode(LPDIRECT3DDEVICE9EX iface) {
1434 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1435 float ret;
1436 TRACE("(%p) Relay\n" , This);
1437
1438 wined3d_mutex_lock();
1439 ret = IWineD3DDevice_GetNPatchMode(This->WineD3DDevice);
1440 wined3d_mutex_unlock();
1441
1442 return ret;
1443 }
1444
1445 static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitive(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE PrimitiveType,
1446 UINT StartVertex, UINT PrimitiveCount)
1447 {
1448 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1449 HRESULT hr;
1450 TRACE("(%p) Relay\n" , This);
1451
1452 wined3d_mutex_lock();
1453 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1454 hr = IWineD3DDevice_DrawPrimitive(This->WineD3DDevice, StartVertex,
1455 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount));
1456 wined3d_mutex_unlock();
1457
1458 return hr;
1459 }
1460
1461 static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitive(LPDIRECT3DDEVICE9EX iface, D3DPRIMITIVETYPE PrimitiveType,
1462 INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) {
1463 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1464 HRESULT hr;
1465 TRACE("(%p) Relay\n" , This);
1466
1467 /* D3D8 passes the baseVertexIndex in SetIndices, and due to the stateblock functions wined3d has to work that way */
1468 wined3d_mutex_lock();
1469 IWineD3DDevice_SetBaseVertexIndex(This->WineD3DDevice, BaseVertexIndex);
1470 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1471 hr = IWineD3DDevice_DrawIndexedPrimitive(This->WineD3DDevice, MinVertexIndex, NumVertices,
1472 startIndex, vertex_count_from_primitive_count(PrimitiveType, primCount));
1473 wined3d_mutex_unlock();
1474
1475 return hr;
1476 }
1477
1478 static HRESULT WINAPI IDirect3DDevice9Impl_DrawPrimitiveUP(IDirect3DDevice9Ex *iface, D3DPRIMITIVETYPE PrimitiveType,
1479 UINT PrimitiveCount, const void *pVertexStreamZeroData, UINT VertexStreamZeroStride)
1480 {
1481 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1482 HRESULT hr;
1483 TRACE("(%p) Relay\n" , This);
1484
1485 wined3d_mutex_lock();
1486 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1487 hr = IWineD3DDevice_DrawPrimitiveUP(This->WineD3DDevice,
1488 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount),
1489 pVertexStreamZeroData, VertexStreamZeroStride);
1490 wined3d_mutex_unlock();
1491
1492 return hr;
1493 }
1494
1495 static HRESULT WINAPI IDirect3DDevice9Impl_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE9EX iface, D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex,
1496 UINT NumVertexIndices, UINT PrimitiveCount, CONST void* pIndexData,
1497 D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride) {
1498 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1499 HRESULT hr;
1500 TRACE("(%p) Relay\n" , This);
1501
1502 wined3d_mutex_lock();
1503 IWineD3DDevice_SetPrimitiveType(This->WineD3DDevice, PrimitiveType);
1504 hr = IWineD3DDevice_DrawIndexedPrimitiveUP(This->WineD3DDevice, MinVertexIndex, NumVertexIndices,
1505 vertex_count_from_primitive_count(PrimitiveType, PrimitiveCount), pIndexData,
1506 wined3dformat_from_d3dformat(IndexDataFormat), pVertexStreamZeroData, VertexStreamZeroStride);
1507 wined3d_mutex_unlock();
1508
1509 return hr;
1510 }
1511
1512 static HRESULT WINAPI IDirect3DDevice9Impl_ProcessVertices(LPDIRECT3DDEVICE9EX iface, UINT SrcStartIndex, UINT DestIndex, UINT VertexCount, IDirect3DVertexBuffer9* pDestBuffer, IDirect3DVertexDeclaration9* pVertexDecl, DWORD Flags) {
1513 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1514 IDirect3DVertexDeclaration9Impl *Decl = (IDirect3DVertexDeclaration9Impl *) pVertexDecl;
1515 HRESULT hr;
1516 IDirect3DVertexBuffer9Impl *dest = (IDirect3DVertexBuffer9Impl *) pDestBuffer;
1517 TRACE("(%p) Relay\n" , This);
1518
1519 wined3d_mutex_lock();
1520 hr = IWineD3DDevice_ProcessVertices(This->WineD3DDevice,SrcStartIndex, DestIndex, VertexCount, dest->wineD3DVertexBuffer, Decl ? Decl->wineD3DVertexDeclaration : NULL, Flags, dest->fvf);
1521 wined3d_mutex_unlock();
1522
1523 return hr;
1524 }
1525
1526 static IDirect3DVertexDeclaration9 *getConvertedDecl(IDirect3DDevice9Impl *This, DWORD fvf) {
1527 HRESULT hr;
1528 D3DVERTEXELEMENT9* elements = NULL;
1529 IDirect3DVertexDeclaration9* pDecl = NULL;
1530 int p, low, high; /* deliberately signed */
1531 IDirect3DVertexDeclaration9 **convertedDecls = This->convertedDecls;
1532
1533 TRACE("Searching for declaration for fvf %08x... ", fvf);
1534
1535 low = 0;
1536 high = This->numConvertedDecls - 1;
1537 while(low <= high) {
1538 p = (low + high) >> 1;
1539 TRACE("%d ", p);
1540 if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF == fvf) {
1541 TRACE("found %p\n", convertedDecls[p]);
1542 return convertedDecls[p];
1543 } else if(((IDirect3DVertexDeclaration9Impl *) convertedDecls[p])->convFVF < fvf) {
1544 low = p + 1;
1545 } else {
1546 high = p - 1;
1547 }
1548 }
1549 TRACE("not found. Creating and inserting at position %d.\n", low);
1550
1551 hr = vdecl_convert_fvf(fvf, &elements);
1552 if (hr != S_OK) return NULL;
1553
1554 hr = IDirect3DDevice9Impl_CreateVertexDeclaration((IDirect3DDevice9Ex *) This, elements, &pDecl);
1555 HeapFree(GetProcessHeap(), 0, elements); /* CreateVertexDeclaration makes a copy */
1556 if (hr != S_OK) return NULL;
1557
1558 if(This->declArraySize == This->numConvertedDecls) {
1559 int grow = max(This->declArraySize / 2, 8);
1560 convertedDecls = HeapReAlloc(GetProcessHeap(), 0, convertedDecls,
1561 sizeof(convertedDecls[0]) * (This->numConvertedDecls + grow));
1562 if(!convertedDecls) {
1563 /* This will destroy it */
1564 IDirect3DVertexDeclaration9_Release(pDecl);
1565 return NULL;
1566 }
1567 This->convertedDecls = convertedDecls;
1568 This->declArraySize += grow;
1569 }
1570
1571 memmove(convertedDecls + low + 1, convertedDecls + low, sizeof(IDirect3DVertexDeclaration9Impl *) * (This->numConvertedDecls - low));
1572 convertedDecls[low] = pDecl;
1573 This->numConvertedDecls++;
1574
1575 /* Will prevent the decl from being destroyed */
1576 ((IDirect3DVertexDeclaration9Impl *) pDecl)->convFVF = fvf;
1577 IDirect3DVertexDeclaration9_Release(pDecl); /* Does not destroy now */
1578
1579 TRACE("Returning %p. %d decls in array\n", pDecl, This->numConvertedDecls);
1580 return pDecl;
1581 }
1582
1583 static HRESULT WINAPI IDirect3DDevice9Impl_SetFVF(LPDIRECT3DDEVICE9EX iface, DWORD FVF) {
1584 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1585 IDirect3DVertexDeclaration9 *decl;
1586 HRESULT hr;
1587
1588 TRACE("(%p) Relay\n" , This);
1589
1590 if (!FVF)
1591 {
1592 WARN("%#x is not a valid FVF\n", FVF);
1593 return D3D_OK;
1594 }
1595
1596 wined3d_mutex_lock();
1597 decl = getConvertedDecl(This, FVF);
1598 wined3d_mutex_unlock();
1599
1600 if (!decl)
1601 {
1602 /* Any situation when this should happen, except out of memory? */
1603 ERR("Failed to create a converted vertex declaration\n");
1604 return D3DERR_DRIVERINTERNALERROR;
1605 }
1606
1607 hr = IDirect3DDevice9Impl_SetVertexDeclaration(iface, decl);
1608 if (FAILED(hr)) ERR("Failed to set vertex declaration\n");
1609
1610 return hr;
1611 }
1612
1613 static HRESULT WINAPI IDirect3DDevice9Impl_GetFVF(LPDIRECT3DDEVICE9EX iface, DWORD* pFVF) {
1614 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1615 IDirect3DVertexDeclaration9 *decl;
1616 HRESULT hr;
1617 TRACE("(%p) Relay\n" , This);
1618
1619 hr = IDirect3DDevice9_GetVertexDeclaration(iface, &decl);
1620 if (FAILED(hr))
1621 {
1622 WARN("Failed to get vertex declaration, %#x\n", hr);
1623 *pFVF = 0;
1624 return hr;
1625 }
1626
1627 if (decl)
1628 {
1629 *pFVF = ((IDirect3DVertexDeclaration9Impl *)decl)->convFVF;
1630 IDirect3DVertexDeclaration9_Release(decl);
1631 }
1632 else
1633 {
1634 *pFVF = 0;
1635 }
1636
1637 TRACE("Returning FVF %#x\n", *pFVF);
1638
1639 return hr;
1640 }
1641
1642 static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSource(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT Stride) {
1643 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1644 HRESULT hr;
1645 TRACE("(%p) Relay\n" , This);
1646
1647 wined3d_mutex_lock();
1648 hr = IWineD3DDevice_SetStreamSource(This->WineD3DDevice, StreamNumber,
1649 pStreamData ? ((IDirect3DVertexBuffer9Impl *)pStreamData)->wineD3DVertexBuffer : NULL,
1650 OffsetInBytes, Stride);
1651 wined3d_mutex_unlock();
1652
1653 return hr;
1654 }
1655
1656 static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSource(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, IDirect3DVertexBuffer9 **pStream, UINT* OffsetInBytes, UINT* pStride) {
1657 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1658 IWineD3DBuffer *retStream = NULL;
1659 HRESULT rc = D3D_OK;
1660
1661 TRACE("(%p) Relay\n" , This);
1662
1663 if(pStream == NULL){
1664 return D3DERR_INVALIDCALL;
1665 }
1666
1667 wined3d_mutex_lock();
1668 rc = IWineD3DDevice_GetStreamSource(This->WineD3DDevice, StreamNumber, &retStream, OffsetInBytes, pStride);
1669 if (rc == D3D_OK && NULL != retStream) {
1670 IWineD3DBuffer_GetParent(retStream, (IUnknown **)pStream);
1671 IWineD3DBuffer_Release(retStream);
1672 }else{
1673 if (rc != D3D_OK){
1674 FIXME("Call to GetStreamSource failed %p %p\n", OffsetInBytes, pStride);
1675 }
1676 *pStream = NULL;
1677 }
1678 wined3d_mutex_unlock();
1679
1680 return rc;
1681 }
1682
1683 static HRESULT WINAPI IDirect3DDevice9Impl_SetStreamSourceFreq(IDirect3DDevice9Ex *iface, UINT StreamNumber,
1684 UINT Divider)
1685 {
1686 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1687 HRESULT hr;
1688 TRACE("(%p) Relay\n" , This);
1689
1690 wined3d_mutex_lock();
1691 hr = IWineD3DDevice_SetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
1692 wined3d_mutex_unlock();
1693
1694 return hr;
1695 }
1696
1697 static HRESULT WINAPI IDirect3DDevice9Impl_GetStreamSourceFreq(LPDIRECT3DDEVICE9EX iface, UINT StreamNumber, UINT* Divider) {
1698 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1699 HRESULT hr;
1700 TRACE("(%p) Relay\n" , This);
1701
1702 wined3d_mutex_lock();
1703 hr = IWineD3DDevice_GetStreamSourceFreq(This->WineD3DDevice, StreamNumber, Divider);
1704 wined3d_mutex_unlock();
1705
1706 return hr;
1707 }
1708
1709 static HRESULT WINAPI IDirect3DDevice9Impl_SetIndices(LPDIRECT3DDEVICE9EX iface, IDirect3DIndexBuffer9* pIndexData) {
1710 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1711 HRESULT hr;
1712 IDirect3DIndexBuffer9Impl *ib = (IDirect3DIndexBuffer9Impl *) pIndexData;
1713 TRACE("(%p) Relay\n", This);
1714
1715 wined3d_mutex_lock();
1716 hr = IWineD3DDevice_SetIndices(This->WineD3DDevice,
1717 ib ? ib->wineD3DIndexBuffer : NULL,
1718 ib ? ib->format : WINED3DFMT_UNKNOWN);
1719 wined3d_mutex_unlock();
1720
1721 return hr;
1722 }
1723
1724 static HRESULT WINAPI IDirect3DDevice9Impl_GetIndices(LPDIRECT3DDEVICE9EX iface, IDirect3DIndexBuffer9 **ppIndexData) {
1725 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1726 IWineD3DBuffer *retIndexData = NULL;
1727 HRESULT rc = D3D_OK;
1728
1729 TRACE("(%p) Relay\n", This);
1730
1731 if(ppIndexData == NULL){
1732 return D3DERR_INVALIDCALL;
1733 }
1734
1735 wined3d_mutex_lock();
1736 rc = IWineD3DDevice_GetIndices(This->WineD3DDevice, &retIndexData);
1737 if (SUCCEEDED(rc) && retIndexData) {
1738 IWineD3DBuffer_GetParent(retIndexData, (IUnknown **)ppIndexData);
1739 IWineD3DBuffer_Release(retIndexData);
1740 } else {
1741 if (FAILED(rc)) FIXME("Call to GetIndices failed\n");
1742 *ppIndexData = NULL;
1743 }
1744 wined3d_mutex_unlock();
1745
1746 return rc;
1747 }
1748
1749 static HRESULT WINAPI IDirect3DDevice9Impl_DrawRectPatch(LPDIRECT3DDEVICE9EX iface, UINT Handle, CONST float* pNumSegs, CONST D3DRECTPATCH_INFO* pRectPatchInfo) {
1750 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1751 HRESULT hr;
1752 TRACE("(%p) Relay\n", This);
1753
1754 wined3d_mutex_lock();
1755 hr = IWineD3DDevice_DrawRectPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DRECTPATCH_INFO *)pRectPatchInfo);
1756 wined3d_mutex_unlock();
1757
1758 return hr;
1759 }
1760
1761 static HRESULT WINAPI IDirect3DDevice9Impl_DrawTriPatch(LPDIRECT3DDEVICE9EX iface, UINT Handle, CONST float* pNumSegs, CONST D3DTRIPATCH_INFO* pTriPatchInfo) {
1762 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1763 HRESULT hr;
1764 TRACE("(%p) Relay\n", This);
1765
1766 wined3d_mutex_lock();
1767 hr = IWineD3DDevice_DrawTriPatch(This->WineD3DDevice, Handle, pNumSegs, (CONST WINED3DTRIPATCH_INFO *)pTriPatchInfo);
1768 wined3d_mutex_unlock();
1769
1770 return hr;
1771 }
1772
1773 static HRESULT WINAPI IDirect3DDevice9Impl_DeletePatch(LPDIRECT3DDEVICE9EX iface, UINT Handle) {
1774 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *)iface;
1775 HRESULT hr;
1776 TRACE("(%p) Relay\n", This);
1777
1778 wined3d_mutex_lock();
1779 hr = IWineD3DDevice_DeletePatch(This->WineD3DDevice, Handle);
1780 wined3d_mutex_unlock();
1781
1782 return hr;
1783 }
1784
1785 static HRESULT WINAPI IDirect3DDevice9ExImpl_SetConvolutionMonoKernel(LPDIRECT3DDEVICE9EX iface, UINT width, UINT height, float *rows, float *columns) {
1786 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1787 FIXME("(%p)->(%d, %d, %p, %p) Stub!\n", This, width, height, rows, columns);
1788 return WINED3DERR_INVALIDCALL;
1789 }
1790
1791 static HRESULT WINAPI IDirect3DDevice9ExImpl_ComposeRects(LPDIRECT3DDEVICE9EX iface, IDirect3DSurface9 *pSrc, IDirect3DDevice9 *pDst, IDirect3DVertexBuffer9 *pSrcRectDescs, UINT NumRects, IDirect3DVertexBuffer9 *pDstRectDescs, D3DCOMPOSERECTSOP Operation, int Xoffset, int Yoffset) {
1792 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1793 FIXME("(%p)->(%p, %p, %p, %d, %p, %d, %d, %d) Stub!\n", This, pSrc, pDst, pSrcRectDescs, NumRects, pDstRectDescs, Operation, Xoffset, Yoffset);
1794 return WINED3DERR_INVALIDCALL;
1795 }
1796
1797 static HRESULT WINAPI IDirect3DDevice9ExImpl_PresentEx(LPDIRECT3DDEVICE9EX iface, CONST RECT *pSourceRect, CONST RECT *pDestRect, HWND hDestWindowOverride, CONST RGNDATA *pDirtyRegion, DWORD dwFlags) {
1798 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1799 FIXME("(%p= -> (%p), %p, %p, %p, 0x%08x) Stub!\n", This, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags);
1800 return WINED3DERR_INVALIDCALL;
1801 }
1802
1803 static HRESULT WINAPI IDirect3DDevice9ExImpl_GetGPUThreadPriority(LPDIRECT3DDEVICE9EX iface, INT *pPriority) {
1804 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1805 FIXME("(%p)->(%p) Stub!\n", This, pPriority);
1806 return WINED3DERR_INVALIDCALL;
1807 }
1808
1809 static HRESULT WINAPI IDirect3DDevice9ExImpl_SetGPUThreadPriority(LPDIRECT3DDEVICE9EX iface, INT Priority) {
1810 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1811 FIXME("(%p)->(%d) Stub!\n", This, Priority);
1812 return WINED3DERR_INVALIDCALL;
1813 }
1814
1815 static HRESULT WINAPI IDirect3DDevice9ExImpl_WaitForVBlank(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain) {
1816 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1817 FIXME("(%p)->(%d) Stub!\n", This, iSwapChain);
1818 return WINED3DERR_INVALIDCALL;
1819 }
1820
1821 static HRESULT WINAPI IDirect3DDevice9ExImpl_CheckresourceResidency(LPDIRECT3DDEVICE9EX iface, IDirect3DResource9 ** pResourceArray, UINT32 Numresources) {
1822 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1823 FIXME("(%p)->(%p, %d) Stub!\n", This, pResourceArray, Numresources);
1824 return WINED3DERR_INVALIDCALL;
1825 }
1826
1827 static HRESULT WINAPI IDirect3DDevice9ExImpl_SetMaximumFrameLatency(LPDIRECT3DDEVICE9EX iface, UINT MaxLatency) {
1828 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1829 FIXME("(%p)->(%d) Stub!\n", This, MaxLatency);
1830 return WINED3DERR_INVALIDCALL;
1831 }
1832
1833 static HRESULT WINAPI IDirect3DDevice9ExImpl_GetMaximumFrameLatency(LPDIRECT3DDEVICE9EX iface, UINT *pMaxLatency) {
1834 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1835 FIXME("(%p)->(%p) Stub!\n", This, pMaxLatency);
1836 *pMaxLatency = 2;
1837 return WINED3DERR_INVALIDCALL;
1838 }
1839
1840 static HRESULT WINAPI IDirect3DDevice9ExImpl_CheckdeviceState(LPDIRECT3DDEVICE9EX iface, HWND hDestinationWindow) {
1841 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1842 FIXME("(%p)->(%p) Stub!\n", This, hDestinationWindow);
1843 return WINED3DERR_INVALIDCALL;
1844 }
1845
1846 static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateRenderTargetEx(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultiSampleQuality, BOOL Lockable, IDirect3DSurface9 ** ppSurface, HANDLE *pSharedHandle, DWORD Usage) {
1847 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1848 FIXME("(%p)->(%d, %d, %d, %d, %d, %s, %p, %p, 0x%08x) Stub!\n", This, Width, Height, Format, MultiSample, MultiSampleQuality, Lockable ? "true" : "false", ppSurface, pSharedHandle, Usage);
1849 return WINED3DERR_INVALIDCALL;
1850 }
1851
1852 static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateOffscreenPlainSurfaceEx(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle, DWORD Usage) {
1853 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1854 FIXME("(%p)->(%d, %d, %d, %d, %p, %p, 0x%08x) Stub!\n", This, Width, Height, Format, Pool, ppSurface, pSharedHandle, Usage);
1855 return WINED3DERR_INVALIDCALL;
1856 }
1857
1858 static HRESULT WINAPI IDirect3DDevice9ExImpl_CreateDepthStencilSurfaceEx(LPDIRECT3DDEVICE9EX iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultiSampleQuality, BOOL Discard, IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle, DWORD Usage) {
1859 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1860 FIXME("(%p)->(%d, %d, %d, %d, %d, %s, %p, %p, 0x%08x) Stub!\n", This, Width, Height, Format, MultiSample, MultiSampleQuality, Discard ? "true" : "false", ppSurface, pSharedHandle, Usage);
1861 return WINED3DERR_INVALIDCALL;
1862 }
1863
1864 static HRESULT WINAPI IDirect3DDevice9ExImpl_ResetEx(LPDIRECT3DDEVICE9EX iface, D3DPRESENT_PARAMETERS *pPresentationParameters, D3DDISPLAYMODEEX *pFullscreenDisplayMode) {
1865 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1866 FIXME("(%p)->(%p) Stub!\n", This, pPresentationParameters);
1867 return WINED3DERR_INVALIDCALL;
1868 }
1869
1870 static HRESULT WINAPI IDirect3DDevice9ExImpl_GetDisplayModeEx(LPDIRECT3DDEVICE9EX iface, UINT iSwapChain, D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation) {
1871 IDirect3DDevice9Impl *This = (IDirect3DDevice9Impl *) iface;
1872 FIXME("(%p)->(%d, %p, %p) Stub!\n", This, iSwapChain, pMode, pRotation);
1873 return WINED3DERR_INVALIDCALL;
1874 }
1875
1876 const IDirect3DDevice9ExVtbl Direct3DDevice9_Vtbl =
1877 {
1878 /* IUnknown */
1879 IDirect3DDevice9Impl_QueryInterface,
1880 IDirect3DDevice9Impl_AddRef,
1881 IDirect3DDevice9Impl_Release,
1882 /* IDirect3DDevice9 */
1883 IDirect3DDevice9Impl_TestCooperativeLevel,
1884 IDirect3DDevice9Impl_GetAvailableTextureMem,
1885 IDirect3DDevice9Impl_EvictManagedResources,
1886 IDirect3DDevice9Impl_GetDirect3D,
1887 IDirect3DDevice9Impl_GetDeviceCaps,
1888 IDirect3DDevice9Impl_GetDisplayMode,
1889 IDirect3DDevice9Impl_GetCreationParameters,
1890 IDirect3DDevice9Impl_SetCursorProperties,
1891 IDirect3DDevice9Impl_SetCursorPosition,
1892 IDirect3DDevice9Impl_ShowCursor,
1893 IDirect3DDevice9Impl_CreateAdditionalSwapChain,
1894 IDirect3DDevice9Impl_GetSwapChain,
1895 IDirect3DDevice9Impl_GetNumberOfSwapChains,
1896 IDirect3DDevice9Impl_Reset,
1897 IDirect3DDevice9Impl_Present,
1898 IDirect3DDevice9Impl_GetBackBuffer,
1899 IDirect3DDevice9Impl_GetRasterStatus,
1900 IDirect3DDevice9Impl_SetDialogBoxMode,
1901 IDirect3DDevice9Impl_SetGammaRamp,
1902 IDirect3DDevice9Impl_GetGammaRamp,
1903 IDirect3DDevice9Impl_CreateTexture,
1904 IDirect3DDevice9Impl_CreateVolumeTexture,
1905 IDirect3DDevice9Impl_CreateCubeTexture,
1906 IDirect3DDevice9Impl_CreateVertexBuffer,
1907 IDirect3DDevice9Impl_CreateIndexBuffer,
1908 IDirect3DDevice9Impl_CreateRenderTarget,
1909 IDirect3DDevice9Impl_CreateDepthStencilSurface,
1910 IDirect3DDevice9Impl_UpdateSurface,
1911 IDirect3DDevice9Impl_UpdateTexture,
1912 IDirect3DDevice9Impl_GetRenderTargetData,
1913 IDirect3DDevice9Impl_GetFrontBufferData,
1914 IDirect3DDevice9Impl_StretchRect,
1915 IDirect3DDevice9Impl_ColorFill,
1916 IDirect3DDevice9Impl_CreateOffscreenPlainSurface,
1917 IDirect3DDevice9Impl_SetRenderTarget,
1918 IDirect3DDevice9Impl_GetRenderTarget,
1919 IDirect3DDevice9Impl_SetDepthStencilSurface,
1920 IDirect3DDevice9Impl_GetDepthStencilSurface,
1921 IDirect3DDevice9Impl_BeginScene,
1922 IDirect3DDevice9Impl_EndScene,
1923 IDirect3DDevice9Impl_Clear,
1924 IDirect3DDevice9Impl_SetTransform,
1925 IDirect3DDevice9Impl_GetTransform,
1926 IDirect3DDevice9Impl_MultiplyTransform,
1927 IDirect3DDevice9Impl_SetViewport,
1928 IDirect3DDevice9Impl_GetViewport,
1929 IDirect3DDevice9Impl_SetMaterial,
1930 IDirect3DDevice9Impl_GetMaterial,
1931 IDirect3DDevice9Impl_SetLight,
1932 IDirect3DDevice9Impl_GetLight,
1933 IDirect3DDevice9Impl_LightEnable,
1934 IDirect3DDevice9Impl_GetLightEnable,
1935 IDirect3DDevice9Impl_SetClipPlane,
1936 IDirect3DDevice9Impl_GetClipPlane,
1937 IDirect3DDevice9Impl_SetRenderState,
1938 IDirect3DDevice9Impl_GetRenderState,
1939 IDirect3DDevice9Impl_CreateStateBlock,
1940 IDirect3DDevice9Impl_BeginStateBlock,
1941 IDirect3DDevice9Impl_EndStateBlock,
1942 IDirect3DDevice9Impl_SetClipStatus,
1943 IDirect3DDevice9Impl_GetClipStatus,
1944 IDirect3DDevice9Impl_GetTexture,
1945 IDirect3DDevice9Impl_SetTexture,
1946 IDirect3DDevice9Impl_GetTextureStageState,
1947 IDirect3DDevice9Impl_SetTextureStageState,
1948 IDirect3DDevice9Impl_GetSamplerState,
1949 IDirect3DDevice9Impl_SetSamplerState,
1950 IDirect3DDevice9Impl_ValidateDevice,
1951 IDirect3DDevice9Impl_SetPaletteEntries,
1952 IDirect3DDevice9Impl_GetPaletteEntries,
1953 IDirect3DDevice9Impl_SetCurrentTexturePalette,
1954 IDirect3DDevice9Impl_GetCurrentTexturePalette,
1955 IDirect3DDevice9Impl_SetScissorRect,
1956 IDirect3DDevice9Impl_GetScissorRect,
1957 IDirect3DDevice9Impl_SetSoftwareVertexProcessing,
1958 IDirect3DDevice9Impl_GetSoftwareVertexProcessing,
1959 IDirect3DDevice9Impl_SetNPatchMode,
1960 IDirect3DDevice9Impl_GetNPatchMode,
1961 IDirect3DDevice9Impl_DrawPrimitive,
1962 IDirect3DDevice9Impl_DrawIndexedPrimitive,
1963 IDirect3DDevice9Impl_DrawPrimitiveUP,
1964 IDirect3DDevice9Impl_DrawIndexedPrimitiveUP,
1965 IDirect3DDevice9Impl_ProcessVertices,
1966 IDirect3DDevice9Impl_CreateVertexDeclaration,
1967 IDirect3DDevice9Impl_SetVertexDeclaration,
1968 IDirect3DDevice9Impl_GetVertexDeclaration,
1969 IDirect3DDevice9Impl_SetFVF,
1970 IDirect3DDevice9Impl_GetFVF,
1971 IDirect3DDevice9Impl_CreateVertexShader,
1972 IDirect3DDevice9Impl_SetVertexShader,
1973 IDirect3DDevice9Impl_GetVertexShader,
1974 IDirect3DDevice9Impl_SetVertexShaderConstantF,
1975 IDirect3DDevice9Impl_GetVertexShaderConstantF,
1976 IDirect3DDevice9Impl_SetVertexShaderConstantI,
1977 IDirect3DDevice9Impl_GetVertexShaderConstantI,
1978 IDirect3DDevice9Impl_SetVertexShaderConstantB,
1979 IDirect3DDevice9Impl_GetVertexShaderConstantB,
1980 IDirect3DDevice9Impl_SetStreamSource,
1981 IDirect3DDevice9Impl_GetStreamSource,
1982 IDirect3DDevice9Impl_SetStreamSourceFreq,
1983 IDirect3DDevice9Impl_GetStreamSourceFreq,
1984 IDirect3DDevice9Impl_SetIndices,
1985 IDirect3DDevice9Impl_GetIndices,
1986 IDirect3DDevice9Impl_CreatePixelShader,
1987 IDirect3DDevice9Impl_SetPixelShader,
1988 IDirect3DDevice9Impl_GetPixelShader,
1989 IDirect3DDevice9Impl_SetPixelShaderConstantF,
1990 IDirect3DDevice9Impl_GetPixelShaderConstantF,
1991 IDirect3DDevice9Impl_SetPixelShaderConstantI,
1992 IDirect3DDevice9Impl_GetPixelShaderConstantI,
1993 IDirect3DDevice9Impl_SetPixelShaderConstantB,
1994 IDirect3DDevice9Impl_GetPixelShaderConstantB,
1995 IDirect3DDevice9Impl_DrawRectPatch,
1996 IDirect3DDevice9Impl_DrawTriPatch,
1997 IDirect3DDevice9Impl_DeletePatch,
1998 IDirect3DDevice9Impl_CreateQuery,
1999 /* IDirect3DDevice9Ex */
2000 IDirect3DDevice9ExImpl_SetConvolutionMonoKernel,
2001 IDirect3DDevice9ExImpl_ComposeRects,
2002 IDirect3DDevice9ExImpl_PresentEx,
2003 IDirect3DDevice9ExImpl_GetGPUThreadPriority,
2004 IDirect3DDevice9ExImpl_SetGPUThreadPriority,
2005 IDirect3DDevice9ExImpl_WaitForVBlank,
2006 IDirect3DDevice9ExImpl_CheckresourceResidency,
2007 IDirect3DDevice9ExImpl_SetMaximumFrameLatency,
2008 IDirect3DDevice9ExImpl_GetMaximumFrameLatency,
2009 IDirect3DDevice9ExImpl_CheckdeviceState,
2010 IDirect3DDevice9ExImpl_CreateRenderTargetEx,
2011 IDirect3DDevice9ExImpl_CreateOffscreenPlainSurfaceEx,
2012 IDirect3DDevice9ExImpl_CreateDepthStencilSurfaceEx,
2013 IDirect3DDevice9ExImpl_ResetEx,
2014 IDirect3DDevice9ExImpl_GetDisplayModeEx
2015 };
2016
2017 ULONG WINAPI D3D9CB_DestroySurface(IWineD3DSurface *pSurface) {
2018 IDirect3DSurface9Impl* surfaceParent;
2019 TRACE("(%p) call back\n", pSurface);
2020
2021 IWineD3DSurface_GetParent(pSurface, (IUnknown **) &surfaceParent);
2022 /* GetParent's AddRef was forwarded to an object in destruction.
2023 * Releasing it here again would cause an endless recursion. */
2024 surfaceParent->forwardReference = NULL;
2025 return IDirect3DSurface9_Release((IDirect3DSurface9*) surfaceParent);
2026 }
2027
2028 /* IWineD3DDeviceParent IUnknown methods */
2029
2030 static inline struct IDirect3DDevice9Impl *device_from_device_parent(IWineD3DDeviceParent *iface)
2031 {
2032 return (struct IDirect3DDevice9Impl *)((char*)iface
2033 - FIELD_OFFSET(struct IDirect3DDevice9Impl, device_parent_vtbl));
2034 }
2035
2036 static HRESULT STDMETHODCALLTYPE device_parent_QueryInterface(IWineD3DDeviceParent *iface, REFIID riid, void **object)
2037 {
2038 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2039 return IDirect3DDevice9Impl_QueryInterface((IDirect3DDevice9Ex *)This, riid, object);
2040 }
2041
2042 static ULONG STDMETHODCALLTYPE device_parent_AddRef(IWineD3DDeviceParent *iface)
2043 {
2044 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2045 return IDirect3DDevice9Impl_AddRef((IDirect3DDevice9Ex *)This);
2046 }
2047
2048 static ULONG STDMETHODCALLTYPE device_parent_Release(IWineD3DDeviceParent *iface)
2049 {
2050 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2051 return IDirect3DDevice9Impl_Release((IDirect3DDevice9Ex *)This);
2052 }
2053
2054 /* IWineD3DDeviceParent methods */
2055
2056 static void STDMETHODCALLTYPE device_parent_WineD3DDeviceCreated(IWineD3DDeviceParent *iface, IWineD3DDevice *device)
2057 {
2058 TRACE("iface %p, device %p\n", iface, device);
2059 }
2060
2061 static HRESULT STDMETHODCALLTYPE device_parent_CreateSurface(IWineD3DDeviceParent *iface,
2062 IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, DWORD usage,
2063 WINED3DPOOL pool, UINT level, WINED3DCUBEMAP_FACES face, IWineD3DSurface **surface)
2064 {
2065 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2066 IDirect3DSurface9Impl *d3d_surface;
2067 BOOL lockable = TRUE;
2068 HRESULT hr;
2069
2070 TRACE("iface %p, superior %p, width %u, height %u, format %#x, usage %#x,\n"
2071 "\tpool %#x, level %u, face %u, surface %p\n",
2072 iface, superior, width, height, format, usage, pool, level, face, surface);
2073
2074 if (pool == WINED3DPOOL_DEFAULT && !(usage & D3DUSAGE_DYNAMIC))
2075 lockable = FALSE;
2076
2077 hr = IDirect3DDevice9Impl_CreateSurface((IDirect3DDevice9Ex *)This, width, height,
2078 d3dformat_from_wined3dformat(format), lockable, FALSE /* Discard */, level,
2079 (IDirect3DSurface9 **)&d3d_surface, usage, pool, D3DMULTISAMPLE_NONE, 0 /* MultisampleQuality */);
2080 if (FAILED(hr))
2081 {
2082 ERR("(%p) CreateSurface failed, returning %#x\n", iface, hr);
2083 return hr;
2084 }
2085
2086 *surface = d3d_surface->wineD3DSurface;
2087 d3d_surface->container = superior;
2088 IDirect3DDevice9Ex_Release(d3d_surface->parentDevice);
2089 d3d_surface->parentDevice = NULL;
2090 d3d_surface->forwardReference = superior;
2091
2092 return hr;
2093 }
2094
2095 static HRESULT STDMETHODCALLTYPE device_parent_CreateRenderTarget(IWineD3DDeviceParent *iface,
2096 IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, WINED3DMULTISAMPLE_TYPE multisample_type,
2097 DWORD multisample_quality, BOOL lockable, IWineD3DSurface **surface)
2098 {
2099 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2100 IDirect3DSurface9Impl *d3d_surface;
2101 HRESULT hr;
2102
2103 TRACE("iface %p, superior %p, width %u, height %u, format %#x, multisample_type %#x,\n"
2104 "\tmultisample_quality %u, lockable %u, surface %p\n",
2105 iface, superior, width, height, format, multisample_type, multisample_quality, lockable, surface);
2106
2107 hr = IDirect3DDevice9Impl_CreateRenderTarget((IDirect3DDevice9Ex *)This, width, height,
2108 d3dformat_from_wined3dformat(format), multisample_type, multisample_quality, lockable,
2109 (IDirect3DSurface9 **)&d3d_surface, NULL);
2110 if (FAILED(hr))
2111 {
2112 ERR("(%p) CreateRenderTarget failed, returning %#x\n", iface, hr);
2113 return hr;
2114 }
2115
2116 *surface = d3d_surface->wineD3DSurface;
2117 d3d_surface->container = superior;
2118 d3d_surface->isImplicit = TRUE;
2119 /* Implicit surfaces are created with an refcount of 0 */
2120 IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
2121
2122 return hr;
2123 }
2124
2125 static HRESULT STDMETHODCALLTYPE device_parent_CreateDepthStencilSurface(IWineD3DDeviceParent *iface,
2126 IUnknown *superior, UINT width, UINT height, WINED3DFORMAT format, WINED3DMULTISAMPLE_TYPE multisample_type,
2127 DWORD multisample_quality, BOOL discard, IWineD3DSurface **surface)
2128 {
2129 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2130 IDirect3DSurface9Impl *d3d_surface;
2131 HRESULT hr;
2132
2133 TRACE("iface %p, superior %p, width %u, height %u, format %#x, multisample_type %#x,\n"
2134 "\tmultisample_quality %u, discard %u, surface %p\n",
2135 iface, superior, width, height, format, multisample_type, multisample_quality, discard, surface);
2136
2137 hr = IDirect3DDevice9Impl_CreateDepthStencilSurface((IDirect3DDevice9Ex *)This, width, height,
2138 d3dformat_from_wined3dformat(format), multisample_type, multisample_quality, discard,
2139 (IDirect3DSurface9 **)&d3d_surface, NULL);
2140 if (FAILED(hr))
2141 {
2142 ERR("(%p) CreateDepthStencilSurface failed, returning %#x\n", iface, hr);
2143 return hr;
2144 }
2145
2146 *surface = d3d_surface->wineD3DSurface;
2147 d3d_surface->container = (IUnknown *)This;
2148 d3d_surface->isImplicit = TRUE;
2149 /* Implicit surfaces are created with an refcount of 0 */
2150 IDirect3DSurface9_Release((IDirect3DSurface9 *)d3d_surface);
2151
2152 return hr;
2153 }
2154
2155 static HRESULT STDMETHODCALLTYPE device_parent_CreateVolume(IWineD3DDeviceParent *iface,
2156 IUnknown *superior, UINT width, UINT height, UINT depth, WINED3DFORMAT format,
2157 WINED3DPOOL pool, DWORD usage, IWineD3DVolume **volume)
2158 {
2159 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2160 IDirect3DVolume9Impl *object;
2161 HRESULT hr;
2162
2163 TRACE("iface %p, superior %p, width %u, height %u, depth %u, format %#x, pool %#x, usage %#x, volume %p\n",
2164 iface, superior, width, height, depth, format, pool, usage, volume);
2165
2166 /* Allocate the storage for the device */
2167 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
2168 if (!object)
2169 {
2170 FIXME("Allocation of memory failed\n");
2171 *volume = NULL;
2172 return D3DERR_OUTOFVIDEOMEMORY;
2173 }
2174
2175 object->lpVtbl = &Direct3DVolume9_Vtbl;
2176 object->ref = 1;
2177 hr = IWineD3DDevice_CreateVolume(This->WineD3DDevice, width, height, depth, usage & WINED3DUSAGE_MASK,
2178 format, pool, &object->wineD3DVolume, (IUnknown *)object);
2179 if (FAILED(hr))
2180 {
2181 ERR("(%p) CreateVolume failed, returning %#x\n", iface, hr);
2182 HeapFree(GetProcessHeap(), 0, object);
2183 *volume = NULL;
2184 return hr;
2185 }
2186
2187 *volume = object->wineD3DVolume;
2188 object->container = superior;
2189 object->forwardReference = superior;
2190
2191 TRACE("(%p) Created volume %p\n", iface, *volume);
2192
2193 return hr;
2194 }
2195
2196 static HRESULT STDMETHODCALLTYPE device_parent_CreateSwapChain(IWineD3DDeviceParent *iface,
2197 WINED3DPRESENT_PARAMETERS *present_parameters, IWineD3DSwapChain **swapchain)
2198 {
2199 struct IDirect3DDevice9Impl *This = device_from_device_parent(iface);
2200 IDirect3DSwapChain9Impl *d3d_swapchain;
2201 D3DPRESENT_PARAMETERS local_parameters;
2202 HRESULT hr;
2203
2204 TRACE("iface %p, present_parameters %p, swapchain %p\n", iface, present_parameters, swapchain);
2205
2206 /* Copy the presentation parameters */
2207 local_parameters.BackBufferWidth = present_parameters->BackBufferWidth;
2208 local_parameters.BackBufferHeight = present_parameters->BackBufferHeight;
2209 local_parameters.BackBufferFormat = d3dformat_from_wined3dformat(present_parameters->BackBufferFormat);
2210 local_parameters.BackBufferCount = present_parameters->BackBufferCount;
2211 local_parameters.MultiSampleType = present_parameters->MultiSampleType;
2212 local_parameters.MultiSampleQuality = present_parameters->MultiSampleQuality;
2213 local_parameters.SwapEffect = present_parameters->SwapEffect;
2214 local_parameters.hDeviceWindow = present_parameters->hDeviceWindow;
2215 local_parameters.Windowed = present_parameters->Windowed;
2216 local_parameters.EnableAutoDepthStencil = present_parameters->EnableAutoDepthStencil;
2217 local_parameters.AutoDepthStencilFormat = d3dformat_from_wined3dformat(present_parameters->AutoDepthStencilFormat);
2218 local_parameters.Flags = present_parameters->Flags;
2219 local_parameters.FullScreen_RefreshRateInHz = present_parameters->FullScreen_RefreshRateInHz;
2220 local_parameters.PresentationInterval = present_parameters->PresentationInterval;
2221
2222 hr = IDirect3DDevice9Impl_CreateAdditionalSwapChain((IDirect3DDevice9Ex *)This,
2223 &local_parameters, (IDirect3DSwapChain9 **)&d3d_swapchain);
2224 if (FAILED(hr))
2225 {
2226 ERR("(%p) CreateAdditionalSwapChain failed, returning %#x\n", iface, hr);
2227 *swapchain = NULL;
2228 return hr;
2229 }
2230
2231 *swapchain = d3d_swapchain->wineD3DSwapChain;
2232 d3d_swapchain->isImplicit = TRUE;
2233 /* Implicit swap chains are created with an refcount of 0 */
2234 IDirect3DSwapChain9_Release((IDirect3DSwapChain9 *)d3d_swapchain);
2235
2236 /* Copy back the presentation parameters */
2237 present_parameters->BackBufferWidth = local_parameters.BackBufferWidth;
2238 present_parameters->BackBufferHeight = local_parameters.BackBufferHeight;
2239 present_parameters->BackBufferFormat = wined3dformat_from_d3dformat(local_parameters.BackBufferFormat);
2240 present_parameters->BackBufferCount = local_parameters.BackBufferCount;
2241 present_parameters->MultiSampleType = local_parameters.MultiSampleType;
2242 present_parameters->MultiSampleQuality = local_parameters.MultiSampleQuality;
2243 present_parameters->SwapEffect = local_parameters.SwapEffect;
2244 present_parameters->hDeviceWindow = local_parameters.hDeviceWindow;
2245 present_parameters->Windowed = local_parameters.Windowed;
2246 present_parameters->EnableAutoDepthStencil = local_parameters.EnableAutoDepthStencil;
2247 present_parameters->AutoDepthStencilFormat = wined3dformat_from_d3dformat(local_parameters.AutoDepthStencilFormat);
2248 present_parameters->Flags = local_parameters.Flags;
2249 present_parameters->FullScreen_RefreshRateInHz = local_parameters.FullScreen_RefreshRateInHz;
2250 present_parameters->PresentationInterval = local_parameters.PresentationInterval;
2251
2252 return hr;
2253 }
2254
2255 const IWineD3DDeviceParentVtbl d3d9_wined3d_device_parent_vtbl =
2256 {
2257 /* IUnknown methods */
2258 device_parent_QueryInterface,
2259 device_parent_AddRef,
2260 device_parent_Release,
2261 /* IWineD3DDeviceParent methods */
2262 device_parent_WineD3DDeviceCreated,
2263 device_parent_CreateSurface,
2264 device_parent_CreateRenderTarget,
2265 device_parent_CreateDepthStencilSurface,
2266 device_parent_CreateVolume,
2267 device_parent_CreateSwapChain,
2268 };