VirtualBox

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

Last change on this file since 38238 was 37626, checked in by vboxsync, 13 years ago

wddm/3d: fix card resets

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.8 KB
Line 
1/* $Id: VBoxDispKmt.cpp 37626 2011-06-24 12:01:33Z 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
21HRESULT vboxDispKmtCallbacksInit(PVBOXDISPKMT_CALLBACKS pCallbacks)
22{
23 HRESULT hr = S_OK;
24
25 memset(pCallbacks, 0, sizeof (*pCallbacks));
26
27 pCallbacks->hGdi32 = LoadLibraryW(L"gdi32.dll");
28 if (pCallbacks->hGdi32 != NULL)
29 {
30 bool bSupported = true;
31 pCallbacks->pfnD3DKMTOpenAdapterFromHdc = (PFND3DKMT_OPENADAPTERFROMHDC)GetProcAddress(pCallbacks->hGdi32, "D3DKMTOpenAdapterFromHdc");
32 Log((__FUNCTION__"pfnD3DKMTOpenAdapterFromHdc = %p\n", pCallbacks->pfnD3DKMTOpenAdapterFromHdc));
33 bSupported &= !!(pCallbacks->pfnD3DKMTOpenAdapterFromHdc);
34
35 pCallbacks->pfnD3DKMTOpenAdapterFromGdiDisplayName = (PFND3DKMT_OPENADAPTERFROMGDIDISPLAYNAME)GetProcAddress(pCallbacks->hGdi32, "D3DKMTOpenAdapterFromGdiDisplayName");
36 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromGdiDisplayName = %p\n", pCallbacks->pfnD3DKMTOpenAdapterFromGdiDisplayName));
37 bSupported &= !!(pCallbacks->pfnD3DKMTOpenAdapterFromGdiDisplayName);
38
39 pCallbacks->pfnD3DKMTCloseAdapter = (PFND3DKMT_CLOSEADAPTER)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCloseAdapter");
40 Log((__FUNCTION__": pfnD3DKMTCloseAdapter = %p\n", pCallbacks->pfnD3DKMTCloseAdapter));
41 bSupported &= !!(pCallbacks->pfnD3DKMTCloseAdapter);
42
43 pCallbacks->pfnD3DKMTEscape = (PFND3DKMT_ESCAPE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTEscape");
44 Log((__FUNCTION__": pfnD3DKMTEscape = %p\n", pCallbacks->pfnD3DKMTEscape));
45 bSupported &= !!(pCallbacks->pfnD3DKMTEscape);
46
47 pCallbacks->pfnD3DKMTCreateDevice = (PFND3DKMT_CREATEDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateDevice");
48 Log((__FUNCTION__": pfnD3DKMTCreateDevice = %p\n", pCallbacks->pfnD3DKMTCreateDevice));
49 bSupported &= !!(pCallbacks->pfnD3DKMTCreateDevice);
50
51 pCallbacks->pfnD3DKMTDestroyDevice = (PFND3DKMT_DESTROYDEVICE)GetProcAddress(pCallbacks->hGdi32, "D3DKMTDestroyDevice");
52 Log((__FUNCTION__": pfnD3DKMTDestroyDevice = %p\n", pCallbacks->pfnD3DKMTDestroyDevice));
53 bSupported &= !!(pCallbacks->pfnD3DKMTDestroyDevice);
54
55 pCallbacks->pfnD3DKMTCreateContext = (PFND3DKMT_CREATECONTEXT)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateContext");
56 Log((__FUNCTION__": pfnD3DKMTCreateContext = %p\n", pCallbacks->pfnD3DKMTCreateContext));
57 bSupported &= !!(pCallbacks->pfnD3DKMTCreateContext);
58
59 pCallbacks->pfnD3DKMTDestroyContext = (PFND3DKMT_DESTROYCONTEXT)GetProcAddress(pCallbacks->hGdi32, "D3DKMTDestroyContext");
60 Log((__FUNCTION__": pfnD3DKMTDestroyContext = %p\n", pCallbacks->pfnD3DKMTDestroyContext));
61 bSupported &= !!(pCallbacks->pfnD3DKMTDestroyContext);
62
63 pCallbacks->pfnD3DKMTRender = (PFND3DKMT_RENDER)GetProcAddress(pCallbacks->hGdi32, "D3DKMTRender");
64 Log((__FUNCTION__": pfnD3DKMTRender = %p\n", pCallbacks->pfnD3DKMTRender));
65 bSupported &= !!(pCallbacks->pfnD3DKMTRender);
66
67 pCallbacks->pfnD3DKMTCreateAllocation = (PFND3DKMT_CREATEALLOCATION)GetProcAddress(pCallbacks->hGdi32, "D3DKMTCreateAllocation");
68 Log((__FUNCTION__": pfnD3DKMTCreateAllocation = %p\n", pCallbacks->pfnD3DKMTCreateAllocation));
69 bSupported &= !!(pCallbacks->pfnD3DKMTCreateAllocation);
70
71 pCallbacks->pfnD3DKMTDestroyAllocation = (PFND3DKMT_DESTROYALLOCATION)GetProcAddress(pCallbacks->hGdi32, "D3DKMTDestroyAllocation");
72 Log((__FUNCTION__": pfnD3DKMTDestroyAllocation = %p\n", pCallbacks->pfnD3DKMTDestroyAllocation));
73 bSupported &= !!(pCallbacks->pfnD3DKMTDestroyAllocation);
74
75 pCallbacks->pfnD3DKMTLock = (PFND3DKMT_LOCK)GetProcAddress(pCallbacks->hGdi32, "D3DKMTLock");
76 Log((__FUNCTION__": pfnD3DKMTLock = %p\n", pCallbacks->pfnD3DKMTLock));
77 bSupported &= !!(pCallbacks->pfnD3DKMTLock);
78
79 pCallbacks->pfnD3DKMTUnlock = (PFND3DKMT_UNLOCK)GetProcAddress(pCallbacks->hGdi32, "D3DKMTUnlock");
80 Log((__FUNCTION__": pfnD3DKMTUnlock = %p\n", pCallbacks->pfnD3DKMTUnlock));
81 bSupported &= !!(pCallbacks->pfnD3DKMTUnlock);
82
83 /*Assert(bSupported);*/
84 if (bSupported)
85 {
86 return S_OK;
87 }
88 else
89 {
90 Log((__FUNCTION__": one of pfnD3DKMT function pointers failed to initialize\n"));
91 hr = E_NOINTERFACE;
92 }
93
94 FreeLibrary(pCallbacks->hGdi32);
95 }
96 else
97 {
98 DWORD winEr = GetLastError();
99 hr = HRESULT_FROM_WIN32(winEr);
100 Assert(0);
101 Assert(hr != S_OK);
102 Assert(hr != S_FALSE);
103 if (hr == S_OK || hr == S_FALSE)
104 hr = E_FAIL;
105 }
106
107 return hr;
108}
109
110HRESULT vboxDispKmtCallbacksTerm(PVBOXDISPKMT_CALLBACKS pCallbacks)
111{
112 FreeLibrary(pCallbacks->hGdi32);
113 return S_OK;
114}
115
116HRESULT vboxDispKmtAdpHdcCreate(HDC *phDc)
117{
118 HRESULT hr = E_FAIL;
119 DISPLAY_DEVICE DDev;
120 memset(&DDev, 0, sizeof (DDev));
121 DDev.cb = sizeof (DDev);
122
123 *phDc = NULL;
124
125 for (int i = 0; ; ++i)
126 {
127 if (EnumDisplayDevices(NULL, /* LPCTSTR lpDevice */ i, /* DWORD iDevNum */
128 &DDev, 0 /* DWORD dwFlags*/))
129 {
130 if (DDev.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
131 {
132 HDC hDc = CreateDC(NULL, DDev.DeviceName, NULL, NULL);
133 if (hDc)
134 {
135 *phDc = hDc;
136 return S_OK;
137 }
138 else
139 {
140 DWORD winEr = GetLastError();
141 Assert(0);
142 hr = HRESULT_FROM_WIN32(winEr);
143 Assert(FAILED(hr));
144 break;
145 }
146 }
147 }
148 else
149 {
150 DWORD winEr = GetLastError();
151 WARN_BREAK();
152 hr = HRESULT_FROM_WIN32(winEr);
153#ifdef DEBUG_misha
154 Assert(FAILED(hr));
155#endif
156 if (!FAILED(hr))
157 {
158 hr = E_FAIL;
159 }
160 break;
161 }
162 }
163
164 return hr;
165}
166
167HRESULT vboxDispKmtOpenAdapter(PVBOXDISPKMT_CALLBACKS pCallbacks, PVBOXDISPKMT_ADAPTER pAdapter)
168{
169 D3DKMT_OPENADAPTERFROMHDC OpenAdapterData = {0};
170 HRESULT hr = vboxDispKmtAdpHdcCreate(&OpenAdapterData.hDc);
171 if (hr == S_OK)
172 {
173 Assert(OpenAdapterData.hDc);
174 NTSTATUS Status = pCallbacks->pfnD3DKMTOpenAdapterFromHdc(&OpenAdapterData);
175#ifdef DEBUG_misha
176 /* may fail with xpdm driver */
177 Assert(!Status);
178#endif
179 if (!Status)
180 {
181 pAdapter->hAdapter = OpenAdapterData.hAdapter;
182 pAdapter->hDc = OpenAdapterData.hDc;
183 pAdapter->pCallbacks = pCallbacks;
184 return S_OK;
185 }
186 else
187 {
188 Log((__FUNCTION__": pfnD3DKMTOpenAdapterFromGdiDisplayName failed, Status (0x%x)\n", Status));
189 hr = E_FAIL;
190 }
191
192 DeleteDC(OpenAdapterData.hDc);
193 }
194
195 return hr;
196}
197
198HRESULT vboxDispKmtCloseAdapter(PVBOXDISPKMT_ADAPTER pAdapter)
199{
200 D3DKMT_CLOSEADAPTER ClosaAdapterData = {0};
201 ClosaAdapterData.hAdapter = pAdapter->hAdapter;
202 NTSTATUS Status = pAdapter->pCallbacks->pfnD3DKMTCloseAdapter(&ClosaAdapterData);
203 Assert(!Status);
204 if (!Status)
205 {
206 DeleteDC(pAdapter->hDc);
207 return S_OK;
208 }
209
210 Log((__FUNCTION__": pfnD3DKMTCloseAdapter failed, Status (0x%x)\n", Status));
211
212 return E_FAIL;
213}
214
215HRESULT vboxDispKmtCreateDevice(PVBOXDISPKMT_ADAPTER pAdapter, PVBOXDISPKMT_DEVICE pDevice)
216{
217 D3DKMT_CREATEDEVICE CreateDeviceData = {0};
218 CreateDeviceData.hAdapter = pAdapter->hAdapter;
219 NTSTATUS Status = pAdapter->pCallbacks->pfnD3DKMTCreateDevice(&CreateDeviceData);
220 Assert(!Status);
221 if (!Status)
222 {
223 pDevice->pAdapter = pAdapter;
224 pDevice->hDevice = CreateDeviceData.hDevice;
225 pDevice->pCommandBuffer = CreateDeviceData.pCommandBuffer;
226 pDevice->CommandBufferSize = CreateDeviceData.CommandBufferSize;
227 pDevice->pAllocationList = CreateDeviceData.pAllocationList;
228 pDevice->AllocationListSize = CreateDeviceData.AllocationListSize;
229 pDevice->pPatchLocationList = CreateDeviceData.pPatchLocationList;
230 pDevice->PatchLocationListSize = CreateDeviceData.PatchLocationListSize;
231
232 return S_OK;
233 }
234
235 return E_FAIL;
236}
237
238HRESULT vboxDispKmtDestroyDevice(PVBOXDISPKMT_DEVICE pDevice)
239{
240 D3DKMT_DESTROYDEVICE DestroyDeviceData = {0};
241 DestroyDeviceData.hDevice = pDevice->hDevice;
242 NTSTATUS Status = pDevice->pAdapter->pCallbacks->pfnD3DKMTDestroyDevice(&DestroyDeviceData);
243 Assert(!Status);
244 if (!Status)
245 {
246 return S_OK;
247 }
248 return E_FAIL;
249}
250
251HRESULT vboxDispKmtCreateContext(PVBOXDISPKMT_DEVICE pDevice, PVBOXDISPKMT_CONTEXT pContext,
252 VBOXWDDM_CONTEXT_TYPE enmType, HANDLE hEvent, uint64_t u64UmInfo)
253{
254 VBOXWDDM_CREATECONTEXT_INFO Info = {0};
255 Info.u32IfVersion = 9;
256 Info.enmType = enmType;
257 Info.hUmEvent = (uint64_t)hEvent;
258 Info.u64UmInfo = u64UmInfo;
259 D3DKMT_CREATECONTEXT ContextData = {0};
260 ContextData.hDevice = pDevice->hDevice;
261 ContextData.NodeOrdinal = VBOXWDDM_NODE_ID_3D_KMT;
262 ContextData.EngineAffinity = VBOXWDDM_ENGINE_ID_3D_KMT;
263 ContextData.pPrivateDriverData = &Info;
264 ContextData.PrivateDriverDataSize = sizeof (Info);
265 ContextData.ClientHint = enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_UHGSMI_GL ? D3DKMT_CLIENTHINT_OPENGL : D3DKMT_CLIENTHINT_DX9;
266 NTSTATUS Status = pDevice->pAdapter->pCallbacks->pfnD3DKMTCreateContext(&ContextData);
267 Assert(!Status);
268 if (!Status)
269 {
270 pContext->pDevice = pDevice;
271 pContext->hContext = ContextData.hContext;
272 pContext->pCommandBuffer = ContextData.pCommandBuffer;
273 pContext->CommandBufferSize = ContextData.CommandBufferSize;
274 pContext->pAllocationList = ContextData.pAllocationList;
275 pContext->AllocationListSize = ContextData.AllocationListSize;
276 pContext->pPatchLocationList = ContextData.pPatchLocationList;
277 pContext->PatchLocationListSize = ContextData.PatchLocationListSize;
278 return S_OK;
279 }
280 return E_FAIL;
281}
282
283HRESULT vboxDispKmtDestroyContext(PVBOXDISPKMT_CONTEXT pContext)
284{
285 D3DKMT_DESTROYCONTEXT DestroyContextData = {0};
286 DestroyContextData.hContext = pContext->hContext;
287 NTSTATUS Status = pContext->pDevice->pAdapter->pCallbacks->pfnD3DKMTDestroyContext(&DestroyContextData);
288 Assert(!Status);
289 if (!Status)
290 return S_OK;
291 return E_FAIL;
292}
Note: See TracBrowser for help on using the repository browser.

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