VirtualBox

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

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

wddm/2d: bugfixing

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 33.5 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 = vboxVhwaHlpCreatePrimary(pDevExt, pSource, VidPnSourceId);
718 AssertRC(rc);
719 }
720 else
721 {
722 PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
723 Assert(pFbSurf->hHostHandle);
724 if (pFbSurf->hHostHandle)
725 rc = VINF_ALREADY_INITIALIZED;
726 else
727 rc = VERR_INVALID_STATE;
728 }
729
730 if (RT_FAILURE(rc))
731 ASMAtomicDecU32(&pSource->Vhwa.cOverlaysCreated);
732
733 return rc;
734}
735
736int vboxVhwaHlpCheckTerm(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
737{
738 Assert(VidPnSourceId < (D3DDDI_VIDEO_PRESENT_SOURCE_ID)pDevExt->u.primary.cDisplays);
739 if (VidPnSourceId >= (D3DDDI_VIDEO_PRESENT_SOURCE_ID)pDevExt->u.primary.cDisplays)
740 return VERR_INVALID_PARAMETER;
741
742 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
743
744 Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED));
745
746 /* @todo: need a better synch */
747 uint32_t cNew = ASMAtomicDecU32(&pSource->Vhwa.cOverlaysCreated);
748 int rc = VINF_SUCCESS;
749 if (!cNew)
750 {
751 rc = vboxVhwaHlpDestroyPrimary(pDevExt, pSource, VidPnSourceId);
752 AssertRC(rc);
753 }
754 else
755 {
756 Assert(cNew < UINT32_MAX / 2);
757 }
758
759 return rc;
760}
761
762int vboxVhwaHlpOverlayFlip(PVBOXWDDM_OVERLAY pOverlay, const DXGKARG_FLIPOVERLAY *pFlipInfo)
763{
764 PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pFlipInfo->hSource;
765 Assert(pAlloc->hHostHandle);
766 Assert(pAlloc->pResource);
767 Assert(pAlloc->pResource == pOverlay->pResource);
768 Assert(pFlipInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAYFLIP_INFO));
769 Assert(pFlipInfo->pPrivateDriverData);
770 PVBOXWDDM_SOURCE pSource = &pOverlay->pDevExt->aSources[pOverlay->VidPnSourceId];
771 Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED));
772 PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
773 Assert(pFbSurf);
774 Assert(pFbSurf->hHostHandle);
775 Assert(pFbSurf->offVram != VBOXVIDEOOFFSET_VOID);
776 Assert(pOverlay->pCurentAlloc);
777 Assert(pOverlay->pCurentAlloc->pResource == pOverlay->pResource);
778 Assert(pOverlay->pCurentAlloc != pAlloc);
779 int rc = VINF_SUCCESS;
780 if (pFlipInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAYFLIP_INFO))
781 {
782 PVBOXWDDM_OVERLAYFLIP_INFO pOurInfo = (PVBOXWDDM_OVERLAYFLIP_INFO)pFlipInfo->pPrivateDriverData;
783
784 VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pOverlay->pDevExt, pOverlay->VidPnSourceId,
785 VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP));
786 Assert(pCmd);
787 if(pCmd)
788 {
789 VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP);
790
791 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_FLIP));
792
793// pBody->TargGuestSurfInfo;
794// pBody->CurrGuestSurfInfo;
795 pBody->u.in.hTargSurf = pAlloc->hHostHandle;
796 pBody->u.in.offTargSurface = pFlipInfo->SrcPhysicalAddress.QuadPart;
797 pAlloc->offVram = pFlipInfo->SrcPhysicalAddress.QuadPart;
798 pBody->u.in.hCurrSurf = pOverlay->pCurentAlloc->hHostHandle;
799 pBody->u.in.offCurrSurface = pOverlay->pCurentAlloc->offVram;
800 if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_VALID)
801 {
802 pBody->u.in.xUpdatedTargMemValid = 1;
803 if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_RECT_VALID)
804 pBody->u.in.xUpdatedTargMemRect = *(VBOXVHWA_RECTL*)((void*)&pOurInfo->DirtyRegion.Rect);
805 else
806 {
807 pBody->u.in.xUpdatedTargMemRect.right = pAlloc->SurfDesc.width;
808 pBody->u.in.xUpdatedTargMemRect.bottom = pAlloc->SurfDesc.height;
809 /* top & left are zero-inited with the above memset */
810 }
811 }
812
813 /* we're not interested in completion, just send the command */
814 vboxVhwaCommandSubmitAsynchAndComplete(pOverlay->pDevExt, pCmd);
815
816 pOverlay->pCurentAlloc = pAlloc;
817
818 rc = VINF_SUCCESS;
819 }
820 else
821 rc = VERR_OUT_OF_RESOURCES;
822 }
823 else
824 rc = VERR_INVALID_PARAMETER;
825
826 return rc;
827}
828
829AssertCompile(sizeof (RECT) == sizeof (VBOXVHWA_RECTL));
830AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, left));
831AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, right));
832AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, top));
833AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, bottom));
834AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(VBOXVHWA_RECTL, left));
835AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(VBOXVHWA_RECTL, right));
836AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(VBOXVHWA_RECTL, top));
837AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(VBOXVHWA_RECTL, bottom));
838
839int vboxVhwaHlpOverlayUpdate(PVBOXWDDM_OVERLAY pOverlay, const DXGK_OVERLAYINFO *pOverlayInfo)
840{
841 PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pOverlayInfo->hAllocation;
842 Assert(pAlloc->hHostHandle);
843 Assert(pAlloc->pResource);
844 Assert(pAlloc->pResource == pOverlay->pResource);
845 Assert(pOverlayInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAY_INFO));
846 Assert(pOverlayInfo->pPrivateDriverData);
847 PVBOXWDDM_SOURCE pSource = &pOverlay->pDevExt->aSources[pOverlay->VidPnSourceId];
848 Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED));
849 PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
850 Assert(pFbSurf);
851 Assert(pFbSurf->hHostHandle);
852 Assert(pFbSurf->offVram != VBOXVIDEOOFFSET_VOID);
853 int rc = VINF_SUCCESS;
854 if (pOverlayInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAY_INFO))
855 {
856 PVBOXWDDM_OVERLAY_INFO pOurInfo = (PVBOXWDDM_OVERLAY_INFO)pOverlayInfo->pPrivateDriverData;
857
858 VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pOverlay->pDevExt, pOverlay->VidPnSourceId,
859 VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
860 Assert(pCmd);
861 if(pCmd)
862 {
863 VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE);
864
865 memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE));
866
867 pBody->u.in.hDstSurf = pFbSurf->hHostHandle;
868 pBody->u.in.offDstSurface = pFbSurf->offVram;
869 pBody->u.in.dstRect = *(VBOXVHWA_RECTL*)((void*)&pOverlayInfo->DstRect);
870 pBody->u.in.hSrcSurf = pAlloc->hHostHandle;
871 pBody->u.in.offSrcSurface = pOverlayInfo->PhysicalAddress.QuadPart;
872 pAlloc->offVram = pOverlayInfo->PhysicalAddress.QuadPart;
873 pBody->u.in.srcRect = *(VBOXVHWA_RECTL*)((void*)&pOverlayInfo->SrcRect);
874 pBody->u.in.flags |= VBOXVHWA_OVER_SHOW;
875 if (pOurInfo->OverlayDesc.fFlags & VBOXWDDM_OVERLAY_F_CKEY_DST)
876 {
877 pBody->u.in.flags |= VBOXVHWA_OVER_KEYDESTOVERRIDE /* ?? VBOXVHWA_OVER_KEYDEST */;
878 pBody->u.in.desc.DstCK.high = pOurInfo->OverlayDesc.DstColorKeyHigh;
879 pBody->u.in.desc.DstCK.low = pOurInfo->OverlayDesc.DstColorKeyLow;
880 }
881
882 if (pOurInfo->OverlayDesc.fFlags & VBOXWDDM_OVERLAY_F_CKEY_SRC)
883 {
884 pBody->u.in.flags |= VBOXVHWA_OVER_KEYSRCOVERRIDE /* ?? VBOXVHWA_OVER_KEYSRC */;
885 pBody->u.in.desc.SrcCK.high = pOurInfo->OverlayDesc.SrcColorKeyHigh;
886 pBody->u.in.desc.SrcCK.low = pOurInfo->OverlayDesc.SrcColorKeyLow;
887 }
888
889 if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_VALID)
890 {
891 pBody->u.in.xUpdatedSrcMemValid = 1;
892 if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_RECT_VALID)
893 pBody->u.in.xUpdatedSrcMemRect = *(VBOXVHWA_RECTL*)((void*)&pOurInfo->DirtyRegion.Rect);
894 else
895 {
896 pBody->u.in.xUpdatedSrcMemRect.right = pAlloc->SurfDesc.width;
897 pBody->u.in.xUpdatedSrcMemRect.bottom = pAlloc->SurfDesc.height;
898 /* top & left are zero-inited with the above memset */
899 }
900 }
901
902 /* we're not interested in completion, just send the command */
903 vboxVhwaCommandSubmitAsynchAndComplete(pOverlay->pDevExt, pCmd);
904
905 pOverlay->pCurentAlloc = pAlloc;
906
907 rc = VINF_SUCCESS;
908 }
909 else
910 rc = VERR_OUT_OF_RESOURCES;
911 }
912 else
913 rc = VERR_INVALID_PARAMETER;
914
915 return rc;
916}
917
918int vboxVhwaHlpOverlayDestroy(PVBOXWDDM_OVERLAY pOverlay)
919{
920 int rc = VINF_SUCCESS;
921 for (uint32_t i = 0; i < pOverlay->pResource->cAllocations; ++i)
922 {
923 PVBOXWDDM_ALLOCATION pCurAlloc = &pOverlay->pResource->aAllocations[i];
924 rc = vboxVhwaHlpDestroySurface(pOverlay->pDevExt, pCurAlloc, pOverlay->VidPnSourceId);
925 AssertRC(rc);
926 }
927
928 if (RT_SUCCESS(rc))
929 {
930 int tmpRc = vboxVhwaHlpCheckTerm(pOverlay->pDevExt, pOverlay->VidPnSourceId);
931 AssertRC(tmpRc);
932 }
933
934 return rc;
935}
936
937
938int vboxVhwaHlpOverlayCreate(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, DXGK_OVERLAYINFO *pOverlayInfo,
939 /* OUT */ PVBOXWDDM_OVERLAY pOverlay)
940{
941 int rc = vboxVhwaHlpCheckInit(pDevExt, VidPnSourceId);
942 AssertRC(rc);
943 if (RT_SUCCESS(rc))
944 {
945 PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pOverlayInfo->hAllocation;
946 PVBOXWDDM_RESOURCE pRc = pAlloc->pResource;
947 Assert(pRc);
948 for (uint32_t i = 0; i < pRc->cAllocations; ++i)
949 {
950 PVBOXWDDM_ALLOCATION pCurAlloc = &pRc->aAllocations[i];
951 rc = vboxVhwaHlpCreateSurface(pDevExt, pCurAlloc,
952 0, pRc->cAllocations - 1, VBOXVHWA_SCAPS_OVERLAY | VBOXVHWA_SCAPS_VIDEOMEMORY | VBOXVHWA_SCAPS_LOCALVIDMEM | VBOXVHWA_SCAPS_COMPLEX,
953 VidPnSourceId);
954 AssertRC(rc);
955 if (!RT_SUCCESS(rc))
956 {
957 int tmpRc;
958 for (uint32_t j = 0; j < i; ++j)
959 {
960 PVBOXWDDM_ALLOCATION pDestroyAlloc = &pRc->aAllocations[j];
961 tmpRc = vboxVhwaHlpDestroySurface(pDevExt, pDestroyAlloc, VidPnSourceId);
962 AssertRC(tmpRc);
963 }
964 break;
965 }
966 }
967
968 if (RT_SUCCESS(rc))
969 {
970 pOverlay->pDevExt = pDevExt;
971 pOverlay->pResource = pRc;
972 pOverlay->VidPnSourceId = VidPnSourceId;
973 rc = vboxVhwaHlpOverlayUpdate(pOverlay, pOverlayInfo);
974 if (!RT_SUCCESS(rc))
975 {
976 int tmpRc = vboxVhwaHlpOverlayDestroy(pOverlay);
977 AssertRC(tmpRc);
978 }
979 }
980
981 if (RT_FAILURE(rc))
982 {
983 int tmpRc = vboxVhwaHlpCheckTerm(pDevExt, VidPnSourceId);
984 AssertRC(tmpRc);
985 AssertRC(rc);
986 }
987 }
988
989 return rc;
990}
Note: See TracBrowser for help on using the repository browser.

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