VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/wddm/VBoxDispD3D.cpp

Last change on this file was 106582, checked in by vboxsync, 5 weeks ago

Add/Nt/Graphics: Windows 10 WDK 26100 build fixes (we're getting into harmless trouble with psapi.h because we're mixing this with the W7/WLH DDK). jiraref:VBP-1171

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1/* $Id: VBoxDispD3D.cpp 106582 2024-10-22 22:00:15Z vboxsync $ */
2/** @file
3 * VBoxVideo Display D3D User mode dll
4 */
5
6/*
7 * Copyright (C) 2011-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#define INITGUID
29
30#include <iprt/initterm.h>
31#include <iprt/log.h>
32#include <iprt/mem.h>
33
34#include <VBox/Log.h>
35
36#include <VBox/VBoxGuestLib.h>
37
38#include "VBoxDispD3D.h"
39#include "VBoxDispDbg.h"
40
41#include <iprt/win/psapi.h>
42
43#define VBOXDISP_IS_MODULE_FUNC(_pvModule, _cbModule, _pfn) ( \
44 (((uintptr_t)(_pfn)) >= ((uintptr_t)(_pvModule))) \
45 && (((uintptr_t)(_pfn)) < (((uintptr_t)(_pvModule)) + ((DWORD)(_cbModule)))) \
46 )
47
48static BOOL vboxDispIsDDraw(D3DDDIARG_OPENADAPTER const *pOpenData)
49{
50 /*if we are loaded by ddraw module, the Interface version should be 7
51 * and pAdapterCallbacks should be ddraw-supplied, i.e. reside in ddraw module */
52 if (pOpenData->Interface != 7)
53 return FALSE;
54
55 HMODULE hDDraw = GetModuleHandleA("ddraw.dll");
56 if (!hDDraw)
57 return FALSE;
58
59 HANDLE hProcess = GetCurrentProcess();
60 MODULEINFO ModuleInfo = {0};
61
62 if (!GetModuleInformation(hProcess, hDDraw, &ModuleInfo, sizeof (ModuleInfo)))
63 {
64 DWORD winEr = GetLastError(); NOREF(winEr);
65 WARN(("GetModuleInformation failed, %d", winEr));
66 return FALSE;
67 }
68
69 if (VBOXDISP_IS_MODULE_FUNC(ModuleInfo.lpBaseOfDll, ModuleInfo.SizeOfImage,
70 pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb))
71 return TRUE;
72 if (VBOXDISP_IS_MODULE_FUNC(ModuleInfo.lpBaseOfDll, ModuleInfo.SizeOfImage,
73 pOpenData->pAdapterCallbacks->pfnGetMultisampleMethodListCb))
74 return TRUE;
75
76 return FALSE;
77}
78
79static HRESULT vboxDispQueryAdapterInfo(D3DDDIARG_OPENADAPTER const *pOpenData, VBOXWDDM_QAI **ppAdapterInfo)
80{
81 VBOXWDDM_QAI *pAdapterInfo = (VBOXWDDM_QAI *)RTMemAllocZ(sizeof(VBOXWDDM_QAI));
82 AssertReturn(pAdapterInfo, E_OUTOFMEMORY);
83
84 D3DDDICB_QUERYADAPTERINFO DdiQuery;
85 DdiQuery.PrivateDriverDataSize = sizeof(VBOXWDDM_QAI);
86 DdiQuery.pPrivateDriverData = pAdapterInfo;
87 HRESULT hr = pOpenData->pAdapterCallbacks->pfnQueryAdapterInfoCb(pOpenData->hAdapter, &DdiQuery);
88 AssertReturnStmt(SUCCEEDED(hr), RTMemFree(pAdapterInfo), hr);
89
90 /* Check that the miniport version match display version. */
91 if (pAdapterInfo->u32Version == VBOXVIDEOIF_VERSION)
92 {
93 *ppAdapterInfo = pAdapterInfo;
94 }
95 else
96 {
97 LOGREL_EXACT((__FUNCTION__": miniport version mismatch, expected (%d), but was (%d)\n",
98 VBOXVIDEOIF_VERSION, pAdapterInfo->u32Version));
99 hr = E_FAIL;
100 }
101
102 return hr;
103}
104
105static HRESULT vboxDispAdapterInit(D3DDDIARG_OPENADAPTER const *pOpenData, VBOXWDDM_QAI *pAdapterInfo,
106 PVBOXWDDMDISP_ADAPTER *ppAdapter)
107{
108#ifdef VBOX_WITH_VIDEOHWACCEL
109 Assert(pAdapterInfo->cInfos >= 1);
110 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(RT_UOFFSETOF_DYN(VBOXWDDMDISP_ADAPTER,
111 aHeads[pAdapterInfo->cInfos]));
112#else
113 Assert(pAdapterInfo->cInfos == 0);
114 PVBOXWDDMDISP_ADAPTER pAdapter = (PVBOXWDDMDISP_ADAPTER)RTMemAllocZ(sizeof(VBOXWDDMDISP_ADAPTER));
115#endif
116 AssertReturn(pAdapter, E_OUTOFMEMORY);
117
118 pAdapter->hAdapter = pOpenData->hAdapter;
119 pAdapter->uIfVersion = pOpenData->Interface;
120 pAdapter->uRtVersion = pOpenData->Version;
121 pAdapter->RtCallbacks = *pOpenData->pAdapterCallbacks;
122 pAdapter->enmHwType = pAdapterInfo->enmHwType;
123 if (pAdapter->enmHwType == VBOXVIDEO_HWTYPE_VBOX)
124 pAdapter->u32VBox3DCaps = pAdapterInfo->u.vbox.u32VBox3DCaps;
125 pAdapter->AdapterInfo = *pAdapterInfo;
126 pAdapter->f3D = RT_BOOL(pAdapterInfo->u32AdapterCaps & VBOXWDDM_QAI_CAP_3D)
127 && !vboxDispIsDDraw(pOpenData);
128#ifdef VBOX_WITH_VIDEOHWACCEL
129 pAdapter->cHeads = pAdapterInfo->cInfos;
130 for (uint32_t i = 0; i < pAdapter->cHeads; ++i)
131 pAdapter->aHeads[i].Vhwa.Settings = pAdapterInfo->aInfos[i];
132#endif
133
134 *ppAdapter = pAdapter;
135 return S_OK;
136}
137
138HRESULT APIENTRY OpenAdapter(__inout D3DDDIARG_OPENADAPTER *pOpenData)
139{
140 LOG_EXACT(("==> "__FUNCTION__"\n"));
141
142 LOGREL(("Built %s %s", __DATE__, __TIME__));
143
144 VBOXWDDM_QAI *pAdapterInfo = NULL;
145 PVBOXWDDMDISP_ADAPTER pAdapter = NULL;
146
147 /* Query the miniport about virtual hardware capabilities. */
148 HRESULT hr = vboxDispQueryAdapterInfo(pOpenData, &pAdapterInfo);
149 if (SUCCEEDED(hr))
150 {
151 hr = vboxDispAdapterInit(pOpenData, pAdapterInfo, &pAdapter);
152 if (SUCCEEDED(hr))
153 {
154 if (pAdapter->f3D)
155 {
156 /* 3D adapter. Try enable the 3D. */
157 hr = VBoxDispD3DGlobalOpen(&pAdapter->D3D, &pAdapter->Formats, &pAdapter->AdapterInfo);
158 if (hr == S_OK)
159 {
160 LOG(("SUCCESS 3D Enabled, pAdapter (0x%p)", pAdapter));
161 }
162 else
163 WARN(("VBoxDispD3DOpen failed, hr (%d)", hr));
164 }
165#ifdef VBOX_WITH_VIDEOHWACCEL
166 else
167 {
168 /* 2D adapter. */
169 hr = VBoxDispD3DGlobal2DFormatsInit(pAdapter);
170 if (FAILED(hr))
171 WARN(("VBoxDispD3DGlobal2DFormatsInit failed hr 0x%x", hr));
172 }
173#endif
174 }
175 }
176
177 if (SUCCEEDED(hr))
178 {
179 /* Return data to the OS. */
180 if (pAdapter->enmHwType == VBOXVIDEO_HWTYPE_VBOX)
181 {
182 /* Not supposed to work with this. */
183 hr = E_FAIL;
184 }
185#ifdef VBOX_WITH_MESA3D
186 else if (pAdapter->enmHwType == VBOXVIDEO_HWTYPE_VMSVGA)
187 {
188 pOpenData->hAdapter = pAdapter;
189 pOpenData->pAdapterFuncs->pfnGetCaps = GaDdiAdapterGetCaps;
190 pOpenData->pAdapterFuncs->pfnCreateDevice = GaDdiAdapterCreateDevice;
191 pOpenData->pAdapterFuncs->pfnCloseAdapter = GaDdiAdapterCloseAdapter;
192 pOpenData->DriverVersion = RT_BOOL(pAdapterInfo->u32AdapterCaps & VBOXWDDM_QAI_CAP_WIN7)
193 ? D3D_UMD_INTERFACE_VERSION_WIN7
194 : D3D_UMD_INTERFACE_VERSION_VISTA;
195 }
196#endif
197 else
198 hr = E_FAIL;
199 }
200
201 if (FAILED(hr))
202 {
203 WARN(("OpenAdapter failed hr 0x%x", hr));
204 RTMemFree(pAdapter);
205 }
206
207 RTMemFree(pAdapterInfo);
208
209 LOG_EXACT(("<== "__FUNCTION__", hr (%x)\n", hr));
210 return hr;
211}
212
213
214/**
215 * DLL entry point.
216 */
217BOOL WINAPI DllMain(HINSTANCE hInstance,
218 DWORD dwReason,
219 LPVOID lpReserved)
220{
221 RT_NOREF(hInstance, lpReserved);
222
223 switch (dwReason)
224 {
225 case DLL_PROCESS_ATTACH:
226 {
227 vboxVDbgPrint(("VBoxDispD3D: DLL loaded.\n"));
228#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
229 vboxVDbgVEHandlerRegister();
230#endif
231 int rc = RTR3InitDll(RTR3INIT_FLAGS_UNOBTRUSIVE);
232 AssertRC(rc);
233 if (RT_SUCCESS(rc))
234 {
235 VBoxDispD3DGlobalInit();
236 vboxVDbgPrint(("VBoxDispD3D: DLL loaded OK\n"));
237 return TRUE;
238 }
239
240#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
241 vboxVDbgVEHandlerUnregister();
242#endif
243 break;
244 }
245
246 case DLL_PROCESS_DETACH:
247 {
248#ifdef VBOXWDDMDISP_DEBUG_VEHANDLER
249 vboxVDbgVEHandlerUnregister();
250#endif
251 /// @todo RTR3Term();
252 VBoxDispD3DGlobalTerm();
253 return TRUE;
254
255 break;
256 }
257
258 default:
259 return TRUE;
260 }
261 return FALSE;
262}
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