VirtualBox

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

Last change on this file since 83222 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

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