VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPHGSMI.cpp@ 100010

Last change on this file since 100010 was 98103, checked in by vboxsync, 2 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: 11.9 KB
Line 
1/* $Id: VBoxMPHGSMI.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox Miniport HGSMI related functions
4 */
5
6/*
7 * Copyright (C) 2011-2023 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#include "VBoxMPHGSMI.h"
29#include "VBoxMPCommon.h"
30#include <iprt/alloc.h>
31
32static DECLCALLBACK(void *) hgsmiEnvAlloc(void *pvEnv, HGSMISIZE cb)
33{
34 NOREF(pvEnv);
35 return RTMemAlloc(cb);
36}
37
38static DECLCALLBACK(void) hgsmiEnvFree(void *pvEnv, void *pv)
39{
40 NOREF(pvEnv);
41 RTMemFree(pv);
42}
43
44static HGSMIENV g_hgsmiEnvMP =
45{
46 NULL,
47 hgsmiEnvAlloc,
48 hgsmiEnvFree
49};
50
51/**
52 * Helper function to register secondary displays (DualView).
53 *
54 * Note that this will not be available on pre-XP versions, and some editions on
55 * XP will fail because they are intentionally crippled.
56 *
57 * HGSMI variant is a bit different because it uses only HGSMI interface (VBVA channel)
58 * to talk to the host.
59 */
60void VBoxSetupDisplaysHGSMI(PVBOXMP_COMMON pCommon, PHYSICAL_ADDRESS phVRAM, uint32_t ulApertureSize,
61 uint32_t cbVRAM, uint32_t fCaps)
62{
63 /** @todo I simply converted this from Windows error codes. That is wrong,
64 * but we currently freely mix and match those (failure == rc > 0) and iprt
65 * ones (failure == rc < 0) anyway. This needs to be fully reviewed and
66 * fixed. */
67 LOGF_ENTER();
68
69 memset(pCommon, 0, sizeof(*pCommon));
70 pCommon->phVRAM = phVRAM;
71 pCommon->ulApertureSize = ulApertureSize;
72 pCommon->cbVRAM = cbVRAM;
73 pCommon->cDisplays = 1;
74 pCommon->bHGSMI = VBoxHGSMIIsSupported();
75
76#if 1 /* Style that works for MSC and is easier to read. */
77
78 if (pCommon->bHGSMI)
79 {
80 uint32_t offVRAMBaseMapping, cbMapping, offGuestHeapMemory, cbGuestHeapMemory, offHostFlags;
81 VBoxHGSMIGetBaseMappingInfo(pCommon->cbVRAM, &offVRAMBaseMapping,
82 &cbMapping, &offGuestHeapMemory,
83 &cbGuestHeapMemory, &offHostFlags);
84
85 /* Map the adapter information. It will be needed for HGSMI IO. */
86 int rc = VBoxMPCmnMapAdapterMemory(pCommon, &pCommon->pvAdapterInformation, offVRAMBaseMapping, cbMapping);
87 if (RT_SUCCESS(rc))
88 {
89 /* Setup an HGSMI heap within the adapter information area. */
90 rc = VBoxHGSMISetupGuestContext(&pCommon->guestCtx,
91 pCommon->pvAdapterInformation,
92 cbGuestHeapMemory,
93 offVRAMBaseMapping
94 + offGuestHeapMemory,
95 &g_hgsmiEnvMP);
96 if (RT_SUCCESS(rc))
97 {
98 if (pCommon->bHGSMI) /* Paranoia caused by the structure of the original code, probably unnecessary. */
99 {
100 /* Setup the host heap and the adapter memory. */
101 uint32_t offVRAMHostArea, cbHostArea;
102 VBoxHGSMIGetHostAreaMapping(&pCommon->guestCtx, pCommon->cbVRAM,
103 offVRAMBaseMapping, &offVRAMHostArea,
104 &cbHostArea);
105 if (cbHostArea)
106 {
107 /* Map the heap region.
108 *
109 * Note: the heap will be used for the host buffers submitted to the guest.
110 * The miniport driver is responsible for reading FIFO and notifying
111 * display drivers.
112 */
113 pCommon->cbMiniportHeap = cbHostArea;
114 rc = VBoxMPCmnMapAdapterMemory(pCommon, &pCommon->pvMiniportHeap, offVRAMHostArea, cbHostArea);
115 if (RT_SUCCESS(rc))
116 {
117 VBoxHGSMISetupHostContext(&pCommon->hostCtx,
118 pCommon->pvAdapterInformation,
119 offHostFlags,
120 pCommon->pvMiniportHeap,
121 offVRAMHostArea, cbHostArea);
122
123 if (pCommon->bHGSMI) /* Paranoia caused by the structure of the original code, probably unnecessary. */
124 {
125 /* Setup the information for the host. */
126 rc = VBoxHGSMISendHostCtxInfo(&pCommon->guestCtx,
127 offVRAMBaseMapping + offHostFlags,
128 fCaps,
129 offVRAMHostArea,
130 pCommon->cbMiniportHeap);
131 if (RT_SUCCESS(rc))
132 {
133 /* Check whether the guest supports multimonitors. */
134 if (pCommon->bHGSMI)
135 {
136 /* Query the configured number of displays. */
137 pCommon->cDisplays = VBoxHGSMIGetMonitorCount(&pCommon->guestCtx);
138 /* Query supported VBVA_SCREEN_F_* flags. */
139 pCommon->u16SupportedScreenFlags = VBoxHGSMIGetScreenFlags(&pCommon->guestCtx);
140 LOGF_LEAVE();
141 return;
142 }
143 }
144 else
145 pCommon->bHGSMI = false;
146 }
147 }
148 else
149 {
150 pCommon->pvMiniportHeap = NULL;
151 pCommon->cbMiniportHeap = 0;
152 pCommon->bHGSMI = false;
153 }
154 }
155 else
156 {
157 /* Host has not requested a heap. */
158 pCommon->pvMiniportHeap = NULL;
159 pCommon->cbMiniportHeap = 0;
160 }
161 }
162 }
163 else
164 {
165 LOG(("HGSMIHeapSetup failed rc = %d", rc));
166 pCommon->bHGSMI = false;
167 }
168 }
169 else
170 {
171 LOG(("VBoxMPCmnMapAdapterMemory failed rc = %d", rc));
172 pCommon->bHGSMI = false;
173 }
174 }
175
176 if (!pCommon->bHGSMI)
177 VBoxFreeDisplaysHGSMI(pCommon);
178
179
180#else /* MSC isn't able to keep track of what's initialized and what's not with this style of code. Nor
181 is it clear whether bHGSMI can be modified by the calls made by the code or just the code itself,
182 which makes it hard to figure out! This makes this coding style hard to maintain. */
183 int rc = VINF_SUCCESS;
184 uint32_t offVRAMBaseMapping, cbMapping, offGuestHeapMemory, cbGuestHeapMemory,
185 offHostFlags, offVRAMHostArea, cbHostArea;
186
187 if (pCommon->bHGSMI)
188 {
189 VBoxHGSMIGetBaseMappingInfo(pCommon->cbVRAM, &offVRAMBaseMapping,
190 &cbMapping, &offGuestHeapMemory,
191 &cbGuestHeapMemory, &offHostFlags);
192
193 /* Map the adapter information. It will be needed for HGSMI IO. */
194 rc = VBoxMPCmnMapAdapterMemory(pCommon, &pCommon->pvAdapterInformation, offVRAMBaseMapping, cbMapping);
195 if (RT_FAILURE(rc))
196 {
197 LOG(("VBoxMPCmnMapAdapterMemory failed rc = %d", rc));
198 pCommon->bHGSMI = false;
199 }
200 else
201 {
202 /* Setup an HGSMI heap within the adapter information area. */
203 rc = VBoxHGSMISetupGuestContext(&pCommon->guestCtx,
204 pCommon->pvAdapterInformation,
205 cbGuestHeapMemory,
206 offVRAMBaseMapping
207 + offGuestHeapMemory,
208 &g_hgsmiEnvMP);
209
210 if (RT_FAILURE(rc))
211 {
212 LOG(("HGSMIHeapSetup failed rc = %d", rc));
213 pCommon->bHGSMI = false;
214 }
215 }
216 }
217
218 /* Setup the host heap and the adapter memory. */
219 if (pCommon->bHGSMI)
220 {
221 VBoxHGSMIGetHostAreaMapping(&pCommon->guestCtx, pCommon->cbVRAM,
222 offVRAMBaseMapping, &offVRAMHostArea,
223 &cbHostArea);
224 if (cbHostArea)
225 {
226
227 /* Map the heap region.
228 *
229 * Note: the heap will be used for the host buffers submitted to the guest.
230 * The miniport driver is responsible for reading FIFO and notifying
231 * display drivers.
232 */
233 pCommon->cbMiniportHeap = cbHostArea;
234 rc = VBoxMPCmnMapAdapterMemory (pCommon, &pCommon->pvMiniportHeap,
235 offVRAMHostArea, cbHostArea);
236 if (RT_FAILURE(rc))
237 {
238 pCommon->pvMiniportHeap = NULL;
239 pCommon->cbMiniportHeap = 0;
240 pCommon->bHGSMI = false;
241 }
242 else
243 VBoxHGSMISetupHostContext(&pCommon->hostCtx,
244 pCommon->pvAdapterInformation,
245 offHostFlags,
246 pCommon->pvMiniportHeap,
247 offVRAMHostArea, cbHostArea);
248 }
249 else
250 {
251 /* Host has not requested a heap. */
252 pCommon->pvMiniportHeap = NULL;
253 pCommon->cbMiniportHeap = 0;
254 }
255 }
256
257 if (pCommon->bHGSMI)
258 {
259 /* Setup the information for the host. */
260 rc = VBoxHGSMISendHostCtxInfo(&pCommon->guestCtx,
261 offVRAMBaseMapping + offHostFlags,
262 fCaps,
263 offVRAMHostArea,
264 pCommon->cbMiniportHeap);
265
266 if (RT_FAILURE(rc))
267 {
268 pCommon->bHGSMI = false;
269 }
270 }
271
272 /* Check whether the guest supports multimonitors. */
273 if (pCommon->bHGSMI)
274 {
275 /* Query the configured number of displays. */
276 pCommon->cDisplays = VBoxHGSMIGetMonitorCount(&pCommon->guestCtx);
277 }
278 else
279 {
280 VBoxFreeDisplaysHGSMI(pCommon);
281 }
282#endif
283
284 LOGF_LEAVE();
285}
286
287static bool VBoxUnmapAdpInfoCallback(void *pvCommon)
288{
289 PVBOXMP_COMMON pCommon = (PVBOXMP_COMMON)pvCommon;
290
291 pCommon->hostCtx.pfHostFlags = NULL;
292 return true;
293}
294
295void VBoxFreeDisplaysHGSMI(PVBOXMP_COMMON pCommon)
296{
297 VBoxMPCmnUnmapAdapterMemory(pCommon, &pCommon->pvMiniportHeap);
298#ifdef VBOX_WDDM_MINIPORT
299 VBoxSHGSMITerm(&pCommon->guestCtx.heapCtx);
300#else
301 HGSMIHeapDestroy(&pCommon->guestCtx.heapCtx);
302#endif
303
304 /* Unmap the adapter information needed for HGSMI IO. */
305 VBoxMPCmnSyncToVideoIRQ(pCommon, VBoxUnmapAdpInfoCallback, pCommon);
306 VBoxMPCmnUnmapAdapterMemory(pCommon, &pCommon->pvAdapterInformation);
307}
308
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