[NTOS:KE/x64] Handle NMI vs swapgs race condition
[reactos.git] / dll / directx / d3d9 / d3d9_device.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS ReactX
4 * FILE: dll/directx/d3d9/d3d9_device.c
5 * PURPOSE: d3d9.dll internal device methods
6 * PROGRAMERS: Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se>
7 */
8 #include "d3d9_device.h"
9 #include "d3d9_helpers.h"
10 #include "adapter.h"
11 #include <debug.h>
12 #include "d3d9_create.h"
13 #include "d3d9_mipmap.h"
14
15 #define LOCK_D3DDEVICE9() if (This->bLockDevice) EnterCriticalSection(&This->CriticalSection);
16 #define UNLOCK_D3DDEVICE9() if (This->bLockDevice) LeaveCriticalSection(&This->CriticalSection);
17
18 /* Convert a IDirect3DDevice9 pointer safely to the internal implementation struct */
19 LPDIRECT3DDEVICE9_INT IDirect3DDevice9ToImpl(LPDIRECT3DDEVICE9 iface)
20 {
21 if (NULL == iface)
22 return NULL;
23
24 return (LPDIRECT3DDEVICE9_INT)((ULONG_PTR)iface - FIELD_OFFSET(DIRECT3DDEVICE9_INT, lpVtbl));
25 }
26
27 static HRESULT InvalidCall(LPDIRECT3DDEVICE9_INT This, LPSTR ErrorMsg)
28 {
29 DPRINT1("%s",ErrorMsg);
30 UNLOCK_D3DDEVICE9();
31 return D3DERR_INVALIDCALL;
32 }
33
34 /* IDirect3DDevice9: IUnknown implementation */
35 HRESULT WINAPI IDirect3DDevice9Base_QueryInterface(LPDIRECT3DDEVICE9 iface, REFIID riid, void** ppvObject)
36 {
37 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
38
39 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3DDevice9))
40 {
41 IUnknown_AddRef(iface);
42 *ppvObject = &This->lpVtbl;
43 return D3D_OK;
44 }
45
46 *ppvObject = NULL;
47 return E_NOINTERFACE;
48 }
49
50 ULONG WINAPI IDirect3DDevice9Base_AddRef(LPDIRECT3DDEVICE9 iface)
51 {
52 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
53 ULONG ref = InterlockedIncrement(&This->lRefCnt);
54
55 return ref;
56 }
57
58 ULONG WINAPI IDirect3DDevice9Base_Release(LPDIRECT3DDEVICE9 iface)
59 {
60 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
61 ULONG ref = InterlockedDecrement(&This->lRefCnt);
62
63 if (ref == 0)
64 {
65 DWORD iAdapter;
66
67 EnterCriticalSection(&This->CriticalSection);
68
69 /* TODO: Free resources here */
70 for (iAdapter = 0; iAdapter < This->NumAdaptersInDevice; iAdapter++)
71 {
72 DestroyD3D9DeviceData(&This->DeviceData[iAdapter]);
73 }
74 This->lpVtbl->VirtualDestructor(iface);
75
76 LeaveCriticalSection(&This->CriticalSection);
77 AlignedFree(This);
78 }
79
80 return ref;
81 }
82
83 /* IDirect3DDevice9 public interface */
84 HRESULT WINAPI IDirect3DDevice9Base_TestCooperativeLevel(LPDIRECT3DDEVICE9 iface)
85 {
86 UNIMPLEMENTED
87
88 return D3D_OK;
89 }
90
91 /*++
92 * @name IDirect3DDevice9::GetAvailableTextureMem
93 * @implemented
94 *
95 * The function IDirect3DDevice9Base_GetAvailableTextureMem returns a pointer to the IDirect3D9 object
96 * that created this device.
97 *
98 * @param LPDIRECT3D iface
99 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice()
100 *
101 * @return UINT
102 * The method returns an estimated the currently available texture memory in bytes rounded
103 * to the nearest MB. Applications should NOT use this as an exact number.
104 *
105 */
106 UINT WINAPI IDirect3DDevice9Base_GetAvailableTextureMem(LPDIRECT3DDEVICE9 iface)
107 {
108 UINT AvailableTextureMemory = 0;
109 D3D9_GETAVAILDRIVERMEMORYDATA d3d9GetAvailDriverMemoryData;
110
111 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
112 LOCK_D3DDEVICE9();
113
114 memset(&d3d9GetAvailDriverMemoryData, 0, sizeof(d3d9GetAvailDriverMemoryData));
115 d3d9GetAvailDriverMemoryData.pUnknown6BC = This->DeviceData[0].pUnknown6BC;
116 d3d9GetAvailDriverMemoryData.dwMemoryType = D3D9_GETAVAILDRIVERMEMORY_TYPE_ALL;
117
118 if (TRUE == (*This->DeviceData[0].D3D9Callbacks.DdGetAvailDriverMemory)(&d3d9GetAvailDriverMemoryData))
119 {
120 /* Round it up to the nearest MB */
121 AvailableTextureMemory = (d3d9GetAvailDriverMemoryData.dwFree + 0x80000) & 0xFFF00000;
122 }
123
124 UNLOCK_D3DDEVICE9();
125 return AvailableTextureMemory;
126 }
127
128 HRESULT WINAPI IDirect3DDevice9Base_EvictManagedResources(LPDIRECT3DDEVICE9 iface)
129 {
130 UNIMPLEMENTED
131
132 return D3D_OK;
133 }
134
135 /*++
136 * @name IDirect3DDevice9::GetDirect3D
137 * @implemented
138 *
139 * The function IDirect3DDevice9Base_GetDirect3D returns a pointer to the IDirect3D9 object
140 * that created this device.
141 *
142 * @param LPDIRECT3D iface
143 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice()
144 *
145 * @param IDirect3D9** ppD3D9
146 * Pointer to a IDirect3D9* to receive the IDirect3D9 object pointer.
147 *
148 * @return HRESULT
149 * If the method successfully fills the ppD3D9 structure, the return value is D3D_OK.
150 * If ppD3D9 is a bad pointer, the return value will be D3DERR_INVALIDCALL.
151 *
152 */
153 HRESULT WINAPI IDirect3DDevice9Base_GetDirect3D(LPDIRECT3DDEVICE9 iface, IDirect3D9** ppD3D9)
154 {
155 IDirect3D9* pDirect3D9;
156 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
157 LOCK_D3DDEVICE9();
158
159 if (NULL == ppD3D9)
160 {
161 DPRINT1("Invalid ppD3D9 parameter specified");
162 UNLOCK_D3DDEVICE9();
163 return D3DERR_INVALIDCALL;
164 }
165
166 pDirect3D9 = (IDirect3D9*)&This->pDirect3D9->lpVtbl;
167 IDirect3D9_AddRef(pDirect3D9);
168 *ppD3D9 = pDirect3D9;
169
170 UNLOCK_D3DDEVICE9();
171 return D3D_OK;
172 }
173
174 /*++
175 * @name IDirect3DDevice9::GetDeviceCaps
176 * @implemented
177 *
178 * The function IDirect3DDevice9Base_GetDeviceCaps fills the pCaps argument with the
179 * capabilities of the device.
180 *
181 * @param LPDIRECT3D iface
182 * Pointer to the IDirect3D9 object returned from Direct3DCreate9()
183 *
184 * @param D3DCAPS9* pCaps
185 * Pointer to a D3DCAPS9 structure to be filled with the device's capabilities.
186 *
187 * @return HRESULT
188 * If the method successfully fills the pCaps structure, the return value is D3D_OK.
189 * If pCaps is a bad pointer the return value will be D3DERR_INVALIDCALL.
190 *
191 */
192 HRESULT WINAPI IDirect3DDevice9Base_GetDeviceCaps(LPDIRECT3DDEVICE9 iface, D3DCAPS9* pCaps)
193 {
194 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
195 LOCK_D3DDEVICE9();
196
197 if (NULL == pCaps)
198 {
199 DPRINT1("Invalid pCaps parameter specified");
200 UNLOCK_D3DDEVICE9();
201 return D3DERR_INVALIDCALL;
202 }
203
204 GetAdapterCaps(&This->pDirect3D9->DisplayAdapters[0], This->DeviceData[0].DeviceType, pCaps);
205
206 UNLOCK_D3DDEVICE9();
207 return D3D_OK;
208 }
209
210 /*++
211 * @name IDirect3DDevice9::GetDisplayMode
212 * @implemented
213 *
214 * The function IDirect3DDevice9Base_GetDisplayMode fills the pMode argument with the
215 * display mode for the specified swap chain.
216 *
217 * @param LPDIRECT3D iface
218 * Pointer to the IDirect3D9 object returned from Direct3DCreate9()
219 *
220 * @param UINT iSwapChain
221 * Swap chain index to get object for.
222 * The maximum value for this is the value returned by IDirect3DDevice9::GetNumberOfSwapChains() - 1.
223 *
224 * @param D3DDISPLAYMODE* pMode
225 * Pointer to a D3DDISPLAYMODE structure to be filled with the current swap chain's display mode information.
226 *
227 * @return HRESULT
228 * If the method successfully fills the pMode structure, the return value is D3D_OK.
229 * If iSwapChain is out of range or pMode is a bad pointer, the return value will be D3DERR_INVALIDCALL.
230 *
231 */
232 HRESULT WINAPI IDirect3DDevice9Base_GetDisplayMode(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, D3DDISPLAYMODE* pMode)
233 {
234 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
235 LOCK_D3DDEVICE9();
236
237 if (iSwapChain >= IDirect3DDevice9_GetNumberOfSwapChains(iface))
238 {
239 DPRINT1("Invalid iSwapChain parameter specified");
240 UNLOCK_D3DDEVICE9();
241 return D3DERR_INVALIDCALL;
242 }
243
244 if (NULL == pMode)
245 {
246 DPRINT1("Invalid pMode parameter specified");
247 UNLOCK_D3DDEVICE9();
248 return D3DERR_INVALIDCALL;
249 }
250
251 pMode->Width = This->DeviceData[iSwapChain].DriverCaps.dwDisplayWidth;
252 pMode->Height = This->DeviceData[iSwapChain].DriverCaps.dwDisplayHeight;
253 pMode->Format = This->DeviceData[iSwapChain].DriverCaps.RawDisplayFormat;
254 pMode->RefreshRate = This->DeviceData[iSwapChain].DriverCaps.dwRefreshRate;
255
256 UNLOCK_D3DDEVICE9();
257 return D3D_OK;
258 }
259
260 /*++
261 * @name IDirect3DDevice9::GetCreationParameters
262 * @implemented
263 *
264 * The function IDirect3DDevice9Base_GetCreationParameters fills the pParameters argument with the
265 * parameters the device was created with.
266 *
267 * @param LPDIRECT3D iface
268 * Pointer to the IDirect3D9 object returned from Direct3DCreate9()
269 *
270 * @param D3DDEVICE_CREATION_PARAMETERS* pParameters
271 * Pointer to a D3DDEVICE_CREATION_PARAMETERS structure to be filled with the creation parameter
272 * information for this device.
273 *
274 * @return HRESULT
275 * If the method successfully fills the pParameters structure, the return value is D3D_OK.
276 * If pParameters is a bad pointer, the return value will be D3DERR_INVALIDCALL.
277 *
278 */
279 HRESULT WINAPI IDirect3DDevice9Base_GetCreationParameters(LPDIRECT3DDEVICE9 iface, D3DDEVICE_CREATION_PARAMETERS* pParameters)
280 {
281 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
282 LOCK_D3DDEVICE9();
283
284 if (NULL == pParameters)
285 {
286 DPRINT1("Invalid pParameters parameter specified");
287 UNLOCK_D3DDEVICE9();
288 return D3DERR_INVALIDCALL;
289 }
290
291 pParameters->AdapterOrdinal = This->AdapterIndexInGroup[0];
292 pParameters->DeviceType = This->DeviceType;
293 pParameters->hFocusWindow = This->hWnd;
294 pParameters->BehaviorFlags = This->BehaviourFlags;
295
296 UNLOCK_D3DDEVICE9();
297 return D3D_OK;
298 }
299
300 HRESULT WINAPI IDirect3DDevice9Base_SetCursorProperties(LPDIRECT3DDEVICE9 iface, UINT XHotSpot, UINT YHotSpot, IDirect3DSurface9* pCursorBitmap)
301 {
302 UNIMPLEMENTED
303
304 return D3D_OK;
305 }
306
307 VOID WINAPI IDirect3DDevice9Base_SetCursorPosition(LPDIRECT3DDEVICE9 iface, int X, int Y, DWORD Flags)
308 {
309 UNIMPLEMENTED
310 }
311
312 BOOL WINAPI IDirect3DDevice9Base_ShowCursor(LPDIRECT3DDEVICE9 iface, BOOL bShow)
313 {
314 UNIMPLEMENTED
315
316 return TRUE;
317 }
318
319 /*++
320 * @name IDirect3DDevice9::CreateAdditionalSwapChain
321 * @implemented
322 *
323 * The function IDirect3DDevice9Base_CreateAdditionalSwapChain creates a swap chain object,
324 * useful when rendering multiple views.
325 *
326 * @param LPDIRECT3D iface
327 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice()
328 *
329 * @param D3DPRESENT_PARAMETERS* pPresentationParameters
330 * Pointer to a D3DPRESENT_PARAMETERS structure describing the parameters for the swap chain
331 * to be created.
332 *
333 * @param IDirect3DSwapChain9** ppSwapChain
334 * Pointer to a IDirect3DSwapChain9* to receive the swap chain object pointer.
335 *
336 * @return HRESULT
337 * If the method successfully fills the ppSwapChain structure, the return value is D3D_OK.
338 * If iSwapChain is out of range or ppSwapChain is a bad pointer, the return value
339 * will be D3DERR_INVALIDCALL. Also D3DERR_OUTOFVIDEOMEMORY can be returned if allocation
340 * of the new swap chain object failed.
341 *
342 */
343 HRESULT WINAPI IDirect3DDevice9Base_CreateAdditionalSwapChain(LPDIRECT3DDEVICE9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DSwapChain9** ppSwapChain)
344 {
345 UINT iSwapChain;
346 IDirect3DSwapChain9* pSwapChain;
347 Direct3DSwapChain9_INT* pSwapChain_INT;
348 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
349 LOCK_D3DDEVICE9();
350
351 if (NULL == ppSwapChain)
352 {
353 DPRINT1("Invalid ppSwapChain parameter specified");
354 UNLOCK_D3DDEVICE9();
355 return D3DERR_INVALIDCALL;
356 }
357
358 *ppSwapChain = NULL;
359 iSwapChain = IDirect3DDevice9_GetNumberOfSwapChains(iface) + 1;
360
361 pSwapChain_INT = CreateDirect3DSwapChain9(RT_EXTERNAL, This, iSwapChain);
362 if (NULL == pSwapChain_INT)
363 {
364 DPRINT1("Out of memory");
365 UNLOCK_D3DDEVICE9();
366 return D3DERR_OUTOFVIDEOMEMORY;
367 }
368
369 Direct3DSwapChain9_Init(pSwapChain_INT, pPresentationParameters);
370
371 This->pSwapChains[iSwapChain] = pSwapChain_INT;
372 pSwapChain = (IDirect3DSwapChain9*)&pSwapChain_INT->lpVtbl;
373 IDirect3DSwapChain9_AddRef(pSwapChain);
374 *ppSwapChain = pSwapChain;
375
376 UNLOCK_D3DDEVICE9();
377 return D3D_OK;
378 }
379
380 /*++
381 * @name IDirect3DDevice9::GetSwapChain
382 * @implemented
383 *
384 * The function IDirect3DDevice9Base_GetSwapChain returns a pointer to a swap chain object.
385 *
386 * @param LPDIRECT3D iface
387 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice()
388 *
389 * @param UINT iSwapChain
390 * Swap chain index to get object for.
391 * The maximum value for this is the value returned by IDirect3DDevice9::GetNumberOfSwapChains() - 1.
392 *
393 * @param IDirect3DSwapChain9** ppSwapChain
394 * Pointer to a IDirect3DSwapChain9* to receive the swap chain object pointer.
395 *
396 * @return HRESULT
397 * If the method successfully fills the ppSwapChain structure, the return value is D3D_OK.
398 * If iSwapChain is out of range or ppSwapChain is a bad pointer, the return value
399 * will be D3DERR_INVALIDCALL.
400 *
401 */
402 HRESULT WINAPI IDirect3DDevice9Base_GetSwapChain(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, IDirect3DSwapChain9** ppSwapChain)
403 {
404 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
405 LOCK_D3DDEVICE9();
406
407 if (NULL == ppSwapChain)
408 {
409 DPRINT1("Invalid ppSwapChain parameter specified");
410 UNLOCK_D3DDEVICE9();
411 return D3DERR_INVALIDCALL;
412 }
413
414 *ppSwapChain = NULL;
415
416 if (iSwapChain >= IDirect3DDevice9_GetNumberOfSwapChains(iface))
417 {
418 DPRINT1("Invalid iSwapChain parameter specified");
419 UNLOCK_D3DDEVICE9();
420 return D3DERR_INVALIDCALL;
421 }
422
423 if (This->pSwapChains[iSwapChain] != NULL)
424 {
425 IDirect3DSwapChain9* pSwapChain = (IDirect3DSwapChain9*)&This->pSwapChains[iSwapChain]->lpVtbl;
426 IDirect3DSwapChain9_AddRef(pSwapChain);
427 *ppSwapChain = pSwapChain;
428 }
429 else
430 {
431 *ppSwapChain = NULL;
432 }
433
434 UNLOCK_D3DDEVICE9();
435 return D3D_OK;
436 }
437
438 /*++
439 * @name IDirect3DDevice9::GetNumberOfSwapChains
440 * @implemented
441 *
442 * The function IDirect3DDevice9Base_GetNumberOfSwapChains returns the number of swap chains
443 * created by IDirect3D9::CreateDevice().
444 *
445 * @param LPDIRECT3D iface
446 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice().
447 *
448 * @return UINT
449 * Returns the number of swap chains created by IDirect3D9::CreateDevice().
450 *
451 * NOTE: An application can create additional swap chains using the
452 * IDirect3DDevice9::CreateAdditionalSwapChain() method.
453 *
454 */
455 UINT WINAPI IDirect3DDevice9Base_GetNumberOfSwapChains(LPDIRECT3DDEVICE9 iface)
456 {
457 UINT NumSwapChains;
458
459 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
460 LOCK_D3DDEVICE9();
461
462 NumSwapChains = This->NumAdaptersInDevice;
463
464 UNLOCK_D3DDEVICE9();
465 return NumSwapChains;
466 }
467
468 HRESULT WINAPI IDirect3DDevice9Base_Reset(LPDIRECT3DDEVICE9 iface, D3DPRESENT_PARAMETERS* pPresentationParameters)
469 {
470 UNIMPLEMENTED
471
472 return D3D_OK;
473 }
474
475 /*++
476 * @name IDirect3DDevice9::Present
477 * @implemented
478 *
479 * The function IDirect3DDevice9Base_Present displays the content of the next
480 * back buffer in sequence for the device.
481 *
482 * @param LPDIRECT3D iface
483 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice().
484 *
485 * @param CONST RECT* pSourceRect
486 * A pointer to a RECT structure representing an area of the back buffer to display where
487 * NULL means the whole back buffer. This parameter MUST be NULL unless the back buffer
488 * was created with the D3DSWAPEFFECT_COPY flag.
489 *
490 * @param CONST RECT* pDestRect
491 * A pointer to a RECT structure representing an area of the back buffer where the content
492 * will be displayed where NULL means the whole back buffer starting at (0,0).
493 * This parameter MUST be NULL unless the back buffer was created with the D3DSWAPEFFECT_COPY flag.
494 *
495 * @param HWND hDestWindowOverride
496 * A destination window where NULL means the window specified in the hWndDeviceWindow of the
497 * D3DPRESENT_PARAMETERS structure.
498 *
499 * @param CONST RGNDATA* pDirtyRegion
500 * A pointer to a RGNDATA structure representing an area of the back buffer to display where
501 * NULL means the whole back buffer. This parameter MUST be NULL unless the back buffer
502 * was created with the D3DSWAPEFFECT_COPY flag. This is an optimization region only.
503 *
504 * @return HRESULT
505 * If the method successfully displays the back buffer content, the return value is D3D_OK.
506 * If no swap chains are available, the return value will be D3DERR_INVALIDCALL.
507 */
508 HRESULT WINAPI IDirect3DDevice9Base_Present(LPDIRECT3DDEVICE9 iface, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
509 {
510 UINT i;
511 UINT iNumSwapChains;
512 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
513 LOCK_D3DDEVICE9();
514
515 iNumSwapChains = IDirect3DDevice9Base_GetNumberOfSwapChains(iface);
516 if (0 == iNumSwapChains)
517 {
518 DPRINT1("Not enough swap chains, Present() fails");
519 UNLOCK_D3DDEVICE9();
520 return D3DERR_INVALIDCALL;
521 }
522
523 for (i = 0; i < iNumSwapChains; i++)
524 {
525 HRESULT hResult;
526 IDirect3DSwapChain9* pSwapChain;
527
528 IDirect3DDevice9Base_GetSwapChain(iface, i, &pSwapChain);
529 hResult = IDirect3DSwapChain9_Present(pSwapChain, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, 0);
530
531 if (FAILED(hResult))
532 {
533 UNLOCK_D3DDEVICE9();
534 return hResult;
535 }
536 }
537
538 UNLOCK_D3DDEVICE9();
539 return D3D_OK;
540 }
541
542 /*++
543 * @name IDirect3DDevice9::GetBackBuffer
544 * @implemented
545 *
546 * The function IDirect3DDevice9Base_GetBackBuffer retrieves the back buffer
547 * for the specified swap chain.
548 *
549 * @param LPDIRECT3D iface
550 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice().
551 *
552 * @param UINT iSwapChain
553 * Swap chain index to get object for.
554 * The maximum value for this is the value returned by IDirect3DDevice9::GetNumberOfSwapChains() - 1.
555 *
556 * @param UINT iBackBuffer
557 * Back buffer index to get object for.
558 * The maximum value for this is the the total number of back buffers - 1, as indexing starts at 0.
559 *
560 * @param IDirect3DSurface9** ppBackBuffer
561 * Pointer to a IDirect3DSurface9* to receive the back buffer object
562 *
563 * @return HRESULT
564 * If the method successfully sets the ppBackBuffer pointer, the return value is D3D_OK.
565 * If iSwapChain or iBackBuffer is out of range, Type is invalid or ppBackBuffer is a bad pointer,
566 * the return value will be D3DERR_INVALIDCALL.
567 */
568 HRESULT WINAPI IDirect3DDevice9Base_GetBackBuffer(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9** ppBackBuffer)
569 {
570 HRESULT hResult;
571 IDirect3DSwapChain9* pSwapChain = NULL;
572 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
573 LOCK_D3DDEVICE9();
574
575 IDirect3DDevice9Base_GetSwapChain(iface, iSwapChain, &pSwapChain);
576 if (NULL == pSwapChain)
577 {
578 DPRINT1("Invalid iSwapChain parameter specified");
579 UNLOCK_D3DDEVICE9();
580 return D3DERR_INVALIDCALL;
581 }
582
583 if (NULL == ppBackBuffer)
584 {
585 DPRINT1("Invalid ppBackBuffer parameter specified");
586 UNLOCK_D3DDEVICE9();
587 return D3DERR_INVALIDCALL;
588 }
589
590 hResult = IDirect3DSwapChain9_GetBackBuffer(pSwapChain, iBackBuffer, Type, ppBackBuffer);
591
592 UNLOCK_D3DDEVICE9();
593 return hResult;
594 }
595
596 /*++
597 * @name IDirect3DDevice9::GetRasterStatus
598 * @implemented
599 *
600 * The function IDirect3DDevice9Base_GetRasterStatus retrieves raster information
601 * of the monitor for the specified swap chain.
602 *
603 * @param LPDIRECT3D iface
604 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice().
605 *
606 * @param UINT iSwapChain
607 * Swap chain index to get object for.
608 * The maximum value for this is the value returned by IDirect3DDevice9::GetNumberOfSwapChains() - 1.
609 *
610 * @param D3DRASTER_STATUS* pRasterStatus
611 * Pointer to a D3DRASTER_STATUS to receive the raster information
612 *
613 * @return HRESULT
614 * If the method successfully fills the pRasterStatus structure, the return value is D3D_OK.
615 * If iSwapChain is out of range or pRasterStatus is a bad pointer, the return value
616 * will be D3DERR_INVALIDCALL.
617 */
618 HRESULT WINAPI IDirect3DDevice9Base_GetRasterStatus(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, D3DRASTER_STATUS* pRasterStatus)
619 {
620 HRESULT hResult;
621 IDirect3DSwapChain9* pSwapChain = NULL;
622 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
623 LOCK_D3DDEVICE9();
624
625 IDirect3DDevice9Base_GetSwapChain(iface, iSwapChain, &pSwapChain);
626 if (NULL == pSwapChain)
627 {
628 DPRINT1("Invalid iSwapChain parameter specified");
629 UNLOCK_D3DDEVICE9();
630 return D3DERR_INVALIDCALL;
631 }
632
633 if (NULL == pRasterStatus)
634 {
635 DPRINT1("Invalid pRasterStatus parameter specified");
636 UNLOCK_D3DDEVICE9();
637 return D3DERR_INVALIDCALL;
638 }
639
640 hResult = IDirect3DSwapChain9_GetRasterStatus(pSwapChain, pRasterStatus);
641
642 UNLOCK_D3DDEVICE9();
643 return hResult;
644 }
645
646 HRESULT WINAPI IDirect3DDevice9Base_SetDialogBoxMode(LPDIRECT3DDEVICE9 iface, BOOL bEnableDialogs)
647 {
648 UNIMPLEMENTED
649
650 return D3D_OK;
651 }
652
653 /*++
654 * @name IDirect3DDevice9::SetGammaRamp
655 * @implemented
656 *
657 * The function IDirect3DDevice9Base_SetGammaRamp sets the gamma correction ramp values
658 * for the specified swap chain.
659 *
660 * @param LPDIRECT3D iface
661 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice().
662 *
663 * @param UINT iSwapChain
664 * Swap chain index to get object for.
665 * The maximum value for this is the value returned by IDirect3DDevice9::GetNumberOfSwapChains() - 1.
666 *
667 * @param UINT Flags
668 * Can be on of the following:
669 * D3DSGR_CALIBRATE - Detects if a gamma calibrator is installed and if so modifies the values to correspond to
670 * the monitor and system settings before sending them to the display device.
671 * D3DSGR_NO_CALIBRATION - The gamma calibrations values are sent directly to the display device without
672 * any modification.
673 *
674 * @param CONST D3DGAMMARAMP* pRamp
675 * Pointer to a D3DGAMMARAMP representing the gamma correction ramp values to be set.
676 *
677 */
678 VOID WINAPI IDirect3DDevice9Base_SetGammaRamp(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, DWORD Flags, CONST D3DGAMMARAMP* pRamp)
679 {
680 IDirect3DSwapChain9* pSwapChain = NULL;
681 Direct3DSwapChain9_INT* pSwapChain_INT;
682 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
683 LOCK_D3DDEVICE9();
684
685 IDirect3DDevice9Base_GetSwapChain(iface, iSwapChain, &pSwapChain);
686 if (NULL == pSwapChain)
687 {
688 DPRINT1("Invalid iSwapChain parameter specified");
689 UNLOCK_D3DDEVICE9();
690 return;
691 }
692
693 if (NULL == pRamp)
694 {
695 DPRINT1("Invalid pRamp parameter specified");
696 UNLOCK_D3DDEVICE9();
697 return;
698 }
699
700 pSwapChain_INT = IDirect3DSwapChain9ToImpl(pSwapChain);
701 Direct3DSwapChain9_SetGammaRamp(pSwapChain_INT, Flags, pRamp);
702
703 UNLOCK_D3DDEVICE9();
704 }
705
706 /*++
707 * @name IDirect3DDevice9::GetGammaRamp
708 * @implemented
709 *
710 * The function IDirect3DDevice9Base_GetGammaRamp retrieves the gamma correction ramp values
711 * for the specified swap chain.
712 *
713 * @param LPDIRECT3D iface
714 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice().
715 *
716 * @param UINT iSwapChain
717 * Swap chain index to get object for.
718 * The maximum value for this is the value returned by IDirect3DDevice9::GetNumberOfSwapChains() - 1.
719 *
720 * @param D3DGAMMARAMP* pRamp
721 * Pointer to a D3DGAMMARAMP to receive the gamma correction ramp values.
722 *
723 */
724 VOID WINAPI IDirect3DDevice9Base_GetGammaRamp(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, D3DGAMMARAMP* pRamp)
725 {
726 IDirect3DSwapChain9* pSwapChain = NULL;
727 Direct3DSwapChain9_INT* pSwapChain_INT;
728 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
729 LOCK_D3DDEVICE9();
730
731 IDirect3DDevice9Base_GetSwapChain(iface, iSwapChain, &pSwapChain);
732 if (NULL == pSwapChain)
733 {
734 DPRINT1("Invalid iSwapChain parameter specified");
735 UNLOCK_D3DDEVICE9();
736 return;
737 }
738
739 if (NULL == pRamp)
740 {
741 DPRINT1("Invalid pRamp parameter specified");
742 UNLOCK_D3DDEVICE9();
743 return;
744 }
745
746 pSwapChain_INT = IDirect3DSwapChain9ToImpl(pSwapChain);
747 Direct3DSwapChain9_GetGammaRamp(pSwapChain_INT, pRamp);
748
749 UNLOCK_D3DDEVICE9();
750 }
751
752 /*++
753 * @name IDirect3DDevice9::CreateTexture
754 * @implemented
755 *
756 * The function IDirect3DDevice9Base_CreateTexture creates a D3D9 texture.
757 *
758 * @param LPDIRECT3D iface
759 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice()
760 *
761 * @param UINT Width
762 * Desired width of the texture
763 *
764 * @param UINT Height
765 * Desired height of the texture
766 *
767 * @param UINT Levels
768 * Number of mip-maps. If Levels are zero, mip-maps down to size 1x1 will be generated.
769 *
770 * @param DWORD Usage
771 * Valid combinations of the D3DUSAGE constants.
772 *
773 * @param D3DFORMAT Format
774 * One of the D3DFORMAT enum members for the surface format.
775 *
776 * @param D3DPOOL Pool
777 * One of the D3DPOOL enum members for where the texture should be placed.
778 *
779 * @param IDirect3DTexture9** ppTexture
780 * Return parameter for the created texture
781 *
782 * @param HANDLE* pSharedHandle
783 * Set to NULL, shared resources are not implemented yet
784 *
785 * @return HRESULT
786 * Returns D3D_OK if everything went well.
787 *
788 */
789 HRESULT WINAPI IDirect3DDevice9Base_CreateTexture(LPDIRECT3DDEVICE9 iface, UINT Width, UINT Height, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DTexture9** ppTexture, HANDLE* pSharedHandle)
790 {
791 HRESULT hResult;
792 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
793 LOCK_D3DDEVICE9();
794
795 if (NULL == This)
796 return InvalidCall(This, "Invalid 'this' parameter specified");
797
798 if (NULL == ppTexture)
799 return InvalidCall(This, "Invalid ppTexture parameter specified");
800
801 *ppTexture = NULL;
802
803 if (D3DFMT_UNKNOWN == Format)
804 return InvalidCall(This, "Invalid Format parameter specified, D3DFMT_UNKNOWN is not a valid Format");
805
806 if (NULL != pSharedHandle)
807 {
808 UNIMPLEMENTED;
809 return InvalidCall(This, "Invalid pSharedHandle parameter specified, only NULL is supported at the moment");
810 }
811
812 hResult = CreateD3D9MipMap(This, Width, Height, Levels, Usage, Format, Pool, ppTexture);
813 if (FAILED(hResult))
814 DPRINT1("Failed to create texture");
815
816 UNLOCK_D3DDEVICE9();
817 return hResult;
818 }
819
820 HRESULT WINAPI IDirect3DDevice9Base_CreateVolumeTexture(LPDIRECT3DDEVICE9 iface, UINT Width, UINT Height, UINT Depth, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DVolumeTexture9** ppVolumeTexture, HANDLE* pSharedHandle)
821 {
822 UNIMPLEMENTED
823
824 return D3D_OK;
825 }
826
827 HRESULT WINAPI IDirect3DDevice9Base_CreateCubeTexture(LPDIRECT3DDEVICE9 iface, UINT EdgeLength, UINT Levels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DCubeTexture9** ppCubeTexture, HANDLE* pSharedHandle)
828 {
829 UNIMPLEMENTED
830
831 return D3D_OK;
832 }
833
834 HRESULT WINAPI IDirect3DDevice9Base_CreateVertexBuffer(LPDIRECT3DDEVICE9 iface, UINT Length, DWORD Usage, DWORD FVF, D3DPOOL Pool, IDirect3DVertexBuffer9** ppVertexBuffer, HANDLE* pSharedHandle)
835 {
836 UNIMPLEMENTED
837
838 return D3D_OK;
839 }
840
841 HRESULT WINAPI IDirect3DDevice9Base_CreateIndexBuffer(LPDIRECT3DDEVICE9 iface, UINT Length, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, IDirect3DIndexBuffer9** ppIndexBuffer, HANDLE* pSharedHandle)
842 {
843 UNIMPLEMENTED
844
845 return D3D_OK;
846 }
847
848 HRESULT WINAPI IDirect3DDevice9Base_CreateRenderTarget(LPDIRECT3DDEVICE9 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Lockable, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle)
849 {
850 UNIMPLEMENTED
851
852 return D3D_OK;
853 }
854
855 HRESULT WINAPI IDirect3DDevice9Base_CreateDepthStencilSurface(LPDIRECT3DDEVICE9 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, DWORD MultisampleQuality, BOOL Discard, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle)
856 {
857 UNIMPLEMENTED
858
859 return D3D_OK;
860 }
861
862 HRESULT WINAPI IDirect3DDevice9Base_UpdateSurface(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestinationSurface, CONST POINT* pDestPoint)
863 {
864 UNIMPLEMENTED
865
866 return D3D_OK;
867 }
868
869 HRESULT WINAPI IDirect3DDevice9Base_UpdateTexture(LPDIRECT3DDEVICE9 iface, IDirect3DBaseTexture9* pSourceTexture, IDirect3DBaseTexture9* pDestinationTexture)
870 {
871 UNIMPLEMENTED
872
873 return D3D_OK;
874 }
875
876 HRESULT WINAPI IDirect3DDevice9Base_GetRenderTargetData(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pRenderTarget, IDirect3DSurface9* pDestSurface)
877 {
878 UNIMPLEMENTED
879
880 return D3D_OK;
881 }
882
883 /*++
884 * @name IDirect3DDevice9::GetFrontBufferData
885 * @implemented
886 *
887 * The function IDirect3DDevice9Base_GetFrontBufferData copies the content of
888 * the display device's front buffer in a system memory surface buffer.
889 *
890 * @param LPDIRECT3D iface
891 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice().
892 *
893 * @param UINT iSwapChain
894 * Swap chain index to get object for.
895 * The maximum value for this is the value returned by IDirect3DDevice9::GetNumberOfSwapChains() - 1.
896 *
897 * @param IDirect3DSurface9* pDestSurface
898 * Pointer to a IDirect3DSurface9 to receive front buffer content
899 *
900 * @return HRESULT
901 * If the method successfully fills the pDestSurface buffer, the return value is D3D_OK.
902 * If iSwapChain is out of range or pDestSurface is a bad pointer, the return value
903 * will be D3DERR_INVALIDCALL.
904 */
905 HRESULT WINAPI IDirect3DDevice9Base_GetFrontBufferData(LPDIRECT3DDEVICE9 iface, UINT iSwapChain, IDirect3DSurface9* pDestSurface)
906 {
907 HRESULT hResult;
908 IDirect3DSwapChain9* pSwapChain = NULL;
909 LPDIRECT3DDEVICE9_INT This = IDirect3DDevice9ToImpl(iface);
910 LOCK_D3DDEVICE9();
911
912 IDirect3DDevice9Base_GetSwapChain(iface, iSwapChain, &pSwapChain);
913 if (NULL == pSwapChain)
914 {
915 DPRINT1("Invalid iSwapChain parameter specified");
916 UNLOCK_D3DDEVICE9();
917 return D3DERR_INVALIDCALL;
918 }
919
920 if (NULL == pDestSurface)
921 {
922 DPRINT1("Invalid pDestSurface parameter specified");
923 UNLOCK_D3DDEVICE9();
924 return D3DERR_INVALIDCALL;
925 }
926
927 hResult = IDirect3DSwapChain9_GetFrontBufferData(pSwapChain, pDestSurface);
928
929 UNLOCK_D3DDEVICE9();
930 return hResult;
931 }
932
933 HRESULT WINAPI IDirect3DDevice9Base_StretchRect(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pSourceSurface, CONST RECT* pSourceRect, IDirect3DSurface9* pDestSurface, CONST RECT* pDestRect, D3DTEXTUREFILTERTYPE Filter)
934 {
935 UNIMPLEMENTED
936
937 return D3D_OK;
938 }
939
940 HRESULT WINAPI IDirect3DDevice9Base_ColorFill(LPDIRECT3DDEVICE9 iface, IDirect3DSurface9* pSurface, CONST RECT* pRect, D3DCOLOR color)
941 {
942 UNIMPLEMENTED
943
944 return D3D_OK;
945 }
946
947 HRESULT WINAPI IDirect3DDevice9Base_CreateOffscreenPlainSurface(LPDIRECT3DDEVICE9 iface, UINT Width, UINT Height, D3DFORMAT Format, D3DPOOL Pool, IDirect3DSurface9** ppSurface, HANDLE* pSharedHandle)
948 {
949 UNIMPLEMENTED
950
951 return D3D_OK;
952 }
953
954 /* IDirect3DDevice9 private interface */
955 VOID WINAPI IDirect3DDevice9Base_Destroy(LPDIRECT3DDEVICE9 iface)
956 {
957 UNIMPLEMENTED
958 }
959
960 VOID WINAPI IDirect3DDevice9Base_VirtualDestructor(LPDIRECT3DDEVICE9 iface)
961 {
962 UNIMPLEMENTED
963 }