VirtualBox

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

Last change on this file since 95250 was 93115, checked in by vboxsync, 3 years ago

scm --update-copyright-year

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