VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp@ 30865

Last change on this file since 30865 was 30317, checked in by vboxsync, 15 years ago

wddm/2d: bugfixing + more impl

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 33.8 KB
Line 
1/*
2 * Copyright (C) 2010 Oracle Corporation
3 *
4 * This file is part of VirtualBox Open Source Edition (OSE), as
5 * available from http://www.virtualbox.org. This file is free software;
6 * you can redistribute it and/or modify it under the terms of the GNU
7 * General Public License (GPL) as published by the Free Software
8 * Foundation, in version 2 as it comes in the "COPYING" file of the
9 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
10 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
11 */
12#include "../VBoxVideo.h"
13#include "../Helper.h"
14
15#ifndef VBOXVHWA_WITH_SHGSMI
16# include <iprt/semaphore.h>
17# include <iprt/asm.h>
18#endif
19
20
21
22DECLINLINE(void) vboxVhwaHdrInit(VBOXVHWACMD* pHdr, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, VBOXVHWACMD_TYPE enmCmd)
23{
24 memset(pHdr, 0, sizeof(VBOXVHWACMD));
25 pHdr->iDisplay = srcId;
26 pHdr->rc = VERR_GENERAL_FAILURE;
27 pHdr->enmCmd = enmCmd;
28#ifndef VBOXVHWA_WITH_SHGSMI
29 pHdr->cRefs = 1;
30#endif
31}
32
33#ifdef VBOXVHWA_WITH_SHGSMI
34static int vboxVhwaCommandSubmitHgsmi(struct _DEVICE_EXTENSION* pDevExt, HGSMIOFFSET offDr)
35{
36 VBoxHGSMIGuestWrite(pDevExt, offDr);
37 return VINF_SUCCESS;
38}
39#else
40DECLINLINE(void) vbvaVhwaCommandRelease(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD* pCmd)
41{
42 uint32_t cRefs = ASMAtomicDecU32(&pCmd->cRefs);
43 Assert(cRefs < UINT32_MAX / 2);
44 if(!cRefs)
45 {
46 vboxHGSMIBufferFree(pDevExt, pCmd);
47 }
48}
49
50DECLINLINE(void) vbvaVhwaCommandRetain(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD* pCmd)
51{
52 ASMAtomicIncU32(&pCmd->cRefs);
53}
54
55/* do not wait for completion */
56void vboxVhwaCommandSubmitAsynch(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD* pCmd, PFNVBOXVHWACMDCOMPLETION pfnCompletion, void * pContext)
57{
58 pCmd->GuestVBVAReserved1 = (uintptr_t)pfnCompletion;
59 pCmd->GuestVBVAReserved2 = (uintptr_t)pContext;
60 vbvaVhwaCommandRetain(pDevExt, pCmd);
61
62 vboxHGSMIBufferSubmit(pDevExt, pCmd);
63
64 if(!(pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH)
65 || ((pCmd->Flags & VBOXVHWACMD_FLAG_GH_ASYNCH_NOCOMPLETION)
66 && (pCmd->Flags & VBOXVHWACMD_FLAG_HG_ASYNCH_RETURNED)))
67 {
68 /* the command is completed */
69 pfnCompletion(pDevExt, pCmd, pContext);
70 }
71
72 vbvaVhwaCommandRelease(pDevExt, pCmd);
73}
74
75static DECLCALLBACK(void) vboxVhwaCompletionSetEvent(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD * pCmd, void * pvContext)
76{
77 RTSemEventSignal((RTSEMEVENT)pvContext);
78}
79
80void vboxVhwaCommandSubmitAsynchByEvent(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD* pCmd, RTSEMEVENT hEvent)
81{
82 vboxVhwaCommandSubmitAsynch(pDevExt, pCmd, vboxVhwaCompletionSetEvent, hEvent);
83}
84#endif
85
86VBOXVHWACMD* vboxVhwaCommandCreate(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, VBOXVHWACMD_TYPE enmCmd, VBOXVHWACMD_LENGTH cbCmd)
87{
88#ifdef VBOXVHWA_WITH_SHGSMI
89 VBOXVHWACMD* pHdr = (VBOXVHWACMD*)VBoxSHGSMICommandAlloc(&pDevExt->u.primary.hgsmiAdapterHeap,
90 cbCmd + VBOXVHWACMD_HEADSIZE(),
91 HGSMI_CH_VBVA,
92 VBVA_VHWA_CMD);
93#else
94 VBOXVHWACMD* pHdr = (VBOXVHWACMD*)vboxHGSMIBufferAlloc(pDevExt,
95 cbCmd + VBOXVHWACMD_HEADSIZE(),
96 HGSMI_CH_VBVA,
97 VBVA_VHWA_CMD);
98#endif
99 Assert(pHdr);
100 if (!pHdr)
101 {
102 drprintf((__FUNCTION__": vboxHGSMIBufferAlloc failed\n"));
103 }
104 else
105 {
106 vboxVhwaHdrInit(pHdr, srcId, enmCmd);
107 }
108
109 return pHdr;
110}
111
112void vboxVhwaCommandFree(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD* pCmd)
113{
114#ifdef VBOXVHWA_WITH_SHGSMI
115 VBoxSHGSMICommandFree(&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
116#else
117 vbvaVhwaCommandRelease(pDevExt, pCmd);
118#endif
119}
120
121int vboxVhwaCommandSubmit(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD* pCmd)
122{
123#ifdef VBOXVHWA_WITH_SHGSMI
124 const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
125 Assert(pHdr);
126 int rc = VERR_GENERAL_FAILURE;
127 if (pHdr)
128 {
129 do
130 {
131 HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
132 Assert(offCmd != HGSMIOFFSET_VOID);
133 if (offCmd != HGSMIOFFSET_VOID)
134 {
135 rc = vboxVhwaCommandSubmitHgsmi(pDevExt, offCmd);
136 AssertRC(rc);
137 if (RT_SUCCESS(rc))
138 {
139 VBoxSHGSMICommandDoneSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
140 AssertRC(rc);
141 break;
142 }
143 }
144 else
145 rc = VERR_INVALID_PARAMETER;
146 /* fail to submit, cancel it */
147 VBoxSHGSMICommandCancelSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
148 } while (0);
149 }
150 else
151 rc = VERR_INVALID_PARAMETER;
152 return rc;
153#else
154 RTSEMEVENT hEvent;
155 int rc = RTSemEventCreate(&hEvent);
156 AssertRC(rc);
157 if (RT_SUCCESS(rc))
158 {
159 pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_IRQ;
160 vboxVhwaCommandSubmitAsynchByEvent(pDevExt, pCmd, hEvent);
161 rc = RTSemEventWait(hEvent, RT_INDEFINITE_WAIT);
162 AssertRC(rc);
163 if (RT_SUCCESS(rc))
164 RTSemEventDestroy(hEvent);
165 }
166 return rc;
167#endif
168}
169
170#ifndef VBOXVHWA_WITH_SHGSMI
171static DECLCALLBACK(void) vboxVhwaCompletionFreeCmd(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD * pCmd, void * pContext)
172{
173 vboxVhwaCommandFree(pDevExt, pCmd);
174}
175
176void vboxVhwaCompletionListProcess(PDEVICE_EXTENSION pDevExt, VBOXSHGSMILIST *pList)
177{
178 PVBOXSHGSMILIST_ENTRY pNext, pCur;
179 for (pCur = pList->pFirst; pCur; pCur = pNext)
180 {
181 /* need to save next since the command may be released in a pfnCallback and thus its data might be invalid */
182 pNext = pCur->pNext;
183 VBOXVHWACMD *pCmd = VBOXVHWA_LISTENTRY2CMD(pCur);
184 PFNVBOXVHWACMDCOMPLETION pfnCallback = (PFNVBOXVHWACMDCOMPLETION)pCmd->GuestVBVAReserved1;
185 void *pvCallback = (void*)pCmd->GuestVBVAReserved2;
186 pfnCallback(pDevExt, pCmd, pvCallback);
187 }
188}
189
190#endif
191
192void vboxVhwaCommandSubmitAsynchAndComplete(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD* pCmd)
193{
194#ifdef VBOXVHWA_WITH_SHGSMI
195# error "port me"
196#else
197 pCmd->Flags |= VBOXVHWACMD_FLAG_GH_ASYNCH_NOCOMPLETION;
198
199 vboxVhwaCommandSubmitAsynch(pDevExt, pCmd, vboxVhwaCompletionFreeCmd, NULL);
200#endif
201}
202
203void vboxVhwaFreeHostInfo1(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD_QUERYINFO1* pInfo)
204{
205 VBOXVHWACMD* pCmd = VBOXVHWACMD_HEAD(pInfo);
206 vboxVhwaCommandFree(pDevExt, pCmd);
207}
208
209void vboxVhwaFreeHostInfo2(PDEVICE_EXTENSION pDevExt, VBOXVHWACMD_QUERYINFO2* pInfo)
210{
211 VBOXVHWACMD* pCmd = VBOXVHWACMD_HEAD(pInfo);
212 vboxVhwaCommandFree(pDevExt, pCmd);
213}
214
215VBOXVHWACMD_QUERYINFO1* vboxVhwaQueryHostInfo1(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
216{
217 VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, srcId, VBOXVHWACMD_TYPE_QUERY_INFO1, sizeof(VBOXVHWACMD_QUERYINFO1));
218 VBOXVHWACMD_QUERYINFO1 *pInfo1;
219
220 Assert(pCmd);
221 if (!pCmd)
222 {
223 drprintf((0, "VBoxDISP::vboxVhwaQueryHostInfo1: vboxVhwaCommandCreate failed\n"));
224 return NULL;
225 }
226
227 pInfo1 = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
228 pInfo1->u.in.guestVersion.maj = VBOXVHWA_VERSION_MAJ;
229 pInfo1->u.in.guestVersion.min = VBOXVHWA_VERSION_MIN;
230 pInfo1->u.in.guestVersion.bld = VBOXVHWA_VERSION_BLD;
231 pInfo1->u.in.guestVersion.reserved = VBOXVHWA_VERSION_RSV;
232
233 int rc = vboxVhwaCommandSubmit(pDevExt, pCmd);
234 AssertRC(rc);
235 if(RT_SUCCESS(rc))
236 {
237 if(RT_SUCCESS(pCmd->rc))
238 {
239 return VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1);
240 }
241 }
242
243 vboxVhwaCommandFree(pDevExt, pCmd);
244 return NULL;
245}
246
247VBOXVHWACMD_QUERYINFO2* vboxVhwaQueryHostInfo2(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, uint32_t numFourCC)
248{
249 VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, srcId, VBOXVHWACMD_TYPE_QUERY_INFO2, VBOXVHWAINFO2_SIZE(numFourCC));
250 VBOXVHWACMD_QUERYINFO2 *pInfo2;
251 Assert(pCmd);
252 if (!pCmd)
253 {
254 drprintf((0, "VBoxDISP::vboxVhwaQueryHostInfo2: vboxVhwaCommandCreate failed\n"));
255 return NULL;
256 }
257
258 pInfo2 = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2);
259 pInfo2->numFourCC = numFourCC;
260
261 int rc = vboxVhwaCommandSubmit(pDevExt, pCmd);
262 AssertRC(rc);
263 if(RT_SUCCESS(rc))
264 {
265 AssertRC(pCmd->rc);
266 if(RT_SUCCESS(pCmd->rc))
267 {
268 if(pInfo2->numFourCC == numFourCC)
269 {
270 return pInfo2;
271 }
272 }
273 }
274
275 vboxVhwaCommandFree(pDevExt, pCmd);
276 return NULL;
277}
278
279int vboxVhwaEnable(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
280{
281 int rc = VERR_GENERAL_FAILURE;
282 VBOXVHWACMD* pCmd;
283
284 pCmd = vboxVhwaCommandCreate(pDevExt, srcId, VBOXVHWACMD_TYPE_ENABLE, 0);
285 Assert(pCmd);
286 if (!pCmd)
287 {
288 drprintf((0, "VBoxDISP::vboxVhwaEnable: vboxVhwaCommandCreate failed\n"));
289 return rc;
290 }
291
292 rc = vboxVhwaCommandSubmit(pDevExt, pCmd);
293 AssertRC(rc);
294 if(RT_SUCCESS(rc))
295 {
296 AssertRC(pCmd->rc);
297 if(RT_SUCCESS(pCmd->rc))
298 rc = VINF_SUCCESS;
299 else
300 rc = pCmd->rc;
301 }
302
303 vboxVhwaCommandFree(pDevExt, pCmd);
304 return rc;
305}
306
307int vboxVhwaDisable(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
308{
309 int rc = VERR_GENERAL_FAILURE;
310 VBOXVHWACMD* pCmd;
311
312 pCmd = vboxVhwaCommandCreate(pDevExt, srcId, VBOXVHWACMD_TYPE_DISABLE, 0);
313 Assert(pCmd);
314 if (!pCmd)
315 {
316 drprintf((0, "VBoxDISP::vboxVhwaDisable: vboxVhwaCommandCreate failed\n"));
317 return rc;
318 }
319
320 rc = vboxVhwaCommandSubmit(pDevExt, pCmd);
321 AssertRC(rc);
322 if(RT_SUCCESS(rc))
323 {
324 AssertRC(pCmd->rc);
325 if(RT_SUCCESS(pCmd->rc))
326 rc = VINF_SUCCESS;
327 else
328 rc = pCmd->rc;
329 }
330
331 vboxVhwaCommandFree(pDevExt, pCmd);
332 return rc;
333}
334
335static void vboxVhwaInitSrc(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
336{
337 Assert(srcId < (D3DDDI_VIDEO_PRESENT_SOURCE_ID)pDevExt->u.primary.cDisplays);
338 VBOXVHWA_INFO *pSettings = &pDevExt->aSources[srcId].Vhwa.Settings;
339 memset (pSettings, 0, sizeof (VBOXVHWA_INFO));
340
341 VBOXVHWACMD_QUERYINFO1* pInfo1 = vboxVhwaQueryHostInfo1(pDevExt, srcId);
342 if (pInfo1)
343 {
344 if ((pInfo1->u.out.cfgFlags & VBOXVHWA_CFG_ENABLED)
345 && pInfo1->u.out.numOverlays)
346 {
347 if ((pInfo1->u.out.caps & VBOXVHWA_CAPS_OVERLAY)
348 && (pInfo1->u.out.caps & VBOXVHWA_CAPS_OVERLAYSTRETCH)
349 && (pInfo1->u.out.surfaceCaps & VBOXVHWA_SCAPS_OVERLAY)
350 && (pInfo1->u.out.surfaceCaps & VBOXVHWA_SCAPS_FLIP)
351 && (pInfo1->u.out.surfaceCaps & VBOXVHWA_SCAPS_LOCALVIDMEM)
352 && pInfo1->u.out.numOverlays)
353 {
354 pSettings->fFlags |= VBOXVHWA_F_ENABLED;
355
356 if (pInfo1->u.out.caps & VBOXVHWA_CAPS_COLORKEY)
357 {
358 if (pInfo1->u.out.colorKeyCaps & VBOXVHWA_CKEYCAPS_SRCOVERLAY)
359 {
360 pSettings->fFlags |= VBOXVHWA_F_CKEY_SRC;
361 /* todo: VBOXVHWA_CKEYCAPS_SRCOVERLAYONEACTIVE ? */
362 }
363
364 if (pInfo1->u.out.colorKeyCaps & VBOXVHWA_CKEYCAPS_DESTOVERLAY)
365 {
366 pSettings->fFlags |= VBOXVHWA_F_CKEY_DST;
367 /* todo: VBOXVHWA_CKEYCAPS_DESTOVERLAYONEACTIVE ? */
368 }
369 }
370
371 pSettings->cOverlaysSupported = pInfo1->u.out.numOverlays;
372
373 pSettings->cFormats = 0;
374
375 pSettings->aFormats[pSettings->cFormats] = D3DDDIFMT_X8R8G8B8;
376 ++pSettings->cFormats;
377
378 if (pInfo1->u.out.numFourCC
379 && (pInfo1->u.out.caps & VBOXVHWA_CAPS_OVERLAYFOURCC))
380 {
381 VBOXVHWACMD_QUERYINFO2* pInfo2 = vboxVhwaQueryHostInfo2(pDevExt, srcId, pInfo1->u.out.numFourCC);
382 if (pInfo2)
383 {
384 for (uint32_t i = 0; i < pInfo2->numFourCC; ++i)
385 {
386 pSettings->aFormats[pSettings->cFormats] = (D3DDDIFORMAT)pInfo2->FourCC[i];
387 ++pSettings->cFormats;
388 }
389 vboxVhwaFreeHostInfo2(pDevExt, pInfo2);
390 }
391 }
392 }
393 }
394 vboxVhwaFreeHostInfo1(pDevExt, pInfo1);
395 }
396}
397
398void vboxVhwaInit(PDEVICE_EXTENSION pDevExt)
399{
400 for (int i = 0; i < pDevExt->u.primary.cDisplays; ++i)
401 {
402 vboxVhwaInitSrc(pDevExt, (D3DDDI_VIDEO_PRESENT_SOURCE_ID)i);
403 }
404}
405
406void vboxVhwaFree(PDEVICE_EXTENSION pDevExt)
407{
408 /* we do not allocate/map anything, just issue a Disable command
409 * to ensure all pending commands are flushed */
410 for (int i = 0; i < pDevExt->u.primary.cDisplays; ++i)
411 {
412 vboxVhwaDisable(pDevExt, i);
413 }
414}
415
416int vboxVhwaHlpTranslateFormat(VBOXVHWA_PIXELFORMAT *pFormat, D3DDDIFORMAT enmFormat)
417{
418 pFormat->Reserved = 0;
419 switch (enmFormat)
420 {
421 case D3DDDIFMT_A8R8G8B8:
422 case D3DDDIFMT_X8R8G8B8:
423 pFormat->flags = VBOXVHWA_PF_RGB;
424 pFormat->c.rgbBitCount = 32;
425 pFormat->m1.rgbRBitMask = 0xff0000;
426 pFormat->m2.rgbGBitMask = 0xff00;
427 pFormat->m3.rgbBBitMask = 0xff;
428 /* always zero for now */
429 pFormat->m4.rgbABitMask = 0;
430 return VINF_SUCCESS;
431 case D3DDDIFMT_R8G8B8:
432 pFormat->flags = VBOXVHWA_PF_RGB;
433 pFormat->c.rgbBitCount = 24;
434 pFormat->m1.rgbRBitMask = 0xff0000;
435 pFormat->m2.rgbGBitMask = 0xff00;
436 pFormat->m3.rgbBBitMask = 0xff;
437 /* always zero for now */
438 pFormat->m4.rgbABitMask = 0;
439 return VINF_SUCCESS;
440 case D3DDDIFMT_R5G6B5:
441 pFormat->flags = VBOXVHWA_PF_RGB;
442 pFormat->c.rgbBitCount = 16;
443 pFormat->m1.rgbRBitMask = 0xf800;
444 pFormat->m2.rgbGBitMask = 0x7e0;
445 pFormat->m3.rgbBBitMask = 0x1f;
446 /* always zero for now */
447 pFormat->m4.rgbABitMask = 0;
448 return VINF_SUCCESS;
449 case D3DDDIFMT_P8:
450 case D3DDDIFMT_A8:
451 case D3DDDIFMT_X1R5G5B5:
452 case D3DDDIFMT_A1R5G5B5:
453 case D3DDDIFMT_A4R4G4B4:
454 case D3DDDIFMT_R3G3B2:
455 case D3DDDIFMT_A8R3G3B2:
456 case D3DDDIFMT_X4R4G4B4:
457 case D3DDDIFMT_A2B10G10R10:
458 case D3DDDIFMT_A8B8G8R8:
459 case D3DDDIFMT_X8B8G8R8:
460 case D3DDDIFMT_G16R16:
461 case D3DDDIFMT_A2R10G10B10:
462 case D3DDDIFMT_A16B16G16R16:
463 case D3DDDIFMT_A8P8:
464 default:
465 {
466 uint32_t fourcc = vboxWddmFormatToFourcc(enmFormat);
467 Assert(fourcc);
468 if (fourcc)
469 {
470 pFormat->flags = VBOXVHWA_PF_FOURCC;
471 pFormat->fourCC = fourcc;
472 return VINF_SUCCESS;
473 }
474 return VERR_NOT_SUPPORTED;
475 }
476 }
477}
478
479int vboxVhwaHlpDestroySurface(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pSurf,
480 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
481{
482 Assert(pSurf->hHostHandle);
483 if (!pSurf->hHostHandle)
484 return VERR_INVALID_STATE;
485
486 VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, VidPnSourceId,
487 VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY));
488 Assert(pCmd);
489 if(pCmd)
490 {
491 VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY);
492
493 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY));
494
495 pBody->u.in.hSurf = pSurf->hHostHandle;
496
497 /* we're not interested in completion, just send the command */
498 vboxVhwaCommandSubmitAsynchAndComplete(pDevExt, pCmd);
499
500 pSurf->hHostHandle = VBOXVHWA_SURFHANDLE_INVALID;
501
502 return VINF_SUCCESS;
503 }
504
505 return VERR_OUT_OF_RESOURCES;
506}
507
508int vboxVhwaHlpPopulateSurInfo(VBOXVHWA_SURFACEDESC *pInfo, PVBOXWDDM_ALLOCATION pSurf,
509 uint32_t fFlags, uint32_t cBackBuffers, uint32_t fSCaps,
510 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
511{
512 memset(pInfo, 0, sizeof(VBOXVHWA_SURFACEDESC));
513
514 pInfo->height = pSurf->SurfDesc.height;
515 pInfo->width = pSurf->SurfDesc.width;
516 pInfo->flags |= VBOXVHWA_SD_HEIGHT | VBOXVHWA_SD_WIDTH;
517 if (fFlags & VBOXVHWA_SD_PITCH)
518 {
519 pInfo->pitch = pSurf->SurfDesc.pitch;
520 pInfo->flags |= VBOXVHWA_SD_PITCH;
521 pInfo->sizeX = pSurf->SurfDesc.cbSize;
522 pInfo->sizeY = 1;
523 }
524
525 if (cBackBuffers)
526 {
527 pInfo->cBackBuffers = cBackBuffers;
528 pInfo->flags |= VBOXVHWA_SD_BACKBUFFERCOUNT;
529 }
530 else
531 pInfo->cBackBuffers = 0;
532 pInfo->Reserved = 0;
533 /* @todo: color keys */
534// pInfo->DstOverlayCK;
535// pInfo->DstBltCK;
536// pInfo->SrcOverlayCK;
537// pInfo->SrcBltCK;
538 int rc = vboxVhwaHlpTranslateFormat(&pInfo->PixelFormat, pSurf->SurfDesc.format);
539 AssertRC(rc);
540 if (RT_SUCCESS(rc))
541 {
542 pInfo->flags |= VBOXVHWA_SD_PIXELFORMAT;
543 pInfo->surfCaps = fSCaps;
544 pInfo->flags |= VBOXVHWA_SD_CAPS;
545 pInfo->offSurface = pSurf->offVram;
546 }
547
548 return rc;
549}
550
551int vboxVhwaHlpCheckApplySurfInfo(PVBOXWDDM_ALLOCATION pSurf, VBOXVHWA_SURFACEDESC *pInfo,
552 uint32_t fFlags, bool bApplyHostHandle)
553{
554 int rc = VINF_SUCCESS;
555 if (!(fFlags & VBOXVHWA_SD_PITCH))
556 {
557 /* should be set by host */
558// Assert(pInfo->flags & VBOXVHWA_SD_PITCH);
559 pSurf->SurfDesc.cbSize = pInfo->sizeX * pInfo->sizeY;
560 Assert(pSurf->SurfDesc.cbSize);
561 pSurf->SurfDesc.pitch = pInfo->pitch;
562 Assert(pSurf->SurfDesc.pitch);
563 /* @todo: make this properly */
564 pSurf->SurfDesc.bpp = pSurf->SurfDesc.pitch * 8 / pSurf->SurfDesc.width;
565 Assert(pSurf->SurfDesc.bpp);
566 }
567 else
568 {
569 Assert(pSurf->SurfDesc.cbSize == pInfo->sizeX);
570 Assert(pInfo->sizeY == 1);
571 Assert(pInfo->pitch == pSurf->SurfDesc.pitch);
572 if (pSurf->SurfDesc.cbSize != pInfo->sizeX
573 || pInfo->sizeY != 1
574 || pInfo->pitch != pSurf->SurfDesc.pitch)
575 {
576 rc = VERR_INVALID_PARAMETER;
577 }
578 }
579
580 if (bApplyHostHandle && RT_SUCCESS(rc))
581 {
582 pSurf->hHostHandle = pInfo->hSurf;
583 }
584
585 return rc;
586}
587
588int vboxVhwaHlpCreateSurface(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pSurf,
589 uint32_t fFlags, uint32_t cBackBuffers, uint32_t fSCaps,
590 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
591{
592 /* the first thing we need is to post create primary */
593 VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, VidPnSourceId,
594 VBOXVHWACMD_TYPE_SURF_CREATE, sizeof(VBOXVHWACMD_SURF_CREATE));
595 Assert(pCmd);
596 if (pCmd)
597 {
598 VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE);
599 int rc = VINF_SUCCESS;
600
601 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE));
602
603 rc = vboxVhwaHlpPopulateSurInfo(&pBody->SurfInfo, pSurf,
604 fFlags, cBackBuffers, fSCaps,
605 VidPnSourceId);
606 AssertRC(rc);
607 if (RT_SUCCESS(rc))
608 {
609 vboxVhwaCommandSubmit(pDevExt, pCmd);
610 Assert(pCmd->rc == VINF_SUCCESS);
611 if(pCmd->rc == VINF_SUCCESS)
612 {
613 rc = vboxVhwaHlpCheckApplySurfInfo(pSurf, &pBody->SurfInfo, fFlags, true);
614 }
615 else
616 rc = pCmd->rc;
617 }
618 vboxVhwaCommandFree(pDevExt, pCmd);
619 return rc;
620 }
621
622 return VERR_OUT_OF_RESOURCES;
623}
624
625int vboxVhwaHlpGetSurfInfoForSource(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pSurf, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
626{
627 /* the first thing we need is to post create primary */
628 VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, VidPnSourceId,
629 VBOXVHWACMD_TYPE_SURF_GETINFO, sizeof(VBOXVHWACMD_SURF_GETINFO));
630 Assert(pCmd);
631 if (pCmd)
632 {
633 VBOXVHWACMD_SURF_GETINFO * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_GETINFO);
634 int rc = VINF_SUCCESS;
635
636 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_GETINFO));
637
638 rc = vboxVhwaHlpPopulateSurInfo(&pBody->SurfInfo, pSurf,
639 0, 0, VBOXVHWA_SCAPS_OVERLAY | VBOXVHWA_SCAPS_VIDEOMEMORY | VBOXVHWA_SCAPS_LOCALVIDMEM | VBOXVHWA_SCAPS_COMPLEX,
640 VidPnSourceId);
641 AssertRC(rc);
642 if (RT_SUCCESS(rc))
643 {
644 vboxVhwaCommandSubmit(pDevExt, pCmd);
645 Assert(pCmd->rc == VINF_SUCCESS);
646 if(pCmd->rc == VINF_SUCCESS)
647 {
648 rc = vboxVhwaHlpCheckApplySurfInfo(pSurf, &pBody->SurfInfo, 0, true);
649 }
650 else
651 rc = pCmd->rc;
652 }
653 vboxVhwaCommandFree(pDevExt, pCmd);
654 return rc;
655 }
656
657 return VERR_OUT_OF_RESOURCES;
658}
659
660int vboxVhwaHlpGetSurfInfo(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pSurf)
661{
662 for (int i = 0; i < pDevExt->u.primary.cDisplays; ++i)
663 {
664 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
665 if (pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED)
666 {
667 int rc = vboxVhwaHlpGetSurfInfoForSource(pDevExt, pSurf, i);
668 AssertRC(rc);
669 return rc;
670 }
671 }
672 AssertBreakpoint();
673 return VERR_NOT_SUPPORTED;
674}
675
676int vboxVhwaHlpDestroyPrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
677{
678 PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
679
680 int rc = vboxVhwaHlpDestroySurface(pDevExt, pFbSurf, VidPnSourceId);
681 AssertRC(rc);
682 return rc;
683}
684
685int vboxVhwaHlpCreatePrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
686{
687 PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
688 Assert(pSource->Vhwa.cOverlaysCreated == 1);
689 Assert(pFbSurf->hHostHandle == VBOXVHWA_SURFHANDLE_INVALID);
690 if (pFbSurf->hHostHandle != VBOXVHWA_SURFHANDLE_INVALID)
691 return VERR_INVALID_STATE;
692
693 int rc = vboxVhwaHlpCreateSurface(pDevExt, pFbSurf,
694 VBOXVHWA_SD_PITCH, 0, VBOXVHWA_SCAPS_PRIMARYSURFACE | VBOXVHWA_SCAPS_VIDEOMEMORY | VBOXVHWA_SCAPS_LOCALVIDMEM,
695 VidPnSourceId);
696 AssertRC(rc);
697 return rc;
698}
699
700int vboxVhwaHlpCheckInit(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
701{
702 Assert(VidPnSourceId < (D3DDDI_VIDEO_PRESENT_SOURCE_ID)pDevExt->u.primary.cDisplays);
703 if (VidPnSourceId >= (D3DDDI_VIDEO_PRESENT_SOURCE_ID)pDevExt->u.primary.cDisplays)
704 return VERR_INVALID_PARAMETER;
705
706 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
707
708 Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED));
709 if (!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED))
710 return VERR_NOT_SUPPORTED;
711
712 int rc = VINF_SUCCESS;
713 /* @todo: need a better synch */
714 uint32_t cNew = ASMAtomicIncU32(&pSource->Vhwa.cOverlaysCreated);
715 if (cNew == 1)
716 {
717 rc = vboxVhwaEnable(pDevExt, VidPnSourceId);
718 AssertRC(rc);
719 if (RT_SUCCESS(rc))
720 {
721 rc = vboxVhwaHlpCreatePrimary(pDevExt, pSource, VidPnSourceId);
722 AssertRC(rc);
723 if (RT_FAILURE(rc))
724 {
725 int tmpRc = vboxVhwaDisable(pDevExt, VidPnSourceId);
726 AssertRC(tmpRc);
727 }
728 }
729 }
730 else
731 {
732 PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
733 Assert(pFbSurf->hHostHandle);
734 if (pFbSurf->hHostHandle)
735 rc = VINF_ALREADY_INITIALIZED;
736 else
737 rc = VERR_INVALID_STATE;
738 }
739
740 if (RT_FAILURE(rc))
741 ASMAtomicDecU32(&pSource->Vhwa.cOverlaysCreated);
742
743 return rc;
744}
745
746int vboxVhwaHlpCheckTerm(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
747{
748 Assert(VidPnSourceId < (D3DDDI_VIDEO_PRESENT_SOURCE_ID)pDevExt->u.primary.cDisplays);
749 if (VidPnSourceId >= (D3DDDI_VIDEO_PRESENT_SOURCE_ID)pDevExt->u.primary.cDisplays)
750 return VERR_INVALID_PARAMETER;
751
752 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
753
754 Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED));
755
756 /* @todo: need a better synch */
757 uint32_t cNew = ASMAtomicDecU32(&pSource->Vhwa.cOverlaysCreated);
758 int rc = VINF_SUCCESS;
759 if (!cNew)
760 {
761 rc = vboxVhwaHlpDestroyPrimary(pDevExt, pSource, VidPnSourceId);
762 AssertRC(rc);
763 }
764 else
765 {
766 Assert(cNew < UINT32_MAX / 2);
767 }
768
769 return rc;
770}
771
772int vboxVhwaHlpOverlayFlip(PVBOXWDDM_OVERLAY pOverlay, const DXGKARG_FLIPOVERLAY *pFlipInfo)
773{
774 PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pFlipInfo->hSource;
775 Assert(pAlloc->hHostHandle);
776 Assert(pAlloc->pResource);
777 Assert(pAlloc->pResource == pOverlay->pResource);
778 Assert(pFlipInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAYFLIP_INFO));
779 Assert(pFlipInfo->pPrivateDriverData);
780 PVBOXWDDM_SOURCE pSource = &pOverlay->pDevExt->aSources[pOverlay->VidPnSourceId];
781 Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED));
782 PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
783 Assert(pFbSurf);
784 Assert(pFbSurf->hHostHandle);
785 Assert(pFbSurf->offVram != VBOXVIDEOOFFSET_VOID);
786 Assert(pOverlay->pCurentAlloc);
787 Assert(pOverlay->pCurentAlloc->pResource == pOverlay->pResource);
788 Assert(pOverlay->pCurentAlloc != pAlloc);
789 int rc = VINF_SUCCESS;
790 if (pFlipInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAYFLIP_INFO))
791 {
792 PVBOXWDDM_OVERLAYFLIP_INFO pOurInfo = (PVBOXWDDM_OVERLAYFLIP_INFO)pFlipInfo->pPrivateDriverData;
793
794 VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pOverlay->pDevExt, pOverlay->VidPnSourceId,
795 VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP));
796 Assert(pCmd);
797 if(pCmd)
798 {
799 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
800
801 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_FLIP));
802
803// pBody->TargGuestSurfInfo;
804// pBody->CurrGuestSurfInfo;
805 pBody->u.in.hTargSurf = pAlloc->hHostHandle;
806 pBody->u.in.offTargSurface = pFlipInfo->SrcPhysicalAddress.QuadPart;
807 pAlloc->offVram = pFlipInfo->SrcPhysicalAddress.QuadPart;
808 pBody->u.in.hCurrSurf = pOverlay->pCurentAlloc->hHostHandle;
809 pBody->u.in.offCurrSurface = pOverlay->pCurentAlloc->offVram;
810 if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_VALID)
811 {
812 pBody->u.in.xUpdatedTargMemValid = 1;
813 if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_RECT_VALID)
814 pBody->u.in.xUpdatedTargMemRect = *(VBOXVHWA_RECTL*)((void*)&pOurInfo->DirtyRegion.Rect);
815 else
816 {
817 pBody->u.in.xUpdatedTargMemRect.right = pAlloc->SurfDesc.width;
818 pBody->u.in.xUpdatedTargMemRect.bottom = pAlloc->SurfDesc.height;
819 /* top & left are zero-inited with the above memset */
820 }
821 }
822
823 /* we're not interested in completion, just send the command */
824 vboxVhwaCommandSubmitAsynchAndComplete(pOverlay->pDevExt, pCmd);
825
826 pOverlay->pCurentAlloc = pAlloc;
827
828 rc = VINF_SUCCESS;
829 }
830 else
831 rc = VERR_OUT_OF_RESOURCES;
832 }
833 else
834 rc = VERR_INVALID_PARAMETER;
835
836 return rc;
837}
838
839AssertCompile(sizeof (RECT) == sizeof (VBOXVHWA_RECTL));
840AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, left));
841AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, right));
842AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, top));
843AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, bottom));
844AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(VBOXVHWA_RECTL, left));
845AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(VBOXVHWA_RECTL, right));
846AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(VBOXVHWA_RECTL, top));
847AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(VBOXVHWA_RECTL, bottom));
848
849int vboxVhwaHlpOverlayUpdate(PVBOXWDDM_OVERLAY pOverlay, const DXGK_OVERLAYINFO *pOverlayInfo)
850{
851 PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pOverlayInfo->hAllocation;
852 Assert(pAlloc->hHostHandle);
853 Assert(pAlloc->pResource);
854 Assert(pAlloc->pResource == pOverlay->pResource);
855 Assert(pOverlayInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAY_INFO));
856 Assert(pOverlayInfo->pPrivateDriverData);
857 PVBOXWDDM_SOURCE pSource = &pOverlay->pDevExt->aSources[pOverlay->VidPnSourceId];
858 Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED));
859 PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
860 Assert(pFbSurf);
861 Assert(pFbSurf->hHostHandle);
862 Assert(pFbSurf->offVram != VBOXVIDEOOFFSET_VOID);
863 int rc = VINF_SUCCESS;
864 if (pOverlayInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAY_INFO))
865 {
866 PVBOXWDDM_OVERLAY_INFO pOurInfo = (PVBOXWDDM_OVERLAY_INFO)pOverlayInfo->pPrivateDriverData;
867
868 VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pOverlay->pDevExt, pOverlay->VidPnSourceId,
869 VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
870 Assert(pCmd);
871 if(pCmd)
872 {
873 VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
874
875 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
876
877 pBody->u.in.hDstSurf = pFbSurf->hHostHandle;
878 pBody->u.in.offDstSurface = pFbSurf->offVram;
879 pBody->u.in.dstRect = *(VBOXVHWA_RECTL*)((void*)&pOverlayInfo->DstRect);
880 pBody->u.in.hSrcSurf = pAlloc->hHostHandle;
881 pBody->u.in.offSrcSurface = pOverlayInfo->PhysicalAddress.QuadPart;
882 pAlloc->offVram = pOverlayInfo->PhysicalAddress.QuadPart;
883 pBody->u.in.srcRect = *(VBOXVHWA_RECTL*)((void*)&pOverlayInfo->SrcRect);
884 pBody->u.in.flags |= VBOXVHWA_OVER_SHOW;
885 if (pOurInfo->OverlayDesc.fFlags & VBOXWDDM_OVERLAY_F_CKEY_DST)
886 {
887 pBody->u.in.flags |= VBOXVHWA_OVER_KEYDESTOVERRIDE /* ?? VBOXVHWA_OVER_KEYDEST */;
888 pBody->u.in.desc.DstCK.high = pOurInfo->OverlayDesc.DstColorKeyHigh;
889 pBody->u.in.desc.DstCK.low = pOurInfo->OverlayDesc.DstColorKeyLow;
890 }
891
892 if (pOurInfo->OverlayDesc.fFlags & VBOXWDDM_OVERLAY_F_CKEY_SRC)
893 {
894 pBody->u.in.flags |= VBOXVHWA_OVER_KEYSRCOVERRIDE /* ?? VBOXVHWA_OVER_KEYSRC */;
895 pBody->u.in.desc.SrcCK.high = pOurInfo->OverlayDesc.SrcColorKeyHigh;
896 pBody->u.in.desc.SrcCK.low = pOurInfo->OverlayDesc.SrcColorKeyLow;
897 }
898
899 if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_VALID)
900 {
901 pBody->u.in.xUpdatedSrcMemValid = 1;
902 if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_RECT_VALID)
903 pBody->u.in.xUpdatedSrcMemRect = *(VBOXVHWA_RECTL*)((void*)&pOurInfo->DirtyRegion.Rect);
904 else
905 {
906 pBody->u.in.xUpdatedSrcMemRect.right = pAlloc->SurfDesc.width;
907 pBody->u.in.xUpdatedSrcMemRect.bottom = pAlloc->SurfDesc.height;
908 /* top & left are zero-inited with the above memset */
909 }
910 }
911
912 /* we're not interested in completion, just send the command */
913 vboxVhwaCommandSubmitAsynchAndComplete(pOverlay->pDevExt, pCmd);
914
915 pOverlay->pCurentAlloc = pAlloc;
916
917 rc = VINF_SUCCESS;
918 }
919 else
920 rc = VERR_OUT_OF_RESOURCES;
921 }
922 else
923 rc = VERR_INVALID_PARAMETER;
924
925 return rc;
926}
927
928int vboxVhwaHlpOverlayDestroy(PVBOXWDDM_OVERLAY pOverlay)
929{
930 int rc = VINF_SUCCESS;
931 for (uint32_t i = 0; i < pOverlay->pResource->cAllocations; ++i)
932 {
933 PVBOXWDDM_ALLOCATION pCurAlloc = &pOverlay->pResource->aAllocations[i];
934 rc = vboxVhwaHlpDestroySurface(pOverlay->pDevExt, pCurAlloc, pOverlay->VidPnSourceId);
935 AssertRC(rc);
936 }
937
938 if (RT_SUCCESS(rc))
939 {
940 int tmpRc = vboxVhwaHlpCheckTerm(pOverlay->pDevExt, pOverlay->VidPnSourceId);
941 AssertRC(tmpRc);
942 }
943
944 return rc;
945}
946
947
948int vboxVhwaHlpOverlayCreate(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, DXGK_OVERLAYINFO *pOverlayInfo,
949 /* OUT */ PVBOXWDDM_OVERLAY pOverlay)
950{
951 int rc = vboxVhwaHlpCheckInit(pDevExt, VidPnSourceId);
952 AssertRC(rc);
953 if (RT_SUCCESS(rc))
954 {
955 PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pOverlayInfo->hAllocation;
956 PVBOXWDDM_RESOURCE pRc = pAlloc->pResource;
957 Assert(pRc);
958 for (uint32_t i = 0; i < pRc->cAllocations; ++i)
959 {
960 PVBOXWDDM_ALLOCATION pCurAlloc = &pRc->aAllocations[i];
961 rc = vboxVhwaHlpCreateSurface(pDevExt, pCurAlloc,
962 0, pRc->cAllocations - 1, VBOXVHWA_SCAPS_OVERLAY | VBOXVHWA_SCAPS_VIDEOMEMORY | VBOXVHWA_SCAPS_LOCALVIDMEM | VBOXVHWA_SCAPS_COMPLEX,
963 VidPnSourceId);
964 AssertRC(rc);
965 if (!RT_SUCCESS(rc))
966 {
967 int tmpRc;
968 for (uint32_t j = 0; j < i; ++j)
969 {
970 PVBOXWDDM_ALLOCATION pDestroyAlloc = &pRc->aAllocations[j];
971 tmpRc = vboxVhwaHlpDestroySurface(pDevExt, pDestroyAlloc, VidPnSourceId);
972 AssertRC(tmpRc);
973 }
974 break;
975 }
976 }
977
978 if (RT_SUCCESS(rc))
979 {
980 pOverlay->pDevExt = pDevExt;
981 pOverlay->pResource = pRc;
982 pOverlay->VidPnSourceId = VidPnSourceId;
983 rc = vboxVhwaHlpOverlayUpdate(pOverlay, pOverlayInfo);
984 if (!RT_SUCCESS(rc))
985 {
986 int tmpRc = vboxVhwaHlpOverlayDestroy(pOverlay);
987 AssertRC(tmpRc);
988 }
989 }
990
991 if (RT_FAILURE(rc))
992 {
993 int tmpRc = vboxVhwaHlpCheckTerm(pDevExt, VidPnSourceId);
994 AssertRC(tmpRc);
995 AssertRC(rc);
996 }
997 }
998
999 return rc;
1000}
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