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>
8 #include "d3d9_device.h"
9 #include "d3d9_helpers.h"
12 #include "d3d9_create.h"
13 #include "d3d9_mipmap.h"
15 #define LOCK_D3DDEVICE9() if (This->bLockDevice) EnterCriticalSection(&This->CriticalSection);
16 #define UNLOCK_D3DDEVICE9() if (This->bLockDevice) LeaveCriticalSection(&This->CriticalSection);
18 /* Convert a IDirect3DDevice9 pointer safely to the internal implementation struct */
19 LPDIRECT3DDEVICE9_INT
IDirect3DDevice9ToImpl(LPDIRECT3DDEVICE9 iface
)
24 return (LPDIRECT3DDEVICE9_INT
)((ULONG_PTR
)iface
- FIELD_OFFSET(DIRECT3DDEVICE9_INT
, lpVtbl
));
27 static HRESULT
InvalidCall(LPDIRECT3DDEVICE9_INT This
, LPSTR ErrorMsg
)
31 return D3DERR_INVALIDCALL
;
34 /* IDirect3DDevice9: IUnknown implementation */
35 HRESULT WINAPI
IDirect3DDevice9Base_QueryInterface(LPDIRECT3DDEVICE9 iface
, REFIID riid
, void** ppvObject
)
37 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
39 if (IsEqualGUID(riid
, &IID_IUnknown
) || IsEqualGUID(riid
, &IID_IDirect3DDevice9
))
41 IUnknown_AddRef(iface
);
42 *ppvObject
= &This
->lpVtbl
;
50 ULONG WINAPI
IDirect3DDevice9Base_AddRef(LPDIRECT3DDEVICE9 iface
)
52 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
53 ULONG ref
= InterlockedIncrement(&This
->lRefCnt
);
58 ULONG WINAPI
IDirect3DDevice9Base_Release(LPDIRECT3DDEVICE9 iface
)
60 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
61 ULONG ref
= InterlockedDecrement(&This
->lRefCnt
);
67 EnterCriticalSection(&This
->CriticalSection
);
69 /* TODO: Free resources here */
70 for (iAdapter
= 0; iAdapter
< This
->NumAdaptersInDevice
; iAdapter
++)
72 DestroyD3D9DeviceData(&This
->DeviceData
[iAdapter
]);
74 This
->lpVtbl
->VirtualDestructor(iface
);
76 LeaveCriticalSection(&This
->CriticalSection
);
83 /* IDirect3DDevice9 public interface */
84 HRESULT WINAPI
IDirect3DDevice9Base_TestCooperativeLevel(LPDIRECT3DDEVICE9 iface
)
92 * @name IDirect3DDevice9::GetAvailableTextureMem
95 * The function IDirect3DDevice9Base_GetAvailableTextureMem returns a pointer to the IDirect3D9 object
96 * that created this device.
98 * @param LPDIRECT3D iface
99 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice()
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.
106 UINT WINAPI
IDirect3DDevice9Base_GetAvailableTextureMem(LPDIRECT3DDEVICE9 iface
)
108 UINT AvailableTextureMemory
= 0;
109 D3D9_GETAVAILDRIVERMEMORYDATA d3d9GetAvailDriverMemoryData
;
111 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
114 memset(&d3d9GetAvailDriverMemoryData
, 0, sizeof(d3d9GetAvailDriverMemoryData
));
115 d3d9GetAvailDriverMemoryData
.pUnknown6BC
= This
->DeviceData
[0].pUnknown6BC
;
116 d3d9GetAvailDriverMemoryData
.dwMemoryType
= D3D9_GETAVAILDRIVERMEMORY_TYPE_ALL
;
118 if (TRUE
== (*This
->DeviceData
[0].D3D9Callbacks
.DdGetAvailDriverMemory
)(&d3d9GetAvailDriverMemoryData
))
120 /* Round it up to the nearest MB */
121 AvailableTextureMemory
= (d3d9GetAvailDriverMemoryData
.dwFree
+ 0x80000) & 0xFFF00000;
125 return AvailableTextureMemory
;
128 HRESULT WINAPI
IDirect3DDevice9Base_EvictManagedResources(LPDIRECT3DDEVICE9 iface
)
136 * @name IDirect3DDevice9::GetDirect3D
139 * The function IDirect3DDevice9Base_GetDirect3D returns a pointer to the IDirect3D9 object
140 * that created this device.
142 * @param LPDIRECT3D iface
143 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice()
145 * @param IDirect3D9** ppD3D9
146 * Pointer to a IDirect3D9* to receive the IDirect3D9 object pointer.
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.
153 HRESULT WINAPI
IDirect3DDevice9Base_GetDirect3D(LPDIRECT3DDEVICE9 iface
, IDirect3D9
** ppD3D9
)
155 IDirect3D9
* pDirect3D9
;
156 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
161 DPRINT1("Invalid ppD3D9 parameter specified");
163 return D3DERR_INVALIDCALL
;
166 pDirect3D9
= (IDirect3D9
*)&This
->pDirect3D9
->lpVtbl
;
167 IDirect3D9_AddRef(pDirect3D9
);
168 *ppD3D9
= pDirect3D9
;
175 * @name IDirect3DDevice9::GetDeviceCaps
178 * The function IDirect3DDevice9Base_GetDeviceCaps fills the pCaps argument with the
179 * capabilities of the device.
181 * @param LPDIRECT3D iface
182 * Pointer to the IDirect3D9 object returned from Direct3DCreate9()
184 * @param D3DCAPS9* pCaps
185 * Pointer to a D3DCAPS9 structure to be filled with the device's capabilities.
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.
192 HRESULT WINAPI
IDirect3DDevice9Base_GetDeviceCaps(LPDIRECT3DDEVICE9 iface
, D3DCAPS9
* pCaps
)
194 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
199 DPRINT1("Invalid pCaps parameter specified");
201 return D3DERR_INVALIDCALL
;
204 GetAdapterCaps(&This
->pDirect3D9
->DisplayAdapters
[0], This
->DeviceData
[0].DeviceType
, pCaps
);
211 * @name IDirect3DDevice9::GetDisplayMode
214 * The function IDirect3DDevice9Base_GetDisplayMode fills the pMode argument with the
215 * display mode for the specified swap chain.
217 * @param LPDIRECT3D iface
218 * Pointer to the IDirect3D9 object returned from Direct3DCreate9()
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.
224 * @param D3DDISPLAYMODE* pMode
225 * Pointer to a D3DDISPLAYMODE structure to be filled with the current swap chain's display mode information.
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.
232 HRESULT WINAPI
IDirect3DDevice9Base_GetDisplayMode(LPDIRECT3DDEVICE9 iface
, UINT iSwapChain
, D3DDISPLAYMODE
* pMode
)
234 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
237 if (iSwapChain
>= IDirect3DDevice9_GetNumberOfSwapChains(iface
))
239 DPRINT1("Invalid iSwapChain parameter specified");
241 return D3DERR_INVALIDCALL
;
246 DPRINT1("Invalid pMode parameter specified");
248 return D3DERR_INVALIDCALL
;
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
;
261 * @name IDirect3DDevice9::GetCreationParameters
264 * The function IDirect3DDevice9Base_GetCreationParameters fills the pParameters argument with the
265 * parameters the device was created with.
267 * @param LPDIRECT3D iface
268 * Pointer to the IDirect3D9 object returned from Direct3DCreate9()
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.
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.
279 HRESULT WINAPI
IDirect3DDevice9Base_GetCreationParameters(LPDIRECT3DDEVICE9 iface
, D3DDEVICE_CREATION_PARAMETERS
* pParameters
)
281 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
284 if (NULL
== pParameters
)
286 DPRINT1("Invalid pParameters parameter specified");
288 return D3DERR_INVALIDCALL
;
291 pParameters
->AdapterOrdinal
= This
->AdapterIndexInGroup
[0];
292 pParameters
->DeviceType
= This
->DeviceType
;
293 pParameters
->hFocusWindow
= This
->hWnd
;
294 pParameters
->BehaviorFlags
= This
->BehaviourFlags
;
300 HRESULT WINAPI
IDirect3DDevice9Base_SetCursorProperties(LPDIRECT3DDEVICE9 iface
, UINT XHotSpot
, UINT YHotSpot
, IDirect3DSurface9
* pCursorBitmap
)
307 VOID WINAPI
IDirect3DDevice9Base_SetCursorPosition(LPDIRECT3DDEVICE9 iface
, int X
, int Y
, DWORD Flags
)
312 BOOL WINAPI
IDirect3DDevice9Base_ShowCursor(LPDIRECT3DDEVICE9 iface
, BOOL bShow
)
319 HRESULT WINAPI
IDirect3DDevice9Base_CreateAdditionalSwapChain(LPDIRECT3DDEVICE9 iface
, D3DPRESENT_PARAMETERS
* pPresentationParameters
, IDirect3DSwapChain9
** ppSwapChain
)
327 * @name IDirect3DDevice9::GetSwapChain
330 * The function IDirect3DDevice9Base_GetSwapChain returns a pointer to a swap chain object.
332 * @param LPDIRECT3D iface
333 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice()
335 * @param UINT iSwapChain
336 * Swap chain index to get object for.
337 * The maximum value for this is the value returned by IDirect3DDevice9::GetNumberOfSwapChains() - 1.
339 * @param IDirect3DSwapChain9** ppSwapChain
340 * Pointer to a IDirect3DSwapChain9* to receive the swap chain object pointer.
343 * If the method successfully fills the ppSwapChain structure, the return value is D3D_OK.
344 * If iSwapChain is out of range or ppSwapChain is a bad pointer, the return value
345 * will be D3DERR_INVALIDCALL.
348 HRESULT WINAPI
IDirect3DDevice9Base_GetSwapChain(LPDIRECT3DDEVICE9 iface
, UINT iSwapChain
, IDirect3DSwapChain9
** ppSwapChain
)
350 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
353 if (NULL
== ppSwapChain
)
355 DPRINT1("Invalid ppSwapChain parameter specified");
357 return D3DERR_INVALIDCALL
;
362 if (iSwapChain
>= IDirect3DDevice9_GetNumberOfSwapChains(iface
))
364 DPRINT1("Invalid iSwapChain parameter specified");
366 return D3DERR_INVALIDCALL
;
369 if (This
->pSwapChains
[iSwapChain
] != NULL
)
371 IDirect3DSwapChain9
* pSwapChain
= (IDirect3DSwapChain9
*)&This
->pSwapChains
[iSwapChain
]->lpVtbl
;
372 IDirect3DSwapChain9_AddRef(pSwapChain
);
373 *ppSwapChain
= pSwapChain
;
385 * @name IDirect3DDevice9::GetNumberOfSwapChains
388 * The function IDirect3DDevice9Base_GetNumberOfSwapChains returns the number of swap chains
389 * created by IDirect3D9::CreateDevice().
391 * @param LPDIRECT3D iface
392 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice().
395 * Returns the number of swap chains created by IDirect3D9::CreateDevice().
397 * NOTE: An application can create additional swap chains using the
398 * IDirect3DDevice9::CreateAdditionalSwapChain() method.
401 UINT WINAPI
IDirect3DDevice9Base_GetNumberOfSwapChains(LPDIRECT3DDEVICE9 iface
)
405 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
408 NumSwapChains
= This
->NumAdaptersInDevice
;
411 return NumSwapChains
;
414 HRESULT WINAPI
IDirect3DDevice9Base_Reset(LPDIRECT3DDEVICE9 iface
, D3DPRESENT_PARAMETERS
* pPresentationParameters
)
421 HRESULT WINAPI
IDirect3DDevice9Base_Present(LPDIRECT3DDEVICE9 iface
, CONST RECT
* pSourceRect
, CONST RECT
* pDestRect
, HWND hDestWindowOverride
, CONST RGNDATA
* pDirtyRegion
)
428 HRESULT WINAPI
IDirect3DDevice9Base_GetBackBuffer(LPDIRECT3DDEVICE9 iface
, UINT iSwapChain
, UINT iBackBuffer
, D3DBACKBUFFER_TYPE Type
, IDirect3DSurface9
** ppBackBuffer
)
435 HRESULT WINAPI
IDirect3DDevice9Base_GetRasterStatus(LPDIRECT3DDEVICE9 iface
, UINT iSwapChain
, D3DRASTER_STATUS
* pRasterStatus
)
442 HRESULT WINAPI
IDirect3DDevice9Base_SetDialogBoxMode(LPDIRECT3DDEVICE9 iface
, BOOL bEnableDialogs
)
449 VOID WINAPI
IDirect3DDevice9Base_SetGammaRamp(LPDIRECT3DDEVICE9 iface
, UINT iSwapChain
, DWORD Flags
, CONST D3DGAMMARAMP
* pRamp
)
454 VOID WINAPI
IDirect3DDevice9Base_GetGammaRamp(LPDIRECT3DDEVICE9 iface
, UINT iSwapChain
, D3DGAMMARAMP
* pRamp
)
460 * @name IDirect3DDevice9::CreateTexture
463 * The function IDirect3DDevice9Base_CreateTexture creates a D3D9 texture.
465 * @param LPDIRECT3D iface
466 * Pointer to the IDirect3DDevice9 object returned from IDirect3D9::CreateDevice()
469 * Desired width of the texture
472 * Desired height of the texture
475 * Number of mip-maps. If Levels are zero, mip-maps down to size 1x1 will be generated.
478 * Valid combinations of the D3DUSAGE constants.
480 * @param D3DFORMAT Format
481 * One of the D3DFORMAT enum members for the surface format.
483 * @param D3DPOOL Pool
484 * One of the D3DPOOL enum members for where the texture should be placed.
486 * @param IDirect3DTexture9** ppTexture
487 * Return parameter for the created texture
489 * @param HANDLE* pSharedHandle
490 * Set to NULL, shared resources are not implemented yet
493 * Returns D3D_OK if everything went well.
496 HRESULT WINAPI
IDirect3DDevice9Base_CreateTexture(LPDIRECT3DDEVICE9 iface
, UINT Width
, UINT Height
, UINT Levels
, DWORD Usage
, D3DFORMAT Format
, D3DPOOL Pool
, IDirect3DTexture9
** ppTexture
, HANDLE
* pSharedHandle
)
499 LPDIRECT3DDEVICE9_INT This
= IDirect3DDevice9ToImpl(iface
);
503 return InvalidCall(This
, "Invalid 'this' parameter specified");
505 if (NULL
== ppTexture
)
506 return InvalidCall(This
, "Invalid ppTexture parameter specified");
510 if (D3DFMT_UNKNOWN
== Format
)
511 return InvalidCall(This
, "Invalid Format parameter specified, D3DFMT_UNKNOWN is not a valid Format");
513 if (NULL
!= pSharedHandle
)
516 return InvalidCall(This
, "Invalid pSharedHandle parameter specified, only NULL is supported at the moment");
519 hResult
= CreateD3D9MipMap(This
, Width
, Height
, Levels
, Usage
, Format
, Pool
, ppTexture
);
521 DPRINT1("Failed to create texture");
527 HRESULT WINAPI
IDirect3DDevice9Base_CreateVolumeTexture(LPDIRECT3DDEVICE9 iface
, UINT Width
, UINT Height
, UINT Depth
, UINT Levels
, DWORD Usage
, D3DFORMAT Format
, D3DPOOL Pool
, IDirect3DVolumeTexture9
** ppVolumeTexture
, HANDLE
* pSharedHandle
)
534 HRESULT WINAPI
IDirect3DDevice9Base_CreateCubeTexture(LPDIRECT3DDEVICE9 iface
, UINT EdgeLength
, UINT Levels
, DWORD Usage
, D3DFORMAT Format
, D3DPOOL Pool
, IDirect3DCubeTexture9
** ppCubeTexture
, HANDLE
* pSharedHandle
)
541 HRESULT WINAPI
IDirect3DDevice9Base_CreateVertexBuffer(LPDIRECT3DDEVICE9 iface
, UINT Length
, DWORD Usage
, DWORD FVF
, D3DPOOL Pool
, IDirect3DVertexBuffer9
** ppVertexBuffer
, HANDLE
* pSharedHandle
)
548 HRESULT WINAPI
IDirect3DDevice9Base_CreateIndexBuffer(LPDIRECT3DDEVICE9 iface
, UINT Length
, DWORD Usage
, D3DFORMAT Format
, D3DPOOL Pool
, IDirect3DIndexBuffer9
** ppIndexBuffer
, HANDLE
* pSharedHandle
)
555 HRESULT WINAPI
IDirect3DDevice9Base_CreateRenderTarget(LPDIRECT3DDEVICE9 iface
, UINT Width
, UINT Height
, D3DFORMAT Format
, D3DMULTISAMPLE_TYPE MultiSample
, DWORD MultisampleQuality
, BOOL Lockable
, IDirect3DSurface9
** ppSurface
, HANDLE
* pSharedHandle
)
562 HRESULT WINAPI
IDirect3DDevice9Base_CreateDepthStencilSurface(LPDIRECT3DDEVICE9 iface
, UINT Width
, UINT Height
, D3DFORMAT Format
, D3DMULTISAMPLE_TYPE MultiSample
, DWORD MultisampleQuality
, BOOL Discard
, IDirect3DSurface9
** ppSurface
, HANDLE
* pSharedHandle
)
569 HRESULT WINAPI
IDirect3DDevice9Base_UpdateSurface(LPDIRECT3DDEVICE9 iface
, IDirect3DSurface9
* pSourceSurface
, CONST RECT
* pSourceRect
, IDirect3DSurface9
* pDestinationSurface
, CONST POINT
* pDestPoint
)
576 HRESULT WINAPI
IDirect3DDevice9Base_UpdateTexture(LPDIRECT3DDEVICE9 iface
, IDirect3DBaseTexture9
* pSourceTexture
, IDirect3DBaseTexture9
* pDestinationTexture
)
583 HRESULT WINAPI
IDirect3DDevice9Base_GetRenderTargetData(LPDIRECT3DDEVICE9 iface
, IDirect3DSurface9
* pRenderTarget
, IDirect3DSurface9
* pDestSurface
)
590 HRESULT WINAPI
IDirect3DDevice9Base_GetFrontBufferData(LPDIRECT3DDEVICE9 iface
, UINT iSwapChain
, IDirect3DSurface9
* pDestSurface
)
597 HRESULT WINAPI
IDirect3DDevice9Base_StretchRect(LPDIRECT3DDEVICE9 iface
, IDirect3DSurface9
* pSourceSurface
, CONST RECT
* pSourceRect
, IDirect3DSurface9
* pDestSurface
, CONST RECT
* pDestRect
, D3DTEXTUREFILTERTYPE Filter
)
604 HRESULT WINAPI
IDirect3DDevice9Base_ColorFill(LPDIRECT3DDEVICE9 iface
, IDirect3DSurface9
* pSurface
, CONST RECT
* pRect
, D3DCOLOR color
)
611 HRESULT WINAPI
IDirect3DDevice9Base_CreateOffscreenPlainSurface(LPDIRECT3DDEVICE9 iface
, UINT Width
, UINT Height
, D3DFORMAT Format
, D3DPOOL Pool
, IDirect3DSurface9
** ppSurface
, HANDLE
* pSharedHandle
)
618 /* IDirect3DDevice9 private interface */
619 VOID WINAPI
IDirect3DDevice9Base_Destroy(LPDIRECT3DDEVICE9 iface
)
624 VOID WINAPI
IDirect3DDevice9Base_VirtualDestructor(LPDIRECT3DDEVICE9 iface
)