* Fixed d3d9 critical section not being unlocked in GetAdapterIdentifier
[reactos.git] / reactos / dll / directx / d3d9 / d3d9_impl.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS ReactX
4 * FILE: dll/directx/d3d9/d3d9_impl.c
5 * PURPOSE: IDirect3D9 implementation
6 * PROGRAMERS: Gregor Brunmar <gregor (dot) brunmar (at) home (dot) se>
7 */
8
9 #include "d3d9_common.h"
10 #include <d3d9.h>
11 #include <debug.h>
12 #include "d3d9_helpers.h"
13 #include "adapter.h"
14
15 /* IDirect3D9: IUnknown implementation */
16 static HRESULT WINAPI IDirect3D9Impl_QueryInterface(LPDIRECT3D9 iface, REFIID riid, LPVOID* ppvObject)
17 {
18 LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
19
20 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDirect3D9))
21 {
22 IUnknown_AddRef(iface);
23 *ppvObject = &This->lpVtbl;
24 return S_OK;
25 }
26
27 *ppvObject = NULL;
28 return E_NOINTERFACE;
29 }
30
31 static ULONG WINAPI IDirect3D9Impl_AddRef(LPDIRECT3D9 iface)
32 {
33 LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
34 ULONG ref = InterlockedIncrement(&This->dwRefCnt);
35
36 return ref;
37 }
38
39 static ULONG WINAPI IDirect3D9Impl_Release(LPDIRECT3D9 iface)
40 {
41 LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
42 ULONG ref = InterlockedDecrement(&This->dwRefCnt);
43
44 if (ref == 0)
45 {
46 EnterCriticalSection(&This->d3d9_cs);
47 /* TODO: Free resources here */
48 LeaveCriticalSection(&This->d3d9_cs);
49 AlignedFree(This);
50 }
51
52 return ref;
53 }
54
55 /* IDirect3D9 interface */
56 static HRESULT WINAPI IDirect3D9Impl_RegisterSoftwareDevice(LPDIRECT3D9 iface, void* pInitializeFunction)
57 {
58 UNIMPLEMENTED
59
60 return D3D_OK;
61 }
62
63 /*++
64 * @name IDirect3D9::GetAdapterCount
65 * @implemented
66 *
67 * The function IDirect3D9Impl_GetAdapterCount returns the number of adapters
68 *
69 * @param LPDIRECT3D iface
70 * Pointer to the IDirect3D object returned from Direct3DCreate9()
71 *
72 * @return UINT
73 * The number of display adapters on the system when Direct3DCreate9() was called.
74 *
75 */
76 static UINT WINAPI IDirect3D9Impl_GetAdapterCount(LPDIRECT3D9 iface)
77 {
78 UINT NumDisplayAdapters;
79
80 LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
81 LOCK_D3D9();
82
83 NumDisplayAdapters = This->NumDisplayAdapters;
84
85 UNLOCK_D3D9();
86 return NumDisplayAdapters;
87 }
88
89 /*++
90 * @name IDirect3D9::GetAdapterIdentifier
91 * @implemented
92 *
93 * The function IDirect3D9Impl_GetAdapterIdentifier gathers information about
94 * a specified display adapter and fills the pIdentifier argument with the available information.
95 *
96 * @param LPDIRECT3D iface
97 * Pointer to the IDirect3D object returned from Direct3DCreate9()
98 *
99 * @param UINT Adapter
100 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
101 * The maximum value for this is the value returned by IDirect3D::GetAdapterCount().
102 *
103 * @param DWORD Flags
104 * Ignored at the moment, but the only valid flag is D3DENUM_WHQL_LEVEL
105 *
106 * @param D3DADAPTER_IDENTIFIER9* pIdentifier
107 * Pointer to a D3DADAPTER_IDENTIFIER9 structure to be filled with the available information
108 * about the display adapter.
109 *
110 * @return HRESULT
111 * If the method successfully fills the pIdentified structure, the return value is D3D_OK.
112 * If Adapter is out of range, Flags is invalid or pIdentifier is a bad pointer, the return value
113 * will be D3DERR_INVALIDCALL.
114 *
115 */
116 HRESULT WINAPI IDirect3D9Impl_GetAdapterIdentifier(LPDIRECT3D9 iface, UINT Adapter, DWORD Flags,
117 D3DADAPTER_IDENTIFIER9* pIdentifier)
118 {
119 LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
120 LOCK_D3D9();
121
122 if (Adapter >= This->NumDisplayAdapters)
123 {
124 DPRINT1("Invalid Adapter number specified");
125 UNLOCK_D3D9();
126 return D3DERR_INVALIDCALL;
127 }
128
129 if (Flags & ~D3DENUM_WHQL_LEVEL)
130 {
131 DPRINT1("Invalid Flags specified");
132 UNLOCK_D3D9();
133 return D3DERR_INVALIDCALL;
134 }
135
136 if (IsBadWritePtr(pIdentifier, sizeof(D3DADAPTER_IDENTIFIER9)))
137 {
138 UNLOCK_D3D9();
139 return D3DERR_INVALIDCALL;
140 }
141
142 memset(pIdentifier, 0, sizeof(D3DADAPTER_IDENTIFIER9));
143
144 if (FALSE == GetAdapterInfo(This->DisplayAdapters[Adapter].szDeviceName, pIdentifier))
145 {
146 DPRINT1("Internal error: Couldn't get the adapter info for device (%d): %s", Adapter, This->DisplayAdapters[Adapter].szDeviceName);
147 UNLOCK_D3D9();
148 return D3DERR_INVALIDCALL;
149 }
150
151 UNLOCK_D3D9();
152 return D3D_OK;
153 }
154
155 static UINT WINAPI IDirect3D9Impl_GetAdapterModeCount(LPDIRECT3D9 iface, UINT Adapter, D3DFORMAT Format)
156 {
157 UNIMPLEMENTED
158
159 return D3D_OK;
160 }
161
162 static HRESULT WINAPI IDirect3D9Impl_EnumAdapterModes(LPDIRECT3D9 iface, UINT Adapter, D3DFORMAT Format,
163 UINT Mode, D3DDISPLAYMODE* pMode)
164 {
165 UNIMPLEMENTED
166
167 return D3D_OK;
168 }
169
170 static HRESULT WINAPI IDirect3D9Impl_GetAdapterDisplayMode(LPDIRECT3D9 iface, UINT Adapter, D3DDISPLAYMODE* pMode)
171 {
172 UNIMPLEMENTED
173
174 return D3D_OK;
175 }
176
177 static HRESULT WINAPI IDirect3D9Impl_CheckDeviceType(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE CheckType,
178 D3DFORMAT DisplayFormat, D3DFORMAT BackBufferFormat, BOOL Windowed)
179 {
180 UNIMPLEMENTED
181
182 return D3D_OK;
183 }
184
185 static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormat(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType,
186 D3DFORMAT AdapterFormat, DWORD Usage, D3DRESOURCETYPE RType,
187 D3DFORMAT CheckFormat)
188 {
189 UNIMPLEMENTED
190
191 return D3D_OK;
192 }
193
194 static HRESULT WINAPI IDirect3D9Impl_CheckDeviceMultiSampleType(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType,
195 D3DFORMAT SurfaceFormat, BOOL Windowed,
196 D3DMULTISAMPLE_TYPE MultiSampleType, DWORD* pQualityLevels)
197 {
198 UNIMPLEMENTED
199
200 return D3D_OK;
201 }
202
203 static HRESULT WINAPI IDirect3D9Impl_CheckDepthStencilMatch(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType,
204 D3DFORMAT AdapterFormat, D3DFORMAT RenderTargetFormat,
205 D3DFORMAT DepthStencilFormat)
206 {
207 UNIMPLEMENTED
208
209 return D3D_OK;
210 }
211
212 static HRESULT WINAPI IDirect3D9Impl_CheckDeviceFormatConversion(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType,
213 D3DFORMAT SourceFormat, D3DFORMAT TargetFormat)
214 {
215 UNIMPLEMENTED
216
217 return D3D_OK;
218 }
219
220 static HRESULT WINAPI IDirect3D9Impl_GetDeviceCaps(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps)
221 {
222 UNIMPLEMENTED
223
224 return D3D_OK;
225 }
226
227 /*++
228 * @name IDirect3D9::GetAdapterMonitor
229 * @implemented
230 *
231 * The function IDirect3D9Impl_GetAdapterMonitor returns the monitor associated
232 * with the specified display adapter.
233 *
234 * @param LPDIRECT3D iface
235 * Pointer to the IDirect3D object returned from Direct3DCreate9()
236 *
237 * @param UINT Adapter
238 * Adapter index to get information about. D3DADAPTER_DEFAULT is the primary display.
239 * The maximum value for this is the value returned by IDirect3D::GetAdapterCount().
240 *
241 * @return HMONITOR
242 * If the method successfully it returns the HMONITOR belonging to the specified adapter.
243 * If the method fails, the return value is NULL.
244 *
245 */
246 static HMONITOR WINAPI IDirect3D9Impl_GetAdapterMonitor(LPDIRECT3D9 iface, UINT Adapter)
247 {
248 HMONITOR hAdapterMonitor = NULL;
249
250 LPDIRECT3D9_INT This = impl_from_IDirect3D9(iface);
251 LOCK_D3D9();
252
253 if (Adapter < This->NumDisplayAdapters)
254 {
255 hAdapterMonitor = GetAdapterMonitor(This->DisplayAdapters[Adapter].szDeviceName);
256 }
257 else
258 {
259 DPRINT1("Invalid Adapter number specified");
260 }
261
262 UNLOCK_D3D9();
263 return hAdapterMonitor;
264 }
265
266 static HRESULT WINAPI IDirect3D9Impl_CreateDevice(LPDIRECT3D9 iface, UINT Adapter, D3DDEVTYPE DeviceType,
267 HWND hFocusWindow, DWORD BehaviourFlags,
268 D3DPRESENT_PARAMETERS* pPresentationParameters,
269 struct IDirect3DDevice9** ppReturnedDeviceInterface)
270 {
271 UNIMPLEMENTED
272
273 return D3D_OK;
274 }
275
276 IDirect3D9Vtbl Direct3D9_Vtbl =
277 {
278 /* IUnknown */
279 IDirect3D9Impl_QueryInterface,
280 IDirect3D9Impl_AddRef,
281 IDirect3D9Impl_Release,
282
283 /* IDirect3D9 */
284 IDirect3D9Impl_RegisterSoftwareDevice,
285 IDirect3D9Impl_GetAdapterCount,
286 IDirect3D9Impl_GetAdapterIdentifier,
287 IDirect3D9Impl_GetAdapterModeCount,
288 IDirect3D9Impl_EnumAdapterModes,
289 IDirect3D9Impl_GetAdapterDisplayMode,
290 IDirect3D9Impl_CheckDeviceType,
291 IDirect3D9Impl_CheckDeviceFormat,
292 IDirect3D9Impl_CheckDeviceMultiSampleType,
293 IDirect3D9Impl_CheckDepthStencilMatch,
294 IDirect3D9Impl_CheckDeviceFormatConversion,
295 IDirect3D9Impl_GetDeviceCaps,
296 IDirect3D9Impl_GetAdapterMonitor,
297 IDirect3D9Impl_CreateDevice
298 };