VirtualBox

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

Last change on this file since 38117 was 36867, checked in by vboxsync, 14 years ago

Additions/Video: display/miniport drivers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.0 KB
Line 
1/* $Id: VBoxDispVHWA.cpp 36867 2011-04-28 07:27:03Z vboxsync $ */
2
3/** @file
4 * VBox XPDM Display driver
5 */
6
7/*
8 * Copyright (C) 2011 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#include "VBoxDisp.h"
20#include "VBoxDispMini.h"
21#include <iprt/asm.h>
22#include <iprt/asm-amd64-x86.h>
23
24static void VBoxDispVHWACommandFree(PVBOXDISPDEV pDev, VBOXVHWACMD* pCmd)
25{
26 VBoxHGSMIBufferFree(&pDev->hgsmi.ctx, pCmd);
27}
28
29static void VBoxDispVHWACommandRetain(PVBOXDISPDEV pDev, VBOXVHWACMD* pCmd)
30{
31 ASMAtomicIncU32(&pCmd->cRefs);
32}
33
34static void VBoxDispVHWACommandSubmitAsynchByEvent(PVBOXDISPDEV pDev, VBOXVHWACMD* pCmd, 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(pDev, 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 * pHostCmd)
55{
56 VBVAHOSTCMDVHWACMDCOMPLETE * pComplete = VBVAHOSTCMD_BODY(pHostCmd, VBVAHOSTCMDVHWACMDCOMPLETE);
57 VBOXVHWACMD* pComplCmd = (VBOXVHWACMD*)HGSMIOffsetToPointer(&pDev->hgsmi.ctx.heapCtx.area, pComplete->offCmd);
58 PFNVBOXVHWACMDCOMPLETION pfnCompletion = (PFNVBOXVHWACMDCOMPLETION)pComplCmd->GuestVBVAReserved1;
59 void *pContext = (void *)pComplCmd->GuestVBVAReserved2;
60
61 pfnCompletion(pDev, pComplCmd, pContext);
62
63 VBoxDispVBVAHostCommandComplete(pDev, pHostCmd);
64}
65
66static void VBoxVHWAHostCommandHandler(PVBOXDISPDEV pDev, VBVAHOSTCMD * pCmd)
67{
68 switch(pCmd->customOpCode)
69 {
70 case VBVAHG_DCUSTOM_VHWA_CMDCOMPLETE:
71 {
72 VBoxDispVHWAHanldeVHWACmdCompletion(pDev, pCmd);
73 break;
74 }
75 default:
76 {
77 VBoxDispVBVAHostCommandComplete(pDev, pCmd);
78 }
79 }
80}
81
82void VBoxDispVHWAInit(PVBOXDISPDEV pDev)
83{
84 VHWAQUERYINFO info;
85 int rc;
86
87 rc = VBoxDispMPVHWAQueryInfo(pDev->hDriver, &info);
88 VBOX_WARNRC(rc);
89
90 if (RT_SUCCESS(rc))
91 {
92 pDev->vhwa.offVramBase = info.offVramBase;
93 }
94}
95
96int VBoxDispVHWAEnable(PVBOXDISPDEV pDev)
97{
98 int rc = VERR_GENERAL_FAILURE;
99 VBOXVHWACMD* pCmd;
100
101 if (!pDev->hgsmi.bSupported)
102 {
103 return VERR_NOT_SUPPORTED;
104 }
105
106 pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_ENABLE, 0);
107 if (!pCmd)
108 {
109 WARN(("VBoxDispVHWACommandCreate failed"));
110 return rc;
111 }
112
113 if(VBoxDispVHWACommandSubmit(pDev, pCmd))
114 {
115 if(RT_SUCCESS(pCmd->rc))
116 {
117 rc = VINF_SUCCESS;
118 }
119 }
120
121 VBoxDispVHWACommandRelease(pDev, pCmd);
122 return rc;
123}
124
125VBOXVHWACMD* VBoxDispVHWACommandCreate(PVBOXDISPDEV pDev, VBOXVHWACMD_TYPE enmCmd, VBOXVHWACMD_LENGTH cbCmd)
126{
127 VBOXVHWACMD* pHdr = (VBOXVHWACMD*)VBoxHGSMIBufferAlloc(&pDev->hgsmi.ctx,
128 cbCmd + VBOXVHWACMD_HEADSIZE(),
129 HGSMI_CH_VBVA,
130 VBVA_VHWA_CMD);
131 if (!pHdr)
132 {
133 WARN(("HGSMIHeapAlloc failed"));
134 }
135 else
136 {
137 memset(pHdr, 0, sizeof(VBOXVHWACMD));
138 pHdr->iDisplay = pDev->iDevice;
139 pHdr->rc = VERR_GENERAL_FAILURE;
140 pHdr->enmCmd = enmCmd;
141 pHdr->cRefs = 1;
142 }
143
144 /* @todo: temporary hack */
145 VBoxDispVHWACommandCheckHostCmds(pDev);
146
147 return pHdr;
148}
149
150void VBoxDispVHWACommandRelease(PVBOXDISPDEV pDev, VBOXVHWACMD* pCmd)
151{
152 uint32_t cRefs = ASMAtomicDecU32(&pCmd->cRefs);
153 Assert(cRefs < UINT32_MAX / 2);
154 if(!cRefs)
155 {
156 VBoxDispVHWACommandFree(pDev, pCmd);
157 }
158}
159
160BOOL VBoxDispVHWACommandSubmit(PVBOXDISPDEV pDev, VBOXVHWACMD* pCmd)
161{
162 VBOXPEVENT pEvent;
163 VBOXVP_STATUS rc = pDev->vpAPI.VideoPortProcs.pfnCreateEvent(pDev->vpAPI.pContext, VBOXNOTIFICATION_EVENT, NULL, &pEvent);
164 /* don't assert here, otherwise NT4 will be unhappy */
165 if(rc == VBOXNO_ERROR)
166 {
167 pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ;
168 VBoxDispVHWACommandSubmitAsynchByEvent(pDev, pCmd, pEvent);
169
170 rc = pDev->vpAPI.VideoPortProcs.pfnWaitForSingleObject(pDev->vpAPI.pContext, pEvent,
171 NULL /*IN PLARGE_INTEGER pTimeOut*/
172 );
173 Assert(rc == VBOXNO_ERROR);
174 if(rc == VBOXNO_ERROR)
175 {
176 pDev->vpAPI.VideoPortProcs.pfnDeleteEvent(pDev->vpAPI.pContext, pEvent);
177 }
178 }
179 return rc == VBOXNO_ERROR;
180}
181
182void VBoxDispVHWACommandCheckHostCmds(PVBOXDISPDEV pDev)
183{
184 VBVAHOSTCMD *pCmd, *pNextCmd;
185 int rc = pDev->hgsmi.mp.pfnRequestCommandsHandler(pDev->hgsmi.mp.hContext, HGSMI_CH_VBVA, pDev->iDevice, &pCmd);
186 /* don't assert here, otherwise NT4 will be unhappy */
187 if(RT_SUCCESS(rc))
188 {
189 for(;pCmd; pCmd = pNextCmd)
190 {
191 pNextCmd = pCmd->u.pNext;
192 VBoxVHWAHostCommandHandler(pDev, pCmd);
193 }
194 }
195}
196
197static DECLCALLBACK(void) VBoxDispVHWACommandCompletionCallbackEvent(PVBOXDISPDEV pDev, VBOXVHWACMD * pCmd, void * pContext)
198{
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(pDev, 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 * pContext)
223{
224 VBoxDispVHWACommandRelease(pDev, pCmd);
225}
226
227void VBoxDispVHWACommandSubmitAsynchAndComplete (PVBOXDISPDEV pDev, VBOXVHWACMD* pCmd)
228{
229 pCmd->GuestVBVAReserved1 = (uintptr_t)VBoxDispVHWAFreeCmdCompletion;
230
231 VBoxDispVHWACommandRetain(pDev, pCmd);
232
233 pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_NOCOMPLETION;
234
235 VBoxHGSMIBufferSubmit(&pDev->hgsmi.ctx, pCmd);
236
237 if(!(pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH)
238 || pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH_RETURNED)
239 {
240 /* the command is completed */
241 VBoxDispVHWAFreeCmdCompletion(pDev, pCmd, NULL);
242 }
243
244 VBoxDispVHWACommandRelease(pDev, pCmd);
245}
246
247void VBoxDispVHWAFreeHostInfo1(PVBOXDISPDEV pDev, VBOXVHWACMD_QUERYINFO1* pInfo)
248{
249 VBOXVHWACMD* pCmd = VBOXVHWACMD_HEAD(pInfo);
250 VBoxDispVHWACommandRelease(pDev, pCmd);
251}
252
253void VBoxDispVHWAFreeHostInfo2(PVBOXDISPDEV pDev, VBOXVHWACMD_QUERYINFO2* pInfo)
254{
255 VBOXVHWACMD* pCmd = VBOXVHWACMD_HEAD(pInfo);
256 VBoxDispVHWACommandRelease(pDev, pCmd);
257}
258
259VBOXVHWACMD_QUERYINFO1* VBoxDispVHWAQueryHostInfo1(PVBOXDISPDEV pDev)
260{
261 VBOXVHWACMD* pCmd = VBoxDispVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_QUERY_INFO1, sizeof(VBOXVHWACMD_QUERYINFO1));
262 VBOXVHWACMD_QUERYINFO1 *pInfo1;
263 if (!pCmd)
264 {
265 WARN(("VBoxDispVHWACommandCreate failed"));
266 return NULL;
267 }
268
269 pInfo1 = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
270 pInfo1->u.in.guestVersion.maj = VBOXVHWA_VERSION_MAJ;
271 pInfo1->u.in.guestVersion.min = VBOXVHWA_VERSION_MIN;
272 pInfo1->u.in.guestVersion.bld = VBOXVHWA_VERSION_BLD;
273 pInfo1->u.in.guestVersion.reserved = VBOXVHWA_VERSION_RSV;
274
275 if(VBoxDispVHWACommandSubmit (pDev, pCmd))
276 {
277 if(RT_SUCCESS(pCmd->rc))
278 {
279 return VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
280 }
281 }
282
283 VBoxDispVHWACommandRelease(pDev, pCmd);
284 return NULL;
285}
286
287VBOXVHWACMD_QUERYINFO2* VBoxDispVHWAQueryHostInfo2(PVBOXDISPDEV pDev, uint32_t numFourCC)
288{
289 VBOXVHWACMD* pCmd = VBoxDispVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_QUERY_INFO2, VBOXVHWAINFO2_SIZE(numFourCC));
290 VBOXVHWACMD_QUERYINFO2 *pInfo2;
291 if (!pCmd)
292 {
293 WARN(("VBoxDispVHWACommandCreate failed"));
294 return NULL;
295 }
296
297 pInfo2 = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2);
298 pInfo2->numFourCC = numFourCC;
299
300 if(VBoxDispVHWACommandSubmit (pDev, pCmd))
301 {
302 if(RT_SUCCESS(pCmd->rc))
303 {
304 if(pInfo2->numFourCC == numFourCC)
305 {
306 return pInfo2;
307 }
308 }
309 }
310
311 VBoxDispVHWACommandRelease(pDev, pCmd);
312 return NULL;
313}
314
315int VBoxDispVHWAInitHostInfo1(PVBOXDISPDEV pDev)
316{
317 VBOXVHWACMD_QUERYINFO1* pInfo;
318
319 if (!pDev->hgsmi.bSupported)
320 return VERR_NOT_SUPPORTED;
321
322 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 VBoxDispVHWAFreeHostInfo1(pDev, pInfo);
338 return VINF_SUCCESS;
339}
340
341int VBoxDispVHWAInitHostInfo2(PVBOXDISPDEV pDev, DWORD *pFourCC)
342{
343 VBOXVHWACMD_QUERYINFO2* pInfo;
344 int rc = VINF_SUCCESS;
345
346 if (!pDev->hgsmi.bSupported)
347 return VERR_NOT_SUPPORTED;
348
349 pInfo = VBoxDispVHWAQueryHostInfo2(pDev, pDev->vhwa.numFourCC);
350
351 Assert(pInfo);
352 if(!pInfo)
353 return VERR_OUT_OF_RESOURCES;
354
355 if(pDev->vhwa.numFourCC)
356 {
357 memcpy(pFourCC, pInfo->FourCC, pDev->vhwa.numFourCC * sizeof(pFourCC[0]));
358 }
359 else
360 {
361 Assert(0);
362 rc = VERR_GENERAL_FAILURE;
363 }
364
365 VBoxDispVHWAFreeHostInfo2(pDev, pInfo);
366
367 return rc;
368}
369
370int VBoxDispVHWADisable(PVBOXDISPDEV pDev)
371{
372 int rc = VERR_GENERAL_FAILURE;
373 VBOXVHWACMD* pCmd;
374
375 if (!pDev->hgsmi.bSupported)
376 return VERR_NOT_SUPPORTED;
377
378 pCmd = VBoxDispVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_DISABLE, 0);
379 if (!pCmd)
380 {
381 WARN(("VBoxDispVHWACommandCreate failed"));
382 return rc;
383 }
384
385 if(VBoxDispVHWACommandSubmit (pDev, pCmd))
386 {
387 if(RT_SUCCESS(pCmd->rc))
388 {
389 rc = VINF_SUCCESS;
390 }
391 }
392
393 VBoxDispVHWACommandRelease(pDev, pCmd);
394
395 VBoxDispVHWACommandCheckHostCmds(pDev);
396
397 return rc;
398}
399
400#define MEMTAG 'AWHV'
401PVBOXVHWASURFDESC VBoxDispVHWASurfDescAlloc()
402{
403 return (PVBOXVHWASURFDESC) EngAllocMem(FL_NONPAGED_MEMORY | FL_ZERO_MEMORY, sizeof(VBOXVHWASURFDESC), MEMTAG);
404}
405
406void VBoxDispVHWASurfDescFree(PVBOXVHWASURFDESC pDesc)
407{
408 EngFreeMem(pDesc);
409}
410
411uint64_t VBoxDispVHWAVramOffsetFromPDEV(PVBOXDISPDEV pDev, ULONG_PTR offPdev)
412{
413 return (uint64_t)(pDev->vhwa.offVramBase + offPdev);
414}
415
416#define VBOX_DD(_f) DD##_f
417#define VBOX_VHWA(_f) VBOXVHWA_##_f
418#define VBOX_DD2VHWA(_out, _in, _f) do {if((_in) & VBOX_DD(_f)) _out |= VBOX_VHWA(_f); }while(0)
419#define VBOX_DD_VHWA_PAIR(_v) {VBOX_DD(_v), VBOX_VHWA(_v)}
420#define VBOX_DD_DUMMY_PAIR(_v) {VBOX_DD(_v), 0}
421
422#define VBOXVHWA_SUPPORTED_CAPS ( \
423 VBOXVHWA_CAPS_BLT \
424 | VBOXVHWA_CAPS_BLTCOLORFILL \
425 | VBOXVHWA_CAPS_BLTFOURCC \
426 | VBOXVHWA_CAPS_BLTSTRETCH \
427 | VBOXVHWA_CAPS_BLTQUEUE \
428 | VBOXVHWA_CAPS_OVERLAY \
429 | VBOXVHWA_CAPS_OVERLAYFOURCC \
430 | VBOXVHWA_CAPS_OVERLAYSTRETCH \
431 | VBOXVHWA_CAPS_OVERLAYCANTCLIP \
432 | VBOXVHWA_CAPS_COLORKEY \
433 | VBOXVHWA_CAPS_COLORKEYHWASSIST \
434 )
435
436#define VBOXVHWA_SUPPORTED_SCAPS ( \
437 VBOXVHWA_SCAPS_BACKBUFFER \
438 | VBOXVHWA_SCAPS_COMPLEX \
439 | VBOXVHWA_SCAPS_FLIP \
440 | VBOXVHWA_SCAPS_FRONTBUFFER \
441 | VBOXVHWA_SCAPS_OFFSCREENPLAIN \
442 | VBOXVHWA_SCAPS_OVERLAY \
443 | VBOXVHWA_SCAPS_PRIMARYSURFACE \
444 | VBOXVHWA_SCAPS_SYSTEMMEMORY \
445 | VBOXVHWA_SCAPS_VIDEOMEMORY \
446 | VBOXVHWA_SCAPS_VISIBLE \
447 | VBOXVHWA_SCAPS_LOCALVIDMEM \
448 )
449
450#define VBOXVHWA_SUPPORTED_SCAPS2 ( \
451 VBOXVHWA_CAPS2_CANRENDERWINDOWED \
452 | VBOXVHWA_CAPS2_WIDESURFACES \
453 | VBOXVHWA_CAPS2_COPYFOURCC \
454 )
455
456#define VBOXVHWA_SUPPORTED_PF ( \
457 VBOXVHWA_PF_PALETTEINDEXED8 \
458 | VBOXVHWA_PF_RGB \
459 | VBOXVHWA_PF_RGBTOYUV \
460 | VBOXVHWA_PF_YUV \
461 | VBOXVHWA_PF_FOURCC \
462 )
463
464#define VBOXVHWA_SUPPORTED_SD ( \
465 VBOXVHWA_SD_BACKBUFFERCOUNT \
466 | VBOXVHWA_SD_CAPS \
467 | VBOXVHWA_SD_CKDESTBLT \
468 | VBOXVHWA_SD_CKDESTOVERLAY \
469 | VBOXVHWA_SD_CKSRCBLT \
470 | VBOXVHWA_SD_CKSRCOVERLAY \
471 | VBOXVHWA_SD_HEIGHT \
472 | VBOXVHWA_SD_PITCH \
473 | VBOXVHWA_SD_PIXELFORMAT \
474 | VBOXVHWA_SD_WIDTH \
475 )
476
477#define VBOXVHWA_SUPPORTED_CKEYCAPS ( \
478 VBOXVHWA_CKEYCAPS_DESTBLT \
479 | VBOXVHWA_CKEYCAPS_DESTBLTCLRSPACE \
480 | VBOXVHWA_CKEYCAPS_DESTBLTCLRSPACEYUV \
481 | VBOXVHWA_CKEYCAPS_DESTBLTYUV \
482 | VBOXVHWA_CKEYCAPS_DESTOVERLAY \
483 | VBOXVHWA_CKEYCAPS_DESTOVERLAYCLRSPACE \
484 | VBOXVHWA_CKEYCAPS_DESTOVERLAYCLRSPACEYUV \
485 | VBOXVHWA_CKEYCAPS_DESTOVERLAYONEACTIVE \
486 | VBOXVHWA_CKEYCAPS_DESTOVERLAYYUV \
487 | VBOXVHWA_CKEYCAPS_SRCBLT \
488 | VBOXVHWA_CKEYCAPS_SRCBLTCLRSPACE \
489 | VBOXVHWA_CKEYCAPS_SRCBLTCLRSPACEYUV \
490 | VBOXVHWA_CKEYCAPS_SRCBLTYUV \
491 | VBOXVHWA_CKEYCAPS_SRCOVERLAY \
492 | VBOXVHWA_CKEYCAPS_SRCOVERLAYCLRSPACE \
493 | VBOXVHWA_CKEYCAPS_SRCOVERLAYCLRSPACEYUV \
494 | VBOXVHWA_CKEYCAPS_SRCOVERLAYONEACTIVE \
495 | VBOXVHWA_CKEYCAPS_SRCOVERLAYYUV \
496 | VBOXVHWA_CKEYCAPS_NOCOSTOVERLAY \
497 )
498
499#define VBOXVHWA_SUPPORTED_CKEY ( \
500 VBOXVHWA_CKEY_COLORSPACE \
501 | VBOXVHWA_CKEY_DESTBLT \
502 | VBOXVHWA_CKEY_DESTOVERLAY \
503 | VBOXVHWA_CKEY_SRCBLT \
504 | VBOXVHWA_CKEY_SRCOVERLAY \
505 )
506
507#define VBOXVHWA_SUPPORTED_OVER ( \
508 VBOXVHWA_OVER_DDFX \
509 | VBOXVHWA_OVER_HIDE \
510 | VBOXVHWA_OVER_KEYDEST \
511 | VBOXVHWA_OVER_KEYDESTOVERRIDE \
512 | VBOXVHWA_OVER_KEYSRC \
513 | VBOXVHWA_OVER_KEYSRCOVERRIDE \
514 | VBOXVHWA_OVER_SHOW \
515 )
516
517uint32_t VBoxDispVHWAUnsupportedDDCAPS(uint32_t caps)
518{
519 return caps & (~VBOXVHWA_SUPPORTED_CAPS);
520}
521
522uint32_t VBoxDispVHWAUnsupportedDDSCAPS(uint32_t caps)
523{
524 return caps & (~VBOXVHWA_SUPPORTED_SCAPS);
525}
526
527uint32_t VBoxDispVHWAUnsupportedDDPFS(uint32_t caps)
528{
529 return caps & (~VBOXVHWA_SUPPORTED_PF);
530}
531
532uint32_t VBoxDispVHWAUnsupportedDSS(uint32_t caps)
533{
534 return caps & (~VBOXVHWA_SUPPORTED_SD);
535}
536
537uint32_t VBoxDispVHWAUnsupportedDDCEYCAPS(uint32_t caps)
538{
539 return caps & (~VBOXVHWA_SUPPORTED_CKEYCAPS);
540}
541
542uint32_t VBoxDispVHWASupportedDDCEYCAPS(uint32_t caps)
543{
544 return caps & (VBOXVHWA_SUPPORTED_CKEYCAPS);
545}
546
547
548uint32_t VBoxDispVHWASupportedDDCAPS(uint32_t caps)
549{
550 return caps & (VBOXVHWA_SUPPORTED_CAPS);
551}
552
553uint32_t VBoxDispVHWASupportedDDSCAPS(uint32_t caps)
554{
555 return caps & (VBOXVHWA_SUPPORTED_SCAPS);
556}
557
558uint32_t VBoxDispVHWASupportedDDPFS(uint32_t caps)
559{
560 return caps & (VBOXVHWA_SUPPORTED_PF);
561}
562
563uint32_t VBoxDispVHWASupportedDSS(uint32_t caps)
564{
565 return caps & (VBOXVHWA_SUPPORTED_SD);
566}
567
568uint32_t VBoxDispVHWASupportedOVERs(uint32_t caps)
569{
570 return caps & (VBOXVHWA_SUPPORTED_OVER);
571}
572
573uint32_t VBoxDispVHWAUnsupportedOVERs(uint32_t caps)
574{
575 return caps & (~VBOXVHWA_SUPPORTED_OVER);
576}
577
578uint32_t VBoxDispVHWASupportedCKEYs(uint32_t caps)
579{
580 return caps & (VBOXVHWA_SUPPORTED_CKEY);
581}
582
583uint32_t VBoxDispVHWAUnsupportedCKEYs(uint32_t caps)
584{
585 return caps & (~VBOXVHWA_SUPPORTED_CKEY);
586}
587
588uint32_t VBoxDispVHWAFromDDOVERs(uint32_t caps) { return caps; }
589uint32_t VBoxDispVHWAToDDOVERs(uint32_t caps) { return caps; }
590uint32_t VBoxDispVHWAFromDDCKEYs(uint32_t caps) { return caps; }
591uint32_t VBoxDispVHWAToDDCKEYs(uint32_t caps) { return caps; }
592
593uint32_t VBoxDispVHWAFromDDCAPS(uint32_t caps)
594{
595 return caps;
596}
597
598uint32_t VBoxDispVHWAToDDCAPS(uint32_t caps)
599{
600 return caps;
601}
602
603uint32_t VBoxDispVHWAFromDDCAPS2(uint32_t caps)
604{
605 return caps;
606}
607
608uint32_t VBoxDispVHWAToDDCAPS2(uint32_t caps)
609{
610 return caps;
611}
612
613uint32_t VBoxDispVHWAFromDDSCAPS(uint32_t caps)
614{
615 return caps;
616}
617
618uint32_t VBoxDispVHWAToDDSCAPS(uint32_t caps)
619{
620 return caps;
621}
622
623uint32_t VBoxDispVHWAFromDDPFS(uint32_t caps)
624{
625 return caps;
626}
627
628uint32_t VBoxDispVHWAToDDPFS(uint32_t caps)
629{
630 return caps;
631}
632
633uint32_t VBoxDispVHWAFromDDCKEYCAPS(uint32_t caps)
634{
635 return caps;
636}
637
638uint32_t VBoxDispVHWAToDDCKEYCAPS(uint32_t caps)
639{
640 return caps;
641}
642
643uint32_t VBoxDispVHWAToDDBLTs(uint32_t caps)
644{
645 return caps;
646}
647
648uint32_t VBoxDispVHWAFromDDBLTs(uint32_t caps)
649{
650 return caps;
651}
652
653void VBoxDispVHWAFromDDCOLORKEY(VBOXVHWA_COLORKEY *pVHWACKey, DDCOLORKEY *pDdCKey)
654{
655 pVHWACKey->low = pDdCKey->dwColorSpaceLowValue;
656 pVHWACKey->high = pDdCKey->dwColorSpaceHighValue;
657}
658
659void VBoxDispVHWAFromDDOVERLAYFX(VBOXVHWA_OVERLAYFX *pVHWAOverlay, DDOVERLAYFX *pDdOverlay)
660{
661 //TODO: fxFlags
662 VBoxDispVHWAFromDDCOLORKEY(&pVHWAOverlay->DstCK, &pDdOverlay->dckDestColorkey);
663 VBoxDispVHWAFromDDCOLORKEY(&pVHWAOverlay->SrcCK, &pDdOverlay->dckSrcColorkey);
664}
665
666void VBoxDispVHWAFromDDBLTFX(VBOXVHWA_BLTFX *pVHWABlt, DDBLTFX *pDdBlt)
667{
668 pVHWABlt->fillColor = pDdBlt->dwFillColor;
669
670 VBoxDispVHWAFromDDCOLORKEY(&pVHWABlt->DstCK, &pDdBlt->ddckDestColorkey);
671 VBoxDispVHWAFromDDCOLORKEY(&pVHWABlt->SrcCK, &pDdBlt->ddckSrcColorkey);
672}
673
674int VBoxDispVHWAFromDDPIXELFORMAT(VBOXVHWA_PIXELFORMAT *pVHWAFormat, DDPIXELFORMAT *pDdFormat)
675{
676 uint32_t unsup = VBoxDispVHWAUnsupportedDDPFS(pDdFormat->dwFlags);
677 Assert(!unsup);
678 if(unsup)
679 return VERR_GENERAL_FAILURE;
680
681 pVHWAFormat->flags = VBoxDispVHWAFromDDPFS(pDdFormat->dwFlags);
682 pVHWAFormat->fourCC = pDdFormat->dwFourCC;
683 pVHWAFormat->c.rgbBitCount = pDdFormat->dwRGBBitCount;
684 pVHWAFormat->m1.rgbRBitMask = pDdFormat->dwRBitMask;
685 pVHWAFormat->m2.rgbGBitMask = pDdFormat->dwGBitMask;
686 pVHWAFormat->m3.rgbBBitMask = pDdFormat->dwBBitMask;
687 return VINF_SUCCESS;
688}
689
690int VBoxDispVHWAFromDDSURFACEDESC(VBOXVHWA_SURFACEDESC *pVHWADesc, DDSURFACEDESC *pDdDesc)
691{
692 uint32_t unsupds = VBoxDispVHWAUnsupportedDSS(pDdDesc->dwFlags);
693 Assert(!unsupds);
694 if(unsupds)
695 return VERR_GENERAL_FAILURE;
696
697 pVHWADesc->flags = 0;
698
699 if(pDdDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
700 {
701 pVHWADesc->flags |= VBOXVHWA_SD_BACKBUFFERCOUNT;
702 pVHWADesc->cBackBuffers = pDdDesc->dwBackBufferCount;
703 }
704 if(pDdDesc->dwFlags & DDSD_CAPS)
705 {
706 uint32_t unsup = VBoxDispVHWAUnsupportedDDSCAPS(pDdDesc->ddsCaps.dwCaps);
707 Assert(!unsup);
708 if(unsup)
709 return VERR_GENERAL_FAILURE;
710 pVHWADesc->flags |= VBOXVHWA_SD_CAPS;
711 pVHWADesc->surfCaps = VBoxDispVHWAFromDDSCAPS(pDdDesc->ddsCaps.dwCaps);
712 }
713 if(pDdDesc->dwFlags & DDSD_CKDESTBLT)
714 {
715 pVHWADesc->flags |= VBOXVHWA_SD_CKDESTBLT;
716 VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->DstBltCK, &pDdDesc->ddckCKDestBlt);
717 }
718 if(pDdDesc->dwFlags & DDSD_CKDESTOVERLAY)
719 {
720 pVHWADesc->flags |= VBOXVHWA_SD_CKDESTOVERLAY;
721 VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->DstOverlayCK, &pDdDesc->ddckCKDestOverlay);
722 }
723 if(pDdDesc->dwFlags & DDSD_CKSRCBLT)
724 {
725 pVHWADesc->flags |= VBOXVHWA_SD_CKSRCBLT;
726 VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->SrcBltCK, &pDdDesc->ddckCKSrcBlt);
727 }
728 if(pDdDesc->dwFlags & DDSD_CKSRCOVERLAY)
729 {
730 pVHWADesc->flags |= VBOXVHWA_SD_CKSRCOVERLAY;
731 VBoxDispVHWAFromDDCOLORKEY(&pVHWADesc->SrcOverlayCK, &pDdDesc->ddckCKSrcOverlay);
732 }
733 if(pDdDesc->dwFlags & DDSD_HEIGHT)
734 {
735 pVHWADesc->flags |= VBOXVHWA_SD_HEIGHT;
736 pVHWADesc->height = pDdDesc->dwHeight;
737 }
738 if(pDdDesc->dwFlags & DDSD_WIDTH)
739 {
740 pVHWADesc->flags |= VBOXVHWA_SD_WIDTH;
741 pVHWADesc->width = pDdDesc->dwWidth;
742 }
743 if(pDdDesc->dwFlags & DDSD_PITCH)
744 {
745 pVHWADesc->flags |= VBOXVHWA_SD_PITCH;
746 pVHWADesc->pitch = pDdDesc->lPitch;
747 }
748 if(pDdDesc->dwFlags & DDSD_PIXELFORMAT)
749 {
750 int rc = VBoxDispVHWAFromDDPIXELFORMAT(&pVHWADesc->PixelFormat, &pDdDesc->ddpfPixelFormat);
751 if(RT_FAILURE(rc))
752 return rc;
753 pVHWADesc->flags |= VBOXVHWA_SD_PIXELFORMAT;
754 }
755 return VINF_SUCCESS;
756}
757
758void VBoxDispVHWAFromRECTL(VBOXVHWA_RECTL *pDst, RECTL *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.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette