int vboxVhwaHlpDestroySurface(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pSurf, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId) { Assert(pSurf->hHostHandle); if (!pSurf->hHostHandle) return VERR_INVALID_STATE; VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, VidPnSourceId, VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY)); Assert(pCmd); if(pCmd) { VBOXVHWACMD_SURF_DESTROY * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY)); pBody->u.in.hSurf = pSurf->hHostHandle; /* we're not interested in completion, just send the command */ vboxVhwaCommandSubmitAsynchAndComplete(pDevExt, pCmd); pSurf->hHostHandle = VBOXVHWA_SURFHANDLE_INVALID; return VINF_SUCCESS; } return VERR_OUT_OF_RESOURCES; }
int vboxVhwaHlpGetSurfInfoForSource(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pSurf, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId) { /* the first thing we need is to post create primary */ VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, VidPnSourceId, VBOXVHWACMD_TYPE_SURF_GETINFO, sizeof(VBOXVHWACMD_SURF_GETINFO)); Assert(pCmd); if (pCmd) { VBOXVHWACMD_SURF_GETINFO * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_GETINFO); int rc = VINF_SUCCESS; memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_GETINFO)); rc = vboxVhwaHlpPopulateSurInfo(&pBody->SurfInfo, pSurf, 0, 0, VBOXVHWA_SCAPS_OVERLAY | VBOXVHWA_SCAPS_VIDEOMEMORY | VBOXVHWA_SCAPS_LOCALVIDMEM | VBOXVHWA_SCAPS_COMPLEX, VidPnSourceId); AssertRC(rc); if (RT_SUCCESS(rc)) { vboxVhwaCommandSubmit(pDevExt, pCmd); Assert(pCmd->rc == VINF_SUCCESS); if(pCmd->rc == VINF_SUCCESS) { rc = vboxVhwaHlpCheckApplySurfInfo(pSurf, &pBody->SurfInfo, 0, true); } else rc = pCmd->rc; } vboxVhwaCommandFree(pDevExt, pCmd); return rc; } return VERR_OUT_OF_RESOURCES; }
int vboxVhwaDisable(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId) { vboxVhwaCommandCheckCompletion(pDevExt); int rc = VERR_GENERAL_FAILURE; VBOXVHWACMD* pCmd; pCmd = vboxVhwaCommandCreate(pDevExt, srcId, VBOXVHWACMD_TYPE_DISABLE, 0); Assert(pCmd); if (!pCmd) { LOGREL(("vboxVhwaCommandCreate failed")); return rc; } rc = vboxVhwaCommandSubmit(pDevExt, pCmd); AssertRC(rc); if(RT_SUCCESS(rc)) { AssertRC(pCmd->rc); if(RT_SUCCESS(pCmd->rc)) rc = VINF_SUCCESS; else rc = pCmd->rc; } vboxVhwaCommandFree(pDevExt, pCmd); return rc; }
VBOXVHWACMD_QUERYINFO2* vboxVhwaQueryHostInfo2(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId, uint32_t numFourCC) { VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, srcId, VBOXVHWACMD_TYPE_QUERY_INFO2, VBOXVHWAINFO2_SIZE(numFourCC)); VBOXVHWACMD_QUERYINFO2 *pInfo2; Assert(pCmd); if (!pCmd) { LOGREL(("vboxVhwaCommandCreate failed")); return NULL; } pInfo2 = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2); pInfo2->numFourCC = numFourCC; int rc = vboxVhwaCommandSubmit(pDevExt, pCmd); AssertRC(rc); if(RT_SUCCESS(rc)) { AssertRC(pCmd->rc); if(RT_SUCCESS(pCmd->rc)) { if(pInfo2->numFourCC == numFourCC) { return pInfo2; } } } vboxVhwaCommandFree(pDevExt, pCmd); return NULL; }
VBOXVHWACMD_QUERYINFO1* vboxVhwaQueryHostInfo1(PVBOXMP_DEVEXT pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId) { VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, srcId, VBOXVHWACMD_TYPE_QUERY_INFO1, sizeof(VBOXVHWACMD_QUERYINFO1)); VBOXVHWACMD_QUERYINFO1 *pInfo1; Assert(pCmd); if (!pCmd) { LOGREL(("vboxVhwaCommandCreate failed")); return NULL; } pInfo1 = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1); pInfo1->u.in.guestVersion.maj = VBOXVHWA_VERSION_MAJ; pInfo1->u.in.guestVersion.min = VBOXVHWA_VERSION_MIN; pInfo1->u.in.guestVersion.bld = VBOXVHWA_VERSION_BLD; pInfo1->u.in.guestVersion.reserved = VBOXVHWA_VERSION_RSV; int rc = vboxVhwaCommandSubmit(pDevExt, pCmd); AssertRC(rc); if(RT_SUCCESS(rc)) { if(RT_SUCCESS(pCmd->rc)) { return VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1); } } vboxVhwaCommandFree(pDevExt, pCmd); return NULL; }
int vboxVhwaHlpColorFill(PVBOXWDDM_OVERLAY pOverlay, PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF) { PVBOXWDDM_ALLOCATION pAlloc = pCF->ClrFill.Alloc.pAlloc; Assert(pAlloc->pResource == pOverlay->pResource); #ifdef VBOXWDDM_RENDER_FROM_SHADOW if (pAlloc->bAssigned) { /* check if this is a primary surf */ PVBOXWDDM_SOURCE pSource = &pOverlay->pDevExt->aSources[pOverlay->VidPnSourceId]; if (pSource->pPrimaryAllocation == pAlloc) { pAlloc = pSource->pShadowAllocation; Assert(pAlloc->pResource == pOverlay->pResource); } } #endif Assert(pAlloc->hHostHandle); Assert(pAlloc->pResource); Assert(pAlloc->offVram != VBOXVIDEOOFFSET_VOID); int rc; VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pOverlay->pDevExt, pOverlay->VidPnSourceId, VBOXVHWACMD_TYPE_SURF_FLIP, RT_OFFSETOF(VBOXVHWACMD_SURF_COLORFILL, u.in.aRects[pCF->ClrFill.Rects.cRects])); Assert(pCmd); if(pCmd) { VBOXVHWACMD_SURF_COLORFILL * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORFILL); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_COLORFILL)); pBody->u.in.hSurf = pAlloc->hHostHandle; pBody->u.in.offSurface = pAlloc->offVram; pBody->u.in.cRects = pCF->ClrFill.Rects.cRects; memcpy (pBody->u.in.aRects, pCF->ClrFill.Rects.aRects, pCF->ClrFill.Rects.cRects * sizeof (pCF->ClrFill.Rects.aRects[0])); vboxVhwaCommandSubmitAsynchAndComplete(pOverlay->pDevExt, pCmd); rc = VINF_SUCCESS; } else rc = VERR_OUT_OF_RESOURCES; return rc; }
int vboxVhwaHlpColorFill(PVBOXWDDM_OVERLAY pOverlay, PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF) { PVBOXWDDM_ALLOCATION pAlloc = pCF->ClrFill.Alloc.pAlloc; Assert(pAlloc->pResource == pOverlay->pResource); if (pAlloc->AllocData.Addr.SegmentId != 1) { WARN(("invalid segment id on color fill")); return VERR_INVALID_PARAMETER; } Assert(pAlloc->hHostHandle); Assert(pAlloc->pResource); Assert(pAlloc->AllocData.Addr.offVram != VBOXVIDEOOFFSET_VOID); int rc; VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pOverlay->pDevExt, pOverlay->VidPnSourceId, VBOXVHWACMD_TYPE_SURF_FLIP, RT_OFFSETOF(VBOXVHWACMD_SURF_COLORFILL, u.in.aRects[pCF->ClrFill.Rects.cRects])); Assert(pCmd); if(pCmd) { VBOXVHWACMD_SURF_COLORFILL * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORFILL); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_COLORFILL)); pBody->u.in.hSurf = pAlloc->hHostHandle; pBody->u.in.offSurface = pAlloc->AllocData.Addr.offVram; pBody->u.in.cRects = pCF->ClrFill.Rects.cRects; memcpy (pBody->u.in.aRects, pCF->ClrFill.Rects.aRects, pCF->ClrFill.Rects.cRects * sizeof (pCF->ClrFill.Rects.aRects[0])); vboxVhwaCommandSubmitAsynchAndComplete(pOverlay->pDevExt, pCmd); rc = VINF_SUCCESS; } else rc = VERR_OUT_OF_RESOURCES; return rc; }
int vboxVhwaHlpCreateSurface(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pSurf, uint32_t fFlags, uint32_t cBackBuffers, uint32_t fSCaps, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId) { /* the first thing we need is to post create primary */ VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pDevExt, VidPnSourceId, VBOXVHWACMD_TYPE_SURF_CREATE, sizeof(VBOXVHWACMD_SURF_CREATE)); Assert(pCmd); if (pCmd) { VBOXVHWACMD_SURF_CREATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE); int rc = VINF_SUCCESS; memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE)); rc = vboxVhwaHlpPopulateSurInfo(&pBody->SurfInfo, pSurf, fFlags, cBackBuffers, fSCaps, VidPnSourceId); AssertRC(rc); if (RT_SUCCESS(rc)) { vboxVhwaCommandSubmit(pDevExt, pCmd); Assert(pCmd->rc == VINF_SUCCESS); if(pCmd->rc == VINF_SUCCESS) { rc = vboxVhwaHlpCheckApplySurfInfo(pSurf, &pBody->SurfInfo, fFlags, true); } else rc = pCmd->rc; } vboxVhwaCommandFree(pDevExt, pCmd); return rc; } return VERR_OUT_OF_RESOURCES; }
int vboxVhwaHlpOverlayUpdate(PVBOXWDDM_OVERLAY pOverlay, const DXGK_OVERLAYINFO *pOverlayInfo, RECT * pDstUpdateRect) { PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pOverlayInfo->hAllocation; Assert(pAlloc->hHostHandle); Assert(pAlloc->pResource); Assert(pAlloc->pResource == pOverlay->pResource); Assert(pOverlayInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAY_INFO)); Assert(pOverlayInfo->pPrivateDriverData); PVBOXWDDM_SOURCE pSource = &pOverlay->pDevExt->aSources[pOverlay->VidPnSourceId]; Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED)); PVBOXWDDM_ALLOCATION pFbSurf = VBOXVHWA_PRIMARY_ALLOCATION(pSource); Assert(pFbSurf); Assert(pFbSurf->hHostHandle); Assert(pFbSurf->offVram != VBOXVIDEOOFFSET_VOID); int rc = VINF_SUCCESS; if (pOverlayInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAY_INFO)) { PVBOXWDDM_OVERLAY_INFO pOurInfo = (PVBOXWDDM_OVERLAY_INFO)pOverlayInfo->pPrivateDriverData; VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pOverlay->pDevExt, pOverlay->VidPnSourceId, VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE)); Assert(pCmd); if(pCmd) { VBOXVHWACMD_SURF_OVERLAY_UPDATE * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_UPDATE); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE)); pBody->u.in.hDstSurf = pFbSurf->hHostHandle; pBody->u.in.offDstSurface = pFbSurf->offVram; pBody->u.in.dstRect = *(VBOXVHWA_RECTL*)((void*)&pOverlayInfo->DstRect); pBody->u.in.hSrcSurf = pAlloc->hHostHandle; pBody->u.in.offSrcSurface = pOverlayInfo->PhysicalAddress.QuadPart; pAlloc->offVram = pOverlayInfo->PhysicalAddress.QuadPart; pBody->u.in.srcRect = *(VBOXVHWA_RECTL*)((void*)&pOverlayInfo->SrcRect); pBody->u.in.flags |= VBOXVHWA_OVER_SHOW; if (pOurInfo->OverlayDesc.fFlags & VBOXWDDM_OVERLAY_F_CKEY_DST) { pBody->u.in.flags |= VBOXVHWA_OVER_KEYDESTOVERRIDE /* ?? VBOXVHWA_OVER_KEYDEST */; pBody->u.in.desc.DstCK.high = pOurInfo->OverlayDesc.DstColorKeyHigh; pBody->u.in.desc.DstCK.low = pOurInfo->OverlayDesc.DstColorKeyLow; } if (pOurInfo->OverlayDesc.fFlags & VBOXWDDM_OVERLAY_F_CKEY_SRC) { pBody->u.in.flags |= VBOXVHWA_OVER_KEYSRCOVERRIDE /* ?? VBOXVHWA_OVER_KEYSRC */; pBody->u.in.desc.SrcCK.high = pOurInfo->OverlayDesc.SrcColorKeyHigh; pBody->u.in.desc.SrcCK.low = pOurInfo->OverlayDesc.SrcColorKeyLow; } if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_VALID) { pBody->u.in.xFlags |= VBOXVHWACMD_SURF_OVERLAY_UPDATE_F_SRCMEMRECT; if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_RECT_VALID) pBody->u.in.xUpdatedSrcMemRect = *(VBOXVHWA_RECTL*)((void*)&pOurInfo->DirtyRegion.Rect); else { pBody->u.in.xUpdatedSrcMemRect.right = pAlloc->SurfDesc.width; pBody->u.in.xUpdatedSrcMemRect.bottom = pAlloc->SurfDesc.height; /* top & left are zero-inited with the above memset */ } } if (pDstUpdateRect) { pBody->u.in.xFlags |= VBOXVHWACMD_SURF_OVERLAY_UPDATE_F_DSTMEMRECT; pBody->u.in.xUpdatedDstMemRect = *(VBOXVHWA_RECTL*)((void*)pDstUpdateRect); } /* we're not interested in completion, just send the command */ vboxVhwaCommandSubmitAsynchAndComplete(pOverlay->pDevExt, pCmd); pOverlay->pCurentAlloc = pAlloc; vboxVhwaHlpOverlayDstRectSet(pOverlay->pDevExt, pOverlay, &pOverlayInfo->DstRect); rc = VINF_SUCCESS; } else rc = VERR_OUT_OF_RESOURCES; } else rc = VERR_INVALID_PARAMETER; return rc; }
int vboxVhwaHlpOverlayFlip(PVBOXWDDM_OVERLAY pOverlay, const DXGKARG_FLIPOVERLAY *pFlipInfo) { PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pFlipInfo->hSource; Assert(pAlloc->hHostHandle); Assert(pAlloc->pResource); Assert(pAlloc->pResource == pOverlay->pResource); Assert(pFlipInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAYFLIP_INFO)); Assert(pFlipInfo->pPrivateDriverData); PVBOXWDDM_SOURCE pSource = &pOverlay->pDevExt->aSources[pOverlay->VidPnSourceId]; Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED)); PVBOXWDDM_ALLOCATION pFbSurf = VBOXVHWA_PRIMARY_ALLOCATION(pSource); Assert(pFbSurf); Assert(pFbSurf->hHostHandle); Assert(pFbSurf->offVram != VBOXVIDEOOFFSET_VOID); Assert(pOverlay->pCurentAlloc); Assert(pOverlay->pCurentAlloc->pResource == pOverlay->pResource); Assert(pOverlay->pCurentAlloc != pAlloc); int rc = VINF_SUCCESS; if (pFlipInfo->PrivateDriverDataSize == sizeof (VBOXWDDM_OVERLAYFLIP_INFO)) { PVBOXWDDM_OVERLAYFLIP_INFO pOurInfo = (PVBOXWDDM_OVERLAYFLIP_INFO)pFlipInfo->pPrivateDriverData; VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pOverlay->pDevExt, pOverlay->VidPnSourceId, VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP)); Assert(pCmd); if(pCmd) { VBOXVHWACMD_SURF_FLIP * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_FLIP)); // pBody->TargGuestSurfInfo; // pBody->CurrGuestSurfInfo; pBody->u.in.hTargSurf = pAlloc->hHostHandle; pBody->u.in.offTargSurface = pFlipInfo->SrcPhysicalAddress.QuadPart; pAlloc->offVram = pFlipInfo->SrcPhysicalAddress.QuadPart; pBody->u.in.hCurrSurf = pOverlay->pCurentAlloc->hHostHandle; pBody->u.in.offCurrSurface = pOverlay->pCurentAlloc->offVram; if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_VALID) { pBody->u.in.xUpdatedTargMemValid = 1; if (pOurInfo->DirtyRegion.fFlags & VBOXWDDM_DIRTYREGION_F_RECT_VALID) pBody->u.in.xUpdatedTargMemRect = *(VBOXVHWA_RECTL*)((void*)&pOurInfo->DirtyRegion.Rect); else { pBody->u.in.xUpdatedTargMemRect.right = pAlloc->SurfDesc.width; pBody->u.in.xUpdatedTargMemRect.bottom = pAlloc->SurfDesc.height; /* top & left are zero-inited with the above memset */ } } /* we're not interested in completion, just send the command */ vboxVhwaCommandSubmitAsynchAndComplete(pOverlay->pDevExt, pCmd); pOverlay->pCurentAlloc = pAlloc; rc = VINF_SUCCESS; } else rc = VERR_OUT_OF_RESOURCES; } else rc = VERR_INVALID_PARAMETER; return rc; }