VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispKmt.cpp@ 43490

Last change on this file since 43490 was 42315, checked in by vboxsync, 13 years ago

wddm/3d: remove debug assertions

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.1 KB
Line 
1/* $Id: VBoxDispKmt.cpp 42315 2012-07-23 05:25:54Z vboxsync $ */
2
3/** @file
4 * VBoxVideo Display D3D User mode dll
5 */
6
7/*
8 * Copyright (C) 2011 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "VBoxDispD3DCmn.h"
20
21#ifndef NT_SUCCESS
22# define NT_SUCCESS(_Status) ((_Status) >= 0)
23#endif
24
25HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks)
26{
27 HRESULT hr = S_OK;
28
29 memset(pCallbacks, 0, sizeof (*pCallbacks));
30
31 pCallbacks->hGdi32 = LoadLibraryW(L"gdi32.dll");
32 if (pCallbacks->hGdi32 != NULL)
33 {
34 bool bSupported = true;
35 bool bSupportedWin8 = true;
36 pCallbacks->pfnD3DKMTOpenAdapterFromHdc = (PFND3DKMT_OPENADAPTERFROMHDC)GetProcAddress(pCallbacks->hGdi32, "D3DKMTOpenAdapterFromHdc");
37 Log((__FUNCTION__"pfnD3DKMTOpenAdapterFromHdc = %p\n", pCallbacks->pfnD3DKMTOpenAdapterFromHdc));
38 bSupported &= !!(pCallbacks->pfnD3DKMTOpenAdapterFromHdc);
39
40 pCallbacks->pfnD3DKMTOpenAdapterFromGdiDisplayName = (PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)GetProcAddress(pCallbacks->hGdi32, "D3DKMTOpenAdapterFromGdiDisplayName");
41 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromGdiDisplayName = %p\n", pCallbacks->pfnD3DKMTOpenAdapterFromGdiDisplayName));
42 bSupported &= !!(pCallbacks->pfnD3DKMTOpenAdapterFromGdiDisplayName);
43
44 pCallbacks->pfnD3DKMTCloseAdapter = (PFND3DKMT_CLOSEADAPTER)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCloseAdapter");
45 Log((__FUNCTION__": pfnD3DKMTCloseAdapter = %p\n", pCallbacks->pfnD3DKMTCloseAdapter));
46 bSupported &= !!(pCallbacks->pfnD3DKMTCloseAdapter);
47
48 pCallbacks->pfnD3DKMTEscape = (PFND3DKMT_ESCAPE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTEscape");
49 Log((__FUNCTION__": pfnD3DKMTEscape = %p\n", pCallbacks->pfnD3DKMTEscape));
50 bSupported &= !!(pCallbacks->pfnD3DKMTEscape);
51
52 pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice");
53 Log((__FUNCTION__": pfnD3DKMTCreateDevice = %p\n", pCallbacks->pfnD3DKMTCreateDevice));
54 bSupported &= !!(pCallbacks->pfnD3DKMTCreateDevice);
55
56 pCallbacks->pfnD3DKMTDestroyDevice = (PFND3DKMT_DESTROYDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTDestroyDevice");
57 Log((__FUNCTION__": pfnD3DKMTDestroyDevice = %p\n", pCallbacks->pfnD3DKMTDestroyDevice));
58 bSupported &= !!(pCallbacks->pfnD3DKMTDestroyDevice);
59
60 pCallbacks->pfnD3DKMTCreateContext = (PFND3DKMT_CREATECONTEXT)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateContext");
61 Log((__FUNCTION__": pfnD3DKMTCreateContext = %p\n", pCallbacks->pfnD3DKMTCreateContext));
62 bSupported &= !!(pCallbacks->pfnD3DKMTCreateContext);
63
64 pCallbacks->pfnD3DKMTDestroyContext = (PFND3DKMT_DESTROYCONTEXT)GetProcAddress(pCallbacks->hGdi32, "D3DKMTDestroyContext");
65 Log((__FUNCTION__": pfnD3DKMTDestroyContext = %p\n", pCallbacks->pfnD3DKMTDestroyContext));
66 bSupported &= !!(pCallbacks->pfnD3DKMTDestroyContext);
67
68 pCallbacks->pfnD3DKMTRender = (PFND3DKMT_RENDER)GetProcAddress(pCallbacks->hGdi32, "D3DKMTRender");
69 Log((__FUNCTION__": pfnD3DKMTRender = %p\n", pCallbacks->pfnD3DKMTRender));
70 bSupported &= !!(pCallbacks->pfnD3DKMTRender);
71
72 pCallbacks->pfnD3DKMTCreateAllocation = (PFND3DKMT_CREATEALLOCATION)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateAllocation");
73 Log((__FUNCTION__": pfnD3DKMTCreateAllocation = %p\n", pCallbacks->pfnD3DKMTCreateAllocation));
74 bSupported &= !!(pCallbacks->pfnD3DKMTCreateAllocation);
75
76 pCallbacks->pfnD3DKMTDestroyAllocation = (PFND3DKMT_DESTROYALLOCATION)GetProcAddress(pCallbacks->hGdi32, "D3DKMTDestroyAllocation");
77 Log((__FUNCTION__": pfnD3DKMTDestroyAllocation = %p\n", pCallbacks->pfnD3DKMTDestroyAllocation));
78 bSupported &= !!(pCallbacks->pfnD3DKMTDestroyAllocation);
79
80 pCallbacks->pfnD3DKMTLock = (PFND3DKMT_LOCK)GetProcAddress(pCallbacks->hGdi32, "D3DKMTLock");
81 Log((__FUNCTION__": pfnD3DKMTLock = %p\n", pCallbacks->pfnD3DKMTLock));
82 bSupported &= !!(pCallbacks->pfnD3DKMTLock);
83
84 pCallbacks->pfnD3DKMTUnlock = (PFND3DKMT_UNLOCK)GetProcAddress(pCallbacks->hGdi32, "D3DKMTUnlock");
85 Log((__FUNCTION__": pfnD3DKMTUnlock = %p\n", pCallbacks->pfnD3DKMTUnlock));
86 bSupported &= !!(pCallbacks->pfnD3DKMTUnlock);
87
88 pCallbacks->pfnD3DKMTEnumAdapters = (PFND3DKMT_ENUMADAPTERS)GetProcAddress(pCallbacks->hGdi32, "D3DKMTEnumAdapters");
89 Log((__FUNCTION__": pfnD3DKMTEnumAdapters = %p\n", pCallbacks->pfnD3DKMTEnumAdapters));
90 /* this present starting win8 release preview only, so keep going if it is not available,
91 * i.e. do not clear the bSupported on its absence */
92 bSupportedWin8 &= !!(pCallbacks->pfnD3DKMTEnumAdapters);
93
94 pCallbacks->pfnD3DKMTOpenAdapterFromLuid = (PFND3DKMT_OPENADAPTERFROMLUID)GetProcAddress(pCallbacks->hGdi32, "D3DKMTOpenAdapterFromLuid");
95 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromLuid = %p\n", pCallbacks->pfnD3DKMTOpenAdapterFromLuid));
96 /* this present starting win8 release preview only, so keep going if it is not available,
97 * i.e. do not clear the bSupported on its absence */
98 bSupportedWin8 &= !!(pCallbacks->pfnD3DKMTOpenAdapterFromLuid);
99
100 /*Assert(bSupported);*/
101 if (bSupported)
102 {
103 if (bSupportedWin8)
104 pCallbacks->enmVersion = VBOXDISPKMT_CALLBACKS_VERSION_WIN8;
105 else
106 pCallbacks->enmVersion = VBOXDISPKMT_CALLBACKS_VERSION_VISTA_WIN7;
107 return S_OK;
108 }
109 else
110 {
111 Log((__FUNCTION__": one of pfnD3DKMT function pointers failed to initialize\n"));
112 hr = E_NOINTERFACE;
113 }
114
115 FreeLibrary(pCallbacks->hGdi32);
116 }
117 else
118 {
119 DWORD winEr = GetLastError();
120 hr = HRESULT_FROM_WIN32(winEr);
121 Assert(0);
122 Assert(hr != S_OK);
123 Assert(hr != S_FALSE);
124 if (hr == S_OK || hr == S_FALSE)
125 hr = E_FAIL;
126 }
127
128 return hr;
129}
130
131HRESULT vboxDispKmtCallbacksTerm(PVBOXDISPKMT_CALLBACKS pCallbacks)
132{
133 FreeLibrary(pCallbacks->hGdi32);
134 return S_OK;
135}
136
137HRESULT vboxDispKmtAdpHdcCreate(HDC *phDc)
138{
139 HRESULT hr = E_FAIL;
140 DISPLAY_DEVICE DDev;
141 memset(&DDev, 0, sizeof (DDev));
142 DDev.cb = sizeof (DDev);
143
144 *phDc = NULL;
145
146 for (int i = 0; ; ++i)
147 {
148 if (EnumDisplayDevices(NULL, /* LPCTSTR lpDevice */ i, /* DWORD iDevNum */
149 &DDev, 0 /* DWORD dwFlags*/))
150 {
151 if (DDev.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
152 {
153 HDC hDc = CreateDC(NULL, DDev.DeviceName, NULL, NULL);
154 if (hDc)
155 {
156 *phDc = hDc;
157 return S_OK;
158 }
159 else
160 {
161 DWORD winEr = GetLastError();
162 Assert(0);
163 hr = HRESULT_FROM_WIN32(winEr);
164 Assert(FAILED(hr));
165 break;
166 }
167 }
168 }
169 else
170 {
171 DWORD winEr = GetLastError();
172// BP_WARN();
173 hr = HRESULT_FROM_WIN32(winEr);
174#ifdef DEBUG_misha
175 Assert(FAILED(hr));
176#endif
177 if (!FAILED(hr))
178 {
179 hr = E_FAIL;
180 }
181 break;
182 }
183 }
184
185 return hr;
186}
187
188static HRESULT vboxDispKmtOpenAdapterViaHdc(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
189{
190 D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = {0};
191 HRESULT hr = vboxDispKmtAdpHdcCreate(&OpenAdapterData.hDc);
192 if (!SUCCEEDED(hr))
193 return hr;
194
195 Assert(OpenAdapterData.hDc);
196 NTSTATUS Status = pCallbacks->pfnD3DKMTOpenAdapterFromHdc(&OpenAdapterData);
197#ifdef DEBUG_misha
198 /* may fail with xpdm driver */
199 Assert(NT_SUCCESS(Status));
200#endif
201 if (NT_SUCCESS(Status))
202 {
203 pAdapter->hAdapter = OpenAdapterData.hAdapter;
204 pAdapter->hDc = OpenAdapterData.hDc;
205 pAdapter->pCallbacks = pCallbacks;
206 memset(&pAdapter->Luid, 0, sizeof (pAdapter->Luid));
207 return S_OK;
208 }
209 else
210 {
211 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromGdiDisplayName failed, Status (0x%x)\n", Status));
212 hr = E_FAIL;
213 }
214
215 DeleteDC(OpenAdapterData.hDc);
216
217 return hr;
218}
219
220static HRESULT vboxDispKmtOpenAdapterViaLuid(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
221{
222 if (pCallbacks->enmVersion < VBOXDISPKMT_CALLBACKS_VERSION_WIN8)
223 return E_NOTIMPL;
224
225 D3DKMT_ENUMADAPTERS EnumAdapters = {0};
226 EnumAdapters.NumAdapters = RT_ELEMENTS(EnumAdapters.Adapters);
227
228 NTSTATUS Status = pCallbacks->pfnD3DKMTEnumAdapters(&EnumAdapters);
229#ifdef DEBUG_misha
230 Assert(!Status);
231#endif
232 if (!NT_SUCCESS(Status))
233 return E_FAIL;
234
235 Assert(EnumAdapters.NumAdapters);
236
237 /* try the same twice: if we fail to open the adapter containing present sources,
238 * try to open any adapter */
239 for (ULONG f = 0; f < 2; ++f)
240 {
241 for (ULONG i = 0; i < EnumAdapters.NumAdapters; ++i)
242 {
243 if (f || EnumAdapters.Adapters[i].NumOfSources)
244 {
245 D3DKMT_OPENADAPTERFROMLUID OpenAdapterData = {0};
246 OpenAdapterData.AdapterLuid = EnumAdapters.Adapters[i].AdapterLuid;
247 Status = pCallbacks->pfnD3DKMTOpenAdapterFromLuid(&OpenAdapterData);
248 #ifdef DEBUG_misha
249 Assert(!Status);
250 #endif
251 if (NT_SUCCESS(Status))
252 {
253 pAdapter->hAdapter = OpenAdapterData.hAdapter;
254 pAdapter->hDc = NULL;
255 pAdapter->Luid = EnumAdapters.Adapters[i].AdapterLuid;
256 pAdapter->pCallbacks = pCallbacks;
257 return S_OK;
258 }
259 }
260 }
261 }
262
263#ifdef DEBUG_misha
264 Assert(0);
265#endif
266 return E_FAIL;
267}
268
269HRESULT vboxDispKmtOpenAdapter(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
270{
271 HRESULT hr = vboxDispKmtOpenAdapterViaHdc(pCallbacks, pAdapter);
272 if (SUCCEEDED(hr))
273 return S_OK;
274
275 hr = vboxDispKmtOpenAdapterViaLuid(pCallbacks, pAdapter);
276 if (SUCCEEDED(hr))
277 return S_OK;
278
279 return hr;
280}
281
282HRESULT vboxDispKmtCloseAdapter(PVBOXDISPKMT_ADAPTER pAdapter)
283{
284 D3DKMT_CLOSEADAPTER ClosaAdapterData = {0};
285 ClosaAdapterData.hAdapter = pAdapter->hAdapter;
286 NTSTATUS Status = pAdapter->pCallbacks->pfnD3DKMTCloseAdapter(&ClosaAdapterData);
287 Assert(!Status);
288 if (!Status)
289 {
290 DeleteDC(pAdapter->hDc);
291 return S_OK;
292 }
293
294 Log((__FUNCTION__": pfnD3DKMTCloseAdapter failed, Status (0x%x)\n", Status));
295
296 return E_FAIL;
297}
298
299HRESULT vboxDispKmtCreateDevice(PVBOXDISPKMT_ADAPTER pAdapter, PVBOXDISPKMT_DEVICE pDevice)
300{
301 D3DKMT_CREATEDEVICE CreateDeviceData = {0};
302 CreateDeviceData.hAdapter = pAdapter->hAdapter;
303 NTSTATUS Status = pAdapter->pCallbacks->pfnD3DKMTCreateDevice(&CreateDeviceData);
304 Assert(!Status);
305 if (!Status)
306 {
307 pDevice->pAdapter = pAdapter;
308 pDevice->hDevice = CreateDeviceData.hDevice;
309 pDevice->pCommandBuffer = CreateDeviceData.pCommandBuffer;
310 pDevice->CommandBufferSize = CreateDeviceData.CommandBufferSize;
311 pDevice->pAllocationList = CreateDeviceData.pAllocationList;
312 pDevice->AllocationListSize = CreateDeviceData.AllocationListSize;
313 pDevice->pPatchLocationList = CreateDeviceData.pPatchLocationList;
314 pDevice->PatchLocationListSize = CreateDeviceData.PatchLocationListSize;
315
316 return S_OK;
317 }
318
319 return E_FAIL;
320}
321
322HRESULT vboxDispKmtDestroyDevice(PVBOXDISPKMT_DEVICE pDevice)
323{
324 D3DKMT_DESTROYDEVICE DestroyDeviceData = {0};
325 DestroyDeviceData.hDevice = pDevice->hDevice;
326 NTSTATUS Status = pDevice->pAdapter->pCallbacks->pfnD3DKMTDestroyDevice(&DestroyDeviceData);
327 Assert(!Status);
328 if (!Status)
329 {
330 return S_OK;
331 }
332 return E_FAIL;
333}
334
335HRESULT vboxDispKmtCreateContext(PVBOXDISPKMT_DEVICE pDevice, PVBOXDISPKMT_CONTEXT pContext,
336 VBOXWDDM_CONTEXT_TYPE enmType,
337 uint32_t crVersionMajor, uint32_t crVersionMinor,
338 HANDLE hEvent, uint64_t u64UmInfo)
339{
340 VBOXWDDM_CREATECONTEXT_INFO Info = {0};
341 Info.u32IfVersion = 9;
342 Info.enmType = enmType;
343 Info.crVersionMajor = crVersionMajor;
344 Info.crVersionMinor = crVersionMinor;
345 Info.hUmEvent = (uint64_t)hEvent;
346 Info.u64UmInfo = u64UmInfo;
347 D3DKMT_CREATECONTEXT ContextData = {0};
348 ContextData.hDevice = pDevice->hDevice;
349 ContextData.NodeOrdinal = VBOXWDDM_NODE_ID_3D_KMT;
350 ContextData.EngineAffinity = VBOXWDDM_ENGINE_ID_3D_KMT;
351 ContextData.pPrivateDriverData = &Info;
352 ContextData.PrivateDriverDataSize = sizeof (Info);
353 ContextData.ClientHint = enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_UHGSMI_GL ? D3DKMT_CLIENTHINT_OPENGL : D3DKMT_CLIENTHINT_DX9;
354 NTSTATUS Status = pDevice->pAdapter->pCallbacks->pfnD3DKMTCreateContext(&ContextData);
355 Assert(!Status);
356 if (!Status)
357 {
358 pContext->pDevice = pDevice;
359 pContext->hContext = ContextData.hContext;
360 pContext->pCommandBuffer = ContextData.pCommandBuffer;
361 pContext->CommandBufferSize = ContextData.CommandBufferSize;
362 pContext->pAllocationList = ContextData.pAllocationList;
363 pContext->AllocationListSize = ContextData.AllocationListSize;
364 pContext->pPatchLocationList = ContextData.pPatchLocationList;
365 pContext->PatchLocationListSize = ContextData.PatchLocationListSize;
366 return S_OK;
367 }
368 return E_FAIL;
369}
370
371HRESULT vboxDispKmtDestroyContext(PVBOXDISPKMT_CONTEXT pContext)
372{
373 D3DKMT_DESTROYCONTEXT DestroyContextData = {0};
374 DestroyContextData.hContext = pContext->hContext;
375 NTSTATUS Status = pContext->pDevice->pAdapter->pCallbacks->pfnD3DKMTDestroyContext(&DestroyContextData);
376 Assert(!Status);
377 if (!Status)
378 return S_OK;
379 return E_FAIL;
380}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette