VBOXVHWACMD_QUERYINFO1* VBoxDispVHWAQueryHostInfo1(PVBOXDISPDEV pDev) { VBOXVHWACMD* pCmd = VBoxDispVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_QUERY_INFO1, sizeof(VBOXVHWACMD_QUERYINFO1)); VBOXVHWACMD_QUERYINFO1 *pInfo1; if (!pCmd) { WARN(("VBoxDispVHWACommandCreate 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; if(VBoxDispVHWACommandSubmit (pDev, pCmd)) { if(RT_SUCCESS(pCmd->rc)) { return VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO1); } } VBoxDispVHWACommandRelease(pDev, 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; }
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; }
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; }
VBOXVHWACMD_QUERYINFO2* VBoxDispVHWAQueryHostInfo2(PVBOXDISPDEV pDev, uint32_t numFourCC) { VBOXVHWACMD* pCmd = VBoxDispVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_QUERY_INFO2, VBOXVHWAINFO2_SIZE(numFourCC)); VBOXVHWACMD_QUERYINFO2 *pInfo2; if (!pCmd) { WARN(("VBoxDispVHWACommandCreate failed")); return NULL; } pInfo2 = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_QUERYINFO2); pInfo2->numFourCC = numFourCC; if(VBoxDispVHWACommandSubmit (pDev, pCmd)) { if(RT_SUCCESS(pCmd->rc)) { if(pInfo2->numFourCC == numFourCC) { return pInfo2; } } } VBoxDispVHWACommandRelease(pDev, pCmd); return NULL; }
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; }
DWORD APIENTRY VBoxDispDDSetOverlayPosition(PDD_SETOVERLAYPOSITIONDATA lpSetOverlayPosition) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpSetOverlayPosition->lpDD->dhpdev; DD_SURFACE_LOCAL *pSrcSurf = lpSetOverlayPosition->lpDDSrcSurface; DD_SURFACE_LOCAL *pDstSurf = lpSetOverlayPosition->lpDDDestSurface; PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC) pSrcSurf->lpGbl->dwReserved1; PVBOXVHWASURFDESC pDstDesc = (PVBOXVHWASURFDESC) pDstSurf->lpGbl->dwReserved1; LOGF_ENTER(); if (pSrcDesc && pDstDesc) { if (!pSrcDesc->bVisible) { WARN(("!pSrcDesc->bVisible")); lpSetOverlayPosition->ddRVal = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; } VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_SETPOSITION, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION)); if (pCmd) { VBOXVHWACMD_SURF_OVERLAY_SETPOSITION *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_OVERLAY_SETPOSITION); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_OVERLAY_SETPOSITION)); pBody->u.in.offSrcSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSrcSurf->lpGbl->fpVidMem); pBody->u.in.offDstSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pDstSurf->lpGbl->fpVidMem); pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle; pBody->u.in.hDstSurf = pDstDesc->hHostHandle; pBody->u.in.xPos = lpSetOverlayPosition->lXPos; pBody->u.in.yPos = lpSetOverlayPosition->lYPos; VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd); lpSetOverlayPosition->ddRVal = DD_OK; } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpSetOverlayPosition->ddRVal = DDERR_GENERIC; } } else { WARN(("!(pSrcDesc && pDstDesc)")); lpSetOverlayPosition->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
static DECLCALLBACK(void) VBoxDispVHWASurfFlipCompletion(PVBOXDISPDEV pDev, VBOXVHWACMD * pCmd, void * pContext) { VBOXVHWACMD_SURF_FLIP *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP); PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC)pBody->CurrGuestSurfInfo; PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC)pBody->TargGuestSurfInfo; ASMAtomicDecU32(&pCurrDesc->cPendingFlipsCurr); ASMAtomicDecU32(&pTargDesc->cPendingFlipsTarg); VBoxDispVHWACommandRelease(pDev, pCmd); }
static DECLCALLBACK(void) VBoxDispVHWASurfBltCompletion(PVBOXDISPDEV pDev, VBOXVHWACMD * pCmd, void * pContext) { VBOXVHWACMD_SURF_BLT *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT); PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC)pBody->SrcGuestSurfInfo; PVBOXVHWASURFDESC pDestDesc = (PVBOXVHWASURFDESC)pBody->DstGuestSurfInfo; ASMAtomicDecU32(&pSrcDesc->cPendingBltsSrc); ASMAtomicDecU32(&pDestDesc->cPendingBltsDst); VBoxDispVHWACommandRelease(pDev, pCmd); }
/* Called to destroy DirectDraw surface, * in particular we should free vhwa resources allocated on VBoxDispDDCreateSurface. * Note: we're always returning DDHAL_DRIVER_NOTHANDLED because we rely on DirectDraw memory manager. */ DWORD APIENTRY VBoxDispDDDestroySurface(PDD_DESTROYSURFACEDATA lpDestroySurface) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpDestroySurface->lpDD->dhpdev; LOGF_ENTER(); lpDestroySurface->ddRVal = DD_OK; #ifdef VBOX_WITH_VIDEOHWACCEL if (pDev->vhwa.bEnabled) { VBOXVHWACMD* pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_DESTROY, sizeof(VBOXVHWACMD_SURF_DESTROY)); if (pCmd) { VBOXVHWACMD_SURF_DESTROY *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_DESTROY); PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)lpDestroySurface->lpDDSurface->lpGbl->dwReserved1; if (pDesc) { memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_DESTROY)); pBody->u.in.hSurf = pDesc->hHostHandle; VBoxDispVHWACommandSubmit(pDev, pCmd); VBoxDispVHWACommandRelease(pDev, pCmd); VBoxDispVHWASurfDescFree(pDesc); lpDestroySurface->lpDDSurface->lpGbl->dwReserved1 = (ULONG_PTR)NULL; } else { WARN(("!pDesc, memory overwrite somewhere?")); lpDestroySurface->ddRVal = DDERR_GENERIC; } } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpDestroySurface->ddRVal = DDERR_GENERIC; } } else #endif /*VBOX_WITH_VIDEOHWACCEL*/ LOGF_LEAVE(); return DDHAL_DRIVER_NOTHANDLED; }
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; }
DWORD APIENTRY VBoxDispDDSetColorKey(PDD_SETCOLORKEYDATA lpSetColorKey) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpSetColorKey->lpDD->dhpdev; LOGF_ENTER(); DD_SURFACE_LOCAL *pSurf = lpSetColorKey->lpDDSurface; PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC)pSurf->lpGbl->dwReserved1; VBOXVHWACMD* pCmd; lpSetColorKey->ddRVal = DD_OK; if (pDesc) { pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_COLORKEY_SET, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET)); if (pCmd) { VBOXVHWACMD_SURF_COLORKEY_SET *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORKEY_SET); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_COLORKEY_SET)); pBody->u.in.offSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSurf->lpGbl->fpVidMem); pBody->u.in.hSurf = pDesc->hHostHandle; pBody->u.in.flags = VBoxDispVHWAFromDDCKEYs(lpSetColorKey->dwFlags); VBoxDispVHWAFromDDCOLORKEY(&pBody->u.in.CKey, &lpSetColorKey->ckNew); VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd); } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpSetColorKey->ddRVal = DDERR_GENERIC; } } else { WARN(("!pDesc")); lpSetColorKey->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
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; }
DWORD APIENTRY VBoxDispDDBlt(PDD_BLTDATA lpBlt) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpBlt->lpDD->dhpdev; LOGF_ENTER(); DD_SURFACE_LOCAL *pSrcSurf = lpBlt->lpDDSrcSurface; DD_SURFACE_LOCAL *pDstSurf = lpBlt->lpDDDestSurface; PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC) pSrcSurf->lpGbl->dwReserved1; PVBOXVHWASURFDESC pDstDesc = (PVBOXVHWASURFDESC) pDstSurf->lpGbl->dwReserved1; if (pSrcDesc && pDstDesc) { VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_BLT, sizeof(VBOXVHWACMD_SURF_BLT)); if (pCmd) { VBOXVHWACMD_SURF_BLT *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_BLT); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_BLT)); pBody->u.in.offSrcSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSrcSurf->lpGbl->fpVidMem); pBody->u.in.offDstSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pDstSurf->lpGbl->fpVidMem); pBody->u.in.hDstSurf = pDstDesc->hHostHandle; VBoxDispVHWAFromRECTL(&pBody->u.in.dstRect, &lpBlt->rDest); pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle; VBoxDispVHWAFromRECTL(&pBody->u.in.srcRect, &lpBlt->rSrc); pBody->DstGuestSurfInfo = (uint64_t)pDstDesc; pBody->SrcGuestSurfInfo = (uint64_t)pSrcDesc; pBody->u.in.flags = VBoxDispVHWAFromDDBLTs(lpBlt->dwFlags); VBoxDispVHWAFromDDBLTFX(&pBody->u.in.desc, &lpBlt->bltFX); ASMAtomicIncU32(&pSrcDesc->cPendingBltsSrc); ASMAtomicIncU32(&pDstDesc->cPendingBltsDst); VBoxDispVHWARegionAdd(&pDstDesc->NonupdatedMemRegion, &lpBlt->rDest); VBoxDispVHWARegionTrySubstitute(&pDstDesc->UpdatedMemRegion, &lpBlt->rDest); if(pSrcDesc->UpdatedMemRegion.bValid) { pBody->u.in.xUpdatedSrcMemValid = 1; VBoxDispVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect); VBoxDispVHWARegionClear(&pSrcDesc->UpdatedMemRegion); } VBoxDispVHWACommandSubmitAsynch(pDev, pCmd, VBoxDispVHWASurfBltCompletion, NULL); lpBlt->ddRVal = DD_OK; } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpBlt->ddRVal = DDERR_GENERIC; } } else { WARN(("!(pSrcDesc && pDstDesc)")); lpBlt->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
/* Unlock previously locked surface */ DWORD APIENTRY VBoxDispDDUnlock(PDD_UNLOCKDATA lpUnlock) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpUnlock->lpDD->dhpdev; LOGF_ENTER(); DD_SURFACE_LOCAL *pSurf = lpUnlock->lpDDSurface; lpUnlock->ddRVal = DD_OK; #ifdef VBOX_WITH_VIDEOHWACCEL if(pDev->vhwa.bEnabled) { PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC) pSurf->lpGbl->dwReserved1; if (!pDesc) { WARN(("!pDesc, memory overwrite somewhere?")); lpUnlock->ddRVal = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; } if((pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) && pDesc->UpdatedMemRegion.bValid /* && VBoxVBVABufferBeginUpdate(&pDev->vbvaCtx, &pDev->hgsmi.ctx)*/) { vbvaReportDirtyRect(pDev, &pDesc->UpdatedMemRegion.Rect); if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET) { vrdpReset(pDev); pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents &= ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET; } if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_VRDP) { vrdpReportDirtyRect(pDev, &pDesc->UpdatedMemRegion.Rect); } #if 0 VBoxVBVABufferEndUpdate(&pDev->vbvaCtx); #endif } else if ((pSurf->ddsCaps.dwCaps & DDSCAPS_VISIBLE) || ((pSurf->ddsCaps.dwCaps & DDSCAPS_OVERLAY) && pDesc->bVisible)) { VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_UNLOCK, sizeof(VBOXVHWACMD_SURF_UNLOCK)); if(pCmd) { VBOXVHWACMD_SURF_UNLOCK *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_UNLOCK); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_UNLOCK)); pBody->u.in.hSurf = pDesc->hHostHandle; if(pDesc->UpdatedMemRegion.bValid) { pBody->u.in.xUpdatedMemValid = 1; VBoxDispVHWAFromRECTL(&pBody->u.in.xUpdatedMemRect, &pDesc->UpdatedMemRegion.Rect); VBoxDispVHWARegionClear(&pDesc->UpdatedMemRegion); } VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd); } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpUnlock->ddRVal = DDERR_GENERIC; } } return DDHAL_DRIVER_NOTHANDLED; } #endif /*VBOX_WITH_VIDEOHWACCEL*/ if (pDev->ddpsLock.bLocked) { pDev->ddpsLock.bLocked = FALSE; if (pDev->hgsmi.bSupported /* && VBoxVBVABufferBeginUpdate(&pDev->vbvaCtx, &pDev->hgsmi.ctx)*/) { vbvaReportDirtyRect(pDev, &pDev->ddpsLock.rect); if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET) { vrdpReset(pDev); pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents &= ~VBOX_VIDEO_INFO_HOST_EVENTS_F_VRDP_RESET; } if (pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents & VBVA_F_MODE_VRDP) { vrdpReportDirtyRect(pDev, &pDev->ddpsLock.rect); } #if 0 VBoxVBVABufferEndUpdate(&pDev->vbvaCtx); #endif } } LOGF_LEAVE(); return DDHAL_DRIVER_NOTHANDLED; }
/* Lock specified area of surface */ DWORD APIENTRY VBoxDispDDLock(PDD_LOCKDATA lpLock) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpLock->lpDD->dhpdev; LOGF_ENTER(); DD_SURFACE_LOCAL* pSurf = lpLock->lpDDSurface; lpLock->ddRVal = DD_OK; #if 0 #ifdef VBOX_WITH_VIDEOHWACCEL if(pDev->vhwa.bEnabled) { PVBOXVHWASURFDESC pDesc = (PVBOXVHWASURFDESC) pSurf->lpGbl->dwReserved1; RECTL tmpRect, *pRect; if (!pDesc) { WARN(("!pDesc, memory overwrite somewhere?")); lpLock->ddRVal = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; } /* Check if host is still processing drawing commands */ if (ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc) || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr) || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst) || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)) { VBoxDispVHWACommandCheckHostCmds(pDev); if(ASMAtomicUoReadU32(&pDesc->cPendingBltsSrc) || ASMAtomicUoReadU32(&pDesc->cPendingFlipsCurr) || ASMAtomicUoReadU32(&pDesc->cPendingBltsDst) || ASMAtomicUoReadU32(&pDesc->cPendingFlipsTarg)) { lpLock->ddRVal = DDERR_WASSTILLDRAWING; return DDHAL_DRIVER_HANDLED; } } if (lpLock->bHasRect) { pRect = &lpLock->rArea; } else { tmpRect.left = 0; tmpRect.top = 0; tmpRect.right = pSurf->lpGbl->wWidth-1; tmpRect.bottom = pSurf->lpGbl->wHeight-1; pRect = &tmpRect; } if (lpLock->dwFlags & DDLOCK_DISCARDCONTENTS) { VBoxDispVHWARegionTrySubstitute(&pDesc->NonupdatedMemRegion, pRect); VBoxDispVHWARegionAdd(&pDesc->UpdatedMemRegion, pRect); } else if (!VBoxDispVHWARegionIntersects(&pDesc->NonupdatedMemRegion, pRect)) { VBoxDispVHWARegionAdd(&pDesc->UpdatedMemRegion, pRect); } else { VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_LOCK, sizeof(VBOXVHWACMD_SURF_LOCK)); if (pCmd) { VBOXVHWACMD_SURF_LOCK *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_LOCK); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_LOCK)); pBody->u.in.offSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSurf->lpGbl->fpVidMem); VBoxDispVHWAFromRECTL(&pBody->u.in.rect, &pDesc->NonupdatedMemRegion.Rect); pBody->u.in.rectValid = 1; pBody->u.in.hSurf = pDesc->hHostHandle; /* wait for the surface to be locked and memory buffer updated */ VBoxDispVHWACommandSubmit(pDev, pCmd); VBOX_WARNRC(pCmd->rc); VBoxDispVHWACommandRelease(pDev, pCmd); VBoxDispVHWARegionClear(&pDesc->NonupdatedMemRegion); } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpLock->ddRVal = DDERR_GENERIC; } } return DDHAL_DRIVER_NOTHANDLED; } #endif /*VBOX_WITH_VIDEOHWACCEL*/ #endif /* We only care about primary surface as we'd have to report dirty rectangles to the host in the DDUnlock*/ if (pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { pDev->ddpsLock.bLocked = TRUE; if (lpLock->bHasRect) { pDev->ddpsLock.rect = lpLock->rArea; } else { pDev->ddpsLock.rect.left = 0; pDev->ddpsLock.rect.top = 0; pDev->ddpsLock.rect.right = pDev->mode.ulWidth; pDev->ddpsLock.rect.bottom = pDev->mode.ulHeight; } } LOGF_LEAVE(); return DDHAL_DRIVER_NOTHANDLED; }
/* Called to check if our driver can create surface with requested attributes */ DWORD APIENTRY VBoxDispDDCanCreateSurface(PDD_CANCREATESURFACEDATA lpCanCreateSurface) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpCanCreateSurface->lpDD->dhpdev; LOGF_ENTER(); PDD_SURFACEDESC lpDDS = lpCanCreateSurface->lpDDSurfaceDesc; #ifdef VBOX_WITH_VIDEOHWACCEL if(pDev->vhwa.bEnabled) { VBOXVHWACMD* pCmd; uint32_t unsupportedSCaps = VBoxDispVHWAUnsupportedDDSCAPS(lpDDS->ddsCaps.dwCaps); if(unsupportedSCaps) { WARN(("unsupported ddscaps: %#x", unsupportedSCaps)); lpCanCreateSurface->ddRVal = DDERR_INVALIDCAPS; return DDHAL_DRIVER_HANDLED; } unsupportedSCaps = VBoxDispVHWAUnsupportedDDPFS(lpDDS->ddpfPixelFormat.dwFlags); if(unsupportedSCaps) { WARN(("unsupported pixel format: %#x", unsupportedSCaps)); lpCanCreateSurface->ddRVal = DDERR_INVALIDPIXELFORMAT; return DDHAL_DRIVER_HANDLED; } pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_CANCREATE, sizeof(VBOXVHWACMD_SURF_CANCREATE)); if(pCmd) { int rc; VBOXVHWACMD_SURF_CANCREATE *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CANCREATE); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CANCREATE)); rc = VBoxDispVHWAFromDDSURFACEDESC(&pBody->SurfInfo, lpDDS); pBody->u.in.bIsDifferentPixelFormat = lpCanCreateSurface->bIsDifferentPixelFormat; VBoxDispVHWACommandSubmit(pDev, pCmd); if (RT_SUCCESS(pCmd->rc)) { if(pBody->u.out.ErrInfo) { lpCanCreateSurface->ddRVal = DDERR_GENERIC; } else { WARN(("pBody->u.out.ErrInfo = %#x", pBody->u.out.ErrInfo)); lpCanCreateSurface->ddRVal = DD_OK; } } else { WARN(("VBoxDispVHWACommandSubmit failed with rc=%#x", rc)); lpCanCreateSurface->ddRVal = DDERR_GENERIC; } VBoxDispVHWACommandRelease(pDev, pCmd); } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpCanCreateSurface->ddRVal = DDERR_GENERIC; } return DDHAL_DRIVER_HANDLED; } #endif /*VBOX_WITH_VIDEOHWACCEL*/ if (lpDDS->ddsCaps.dwCaps & DDSCAPS_ZBUFFER) { LOG(("No Z-Bufer support")); lpCanCreateSurface->ddRVal = DDERR_UNSUPPORTED; return DDHAL_DRIVER_HANDLED; } if (lpDDS->ddsCaps.dwCaps & DDSCAPS_TEXTURE) { LOG(("No texture support")); lpCanCreateSurface->ddRVal = DDERR_UNSUPPORTED; return DDHAL_DRIVER_HANDLED; } if (lpCanCreateSurface->bIsDifferentPixelFormat && (lpDDS->ddpfPixelFormat.dwFlags & DDPF_FOURCC)) { LOG(("FOURCC not supported")); lpCanCreateSurface->ddRVal = DDERR_UNSUPPORTED; return DDHAL_DRIVER_HANDLED; } lpCanCreateSurface->ddRVal = DD_OK; LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
DWORD APIENTRY VBoxDispDDFlip(PDD_FLIPDATA lpFlip) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpFlip->lpDD->dhpdev; LOGF_ENTER(); DD_SURFACE_LOCAL *pCurrSurf = lpFlip->lpSurfCurr; DD_SURFACE_LOCAL *pTargSurf = lpFlip->lpSurfTarg; PVBOXVHWASURFDESC pCurrDesc = (PVBOXVHWASURFDESC) pCurrSurf->lpGbl->dwReserved1; PVBOXVHWASURFDESC pTargDesc = (PVBOXVHWASURFDESC) pTargSurf->lpGbl->dwReserved1; if (pCurrDesc && pTargDesc) { if(ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg) || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr) || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg) || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr)) { VBoxDispVHWACommandCheckHostCmds(pDev); if(ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsTarg) || ASMAtomicUoReadU32(&pCurrDesc->cPendingFlipsCurr) || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsTarg) || ASMAtomicUoReadU32(&pTargDesc->cPendingFlipsCurr)) { lpFlip->ddRVal = DDERR_WASSTILLDRAWING; return DDHAL_DRIVER_HANDLED; } } VBOXVHWACMD *pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_FLIP, sizeof(VBOXVHWACMD_SURF_FLIP)); if (pCmd) { VBOXVHWACMD_SURF_FLIP *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_FLIP); memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_FLIP)); pBody->u.in.offCurrSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pCurrSurf->lpGbl->fpVidMem); pBody->u.in.offTargSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pTargSurf->lpGbl->fpVidMem); pBody->u.in.hTargSurf = pTargDesc->hHostHandle; pBody->u.in.hCurrSurf = pCurrDesc->hHostHandle; pBody->TargGuestSurfInfo = (uint64_t)pTargDesc; pBody->CurrGuestSurfInfo = (uint64_t)pCurrDesc; pTargDesc->bVisible = pCurrDesc->bVisible; pCurrDesc->bVisible = false; ASMAtomicIncU32(&pCurrDesc->cPendingFlipsCurr); ASMAtomicIncU32(&pTargDesc->cPendingFlipsTarg); #ifdef DEBUG ASMAtomicIncU32(&pCurrDesc->cFlipsCurr); ASMAtomicIncU32(&pTargDesc->cFlipsTarg); #endif if(pTargDesc->UpdatedMemRegion.bValid) { pBody->u.in.xUpdatedTargMemValid = 1; VBoxDispVHWAFromRECTL(&pBody->u.in.xUpdatedTargMemRect, &pTargDesc->UpdatedMemRegion.Rect); VBoxDispVHWARegionClear(&pTargDesc->UpdatedMemRegion); } VBoxDispVHWACommandSubmitAsynch(pDev, pCmd, VBoxDispVHWASurfFlipCompletion, NULL); lpFlip->ddRVal = DD_OK; } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpFlip->ddRVal = DDERR_GENERIC; } } else { WARN(("!(pCurrDesc && pTargDesc)")); lpFlip->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
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; }
DWORD APIENTRY VBoxDispDDUpdateOverlay(PDD_UPDATEOVERLAYDATA lpUpdateOverlay) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpUpdateOverlay->lpDD->dhpdev; DD_SURFACE_LOCAL* pSrcSurf = lpUpdateOverlay->lpDDSrcSurface; DD_SURFACE_LOCAL* pDstSurf = lpUpdateOverlay->lpDDDestSurface; PVBOXVHWASURFDESC pSrcDesc = (PVBOXVHWASURFDESC) pSrcSurf->lpGbl->dwReserved1; LOGF_ENTER(); if (pSrcDesc) { VBOXVHWACMD* pCmd; pCmd = VBoxDispVHWACommandCreate (pDev, VBOXVHWACMD_TYPE_SURF_OVERLAY_UPDATE, sizeof(VBOXVHWACMD_SURF_OVERLAY_UPDATE)); 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.offSrcSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pSrcSurf->lpGbl->fpVidMem); pBody->u.in.hSrcSurf = pSrcDesc->hHostHandle; VBoxDispVHWAFromRECTL(&pBody->u.in.dstRect, &lpUpdateOverlay->rDest); VBoxDispVHWAFromRECTL(&pBody->u.in.srcRect, &lpUpdateOverlay->rSrc); pBody->u.in.flags = VBoxDispVHWAFromDDOVERs(lpUpdateOverlay->dwFlags); VBoxDispVHWAFromDDOVERLAYFX(&pBody->u.in.desc, &lpUpdateOverlay->overlayFX); if (lpUpdateOverlay->dwFlags & DDOVER_HIDE) { pSrcDesc->bVisible = false; } else if(lpUpdateOverlay->dwFlags & DDOVER_SHOW) { pSrcDesc->bVisible = true; if(pSrcDesc->UpdatedMemRegion.bValid) { pBody->u.in.xFlags = VBOXVHWACMD_SURF_OVERLAY_UPDATE_F_SRCMEMRECT; VBoxDispVHWAFromRECTL(&pBody->u.in.xUpdatedSrcMemRect, &pSrcDesc->UpdatedMemRegion.Rect); VBoxDispVHWARegionClear(&pSrcDesc->UpdatedMemRegion); } } if(pDstSurf) { PVBOXVHWASURFDESC pDstDesc = (PVBOXVHWASURFDESC) pDstSurf->lpGbl->dwReserved1; if (!pDstDesc) { WARN(("!pDstDesc")); lpUpdateOverlay->ddRVal = DDERR_GENERIC; return DDHAL_DRIVER_HANDLED; } pBody->u.in.hDstSurf = pDstDesc->hHostHandle; pBody->u.in.offDstSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, pDstSurf->lpGbl->fpVidMem); } VBoxDispVHWACommandSubmitAsynchAndComplete(pDev, pCmd); lpUpdateOverlay->ddRVal = DD_OK; } else { WARN(("VBoxDispVHWACommandCreate failed!")); lpUpdateOverlay->ddRVal = DDERR_GENERIC; } } else { WARN(("!pSrcDesc")); lpUpdateOverlay->ddRVal = DDERR_GENERIC; } LOGF_LEAVE(); return DDHAL_DRIVER_HANDLED; }
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; }
/* Called to create DirectDraw surface. * Note: we always return DDHAL_DRIVER_NOTHANDLED, which asks DirectDraw memory manager * to perform actual memory allocation in our DDraw heap. */ DWORD APIENTRY VBoxDispDDCreateSurface(PDD_CREATESURFACEDATA lpCreateSurface) { PVBOXDISPDEV pDev = (PVBOXDISPDEV) lpCreateSurface->lpDD->dhpdev; LOGF_ENTER(); PDD_SURFACE_LOCAL pSurf = lpCreateSurface->lplpSList[0]; if (pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { LOG(("primary surface")); pSurf->lpGbl->fpVidMem = 0; } else { LOG(("non primary surface")); pSurf->lpGbl->fpVidMem = DDHAL_PLEASEALLOC_BLOCKSIZE; } pSurf->lpGbl->dwReserved1 = 0; #ifdef VBOX_WITH_VIDEOHWACCEL if(pDev->vhwa.bEnabled) { VBOXVHWACMD* pCmd; pCmd = VBoxDispVHWACommandCreate(pDev, VBOXVHWACMD_TYPE_SURF_CREATE, sizeof(VBOXVHWACMD_SURF_CREATE)); if (pCmd) { VBOXVHWACMD_SURF_CREATE *pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_CREATE); PVBOXVHWASURFDESC pDesc; int rc; memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_CREATE)); rc = VBoxDispVHWAFromDDSURFACEDESC(&pBody->SurfInfo, lpCreateSurface->lpDDSurfaceDesc); VBOX_WARNRC(rc); pBody->SurfInfo.surfCaps = VBoxDispVHWAFromDDSCAPS(pSurf->ddsCaps.dwCaps); pBody->SurfInfo.flags |= DDSD_CAPS; pBody->SurfInfo.height = pSurf->lpGbl->wHeight; pBody->SurfInfo.width = pSurf->lpGbl->wWidth; pBody->SurfInfo.flags |= DDSD_HEIGHT | DDSD_WIDTH; VBoxDispVHWAFromDDPIXELFORMAT(&pBody->SurfInfo.PixelFormat, &pSurf->lpGbl->ddpfSurface); pBody->SurfInfo.flags |= VBOXVHWA_SD_PIXELFORMAT; if (pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { pBody->SurfInfo.offSurface = VBoxDispVHWAVramOffsetFromPDEV(pDev, 0); } else { pBody->SurfInfo.offSurface = VBOXVHWA_OFFSET64_VOID; } pDesc = VBoxDispVHWASurfDescAlloc(); if (pDesc) { VBoxDispVHWACommandSubmit(pDev, pCmd); if (RT_SUCCESS(pCmd->rc)) { uint32_t surfSizeX = pBody->SurfInfo.sizeX; uint32_t surfSizeY = pBody->SurfInfo.sizeY; pDesc->hHostHandle = pBody->SurfInfo.hSurf; if(!!(pSurf->ddsCaps.dwCaps & DDSCAPS_OVERLAY) && !!(pSurf->ddsCaps.dwCaps & DDSCAPS_VISIBLE)) { pDesc->bVisible = true; } pSurf->lpGbl->dwBlockSizeX = pBody->SurfInfo.sizeX; pSurf->lpGbl->dwBlockSizeY = pBody->SurfInfo.sizeY; pSurf->lpGbl->lPitch = pBody->SurfInfo.pitch; lpCreateSurface->lpDDSurfaceDesc->lPitch = pSurf->lpGbl->lPitch; lpCreateSurface->lpDDSurfaceDesc->dwFlags |= DDSD_PITCH; /*@todo: it's probably a memory leak, because DDDestroySurface wouldn't be called for * primary surfaces. */ pSurf->lpGbl->dwReserved1 = (ULONG_PTR)pDesc; } else { WARN(("VBoxDispVHWACommandSubmit failed with rc=%#x", rc)); VBoxDispVHWASurfDescFree(pDesc); } } else { WARN(("VBoxDispVHWASurfDescAlloc failed")); } VBoxDispVHWACommandRelease(pDev, pCmd); } else { WARN(("VBoxDispVHWACommandCreate failed")); } return DDHAL_DRIVER_NOTHANDLED; } #endif /*VBOX_WITH_VIDEOHWACCEL*/ LPDDSURFACEDESC pDesc = lpCreateSurface->lpDDSurfaceDesc; if (pDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED4) { pSurf->lpGbl->lPitch = RT_ALIGN_T(pSurf->lpGbl->wWidth/2, 32, LONG); } else if (pDesc->ddpfPixelFormat.dwFlags & DDPF_PALETTEINDEXED8) { pSurf->lpGbl->lPitch = RT_ALIGN_T(pSurf->lpGbl->wWidth, 32, LONG); } else { pSurf->lpGbl->lPitch = pSurf->lpGbl->wWidth*(pDesc->ddpfPixelFormat.dwRGBBitCount/8); } pSurf->lpGbl->dwBlockSizeX = pSurf->lpGbl->lPitch; pSurf->lpGbl->dwBlockSizeY = pSurf->lpGbl->wHeight; pDesc->lPitch = pSurf->lpGbl->lPitch; pDesc->dwFlags |= DDSD_PITCH; LOGF_LEAVE(); return DDHAL_DRIVER_NOTHANDLED; }