VirtualBox

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

Last change on this file since 63058 was 63058, checked in by vboxsync, 8 years ago

GA/NT/Graphics: warnings

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