xref: /reactos/dll/directx/d3d9/d3d9_device.c (revision 4561998a)
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 }
964