VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Video/disp/xpdm/VBoxDispVHWA.cpp@ 102295

Last change on this file since 102295 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: 25.8 KB
Line 
1/* $Id: VBoxDispVHWA.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VBox XPDM Display driver
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 "VBoxDisp.h"
29#include "VBoxDispMini.h"
30#include <iprt/asm.h>
31#include <iprt/asm-amd64-x86.h>
32
33static void VBoxDispVHWACommandFree(PVBOXDISPDEV pDev, VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd)
34{
35 VBoxHGSMIBufferFree(&pDev->hgsmi.ctx, pCmd);
36}
37
38static void VBoxDispVHWACommandRetain(VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd)
39{
40 ASMAtomicIncU32(&pCmd->cRefs);
41}
42
43static void VBoxDispVHWACommandSubmitAsynchByEvent(PVBOXDISPDEV pDev, VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd,
44 VBOXPEVENT pEvent)
45{
46 pCmd->GuestVBVAReserved1 = (uintptr_t)pEvent;
47 pCmd->GuestVBVAReserved2 = 0;
48 /* ensure the command is not removed until we're processing it */
49 VBoxDispVHWACommandRetain(pCmd);
50
51 /* complete it asynchronously by setting event */
52 pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_EVENT;
53 VBoxHGSMIBufferSubmit(&pDev->hgsmi.ctx, pCmd);
54
55 if(!(ASMAtomicReadU32((volatile uint32_t *)&pCmd->Flags) & VBOXVHWACMD_FLAG_HG_ASYNCH))
56 {
57 /* the command is completed */
58 pDev->vpAPI.VideoPortProcs.pfnSetEvent(pDev->vpAPI.pContext, pEvent);
59 }
60
61 VBoxDispVHWACommandRelease(pDev, pCmd);
62}
63
64static void VBoxDispVHWAHanldeVHWACmdCompletion(PVBOXDISPDEV pDev, VBVAHOSTCMD RT_UNTRUSTED_VOLATILE_HOST *pHostCmd)
65{
66 VBVAHOSTCMDVHWACMDCOMPLETE RT_UNTRUSTED_VOLATILE_HOST *pComplete = VBVAHOSTCMD_BODY(pHostCmd, VBVAHOSTCMDVHWACMDCOMPLETE);
67 VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pComplCmd =
68 (VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *)HGSMIOffsetToPointer(&pDev->hgsmi.ctx.heapCtx.area, pComplete->offCmd);
69
70 PFNVBOXVHWACMDCOMPLETION pfnCompletion = (PFNVBOXVHWACMDCOMPLETION)(uintptr_t)pComplCmd->GuestVBVAReserved1;
71 void *pContext = (void *)(uintptr_t)pComplCmd->GuestVBVAReserved2;
72
73 pfnCompletion(pDev, pComplCmd, pContext);
74
75 VBoxDispVBVAHostCommandComplete(pDev, pHostCmd);
76}
77
78static void VBoxVHWAHostCommandHandler(PVBOXDISPDEV pDev, VBVAHOSTCMD RT_UNTRUSTED_VOLATILE_HOST *pCmd)
79{
80 switch (pCmd->customOpCode)
81 {
82 case VBVAHG_DCUSTOM_VHWA_CMDCOMPLETE:
83 VBoxDispVHWAHanldeVHWACmdCompletion(pDev, pCmd);
84 break;
85
86 default:
87 VBoxDispVBVAHostCommandComplete(pDev, pCmd);
88 }
89}
90
91void VBoxDispVHWAInit(PVBOXDISPDEV pDev)
92{
93 VHWAQUERYINFO info;
94 int rc;
95
96 rc = VBoxDispMPVHWAQueryInfo(pDev->hDriver, &info);
97 VBOX_WARNRC(rc);
98
99 if (RT_SUCCESS(rc))
100 {
101 pDev->vhwa.offVramBase = info.offVramBase;
102 }
103}
104
105int VBoxDispVHWAEnable(PVBOXDISPDEV pDev)
106{
107 int rc = VERR_GENERAL_FAILURE;
108
109 if (!pDev->hgsmi.bSupported)
110 {
111 return VERR_NOT_SUPPORTED;
112 }
113
114 VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_ENABLE, 0);
115 if (!pCmd)
116 {
117 WARN(("VBoxDispVHWACommandCreate failed"));
118 return rc;
119 }
120
121 if (VBoxDispVHWACommandSubmit(pDev, pCmd))
122 if (RT_SUCCESS(pCmd->rc))
123 rc = VINF_SUCCESS;
124
125 VBoxDispVHWACommandRelease(pDev, pCmd);
126 return rc;
127}
128
129VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *
130VBoxDispVHWACommandCreate(PVBOXDISPDEV pDev, VBOXVHWACMD_TYPE enmCmd, VBOXVHWACMD_LENGTH cbCmd)
131{
132 uint32_t cbTotal = cbCmd + VBOXVHWACMD_HEADSIZE();
133 VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pHdr
134 = (VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *)VBoxHGSMIBufferAlloc(&pDev->hgsmi.ctx, cbTotal, HGSMI_CH_VBVA, VBVA_VHWA_CMD);
135 if (!pHdr)
136 {
137 WARN(("HGSMIHeapAlloc failed"));
138 }
139 else
140 {
141 memset((void *)pHdr, 0, cbTotal); /* always clear the whole body so caller doesn't need to */
142 pHdr->iDisplay = pDev->iDevice;
143 pHdr->rc = VERR_GENERAL_FAILURE;
144 pHdr->enmCmd = enmCmd;
145 pHdr->cRefs = 1;
146 }
147
148 /** @todo temporary hack */
149 VBoxDispVHWACommandCheckHostCmds(pDev);
150
151 return pHdr;
152}
153
154void VBoxDispVHWACommandRelease(PVBOXDISPDEV pDev, VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd)
155{
156 uint32_t cRefs = ASMAtomicDecU32(&pCmd->cRefs);
157 Assert(cRefs < UINT32_MAX / 2);
158 if (!cRefs)
159 VBoxDispVHWACommandFree(pDev, pCmd);
160}
161
162BOOL VBoxDispVHWACommandSubmit(PVBOXDISPDEV pDev, VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd)
163{
164 VBOXPEVENT pEvent;
165 VBOXVP_STATUS rc = pDev->vpAPI.VideoPortProcs.pfnCreateEvent(pDev->vpAPI.pContext, VBOXNOTIFICATION_EVENT, NULL, &pEvent);
166 /* don't assert here, otherwise NT4 will be unhappy */
167 if(rc == VBOXNO_ERROR)
168 {
169 pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ;
170 VBoxDispVHWACommandSubmitAsynchByEvent(pDev, pCmd, pEvent);
171
172 rc = pDev->vpAPI.VideoPortProcs.pfnWaitForSingleObject(pDev->vpAPI.pContext, pEvent,
173 NULL /*IN PLARGE_INTEGER pTimeOut*/
174 );
175 Assert(rc == VBOXNO_ERROR);
176 if(rc == VBOXNO_ERROR)
177 {
178 pDev->vpAPI.VideoPortProcs.pfnDeleteEvent(pDev->vpAPI.pContext, pEvent);
179 }
180 }
181 return rc == VBOXNO_ERROR;
182}
183
184void VBoxDispVHWACommandCheckHostCmds(PVBOXDISPDEV pDev)
185{
186 VBVAHOSTCMD RT_UNTRUSTED_VOLATILE_HOST *pCmd;
187 int rc = pDev->hgsmi.mp.pfnRequestCommandsHandler(pDev->hgsmi.mp.hContext, HGSMI_CH_VBVA, pDev->iDevice, &pCmd);
188 /* don't assert here, otherwise NT4 will be unhappy */
189 if (RT_SUCCESS(rc))
190 {
191 while (pCmd)
192 {
193 VBVAHOSTCMD RT_UNTRUSTED_VOLATILE_HOST *pNextCmd = pCmd->u.pNext;
194 VBoxVHWAHostCommandHandler(pDev, pCmd);
195 pCmd = pNextCmd;
196 }
197 }
198}
199
200static DECLCALLBACK(void) VBoxDispVHWACommandCompletionCallbackEvent(PVBOXDISPDEV pDev, VBOXVHWACMD * pCmd, void * pContext)
201{
202 RT_NOREF(pCmd);
203 VBOXPEVENT pEvent = (VBOXPEVENT)pContext;
204 LONG oldState = pDev->vpAPI.VideoPortProcs.pfnSetEvent(pDev->vpAPI.pContext, pEvent);
205 Assert(!oldState); NOREF(oldState);
206}
207
208/* do not wait for completion */
209void VBoxDispVHWACommandSubmitAsynch(PVBOXDISPDEV pDev, VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd,
210 PFNVBOXVHWACMDCOMPLETION pfnCompletion, void * pContext)
211{
212 pCmd->GuestVBVAReserved1 = (uintptr_t)pfnCompletion;
213 pCmd->GuestVBVAReserved2 = (uintptr_t)pContext;
214 VBoxDispVHWACommandRetain(pCmd);
215
216 VBoxHGSMIBufferSubmit(&pDev->hgsmi.ctx, pCmd);
217
218 if(!(pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH))
219 {
220 /* the command is completed */
221 pfnCompletion(pDev, pCmd, pContext);
222 }
223
224 VBoxDispVHWACommandRelease(pDev, pCmd);
225}
226
227static DECLCALLBACK(void) VBoxDispVHWAFreeCmdCompletion(PVBOXDISPDEV pDev, VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd,
228 void *pvContext)
229{
230 RT_NOREF(pvContext);
231 VBoxDispVHWACommandRelease(pDev, pCmd);
232}
233
234void VBoxDispVHWACommandSubmitAsynchAndComplete (PVBOXDISPDEV pDev, VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd)
235{
236 pCmd->GuestVBVAReserved1 = (uintptr_t)VBoxDispVHWAFreeCmdCompletion;
237
238 VBoxDispVHWACommandRetain(pCmd);
239
240 pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_NOCOMPLETION;
241
242 VBoxHGSMIBufferSubmit(&pDev->hgsmi.ctx, pCmd);
243
244 uint32_t const fCmdFlags = pCmd->Flags;
245 if ( !(fCmdFlags & VBOXVHWACMD_FLAG_HG_ASYNCH)
246 || (fCmdFlags & VBOXVHWACMD_FLAG_HG_ASYNCH_RETURNED))
247 {
248 /* the command is completed */
249 VBoxDispVHWAFreeCmdCompletion(pDev, pCmd, NULL);
250 }
251
252 VBoxDispVHWACommandRelease(pDev, pCmd);
253}
254
255void VBoxDispVHWAFreeHostInfo1(PVBOXDISPDEV pDev, VBOXVHWACMD_QUERYINFO1 RT_UNTRUSTED_VOLATILE_HOST *pInfo)
256{
257 VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd = VBOXVHWACMD_HEAD(pInfo);
258 VBoxDispVHWACommandRelease(pDev, pCmd);
259}
260
261void VBoxDispVHWAFreeHostInfo2(PVBOXDISPDEV pDev, VBOXVHWACMD_QUERYINFO2 RT_UNTRUSTED_VOLATILE_HOST *pInfo)
262{
263 VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd = VBOXVHWACMD_HEAD(pInfo);
264 VBoxDispVHWACommandRelease(pDev, pCmd);
265}
266
267static VBOXVHWACMD_QUERYINFO1 RT_UNTRUSTED_VOLATILE_HOST *VBoxDispVHWAQueryHostInfo1(PVBOXDISPDEV pDev)
268{
269 VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_QUERY_INFO1,
270 sizeof(VBOXVHWACMD_QUERYINFO1));
271 if (!pCmd)
272 {
273 WARN(("VBoxDispVHWACommandCreate failed"));
274 return NULL;
275 }
276
277 VBOXVHWACMD_QUERYINFO1 RT_UNTRUSTED_VOLATILE_HOST *pInfo1= VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
278 pInfo1->u.in.guestVersion.maj = VBOXVHWA_VERSION_MAJ;
279 pInfo1->u.in.guestVersion.min = VBOXVHWA_VERSION_MIN;
280 pInfo1->u.in.guestVersion.bld = VBOXVHWA_VERSION_BLD;
281 pInfo1->u.in.guestVersion.reserved = VBOXVHWA_VERSION_RSV;
282
283 if(VBoxDispVHWACommandSubmit (pDev, pCmd))
284 {
285 if(RT_SUCCESS(pCmd->rc))
286 {
287 return VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
288 }
289 }
290
291 VBoxDispVHWACommandRelease(pDev, pCmd);
292 return NULL;
293}
294
295static VBOXVHWACMD_QUERYINFO2 RT_UNTRUSTED_VOLATILE_HOST *VBoxDispVHWAQueryHostInfo2(PVBOXDISPDEV pDev, uint32_t numFourCC)
296{
297 VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_QUERY_INFO2,
298 VBOXVHWAINFO2_SIZE(numFourCC));
299 if (!pCmd)
300 {
301 WARN(("VBoxDispVHWACommandCreate failed"));
302 return NULL;
303 }
304
305 VBOXVHWACMD_QUERYINFO2 RT_UNTRUSTED_VOLATILE_HOST *pInfo2 = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2);
306 pInfo2->numFourCC = numFourCC;
307 if (VBoxDispVHWACommandSubmit(pDev, pCmd))
308 if (RT_SUCCESS(pCmd->rc))
309 if (pInfo2->numFourCC == numFourCC)
310 return pInfo2;
311
312 VBoxDispVHWACommandRelease(pDev, pCmd);
313 return NULL;
314}
315
316int VBoxDispVHWAInitHostInfo1(PVBOXDISPDEV pDev)
317{
318
319 if (!pDev->hgsmi.bSupported)
320 return VERR_NOT_SUPPORTED;
321
322 VBOXVHWACMD_QUERYINFO1 RT_UNTRUSTED_VOLATILE_HOST *pInfo = VBoxDispVHWAQueryHostInfo1(pDev);
323 if(!pInfo)
324 {
325 pDev->vhwa.bEnabled = false;
326 return VERR_OUT_OF_RESOURCES;
327 }
328
329 pDev->vhwa.caps = pInfo->u.out.caps;
330 pDev->vhwa.caps2 = pInfo->u.out.caps2;
331 pDev->vhwa.colorKeyCaps = pInfo->u.out.colorKeyCaps;
332 pDev->vhwa.stretchCaps = pInfo->u.out.stretchCaps;
333 pDev->vhwa.surfaceCaps = pInfo->u.out.surfaceCaps;
334 pDev->vhwa.numOverlays = pInfo->u.out.numOverlays;
335 pDev->vhwa.numFourCC = pInfo->u.out.numFourCC;
336 pDev->vhwa.bEnabled = (pInfo->u.out.cfgFlags & VBOXVHWA_CFG_ENABLED);
337
338 VBoxDispVHWAFreeHostInfo1(pDev, pInfo);
339 return VINF_SUCCESS;
340}
341
342int VBoxDispVHWAInitHostInfo2(PVBOXDISPDEV pDev, DWORD *pFourCC)
343{
344 int rc = VINF_SUCCESS;
345
346 if (!pDev->hgsmi.bSupported)
347 return VERR_NOT_SUPPORTED;
348
349 VBOXVHWACMD_QUERYINFO2 RT_UNTRUSTED_VOLATILE_HOST *pInfo = VBoxDispVHWAQueryHostInfo2(pDev, pDev->vhwa.numFourCC);
350 Assert(pInfo);
351 if(!pInfo)
352 return VERR_OUT_OF_RESOURCES;
353
354 if (pDev->vhwa.numFourCC)
355 memcpy(pFourCC, (void const *)pInfo->FourCC, pDev->vhwa.numFourCC * sizeof(pFourCC[0]));
356 else
357 {
358 Assert(0);
359 rc = VERR_GENERAL_FAILURE;
360 }
361
362 VBoxDispVHWAFreeHostInfo2(pDev, pInfo);
363
364 return rc;
365}
366
367int VBoxDispVHWADisable(PVBOXDISPDEV pDev)
368{
369 int rc = VERR_GENERAL_FAILURE;
370
371 if (!pDev->hgsmi.bSupported)
372 return VERR_NOT_SUPPORTED;
373
374 VBOXVHWACMD RT_UNTRUSTED_VOLATILE_HOST *pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_DISABLE, 0);
375 if (!pCmd)
376 {
377 WARN(("VBoxDispVHWACommandCreate failed"));
378 return rc;
379 }
380
381 if (VBoxDispVHWACommandSubmit(pDev, pCmd))
382 if(RT_SUCCESS(pCmd->rc))
383 rc = VINF_SUCCESS;
384
385 VBoxDispVHWACommandRelease(pDev, pCmd);
386
387 VBoxDispVHWACommandCheckHostCmds(pDev);
388
389 return rc;
390}
391
392#define MEMTAG 'AWHV'
393PVBOXVHWASURFDESC VBoxDispVHWASurfDescAlloc()
394{
395 return (PVBOXVHWASURFDESC) EngAllocMem(FL_NONPAGED_MEMORY | FL_ZERO_MEMORY, sizeof(VBOXVHWASURFDESC), MEMTAG);
396}
397
398void VBoxDispVHWASurfDescFree(PVBOXVHWASURFDESC pDesc)
399{
400 EngFreeMem(pDesc);
401}
402
403uint64_t VBoxDispVHWAVramOffsetFromPDEV(PVBOXDISPDEV pDev, ULONG_PTR offPdev)
404{
405 return (uint64_t)(pDev->vhwa.offVramBase + offPdev);
406}
407
408#define VBOX_DD(_f) DD##_f
409#define VBOX_VHWA(_f) VBOXVHWA_##_f
410#define VBOX_DD2VHWA(_out, _in, _f) do {if((_in) & VBOX_DD(_f)) _out |= VBOX_VHWA(_f); }while(0)
411#define VBOX_DD_VHWA_PAIR(_v) {VBOX_DD(_v), VBOX_VHWA(_v)}
412#define VBOX_DD_DUMMY_PAIR(_v) {VBOX_DD(_v), 0}
413
414#define VBOXVHWA_SUPPORTED_CAPS ( \
415 VBOXVHWA_CAPS_BLT \
416 | VBOXVHWA_CAPS_BLTCOLORFILL \
417 | VBOXVHWA_CAPS_BLTFOURCC \
418 | VBOXVHWA_CAPS_BLTSTRETCH \
419 | VBOXVHWA_CAPS_BLTQUEUE \
420 | VBOXVHWA_CAPS_OVERLAY \
421 | VBOXVHWA_CAPS_OVERLAYFOURCC \
422 | VBOXVHWA_CAPS_OVERLAYSTRETCH \
423 | VBOXVHWA_CAPS_OVERLAYCANTCLIP \
424 | VBOXVHWA_CAPS_COLORKEY \
425 | VBOXVHWA_CAPS_COLORKEYHWASSIST \
426 )
427
428#define VBOXVHWA_SUPPORTED_SCAPS ( \
429 VBOXVHWA_SCAPS_BACKBUFFER \
430 | VBOXVHWA_SCAPS_COMPLEX \
431 | VBOXVHWA_SCAPS_FLIP \
432 | VBOXVHWA_SCAPS_FRONTBUFFER \
433 | VBOXVHWA_SCAPS_OFFSCREENPLAIN \
434 | VBOXVHWA_SCAPS_OVERLAY \
435 | VBOXVHWA_SCAPS_PRIMARYSURFACE \
436 | VBOXVHWA_SCAPS_SYSTEMMEMORY \
437 | VBOXVHWA_SCAPS_VIDEOMEMORY \
438 | VBOXVHWA_SCAPS_VISIBLE \
439 | VBOXVHWA_SCAPS_LOCALVIDMEM \
440 )
441
442#define VBOXVHWA_SUPPORTED_SCAPS2 ( \
443 VBOXVHWA_CAPS2_CANRENDERWINDOWED \
444 | VBOXVHWA_CAPS2_WIDESURFACES \
445 | VBOXVHWA_CAPS2_COPYFOURCC \
446 )
447
448#define VBOXVHWA_SUPPORTED_PF ( \
449 VBOXVHWA_PF_PALETTEINDEXED8 \
450 | VBOXVHWA_PF_RGB \
451 | VBOXVHWA_PF_RGBTOYUV \
452 | VBOXVHWA_PF_YUV \
453 | VBOXVHWA_PF_FOURCC \
454 )
455
456#define VBOXVHWA_SUPPORTED_SD ( \
457 VBOXVHWA_SD_BACKBUFFERCOUNT \
458 | VBOXVHWA_SD_CAPS \
459 | VBOXVHWA_SD_CKDESTBLT \
460 | VBOXVHWA_SD_CKDESTOVERLAY \
461 | VBOXVHWA_SD_CKSRCBLT \
462 | VBOXVHWA_SD_CKSRCOVERLAY \
463 | VBOXVHWA_SD_HEIGHT \
464 | VBOXVHWA_SD_PITCH \
465 | VBOXVHWA_SD_PIXELFORMAT \
466 | VBOXVHWA_SD_WIDTH \
467 )
468
469#define VBOXVHWA_SUPPORTED_CKEYCAPS ( \
470 VBOXVHWA_CKEYCAPS_DESTBLT \
471 | VBOXVHWA_CKEYCAPS_DESTBLTCLRSPACE \
472 | VBOXVHWA_CKEYCAPS_DESTBLTCLRSPACEYUV \
473 | VBOXVHWA_CKEYCAPS_DESTBLTYUV \
474 | VBOXVHWA_CKEYCAPS_DESTOVERLAY \
475 | VBOXVHWA_CKEYCAPS_DESTOVERLAYCLRSPACE \
476 | VBOXVHWA_CKEYCAPS_DESTOVERLAYCLRSPACEYUV \
477 | VBOXVHWA_CKEYCAPS_DESTOVERLAYONEACTIVE \
478 | VBOXVHWA_CKEYCAPS_DESTOVERLAYYUV \
479 | VBOXVHWA_CKEYCAPS_SRCBLT \
480 | VBOXVHWA_CKEYCAPS_SRCBLTCLRSPACE \
481 | VBOXVHWA_CKEYCAPS_SRCBLTCLRSPACEYUV \
482 | VBOXVHWA_CKEYCAPS_SRCBLTYUV \
483 | VBOXVHWA_CKEYCAPS_SRCOVERLAY \
484 | VBOXVHWA_CKEYCAPS_SRCOVERLAYCLRSPACE \
485 | VBOXVHWA_CKEYCAPS_SRCOVERLAYCLRSPACEYUV \
486 | VBOXVHWA_CKEYCAPS_SRCOVERLAYONEACTIVE \
487 | VBOXVHWA_CKEYCAPS_SRCOVERLAYYUV \
488 | VBOXVHWA_CKEYCAPS_NOCOSTOVERLAY \
489 )
490
491#define VBOXVHWA_SUPPORTED_CKEY ( \
492 VBOXVHWA_CKEY_COLORSPACE \
493 | VBOXVHWA_CKEY_DESTBLT \
494 | VBOXVHWA_CKEY_DESTOVERLAY \
495 | VBOXVHWA_CKEY_SRCBLT \
496 | VBOXVHWA_CKEY_SRCOVERLAY \
497 )
498
499#define VBOXVHWA_SUPPORTED_OVER ( \
500 VBOXVHWA_OVER_DDFX \
501 | VBOXVHWA_OVER_HIDE \
502 | VBOXVHWA_OVER_KEYDEST \
503 | VBOXVHWA_OVER_KEYDESTOVERRIDE \
504 | VBOXVHWA_OVER_KEYSRC \
505 | VBOXVHWA_OVER_KEYSRCOVERRIDE \
506 | VBOXVHWA_OVER_SHOW \
507 )
508
509uint32_t VBoxDispVHWAUnsupportedDDCAPS(uint32_t caps)
510{
511 return caps & (~VBOXVHWA_SUPPORTED_CAPS);
512}
513
514uint32_t VBoxDispVHWAUnsupportedDDSCAPS(uint32_t caps)
515{
516 return caps & (~VBOXVHWA_SUPPORTED_SCAPS);
517}
518
519uint32_t VBoxDispVHWAUnsupportedDDPFS(uint32_t caps)
520{
521 return caps & (~VBOXVHWA_SUPPORTED_PF);
522}
523
524uint32_t VBoxDispVHWAUnsupportedDSS(uint32_t caps)
525{
526 return caps & (~VBOXVHWA_SUPPORTED_SD);
527}
528
529uint32_t VBoxDispVHWAUnsupportedDDCEYCAPS(uint32_t caps)
530{
531 return caps & (~VBOXVHWA_SUPPORTED_CKEYCAPS);
532}
533
534uint32_t VBoxDispVHWASupportedDDCEYCAPS(uint32_t caps)
535{
536 return caps & (VBOXVHWA_SUPPORTED_CKEYCAPS);
537}
538
539
540uint32_t VBoxDispVHWASupportedDDCAPS(uint32_t caps)
541{
542 return caps & (VBOXVHWA_SUPPORTED_CAPS);
543}
544
545uint32_t VBoxDispVHWASupportedDDSCAPS(uint32_t caps)
546{
547 return caps & (VBOXVHWA_SUPPORTED_SCAPS);
548}
549
550uint32_t VBoxDispVHWASupportedDDPFS(uint32_t caps)
551{
552 return caps & (VBOXVHWA_SUPPORTED_PF);
553}
554
555uint32_t VBoxDispVHWASupportedDSS(uint32_t caps)
556{
557 return caps & (VBOXVHWA_SUPPORTED_SD);
558}
559
560uint32_t VBoxDispVHWASupportedOVERs(uint32_t caps)
561{
562 return caps & (VBOXVHWA_SUPPORTED_OVER);
563}
564
565uint32_t VBoxDispVHWAUnsupportedOVERs(uint32_t caps)
566{
567 return caps & (~VBOXVHWA_SUPPORTED_OVER);
568}
569
570uint32_t VBoxDispVHWASupportedCKEYs(uint32_t caps)
571{
572 return caps & (VBOXVHWA_SUPPORTED_CKEY);
573}
574
575uint32_t VBoxDispVHWAUnsupportedCKEYs(uint32_t caps)
576{
577 return caps & (~VBOXVHWA_SUPPORTED_CKEY);
578}
579
580uint32_t VBoxDispVHWAFromDDOVERs(uint32_t caps) { return caps; }
581uint32_t VBoxDispVHWAToDDOVERs(uint32_t caps) { return caps; }
582uint32_t VBoxDispVHWAFromDDCKEYs(uint32_t caps) { return caps; }
583uint32_t VBoxDispVHWAToDDCKEYs(uint32_t caps) { return caps; }
584
585uint32_t VBoxDispVHWAFromDDCAPS(uint32_t caps)
586{
587 return caps;
588}
589
590uint32_t VBoxDispVHWAToDDCAPS(uint32_t caps)
591{
592 return caps;
593}
594
595uint32_t VBoxDispVHWAFromDDCAPS2(uint32_t caps)
596{
597 return caps;
598}
599
600uint32_t VBoxDispVHWAToDDCAPS2(uint32_t caps)
601{
602 return caps;
603}
604
605uint32_t VBoxDispVHWAFromDDSCAPS(uint32_t caps)
606{
607 return caps;
608}
609
610uint32_t VBoxDispVHWAToDDSCAPS(uint32_t caps)
611{
612 return caps;
613}
614
615uint32_t VBoxDispVHWAFromDDPFS(uint32_t caps)
616{
617 return caps;
618}
619
620uint32_t VBoxDispVHWAToDDPFS(uint32_t caps)
621{
622 return caps;
623}
624
625uint32_t VBoxDispVHWAFromDDCKEYCAPS(uint32_t caps)
626{
627 return caps;
628}
629
630uint32_t VBoxDispVHWAToDDCKEYCAPS(uint32_t caps)
631{
632 return caps;
633}
634
635uint32_t VBoxDispVHWAToDDBLTs(uint32_t caps)
636{
637 return caps;
638}
639
640uint32_t VBoxDispVHWAFromDDBLTs(uint32_t caps)
641{
642 return caps;
643}
644
645void VBoxDispVHWAFromDDCOLORKEY(VBOXVHWA_COLORKEY RT_UNTRUSTED_VOLATILE_HOST *pVHWACKey, DDCOLORKEY *pDdCKey)
646{
647 pVHWACKey->low = pDdCKey->dwColorSpaceLowValue;
648 pVHWACKey->high = pDdCKey->dwColorSpaceHighValue;
649}
650
651void VBoxDispVHWAFromDDOVERLAYFX(VBOXVHWA_OVERLAYFX RT_UNTRUSTED_VOLATILE_HOST *pVHWAOverlay, DDOVERLAYFX *pDdOverlay)
652{
653 /// @todo fxFlags
654 VBoxDispVHWAFromDDCOLORKEY(&pVHWAOverlay->DstCK, &pDdOverlay->dckDestColorkey);
655 VBoxDispVHWAFromDDCOLORKEY(&pVHWAOverlay->SrcCK, &pDdOverlay->dckSrcColorkey);
656}
657
658void VBoxDispVHWAFromDDBLTFX(VBOXVHWA_BLTFX RT_UNTRUSTED_VOLATILE_HOST *pVHWABlt, DDBLTFX *pDdBlt)
659{
660 pVHWABlt->fillColor = pDdBlt->dwFillColor;
661
662 VBoxDispVHWAFromDDCOLORKEY(&pVHWABlt->DstCK, &pDdBlt->ddckDestColorkey);
663 VBoxDispVHWAFromDDCOLORKEY(&pVHWABlt->SrcCK, &pDdBlt->ddckSrcColorkey);
664}
665
666int VBoxDispVHWAFromDDPIXELFORMAT(VBOXVHWA_PIXELFORMAT RT_UNTRUSTED_VOLATILE_HOST *pVHWAFormat, DDPIXELFORMAT *pDdFormat)
667{
668 uint32_t unsup = VBoxDispVHWAUnsupportedDDPFS(pDdFormat->dwFlags);
669 Assert(!unsup);
670 if(unsup)
671 return VERR_GENERAL_FAILURE;
672
673 pVHWAFormat->flags = VBoxDispVHWAFromDDPFS(pDdFormat->dwFlags);
674 pVHWAFormat->fourCC = pDdFormat->dwFourCC;
675 pVHWAFormat->c.rgbBitCount = pDdFormat->dwRGBBitCount;
676 pVHWAFormat->m1.rgbRBitMask = pDdFormat->dwRBitMask;
677 pVHWAFormat->m2.rgbGBitMask = pDdFormat->dwGBitMask;
678 pVHWAFormat->m3.rgbBBitMask = pDdFormat->dwBBitMask;
679 return VINF_SUCCESS;
680}
681
682int VBoxDispVHWAFromDDSURFACEDESC(VBOXVHWA_SURFACEDESC RT_UNTRUSTED_VOLATILE_HOST *pVHWADesc, DDSURFACEDESC *pDdDesc)
683{
684 uint32_t unsupds = VBoxDispVHWAUnsupportedDSS(pDdDesc->dwFlags);
685 Assert(!unsupds);
686 if(unsupds)
687 return VERR_GENERAL_FAILURE;
688
689 pVHWADesc->flags = 0;
690
691 if(pDdDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
692 {
693 pVHWADesc->flags |= VBOXVHWA_SD_BACKBUFFERCOUNT;
694 pVHWADesc->cBackBuffers = pDdDesc->dwBackBufferCount;
695 }
696 if(pDdDesc->dwFlags & DDSD_CAPS)
697 {
698 uint32_t unsup = VBoxDispVHWAUnsupportedDDSCAPS(pDdDesc->ddsCaps.dwCaps);
699 Assert(!unsup);
700 if(unsup)
701 return VERR_GENERAL_FAILURE;
702 pVHWADesc->flags |= VBOXVHWA_SD_CAPS;
703 pVHWADesc->surfCaps = VBoxDispVHWAFromDDSCAPS(pDdDesc->ddsCaps.dwCaps);
704 }
705 if(pDdDesc->dwFlags & DDSD_CKDESTBLT)
706 {
707 pVHWADesc->flags |= VBOXVHWA_SD_CKDESTBLT;
708 VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->DstBltCK, &pDdDesc->ddckCKDestBlt);
709 }
710 if(pDdDesc->dwFlags & DDSD_CKDESTOVERLAY)
711 {
712 pVHWADesc->flags |= VBOXVHWA_SD_CKDESTOVERLAY;
713 VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->DstOverlayCK, &pDdDesc->ddckCKDestOverlay);
714 }
715 if(pDdDesc->dwFlags & DDSD_CKSRCBLT)
716 {
717 pVHWADesc->flags |= VBOXVHWA_SD_CKSRCBLT;
718 VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->SrcBltCK, &pDdDesc->ddckCKSrcBlt);
719 }
720 if(pDdDesc->dwFlags & DDSD_CKSRCOVERLAY)
721 {
722 pVHWADesc->flags |= VBOXVHWA_SD_CKSRCOVERLAY;
723 VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->SrcOverlayCK, &pDdDesc->ddckCKSrcOverlay);
724 }
725 if(pDdDesc->dwFlags & DDSD_HEIGHT)
726 {
727 pVHWADesc->flags |= VBOXVHWA_SD_HEIGHT;
728 pVHWADesc->height = pDdDesc->dwHeight;
729 }
730 if(pDdDesc->dwFlags & DDSD_WIDTH)
731 {
732 pVHWADesc->flags |= VBOXVHWA_SD_WIDTH;
733 pVHWADesc->width = pDdDesc->dwWidth;
734 }
735 if(pDdDesc->dwFlags & DDSD_PITCH)
736 {
737 pVHWADesc->flags |= VBOXVHWA_SD_PITCH;
738 pVHWADesc->pitch = pDdDesc->lPitch;
739 }
740 if(pDdDesc->dwFlags & DDSD_PIXELFORMAT)
741 {
742 int rc = VBoxDispVHWAFromDDPIXELFORMAT(&pVHWADesc->PixelFormat, &pDdDesc->ddpfPixelFormat);
743 if(RT_FAILURE(rc))
744 return rc;
745 pVHWADesc->flags |= VBOXVHWA_SD_PIXELFORMAT;
746 }
747 return VINF_SUCCESS;
748}
749
750void VBoxDispVHWAFromRECTL(VBOXVHWA_RECTL *pDst, RECTL const *pSrc)
751{
752 pDst->left = pSrc->left;
753 pDst->top = pSrc->top;
754 pDst->right = pSrc->right;
755 pDst->bottom = pSrc->bottom;
756}
757
758void VBoxDispVHWAFromRECTL(VBOXVHWA_RECTL RT_UNTRUSTED_VOLATILE_HOST *pDst, RECTL const *pSrc)
759{
760 pDst->left = pSrc->left;
761 pDst->top = pSrc->top;
762 pDst->right = pSrc->right;
763 pDst->bottom = pSrc->bottom;
764}
765
766#define MIN(_a, _b) (_a) < (_b) ? (_a) : (_b)
767#define MAX(_a, _b) (_a) > (_b) ? (_a) : (_b)
768
769void VBoxDispVHWARectUnited(RECTL * pDst, RECTL * pRect1, RECTL * pRect2)
770{
771 pDst->left = MIN(pRect1->left, pRect2->left);
772 pDst->top = MIN(pRect1->top, pRect2->top);
773 pDst->right = MAX(pRect1->right, pRect2->right);
774 pDst->bottom = MAX(pRect1->bottom, pRect2->bottom);
775}
776
777bool VBoxDispVHWARectIsEmpty(RECTL * pRect)
778{
779 return pRect->left == pRect->right-1 && pRect->top == pRect->bottom-1;
780}
781
782bool VBoxDispVHWARectIntersect(RECTL * pRect1, RECTL * pRect2)
783{
784 return !((pRect1->left < pRect2->left && pRect1->right < pRect2->left)
785 || (pRect2->left < pRect1->left && pRect2->right < pRect1->left)
786 || (pRect1->top < pRect2->top && pRect1->bottom < pRect2->top)
787 || (pRect2->top < pRect1->top && pRect2->bottom < pRect1->top));
788}
789
790bool VBoxDispVHWARectInclude(RECTL * pRect1, RECTL * pRect2)
791{
792 return ((pRect1->left <= pRect2->left && pRect1->right >= pRect2->right)
793 && (pRect1->top <= pRect2->top && pRect1->bottom >= pRect2->bottom));
794}
795
796
797bool VBoxDispVHWARegionIntersects(PVBOXVHWAREGION pReg, RECTL * pRect)
798{
799 if(!pReg->bValid)
800 return false;
801 return VBoxDispVHWARectIntersect(&pReg->Rect, pRect);
802}
803
804bool VBoxDispVHWARegionIncludes(PVBOXVHWAREGION pReg, RECTL * pRect)
805{
806 if(!pReg->bValid)
807 return false;
808 return VBoxDispVHWARectInclude(&pReg->Rect, pRect);
809}
810
811bool VBoxDispVHWARegionIncluded(PVBOXVHWAREGION pReg, RECTL * pRect)
812{
813 if(!pReg->bValid)
814 return true;
815 return VBoxDispVHWARectInclude(pRect, &pReg->Rect);
816}
817
818void VBoxDispVHWARegionSet(PVBOXVHWAREGION pReg, RECTL * pRect)
819{
820 if(VBoxDispVHWARectIsEmpty(pRect))
821 {
822 pReg->bValid = false;
823 }
824 else
825 {
826 pReg->Rect = *pRect;
827 pReg->bValid = true;
828 }
829}
830
831void VBoxDispVHWARegionAdd(PVBOXVHWAREGION pReg, RECTL * pRect)
832{
833 if(VBoxDispVHWARectIsEmpty(pRect))
834 {
835 return;
836 }
837 else if(!pReg->bValid)
838 {
839 VBoxDispVHWARegionSet(pReg, pRect);
840 }
841 else
842 {
843 VBoxDispVHWARectUnited(&pReg->Rect, &pReg->Rect, pRect);
844 }
845}
846
847void VBoxDispVHWARegionInit(PVBOXVHWAREGION pReg)
848{
849 pReg->bValid = false;
850}
851
852void VBoxDispVHWARegionClear(PVBOXVHWAREGION pReg)
853{
854 pReg->bValid = false;
855}
856
857bool VBoxDispVHWARegionValid(PVBOXVHWAREGION pReg)
858{
859 return pReg->bValid;
860}
861
862void VBoxDispVHWARegionTrySubstitute(PVBOXVHWAREGION pReg, const RECTL *pRect)
863{
864 if(!pReg->bValid)
865 return;
866
867 if(pReg->Rect.left >= pRect->left && pReg->Rect.right <= pRect->right)
868 {
869 LONG t = MAX(pReg->Rect.top, pRect->top);
870 LONG b = MIN(pReg->Rect.bottom, pRect->bottom);
871 if(t < b)
872 {
873 pReg->Rect.top = t;
874 pReg->Rect.bottom = b;
875 }
876 else
877 {
878 pReg->bValid = false;
879 }
880 }
881 else if(pReg->Rect.top >= pRect->top && pReg->Rect.bottom <= pRect->bottom)
882 {
883 LONG l = MAX(pReg->Rect.left, pRect->left);
884 LONG r = MIN(pReg->Rect.right, pRect->right);
885 if(l < r)
886 {
887 pReg->Rect.left = l;
888 pReg->Rect.right = r;
889 }
890 else
891 {
892 pReg->bValid = false;
893 }
894 }
895}
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