VirtualBox

Ignore:
Timestamp:
Sep 29, 2010 4:50:53 PM (14 years ago)
Author:
vboxsync
Message:

wddm/2d: 2D video accel support fixes

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoMisc.h

    r32766 r32823  
    1313#ifndef ___VBoxVideoMisc_h__
    1414#define ___VBoxVideoMisc_h__
     15
     16DECLINLINE(void) vboxVideoLeDetach(LIST_ENTRY *pList, LIST_ENTRY *pDstList)
     17{
     18    if (IsListEmpty(pList))
     19    {
     20        InitializeListHead(pDstList);
     21    }
     22    else
     23    {
     24        *pDstList = *pList;
     25        Assert(pDstList->Flink->Blink == pList);
     26        Assert(pDstList->Blink->Flink == pList);
     27        /* pDstList->Flink & pDstList->Blink point to the "real| entries, never to pList
     28         * since we've checked IsListEmpty(pList) above */
     29        pDstList->Flink->Blink = pDstList;
     30        pDstList->Blink->Flink = pDstList;
     31        InitializeListHead(pList);
     32    }
     33}
    1534
    1635typedef struct _DEVICE_EXTENSION *PDEVICE_EXTENSION;
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.cpp

    r32496 r32823  
    228228}
    229229
     230DECLCALLBACK(VOID) vboxVdmaGgDdiCmdDestroy(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
     231{
     232    vboxVdmaGgCmdDestroy((PVBOXVDMAPIPE_CMD_DR)pvContext);
     233}
    230234
    231235/**
     
    257261DECLINLINE(void) vboxVdmaDirtyRectsCalcIntersection(const RECT *pArea, const PVBOXWDDM_RECTS_INFO pRects, PVBOXWDDM_RECTS_INFO pResult)
    258262{
    259     pResult->cRects = 0;
     263    uint32_t cRects = 0;
    260264    for (uint32_t i = 0; i < pRects->cRects; ++i)
    261265    {
    262         if (vboxWddmRectIntersection(pArea, &pRects->aRects[i], &pResult->aRects[pResult->cRects]))
    263         {
    264             ++pResult->cRects;
    265         }
    266     }
     266        if (vboxWddmRectIntersection(pArea, &pRects->aRects[i], &pResult->aRects[cRects]))
     267        {
     268            ++cRects;
     269        }
     270    }
     271
     272    pResult->cRects = cRects;
    267273}
    268274
     
    304310 * @param pDevExt
    305311 */
    306 static NTSTATUS vboxVdmaGgDirtyRectsProcess(VBOXVDMAPIPE_CMD_RECTSINFO *pRectsInfo)
    307 {
    308     PVBOXWDDM_CONTEXT pContext = pRectsInfo->pContext;
    309     PVBOXWDDM_SWAPCHAIN pSwapchain = pRectsInfo->pSwapchain;
    310     PDEVICE_EXTENSION pDevExt = pContext->pDevice->pAdapter;
    311     PVBOXWDDM_RECTS_INFO pRects = &pRectsInfo->ContextsRects.UpdateRects;
     312static NTSTATUS vboxVdmaGgDirtyRectsProcess(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain, VBOXVDMAPIPE_RECTS *pContextRects)
     313{
     314    PVBOXWDDM_RECTS_INFO pRects = &pContextRects->UpdateRects;
    312315    NTSTATUS Status = STATUS_SUCCESS;
    313316    PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = NULL;
     
    394397        else
    395398        {
    396             RECT * pContextRect = &pRectsInfo->ContextsRects.ContextRect;
     399            RECT * pContextRect = &pContextRects->ContextRect;
    397400            bool bRectShanged = (pSwapchain->ViewRect.left != pContextRect->left
    398401                    || pSwapchain->ViewRect.top != pContextRect->top
     
    506509{
    507510    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    508     PVBOXWDDM_CONTEXT pContext = pCF->pContext;
     511    PVBOXWDDM_CONTEXT pContext = pCF->Hdr.DdiCmd.pContext;
    509512    PDEVICE_EXTENSION pDevExt = pContext->pDevice->pAdapter;
    510513    Assert (pDevExt->pvVisibleVram);
    511514    if (pDevExt->pvVisibleVram)
    512515    {
    513         PVBOXWDDM_ALLOCATION pAlloc = pCF->pAllocation;
     516        PVBOXWDDM_ALLOCATION pAlloc = pCF->ClrFill.Alloc.pAlloc;
    514517        Assert(pAlloc->offVram != VBOXVIDEOOFFSET_VOID);
    515518        if (pAlloc->offVram != VBOXVIDEOOFFSET_VOID)
     
    525528                {
    526529                    uint8_t bytestPP = bpp >> 3;
    527                     for (UINT i = 0; i < pCF->Rects.cRects; ++i)
     530                    for (UINT i = 0; i < pCF->ClrFill.Rects.cRects; ++i)
    528531                    {
    529                         RECT *pRect = &pCF->Rects.aRects[i];
     532                        RECT *pRect = &pCF->ClrFill.Rects.aRects[i];
    530533                        for (LONG ir = pRect->top; ir < pRect->bottom; ++ir)
    531534                        {
     
    538541                            for (UINT j = 0; j < cRaw; ++j)
    539542                            {
    540                                 *pvU32Mem = pCF->Color;
     543                                *pvU32Mem = pCF->ClrFill.Color;
    541544                                ++pvU32Mem;
    542545                            }
     
    556559            if (Status == STATUS_SUCCESS)
    557560            {
    558                 if (pCF->VidPnSourceId != D3DDDI_ID_UNINITIALIZED
     561                if (pAlloc->SurfDesc.VidPnSourceId != D3DDDI_ID_UNINITIALIZED
    559562                        && pAlloc->bAssigned
    560 #ifdef VBOXWDDM_RENDER_FROM_SHADOW
     563#if 0//def VBOXWDDM_RENDER_FROM_SHADOW
    561564                        && pAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE
    562565#else
     
    567570                    if (!vboxWddmRectIsEmpty(&UnionRect))
    568571                    {
    569                         PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pCF->VidPnSourceId];
     572                        PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pCF->ClrFill.Alloc.pAlloc->SurfDesc.VidPnSourceId];
    570573                        VBOXVBVA_OP_WITHLOCK(ReportDirtyRect, pDevExt, pSource, &UnionRect);
    571574                    }
     
    579582    }
    580583
    581 
    582     uint32_t cNew = ASMAtomicDecU32(&pDevExt->cDMACmdsOutstanding);
    583     Assert(cNew < UINT32_MAX/2);
     584    return Status;
     585}
     586
     587NTSTATUS vboxVdmaGgDmaBltPerform(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pSrcAlloc, RECT* pSrcRect,
     588        PVBOXWDDM_ALLOCATION pDstAlloc, RECT* pDstRect)
     589{
     590    uint8_t* pvVramBase = pDevExt->pvVisibleVram;
     591    /* we do not support color conversion */
     592    Assert(pSrcAlloc->SurfDesc.format == pDstAlloc->SurfDesc.format);
     593    /* we do not support stretching */
     594    uint32_t srcWidth = pSrcRect->right - pSrcRect->left;
     595    uint32_t srcHeight = pSrcRect->bottom - pSrcRect->top;
     596    uint32_t dstWidth = pDstRect->right - pDstRect->left;
     597    uint32_t dstHeight = pDstRect->bottom - pDstRect->top;
     598    Assert(srcHeight == dstHeight);
     599    Assert(dstWidth == srcWidth);
     600    Assert(pDstAlloc->offVram != VBOXVIDEOOFFSET_VOID);
     601    Assert(pSrcAlloc->offVram != VBOXVIDEOOFFSET_VOID);
     602
     603    if (pSrcAlloc->SurfDesc.format != pDstAlloc->SurfDesc.format)
     604        return STATUS_INVALID_PARAMETER;
     605    if (srcHeight != dstHeight)
     606            return STATUS_INVALID_PARAMETER;
     607    if (srcWidth != dstWidth)
     608            return STATUS_INVALID_PARAMETER;
     609    if (pDstAlloc->offVram == VBOXVIDEOOFFSET_VOID)
     610        return STATUS_INVALID_PARAMETER;
     611    if (pSrcAlloc->offVram == VBOXVIDEOOFFSET_VOID)
     612        return STATUS_INVALID_PARAMETER;
     613
     614    uint8_t *pvDstSurf = pvVramBase + pDstAlloc->offVram;
     615    uint8_t *pvSrcSurf = pvVramBase + pSrcAlloc->offVram;
     616
     617    if (pDstAlloc->SurfDesc.width == dstWidth
     618            && pSrcAlloc->SurfDesc.width == srcWidth
     619            && pSrcAlloc->SurfDesc.width == pDstAlloc->SurfDesc.width)
     620    {
     621        Assert(!pDstRect->left);
     622        Assert(!pSrcRect->left);
     623        uint32_t cbOff = pDstAlloc->SurfDesc.pitch * pDstRect->top;
     624        uint32_t cbSize = pDstAlloc->SurfDesc.pitch * dstHeight;
     625        memcpy(pvDstSurf + cbOff, pvSrcSurf + cbOff, cbSize);
     626    }
     627    else
     628    {
     629        uint32_t offDstLineStart = pDstRect->left * pDstAlloc->SurfDesc.bpp >> 3;
     630        uint32_t offDstLineEnd = ((pDstRect->left * pDstAlloc->SurfDesc.bpp + 7) >> 3) + ((pDstAlloc->SurfDesc.bpp * dstWidth + 7) >> 3);
     631        uint32_t cbDstLine = offDstLineEnd - offDstLineStart;
     632        uint32_t offDstStart = pDstAlloc->SurfDesc.pitch * pDstRect->top + offDstLineStart;
     633        Assert(cbDstLine <= pDstAlloc->SurfDesc.pitch);
     634        uint32_t cbDstSkip = pDstAlloc->SurfDesc.pitch;
     635        uint8_t * pvDstStart = pvDstSurf + offDstStart;
     636
     637        uint32_t offSrcLineStart = pSrcRect->left * pSrcAlloc->SurfDesc.bpp >> 3;
     638        uint32_t offSrcLineEnd = ((pSrcRect->left * pSrcAlloc->SurfDesc.bpp + 7) >> 3) + ((pSrcAlloc->SurfDesc.bpp * srcWidth + 7) >> 3);
     639        uint32_t cbSrcLine = offSrcLineEnd - offSrcLineStart;
     640        uint32_t offSrcStart = pSrcAlloc->SurfDesc.pitch * pSrcRect->top + offSrcLineStart;
     641        Assert(cbSrcLine <= pSrcAlloc->SurfDesc.pitch);
     642        uint32_t cbSrcSkip = pSrcAlloc->SurfDesc.pitch;
     643        const uint8_t * pvSrcStart = pvSrcSurf + offSrcStart;
     644
     645        Assert(cbDstLine == cbSrcLine);
     646
     647        for (uint32_t i = 0; ; ++i)
     648        {
     649            memcpy (pvDstStart, pvSrcStart, cbDstLine);
     650            if (i == dstHeight)
     651                break;
     652            pvDstStart += cbDstSkip;
     653            pvSrcStart += cbSrcSkip;
     654        }
     655    }
     656    return STATUS_SUCCESS;
     657}
     658
     659/*
     660 * @return on success the number of bytes the command contained, otherwise - VERR_xxx error code
     661 */
     662static NTSTATUS vboxVdmaGgDmaBlt(PVBOXVDMAPIPE_CMD_DMACMD_BLT pBlt)
     663{
     664    /* we do not support stretching for now */
     665    Assert(pBlt->Blt.SrcRect.right - pBlt->Blt.SrcRect.left == pBlt->Blt.DstRects.ContextRect.right - pBlt->Blt.DstRects.ContextRect.left);
     666    Assert(pBlt->Blt.SrcRect.bottom - pBlt->Blt.SrcRect.top == pBlt->Blt.DstRects.ContextRect.bottom - pBlt->Blt.DstRects.ContextRect.top);
     667    if (pBlt->Blt.SrcRect.right - pBlt->Blt.SrcRect.left != pBlt->Blt.DstRects.ContextRect.right - pBlt->Blt.DstRects.ContextRect.left)
     668        return STATUS_INVALID_PARAMETER;
     669    if (pBlt->Blt.SrcRect.bottom - pBlt->Blt.SrcRect.top != pBlt->Blt.DstRects.ContextRect.bottom - pBlt->Blt.DstRects.ContextRect.top)
     670        return STATUS_INVALID_PARAMETER;
     671    Assert(pBlt->Blt.DstRects.UpdateRects.cRects);
     672
     673    NTSTATUS Status = STATUS_SUCCESS;
     674    PDEVICE_EXTENSION pDevExt = pBlt->Hdr.pDevExt;
     675
     676    if (pBlt->Blt.DstRects.UpdateRects.cRects)
     677    {
     678        for (uint32_t i = 0; i < pBlt->Blt.DstRects.UpdateRects.cRects; ++i)
     679        {
     680            RECT DstRect;
     681            RECT SrcRect;
     682            vboxWddmRectTranslated(&DstRect, &pBlt->Blt.DstRects.UpdateRects.aRects[i], pBlt->Blt.DstRects.ContextRect.left, pBlt->Blt.DstRects.ContextRect.top);
     683            vboxWddmRectTranslated(&SrcRect, &pBlt->Blt.DstRects.UpdateRects.aRects[i], pBlt->Blt.SrcRect.left, pBlt->Blt.SrcRect.top);
     684
     685            Status = vboxVdmaGgDmaBltPerform(pDevExt, pBlt->Blt.SrcAlloc.pAlloc, &SrcRect,
     686                    pBlt->Blt.DstAlloc.pAlloc, &DstRect);
     687            Assert(Status == STATUS_SUCCESS);
     688            if (Status != STATUS_SUCCESS)
     689                return Status;
     690        }
     691    }
     692    else
     693    {
     694        Status = vboxVdmaGgDmaBltPerform(pDevExt, pBlt->Blt.SrcAlloc.pAlloc, &pBlt->Blt.SrcRect,
     695                pBlt->Blt.DstAlloc.pAlloc, &pBlt->Blt.DstRects.ContextRect);
     696        Assert(Status == STATUS_SUCCESS);
     697        if (Status != STATUS_SUCCESS)
     698            return Status;
     699    }
     700
     701    return Status;
     702}
     703
     704static VOID vboxWddmBltPipeRectsTranslate(VBOXVDMAPIPE_RECTS *pRects, int x, int y)
     705{
     706    vboxWddmRectTranslate(&pRects->ContextRect, x, y);
     707
     708    for (UINT i = 0; i < pRects->UpdateRects.cRects; ++i)
     709    {
     710        vboxWddmRectTranslate(&pRects->UpdateRects.aRects[i], x, y);
     711    }
     712}
     713
     714static NTSTATUS vboxVdmaGgDmaCmdProcess(VBOXVDMAPIPE_CMD_DMACMD *pDmaCmd)
     715{
     716    PDEVICE_EXTENSION pDevExt = pDmaCmd->pDevExt;
     717    PVBOXWDDM_CONTEXT pContext = pDmaCmd->DdiCmd.pContext;
     718    NTSTATUS Status = STATUS_SUCCESS;
     719    switch (pDmaCmd->enmCmd)
     720    {
     721        case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT:
     722        {
     723            PVBOXVDMAPIPE_CMD_DMACMD_BLT pBlt = (PVBOXVDMAPIPE_CMD_DMACMD_BLT)pDmaCmd;
     724            PVBOXWDDM_ALLOCATION pDstAlloc = pBlt->Blt.DstAlloc.pAlloc;
     725            PVBOXWDDM_ALLOCATION pSrcAlloc = pBlt->Blt.SrcAlloc.pAlloc;
     726            BOOLEAN bComplete = TRUE;
     727            switch (pDstAlloc->enmType)
     728            {
     729                case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
     730                case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
     731                {
     732                    if (pDstAlloc->bAssigned)
     733                    {
     734                        VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->SurfDesc.VidPnSourceId];
     735                        Assert(pSource->pPrimaryAllocation == pDstAlloc);
     736                        switch (pSrcAlloc->enmType)
     737                        {
     738                            case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
     739                            {
     740                                Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM);
     741
     742                                if (pBlt->Hdr.fFlags.b2DRelated || pBlt->Hdr.fFlags.b3DRelated)
     743                                {
     744                                    POINT pos;
     745                                    BOOLEAN bPosMoved = FALSE;
     746                                    if (pBlt->Hdr.fFlags.b3DRelated)
     747                                    {
     748                                        pos = pSource->VScreenPos;
     749                                        if (pos.x || pos.y)
     750                                        {
     751                                            vboxWddmBltPipeRectsTranslate(&pBlt->Blt.DstRects, pos.x, pos.y);
     752                                            bPosMoved = TRUE;
     753                                        }
     754                                        Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, NULL, &pBlt->Blt.DstRects);
     755                                        Assert(Status == STATUS_SUCCESS);
     756                                    }
     757
     758
     759                                    if (pBlt->Hdr.fFlags.b2DRelated)
     760                                    {
     761                                        if (bPosMoved)
     762                                        {
     763                                            vboxWddmBltPipeRectsTranslate(&pBlt->Blt.DstRects, -pos.x, -pos.y);
     764                                        }
     765
     766                                        RECT OverlayUnionRect;
     767                                        RECT UpdateRect;
     768                                        UpdateRect = pBlt->Blt.DstRects.UpdateRects.aRects[0];
     769                                        for (UINT i = 1; i < pBlt->Blt.DstRects.UpdateRects.cRects; ++i)
     770                                        {
     771                                            vboxWddmRectUnite(&UpdateRect, &pBlt->Blt.DstRects.UpdateRects.aRects[i]);
     772                                        }
     773                                        vboxVhwaHlpOverlayDstRectUnion(pDevExt, pDstAlloc->SurfDesc.VidPnSourceId, &OverlayUnionRect);
     774                                        Assert(pBlt->Blt.DstRects.ContextRect.left == 0); /* <-| otherwise we would probably need to translate the UpdateRects to left;top first??*/
     775                                        Assert(pBlt->Blt.DstRects.ContextRect.top == 0); /* <--| */
     776                                        vboxVdmaDirtyRectsCalcIntersection(&OverlayUnionRect, &pBlt->Blt.DstRects.UpdateRects, &pBlt->Blt.DstRects.UpdateRects);
     777                                        if (pBlt->Blt.DstRects.UpdateRects.cRects)
     778                                        {
     779                                            vboxVdmaGgDmaBlt(pBlt);
     780                                        }
     781                                        VBOXVBVA_OP_WITHLOCK(ReportDirtyRect, pDevExt, pSource, &UpdateRect);
     782                                    }
     783                                }
     784
     785                                break;
     786                            }
     787                            case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
     788                            {
     789                                Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D);
     790                                Assert(pSrcAlloc->fRcFlags.RenderTarget);
     791                                if (pSrcAlloc->fRcFlags.RenderTarget)
     792                                {
     793                                    if (pBlt->Hdr.fFlags.b3DRelated)
     794                                    {
     795                                        PVBOXWDDM_SWAPCHAIN pSwapchain;
     796                                        pSwapchain = vboxWddmSwapchainRetainByAlloc(pDevExt, pSrcAlloc);
     797                                        if (pSwapchain)
     798                                        {
     799                                            Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, pSwapchain, &pBlt->Blt.DstRects);
     800                                            Assert(Status == STATUS_SUCCESS);
     801                                            vboxWddmSwapchainRelease(pSwapchain);
     802                                        }
     803                                    }
     804                                }
     805                                break;
     806                            }
     807                            default:
     808                                AssertBreakpoint();
     809                                break;
     810                        }
     811                    }
     812                    break;
     813                }
     814                default:
     815                    Assert(0);
     816            }
     817
     818            break;
     819        }
     820        case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
     821        {
     822            PVBOXVDMAPIPE_CMD_DMACMD_FLIP pFlip = (PVBOXVDMAPIPE_CMD_DMACMD_FLIP)pDmaCmd;
     823            Assert(pFlip->Hdr.fFlags.b3DRelated);
     824            Assert(!pFlip->Hdr.fFlags.bDecVBVAUnlock);
     825            Assert(!pFlip->Hdr.fFlags.b2DRelated);
     826            PVBOXWDDM_ALLOCATION pAlloc = pFlip->Flip.Alloc.pAlloc;
     827            VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pAlloc->SurfDesc.VidPnSourceId];
     828            if (pFlip->Hdr.fFlags.b3DRelated)
     829            {
     830                PVBOXWDDM_SWAPCHAIN pSwapchain;
     831                pSwapchain = vboxWddmSwapchainRetainByAlloc(pDevExt, pAlloc);
     832                if (pSwapchain)
     833                {
     834                    POINT pos = pSource->VScreenPos;
     835                    VBOXVDMAPIPE_RECTS Rects;
     836                    Rects.ContextRect.left = pos.x;
     837                    Rects.ContextRect.top = pos.y;
     838                    Rects.ContextRect.right = pAlloc->SurfDesc.width + pos.x;
     839                    Rects.ContextRect.bottom = pAlloc->SurfDesc.height + pos.y;
     840                    Rects.UpdateRects.cRects = 1;
     841                    Rects.UpdateRects.aRects[0] = Rects.ContextRect;
     842                    Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, pSwapchain, &Rects);
     843                    Assert(Status == STATUS_SUCCESS);
     844                    vboxWddmSwapchainRelease(pSwapchain);
     845                }
     846            }
     847
     848            break;
     849        }
     850        case VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL:
     851        {
     852            PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCF = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)pDmaCmd;
     853            Assert(pCF->Hdr.fFlags.b2DRelated);
     854            Assert(pCF->Hdr.fFlags.bDecVBVAUnlock);
     855            Assert(!pCF->Hdr.fFlags.b3DRelated);
     856            Status = vboxVdmaGgDmaColorFill(pCF);
     857            Assert(Status == STATUS_SUCCESS);
     858            break;
     859        }
     860        default:
     861            Assert(0);
     862            break;
     863    }
     864
     865    if (pDmaCmd->fFlags.bDecVBVAUnlock)
     866    {
     867        uint32_t cNew = ASMAtomicDecU32(&pDevExt->cUnlockedVBVADisabled);
     868        Assert(cNew < UINT32_MAX/2);
     869    }
     870
     871    Status = vboxVdmaDdiCmdCompleted(pDevExt, &pDevExt->DdiCmdQueue, &pDmaCmd->DdiCmd);
     872    Assert(Status == STATUS_SUCCESS);
    584873
    585874    return Status;
     
    601890            if (Status == STATUS_SUCCESS)
    602891            {
    603                 for (PLIST_ENTRY pCur = CmdList.Blink; pCur != &CmdList; pCur = CmdList.Blink)
     892                for (PLIST_ENTRY pCur = CmdList.Blink; pCur != &CmdList;)
    604893                {
    605894                    PVBOXVDMAPIPE_CMD_DR pDr = VBOXVDMAPIPE_CMD_DR_FROM_ENTRY(pCur);
     895                    RemoveEntryList(pCur);
     896                    pCur = CmdList.Blink;
    606897                    switch (pDr->enmType)
    607898                    {
     899#if 0
    608900                        case VBOXVDMAPIPE_CMD_TYPE_RECTSINFO:
    609901                        {
     
    611903                            Status = vboxVdmaGgDirtyRectsProcess(pRects);
    612904                            Assert(Status == STATUS_SUCCESS);
     905                            vboxVdmaGgCmdDestroy(pDr);
    613906                            break;
    614907                        }
    615                         case VBOXVDMAPIPE_CMD_TYPE_DMACMD_CLRFILL:
     908#endif
     909                        case VBOXVDMAPIPE_CMD_TYPE_DMACMD:
    616910                        {
    617                             PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCF = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)pDr;
    618                             Status = vboxVdmaGgDmaColorFill(pCF);
     911                            PVBOXVDMAPIPE_CMD_DMACMD pDmaCmd = (PVBOXVDMAPIPE_CMD_DMACMD)pDr;
     912                            Status = vboxVdmaGgDmaCmdProcess(pDmaCmd);
    619913                            Assert(Status == STATUS_SUCCESS);
    620                             break;
    621                         }
     914                        } break;
    622915                        default:
    623916                            AssertBreakpoint();
    624917                    }
    625                     RemoveEntryList(pCur);
    626                     vboxVdmaGgCmdDestroy(pDr);
    627918                }
    628919            }
     
    10261317}
    10271318#endif
     1319
     1320
     1321/* ddi dma command queue */
     1322DECLINLINE(BOOLEAN) vboxVdmaDdiCmdCanComplete(PVBOXVDMADDI_CMD_QUEUE pQueue)
     1323{
     1324    return ASMAtomicUoReadU32(&pQueue->cQueuedCmds) == 0;
     1325}
     1326
     1327DECLCALLBACK(VOID) vboxVdmaDdiCmdCompletionCbFree(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
     1328{
     1329    vboxWddmMemFree(pCmd);
     1330}
     1331
     1332static VOID vboxVdmaDdiCmdNotifyCompletedIrq(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
     1333{
     1334    DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
     1335    memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
     1336    notify.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED;
     1337    notify.DmaCompleted.SubmissionFenceId = pCmd->u32FenceId;
     1338    notify.DmaCompleted.NodeOrdinal = pCmd->pContext->NodeOrdinal;
     1339    notify.DmaCompleted.EngineOrdinal = 0;
     1340    pCmd->pContext->uLastCompletedCmdFenceId = pCmd->u32FenceId;
     1341
     1342    pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
     1343
     1344    InsertTailList(&pQueue->DpcCmdQueue, &pCmd->QueueEntry);
     1345}
     1346
     1347DECLINLINE(VOID) vboxVdmaDdiCmdDequeueIrq(PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
     1348{
     1349    ASMAtomicDecU32(&pQueue->cQueuedCmds);
     1350    RemoveEntryList(&pCmd->QueueEntry);
     1351}
     1352
     1353DECLINLINE(VOID) vboxVdmaDdiCmdEnqueueIrq(PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
     1354{
     1355    ASMAtomicIncU32(&pQueue->cQueuedCmds);
     1356    InsertTailList(&pQueue->CmdQueue, &pCmd->QueueEntry);
     1357}
     1358
     1359VOID vboxVdmaDdiQueueInit(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue)
     1360{
     1361    pQueue->cQueuedCmds = 0;
     1362    InitializeListHead(&pQueue->CmdQueue);
     1363    InitializeListHead(&pQueue->DpcCmdQueue);
     1364}
     1365
     1366BOOLEAN vboxVdmaDdiCmdCompletedIrq(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
     1367{
     1368    BOOLEAN bQueued = pCmd->enmState > VBOXVDMADDI_STATE_NOT_QUEUED;
     1369    BOOLEAN bComplete = FALSE;
     1370    Assert(!bQueued || pQueue->cQueuedCmds);
     1371    Assert(!bQueued || !IsListEmpty(&pQueue->CmdQueue));
     1372    pCmd->enmState = VBOXVDMADDI_STATE_COMPLETED;
     1373    if (bQueued)
     1374    {
     1375        if (pQueue->CmdQueue.Flink == &pCmd->QueueEntry)
     1376        {
     1377            vboxVdmaDdiCmdDequeueIrq(pQueue, pCmd);
     1378            bComplete = TRUE;
     1379        }
     1380    }
     1381    else if (IsListEmpty(&pQueue->CmdQueue))
     1382    {
     1383        bComplete = TRUE;
     1384    }
     1385    else
     1386    {
     1387        vboxVdmaDdiCmdEnqueueIrq(pQueue, pCmd);
     1388    }
     1389
     1390    if (bComplete)
     1391    {
     1392        vboxVdmaDdiCmdNotifyCompletedIrq(pDevExt, pQueue, pCmd);
     1393
     1394        while (!IsListEmpty(&pQueue->CmdQueue))
     1395        {
     1396            pCmd = VBOXVDMADDI_CMD_FROM_ENTRY(pQueue->CmdQueue.Flink);
     1397            if (pCmd->enmState == VBOXVDMADDI_STATE_COMPLETED)
     1398            {
     1399                vboxVdmaDdiCmdDequeueIrq(pQueue, pCmd);
     1400                vboxVdmaDdiCmdNotifyCompletedIrq(pDevExt, pQueue, pCmd);
     1401            }
     1402            else
     1403                break;
     1404        }
     1405    }
     1406    else
     1407    {
     1408        pCmd->enmState = VBOXVDMADDI_STATE_COMPLETED;
     1409    }
     1410
     1411    return bComplete;
     1412}
     1413
     1414VOID vboxVdmaDdiCmdSubmittedIrq(PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
     1415{
     1416    BOOLEAN bQueued = pCmd->enmState >= VBOXVDMADDI_STATE_PENDING;
     1417    Assert(pCmd->enmState < VBOXVDMADDI_STATE_SUBMITTED);
     1418    pCmd->enmState = VBOXVDMADDI_STATE_SUBMITTED;
     1419    if (!bQueued)
     1420        vboxVdmaDdiCmdEnqueueIrq(pQueue, pCmd);
     1421}
     1422
     1423typedef struct VBOXVDMADDI_CMD_COMPLETED_CB
     1424{
     1425    PDEVICE_EXTENSION pDevExt;
     1426    PVBOXVDMADDI_CMD_QUEUE pQueue;
     1427    PVBOXVDMADDI_CMD pCmd;
     1428} VBOXVDMADDI_CMD_COMPLETED_CB, *PVBOXVDMADDI_CMD_COMPLETED_CB;
     1429
     1430static BOOLEAN vboxVdmaDdiCmdCompletedCb(PVOID Context)
     1431{
     1432    PVBOXVDMADDI_CMD_COMPLETED_CB pdc = (PVBOXVDMADDI_CMD_COMPLETED_CB)Context;
     1433    BOOLEAN bNeedDps = vboxVdmaDdiCmdCompletedIrq(pdc->pDevExt, pdc->pQueue, pdc->pCmd);
     1434    pdc->pDevExt->bNotifyDxDpc |= bNeedDps;
     1435
     1436    return bNeedDps;
     1437}
     1438
     1439NTSTATUS vboxVdmaDdiCmdCompleted(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
     1440{
     1441    VBOXVDMADDI_CMD_COMPLETED_CB context;
     1442    context.pDevExt = pDevExt;
     1443    context.pQueue = pQueue;
     1444    context.pCmd = pCmd;
     1445    BOOLEAN bNeedDps;
     1446    NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
     1447            pDevExt->u.primary.DxgkInterface.DeviceHandle,
     1448            vboxVdmaDdiCmdCompletedCb,
     1449            &context,
     1450            0, /* IN ULONG MessageNumber */
     1451            &bNeedDps);
     1452    Assert(Status == STATUS_SUCCESS);
     1453    if (Status == STATUS_SUCCESS && bNeedDps)
     1454    {
     1455        BOOLEAN bRc = pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
     1456        Assert(bRc);
     1457    }
     1458    return Status;
     1459}
     1460
     1461typedef struct VBOXVDMADDI_CMD_SUBMITTED_CB
     1462{
     1463//    PDEVICE_EXTENSION pDevExt;
     1464    PVBOXVDMADDI_CMD_QUEUE pQueue;
     1465    PVBOXVDMADDI_CMD pCmd;
     1466} VBOXVDMADDI_CMD_SUBMITTED_CB, *PVBOXVDMADDI_CMD_SUBMITTED_CB;
     1467
     1468static BOOLEAN vboxVdmaDdiCmdSubmittedCb(PVOID Context)
     1469{
     1470    PVBOXVDMADDI_CMD_SUBMITTED_CB pdc = (PVBOXVDMADDI_CMD_SUBMITTED_CB)Context;
     1471    vboxVdmaDdiCmdSubmittedIrq(pdc->pQueue, pdc->pCmd);
     1472
     1473    return FALSE;
     1474}
     1475
     1476NTSTATUS vboxVdmaDdiCmdSubmitted(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
     1477{
     1478    VBOXVDMADDI_CMD_SUBMITTED_CB context;
     1479    context.pQueue = pQueue;
     1480    context.pCmd = pCmd;
     1481    BOOLEAN bRc;
     1482    NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
     1483            pDevExt->u.primary.DxgkInterface.DeviceHandle,
     1484            vboxVdmaDdiCmdSubmittedCb,
     1485            &context,
     1486            0, /* IN ULONG MessageNumber */
     1487            &bRc);
     1488    Assert(Status == STATUS_SUCCESS);
     1489    return Status;
     1490}
     1491
     1492typedef struct VBOXVDMADDI_CMD_COMPLETE_CB
     1493{
     1494    PDEVICE_EXTENSION pDevExt;
     1495    PVBOXWDDM_CONTEXT pContext;
     1496    uint32_t u32FenceId;
     1497} VBOXVDMADDI_CMD_COMPLETE_CB, *PVBOXVDMADDI_CMD_COMPLETE_CB;
     1498
     1499static BOOLEAN vboxVdmaDdiCmdFenceCompleteCb(PVOID Context)
     1500{
     1501    PVBOXVDMADDI_CMD_COMPLETE_CB pdc = (PVBOXVDMADDI_CMD_COMPLETE_CB)Context;
     1502    PDEVICE_EXTENSION pDevExt = pdc->pDevExt;
     1503    DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
     1504    memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
     1505
     1506    notify.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED;
     1507    notify.DmaCompleted.SubmissionFenceId = pdc->u32FenceId;
     1508    notify.DmaCompleted.NodeOrdinal = pdc->pContext->NodeOrdinal;
     1509    notify.DmaCompleted.EngineOrdinal = 0;
     1510
     1511    pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
     1512
     1513    pDevExt->bNotifyDxDpc = TRUE;
     1514    BOOLEAN bDpcQueued = pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
     1515    Assert(bDpcQueued);
     1516
     1517    return bDpcQueued;
     1518}
     1519
     1520static NTSTATUS vboxVdmaDdiCmdFenceNotifyComplete(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_CONTEXT pContext, uint32_t u32FenceId)
     1521{
     1522    VBOXVDMADDI_CMD_COMPLETE_CB context;
     1523    context.pDevExt = pDevExt;
     1524    context.pContext = pContext;
     1525    context.u32FenceId = u32FenceId;
     1526    BOOLEAN bRet;
     1527    NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
     1528            pDevExt->u.primary.DxgkInterface.DeviceHandle,
     1529            vboxVdmaDdiCmdFenceCompleteCb,
     1530            &context,
     1531            0, /* IN ULONG MessageNumber */
     1532            &bRet);
     1533    Assert(Status == STATUS_SUCCESS);
     1534    return Status;
     1535}
     1536
     1537NTSTATUS vboxVdmaDdiCmdFenceComplete(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_CONTEXT pContext, uint32_t u32FenceId)
     1538{
     1539    if (vboxVdmaDdiCmdCanComplete(&pDevExt->DdiCmdQueue))
     1540        return vboxVdmaDdiCmdFenceNotifyComplete(pDevExt, pContext, u32FenceId);
     1541
     1542    PVBOXVDMADDI_CMD pCmd = (PVBOXVDMADDI_CMD)vboxWddmMemAlloc(sizeof (VBOXVDMADDI_CMD));
     1543    Assert(pCmd);
     1544    if (pCmd)
     1545    {
     1546        vboxVdmaDdiCmdInit(pCmd, u32FenceId, pContext, vboxVdmaDdiCmdCompletionCbFree, NULL);
     1547        NTSTATUS Status = vboxVdmaDdiCmdCompleted(pDevExt, &pDevExt->DdiCmdQueue, pCmd);
     1548        Assert(Status == STATUS_SUCCESS);
     1549        if (Status == STATUS_SUCCESS)
     1550            return STATUS_SUCCESS;
     1551        vboxWddmMemFree(pCmd);
     1552        return Status;
     1553    }
     1554    return STATUS_NO_MEMORY;
     1555}
     1556
     1557#ifdef VBOXWDDM_RENDER_FROM_SHADOW
     1558NTSTATUS vboxVdmaHlpUpdatePrimary(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, RECT* pRect)
     1559{
     1560    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
     1561    Assert(pSource->pPrimaryAllocation);
     1562    Assert(pSource->pShadowAllocation);
     1563    if (!pSource->pPrimaryAllocation)
     1564        return STATUS_INVALID_PARAMETER;
     1565    if (!pSource->pShadowAllocation)
     1566        return STATUS_INVALID_PARAMETER;
     1567
     1568    Assert(pSource->pPrimaryAllocation->offVram != VBOXVIDEOOFFSET_VOID);
     1569    Assert(pSource->pShadowAllocation->offVram != VBOXVIDEOOFFSET_VOID);
     1570    if (pSource->pPrimaryAllocation->offVram == VBOXVIDEOOFFSET_VOID)
     1571        return STATUS_INVALID_PARAMETER;
     1572    if (pSource->pShadowAllocation->offVram == VBOXVIDEOOFFSET_VOID)
     1573        return STATUS_INVALID_PARAMETER;
     1574
     1575    NTSTATUS Status = vboxVdmaGgDmaBltPerform(pDevExt, pSource->pShadowAllocation, pRect, pSource->pPrimaryAllocation, pRect);
     1576    Assert(Status == STATUS_SUCCESS);
     1577    return Status;
     1578}
     1579#endif
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVdma.h

    r32496 r32823  
    1414
    1515#include <iprt/cdefs.h>
     16#include <iprt/asm.h>
    1617#include <VBox/VBoxVideo.h>
    1718#include "../VBoxVideo.h"
     19
     20/* ddi dma command queue handling */
     21typedef enum
     22{
     23    VBOXVDMADDI_STATE_UNCKNOWN = 0,
     24    VBOXVDMADDI_STATE_NOT_QUEUED,
     25    VBOXVDMADDI_STATE_PENDING,
     26    VBOXVDMADDI_STATE_SUBMITTED,
     27    VBOXVDMADDI_STATE_COMPLETED
     28} VBOXVDMADDI_STATE;
     29
     30typedef struct VBOXVDMADDI_CMD *PVBOXVDMADDI_CMD;
     31typedef DECLCALLBACK(VOID) FNVBOXVDMADDICMDCOMPLETE_DPC(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext);
     32typedef FNVBOXVDMADDICMDCOMPLETE_DPC *PFNVBOXVDMADDICMDCOMPLETE_DPC;
     33
     34typedef struct VBOXVDMADDI_CMD
     35{
     36    LIST_ENTRY QueueEntry;
     37    VBOXVDMADDI_STATE enmState;
     38    uint32_t u32FenceId;
     39    PVBOXWDDM_CONTEXT pContext;
     40    PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete;
     41    PVOID pvComplete;
     42} VBOXVDMADDI_CMD, *PVBOXVDMADDI_CMD;
     43
     44typedef struct VBOXVDMADDI_CMD_QUEUE
     45{
     46    volatile uint32_t cQueuedCmds;
     47    LIST_ENTRY CmdQueue;
     48    LIST_ENTRY DpcCmdQueue;
     49} VBOXVDMADDI_CMD_QUEUE, *PVBOXVDMADDI_CMD_QUEUE;
     50
     51VOID vboxVdmaDdiQueueInit(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue);
     52BOOLEAN vboxVdmaDdiCmdCompletedIrq(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd);
     53VOID vboxVdmaDdiCmdSubmittedIrq(PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd);
     54
     55NTSTATUS vboxVdmaDdiCmdCompleted(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd);
     56NTSTATUS vboxVdmaDdiCmdSubmitted(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd);
     57
     58DECLINLINE(VOID) vboxVdmaDdiCmdInit(PVBOXVDMADDI_CMD pCmd,
     59        uint32_t u32FenceId, PVBOXWDDM_CONTEXT pContext,
     60        PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete, PVOID pvComplete)
     61{
     62    pCmd->QueueEntry.Blink = NULL;
     63    pCmd->QueueEntry.Flink = NULL;
     64    pCmd->enmState = VBOXVDMADDI_STATE_NOT_QUEUED;
     65    pCmd->u32FenceId = u32FenceId;
     66    pCmd->pContext = pContext;
     67    pCmd->pfnComplete = pfnComplete;
     68    pCmd->pvComplete = pvComplete;
     69}
     70
     71NTSTATUS vboxVdmaDdiCmdFenceComplete(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_CONTEXT pContext, uint32_t u32FenceId);
     72
     73DECLCALLBACK(VOID) vboxVdmaDdiCmdCompletionCbFree(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext);
     74
     75DECLINLINE(VOID) vboxVdmaDdiCmdGetCompletedListIsr(PVBOXVDMADDI_CMD_QUEUE pQueue, LIST_ENTRY *pList)
     76{
     77    vboxVideoLeDetach(&pQueue->DpcCmdQueue, pList);
     78}
     79
     80#define VBOXVDMADDI_CMD_FROM_ENTRY(_pEntry) ((PVBOXVDMADDI_CMD)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(VBOXVDMADDI_CMD, QueueEntry)))
     81
     82DECLINLINE(VOID) vboxVdmaDdiCmdHandleCompletedList(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, LIST_ENTRY *pList)
     83{
     84    LIST_ENTRY *pEntry = pList->Flink;
     85    while (pEntry != pList)
     86    {
     87        PVBOXVDMADDI_CMD pCmd = VBOXVDMADDI_CMD_FROM_ENTRY(pEntry);
     88        pEntry = pEntry->Flink;
     89        if (pCmd->pfnComplete)
     90            pCmd->pfnComplete(pDevExt, pCmd, pCmd->pvComplete);
     91    }
     92}
     93
     94#ifdef VBOXWDDM_RENDER_FROM_SHADOW
     95NTSTATUS vboxVdmaHlpUpdatePrimary(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, RECT* pRect);
     96#endif
    1897
    1998#if 0
     
    57136{
    58137    VBOXVDMAPIPE_CMD_TYPE_UNDEFINED = 0,
    59     VBOXVDMAPIPE_CMD_TYPE_RECTSINFO = 1,
    60     VBOXVDMAPIPE_CMD_TYPE_DMACMD_CLRFILL    = 2
     138    VBOXVDMAPIPE_CMD_TYPE_RECTSINFO,
     139    VBOXVDMAPIPE_CMD_TYPE_DMACMD
    61140} VBOXVDMAPIPE_CMD_TYPE;
    62141
     
    69148#define VBOXVDMAPIPE_CMD_DR_FROM_ENTRY(_pE)  ( (PVBOXVDMAPIPE_CMD_DR)VBOXVDMAPIPE_CMD_HDR_FROM_ENTRY(_pE) )
    70149
     150typedef struct VBOXWDDM_DMA_ALLOCINFO
     151{
     152    PVBOXWDDM_ALLOCATION pAlloc;
     153    VBOXVIDEOOFFSET offAlloc;
     154    UINT segmentIdAlloc;
     155    D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId;
     156} VBOXWDDM_DMA_ALLOCINFO, *PVBOXWDDM_DMA_ALLOCINFO;
     157
    71158typedef struct VBOXVDMAPIPE_RECTS
    72159{
     
    78165{
    79166    VBOXVDMAPIPE_CMD_DR Hdr;
    80     struct VBOXWDDM_CONTEXT *pContext;
     167    VBOXVDMADDI_CMD DdiCmd;
    81168    struct VBOXWDDM_SWAPCHAIN *pSwapchain;
    82169    VBOXVDMAPIPE_RECTS ContextsRects;
    83170} VBOXVDMAPIPE_CMD_RECTSINFO, *PVBOXVDMAPIPE_CMD_RECTSINFO;
    84171
    85 typedef struct VBOXVDMAPIPE_CMD_DMACMD_CLRFILL
     172typedef struct VBOXVDMAPIPE_FLAGS_DMACMD
     173{
     174    union
     175    {
     176        struct
     177        {
     178            UINT b2DRelated     : 1;
     179            UINT b3DRelated     : 1;
     180            UINT bDecVBVAUnlock : 1;
     181            UINT Reserved       : 29;
     182        };
     183        UINT Value;
     184    };
     185} VBOXVDMAPIPE_FLAGS_DMACMD, *PVBOXVDMAPIPE_FLAGS_DMACMD;
     186typedef struct VBOXVDMAPIPE_CMD_DMACMD
    86187{
    87188    VBOXVDMAPIPE_CMD_DR Hdr;
    88     struct VBOXWDDM_CONTEXT *pContext;
    89     struct VBOXWDDM_ALLOCATION *pAllocation;
    90     UINT SubmissionFenceId;
    91     D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId;
     189    VBOXVDMADDI_CMD DdiCmd;
     190    PDEVICE_EXTENSION pDevExt;
     191    VBOXVDMACMD_TYPE enmCmd;
     192    VBOXVDMAPIPE_FLAGS_DMACMD fFlags;
     193} VBOXVDMAPIPE_CMD_DMACMD, *PVBOXVDMAPIPE_CMD_DMACMD;
     194
     195typedef struct VBOXVDMA_CLRFILL
     196{
     197    VBOXWDDM_DMA_ALLOCINFO Alloc;
    92198    UINT Color;
    93199    VBOXWDDM_RECTS_INFO Rects;
     200} VBOXVDMA_CLRFILL, *PVBOXVDMA_CLRFILL;
     201
     202typedef struct VBOXVDMAPIPE_CMD_DMACMD_CLRFILL
     203{
     204    VBOXVDMAPIPE_CMD_DMACMD Hdr;
     205    VBOXVDMA_CLRFILL ClrFill;
    94206} VBOXVDMAPIPE_CMD_DMACMD_CLRFILL, *PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL;
     207
     208typedef struct VBOXVDMA_BLT
     209{
     210    VBOXWDDM_DMA_ALLOCINFO SrcAlloc;
     211    VBOXWDDM_DMA_ALLOCINFO DstAlloc;
     212    RECT SrcRect;
     213    VBOXVDMAPIPE_RECTS DstRects;
     214} VBOXVDMA_BLT, *PVBOXVDMA_BLT;
     215
     216typedef struct VBOXVDMAPIPE_CMD_DMACMD_BLT
     217{
     218    VBOXVDMAPIPE_CMD_DMACMD Hdr;
     219    VBOXVDMA_BLT Blt;
     220} VBOXVDMAPIPE_CMD_DMACMD_BLT, *PVBOXVDMAPIPE_CMD_DMACMD_BLT;
     221
     222typedef struct VBOXVDMA_FLIP
     223{
     224    VBOXWDDM_DMA_ALLOCINFO Alloc;
     225} VBOXVDMA_FLIP, *PVBOXVDMA_FLIP;
     226
     227typedef struct VBOXVDMAPIPE_CMD_DMACMD_FLIP
     228{
     229    VBOXVDMAPIPE_CMD_DMACMD Hdr;
     230    VBOXVDMA_FLIP Flip;
     231} VBOXVDMAPIPE_CMD_DMACMD_FLIP, *PVBOXVDMAPIPE_CMD_DMACMD_FLIP;
     232
     233typedef struct VBOXVDMA_SHADOW2PRIMARY
     234{
     235    VBOXWDDM_DMA_ALLOCINFO ShadowAlloc;
     236    RECT SrcRect;
     237    D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId;
     238} VBOXVDMA_SHADOW2PRIMARY, *PVBOXVDMA_SHADOW2PRIMARY;
    95239
    96240typedef struct VBOXVDMAGG
     
    141285void vboxVdmaGgCmdDestroy(PVBOXVDMAPIPE_CMD_DR pDr);
    142286
     287#define VBOXVDMAPIPE_CMD_DR_FROM_DDI_CMD(_pCmd) ((PVBOXVDMAPIPE_CMD_DR)(((uint8_t*)(_pCmd)) - RT_OFFSETOF(VBOXVDMAPIPE_CMD_DR, DdiCmd)))
     288DECLCALLBACK(VOID) vboxVdmaGgDdiCmdDestroy(PDEVICE_EXTENSION pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext);
     289
    143290#endif /* #ifndef ___VBoxVideoVdma_h___ */
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.cpp

    r30973 r32823  
    1818#endif
    1919
     20#define VBOXVHWA_PRIMARY_ALLOCATION(_pSrc) ((_pSrc)->pPrimaryAllocation)
    2021
    2122
     
    342343}
    343344
     345DECLINLINE(VOID) vboxVhwaHlpOverlayListInit(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
     346{
     347    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
     348    pSource->cOverlays = 0;
     349    InitializeListHead(&pSource->OverlayList);
     350    KeInitializeSpinLock(&pSource->OverlayListLock);
     351}
     352
    344353static void vboxVhwaInitSrc(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
    345354{
     
    347356    VBOXVHWA_INFO *pSettings = &pDevExt->aSources[srcId].Vhwa.Settings;
    348357    memset (pSettings, 0, sizeof (VBOXVHWA_INFO));
     358
     359    vboxVhwaHlpOverlayListInit(pDevExt, srcId);
    349360
    350361    VBOXVHWACMD_QUERYINFO1* pInfo1 = vboxVhwaQueryHostInfo1(pDevExt, srcId);
     
    685696int vboxVhwaHlpDestroyPrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
    686697{
    687     PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
     698    PVBOXWDDM_ALLOCATION pFbSurf = VBOXVHWA_PRIMARY_ALLOCATION(pSource);
    688699
    689700    int rc = vboxVhwaHlpDestroySurface(pDevExt, pFbSurf, VidPnSourceId);
     
    694705int vboxVhwaHlpCreatePrimary(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_SOURCE pSource, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
    695706{
    696     PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
     707    PVBOXWDDM_ALLOCATION pFbSurf = VBOXVHWA_PRIMARY_ALLOCATION(pSource);
    697708    Assert(pSource->Vhwa.cOverlaysCreated == 1);
    698709    Assert(pFbSurf->hHostHandle == VBOXVHWA_SURFHANDLE_INVALID);
     
    739750    else
    740751    {
    741         PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
     752        PVBOXWDDM_ALLOCATION pFbSurf = VBOXVHWA_PRIMARY_ALLOCATION(pSource);
    742753        Assert(pFbSurf->hHostHandle);
    743754        if (pFbSurf->hHostHandle)
     
    789800    PVBOXWDDM_SOURCE pSource = &pOverlay->pDevExt->aSources[pOverlay->VidPnSourceId];
    790801    Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED));
    791     PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
     802    PVBOXWDDM_ALLOCATION pFbSurf = VBOXVHWA_PRIMARY_ALLOCATION(pSource);
    792803    Assert(pFbSurf);
    793804    Assert(pFbSurf->hHostHandle);
     
    856867AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(VBOXVHWA_RECTL, bottom));
    857868
     869int vboxVhwaHlpColorFill(PVBOXWDDM_OVERLAY pOverlay, PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF)
     870{
     871    PVBOXWDDM_ALLOCATION pAlloc = pCF->ClrFill.Alloc.pAlloc;
     872    Assert(pAlloc->pResource == pOverlay->pResource);
     873#ifdef VBOXWDDM_RENDER_FROM_SHADOW
     874    if (pAlloc->bAssigned)
     875    {
     876        /* check if this is a primary surf */
     877        PVBOXWDDM_SOURCE pSource = &pOverlay->pDevExt->aSources[pOverlay->VidPnSourceId];
     878        if (pSource->pPrimaryAllocation == pAlloc)
     879        {
     880            pAlloc = pSource->pShadowAllocation;
     881            Assert(pAlloc->pResource == pOverlay->pResource);
     882        }
     883    }
     884#endif
     885    Assert(pAlloc->hHostHandle);
     886    Assert(pAlloc->pResource);
     887    Assert(pAlloc->offVram != VBOXVIDEOOFFSET_VOID);
     888
     889    int rc;
     890    VBOXVHWACMD* pCmd = vboxVhwaCommandCreate(pOverlay->pDevExt, pOverlay->VidPnSourceId,
     891                VBOXVHWACMD_TYPE_SURF_FLIP, RT_OFFSETOF(VBOXVHWACMD_SURF_COLORFILL, u.in.aRects[pCF->ClrFill.Rects.cRects]));
     892    Assert(pCmd);
     893    if(pCmd)
     894    {
     895        VBOXVHWACMD_SURF_COLORFILL * pBody = VBOXVHWACMD_BODY(pCmd, VBOXVHWACMD_SURF_COLORFILL);
     896
     897        memset(pBody, 0, sizeof(VBOXVHWACMD_SURF_COLORFILL));
     898
     899        pBody->u.in.hSurf = pAlloc->hHostHandle;
     900        pBody->u.in.offSurface = pAlloc->offVram;
     901        pBody->u.in.cRects = pCF->ClrFill.Rects.cRects;
     902        memcpy (pBody->u.in.aRects, pCF->ClrFill.Rects.aRects, pCF->ClrFill.Rects.cRects * sizeof (pCF->ClrFill.Rects.aRects[0]));
     903        vboxVhwaCommandSubmitAsynchAndComplete(pOverlay->pDevExt, pCmd);
     904
     905        rc = VINF_SUCCESS;
     906    }
     907    else
     908        rc = VERR_OUT_OF_RESOURCES;
     909
     910    return rc;
     911}
     912
     913static void vboxVhwaHlpOverlayDstRectSet(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay, const RECT *pRect)
     914{
     915    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pOverlay->VidPnSourceId];
     916    KIRQL OldIrql;
     917    KeAcquireSpinLock(&pSource->OverlayListLock, &OldIrql);
     918    pOverlay->DstRect = *pRect;
     919    KeReleaseSpinLock(&pSource->OverlayListLock, OldIrql);
     920}
     921
     922AssertCompile(sizeof (RECT) == sizeof (VBOXVHWA_RECTL));
     923AssertCompile(RT_SIZEOFMEMB(RECT, left) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, left));
     924AssertCompile(RT_SIZEOFMEMB(RECT, right) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, right));
     925AssertCompile(RT_SIZEOFMEMB(RECT, top) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, top));
     926AssertCompile(RT_SIZEOFMEMB(RECT, bottom) == RT_SIZEOFMEMB(VBOXVHWA_RECTL, bottom));
     927AssertCompile(RT_OFFSETOF(RECT, left) == RT_OFFSETOF(VBOXVHWA_RECTL, left));
     928AssertCompile(RT_OFFSETOF(RECT, right) == RT_OFFSETOF(VBOXVHWA_RECTL, right));
     929AssertCompile(RT_OFFSETOF(RECT, top) == RT_OFFSETOF(VBOXVHWA_RECTL, top));
     930AssertCompile(RT_OFFSETOF(RECT, bottom) == RT_OFFSETOF(VBOXVHWA_RECTL, bottom));
     931
    858932int vboxVhwaHlpOverlayUpdate(PVBOXWDDM_OVERLAY pOverlay, const DXGK_OVERLAYINFO *pOverlayInfo)
    859933{
     
    866940    PVBOXWDDM_SOURCE pSource = &pOverlay->pDevExt->aSources[pOverlay->VidPnSourceId];
    867941    Assert(!!(pSource->Vhwa.Settings.fFlags & VBOXVHWA_F_ENABLED));
    868     PVBOXWDDM_ALLOCATION pFbSurf = VBOXWDDM_FB_ALLOCATION(pSource);
     942    PVBOXWDDM_ALLOCATION pFbSurf = VBOXVHWA_PRIMARY_ALLOCATION(pSource);
    869943    Assert(pFbSurf);
    870944    Assert(pFbSurf->hHostHandle);
     
    924998            pOverlay->pCurentAlloc = pAlloc;
    925999
     1000            vboxVhwaHlpOverlayDstRectSet(pOverlay->pDevExt, pOverlay, &pOverlayInfo->DstRect);
     1001
    9261002            rc = VINF_SUCCESS;
    9271003        }
     
    10081084    return rc;
    10091085}
     1086
     1087BOOLEAN vboxVhwaHlpOverlayListIsEmpty(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId)
     1088{
     1089    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
     1090    return !ASMAtomicReadU32(&pSource->cOverlays);
     1091}
     1092
     1093void vboxVhwaHlpOverlayListAdd(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay)
     1094{
     1095    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pOverlay->VidPnSourceId];
     1096    KIRQL OldIrql;
     1097    KeAcquireSpinLock(&pSource->OverlayListLock, &OldIrql);
     1098    ASMAtomicIncU32(&pSource->cOverlays);
     1099    InsertHeadList(&pSource->OverlayList, &pOverlay->ListEntry);
     1100    KeReleaseSpinLock(&pSource->OverlayListLock, OldIrql);
     1101}
     1102
     1103void vboxVhwaHlpOverlayListRemove(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay)
     1104{
     1105    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pOverlay->VidPnSourceId];
     1106    KIRQL OldIrql;
     1107    KeAcquireSpinLock(&pSource->OverlayListLock, &OldIrql);
     1108    ASMAtomicDecU32(&pSource->cOverlays);
     1109    RemoveEntryList(&pOverlay->ListEntry);
     1110    KeReleaseSpinLock(&pSource->OverlayListLock, OldIrql);
     1111}
     1112
     1113#define VBOXWDDM_OVERLAY_FROM_ENTRY(_pEntry) ((PVBOXWDDM_OVERLAY)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(VBOXWDDM_OVERLAY, ListEntry)))
     1114
     1115void vboxVhwaHlpOverlayDstRectUnion(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, RECT *pRect)
     1116{
     1117    if (vboxVhwaHlpOverlayListIsEmpty(pDevExt, VidPnSourceId))
     1118    {
     1119        memset(pRect, 0, sizeof (*pRect));
     1120        return;
     1121    }
     1122
     1123    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[VidPnSourceId];
     1124    KIRQL OldIrql;
     1125    KeAcquireSpinLock(&pSource->OverlayListLock, &OldIrql);
     1126    if (pSource->cOverlays)
     1127    {
     1128        PVBOXWDDM_OVERLAY pOverlay = VBOXWDDM_OVERLAY_FROM_ENTRY(pSource->OverlayList.Flink);
     1129        *pRect = pOverlay->DstRect;
     1130        while (pOverlay->ListEntry.Flink != &pSource->OverlayList)
     1131        {
     1132            pOverlay = VBOXWDDM_OVERLAY_FROM_ENTRY(pOverlay->ListEntry.Flink);
     1133            vboxWddmRectUnite(pRect, &pOverlay->DstRect);
     1134        }
     1135    }
     1136    KeReleaseSpinLock(&pSource->OverlayListLock, OldIrql);
     1137}
     1138
     1139void vboxVhwaHlpOverlayDstRectGet(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay, RECT *pRect)
     1140{
     1141    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pOverlay->VidPnSourceId];
     1142    KIRQL OldIrql;
     1143    KeAcquireSpinLock(&pSource->OverlayListLock, &OldIrql);
     1144    *pRect = pOverlay->DstRect;
     1145    KeReleaseSpinLock(&pSource->OverlayListLock, OldIrql);
     1146}
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoVhwa.h

    r30317 r32823  
    5959int vboxVhwaHlpOverlayCreate(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, DXGK_OVERLAYINFO *pOverlayInfo, /* OUT */ PVBOXWDDM_OVERLAY pOverlay);
    6060
     61int vboxVhwaHlpColorFill(PVBOXWDDM_OVERLAY pOverlay, PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF);
     62
    6163int vboxVhwaHlpGetSurfInfo(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pSurf);
    6264
     65BOOLEAN vboxVhwaHlpOverlayListIsEmpty(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId);
     66void vboxVhwaHlpOverlayListAdd(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay);
     67void vboxVhwaHlpOverlayListRemove(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay);
     68void vboxVhwaHlpOverlayDstRectUnion(PDEVICE_EXTENSION pDevExt, D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId, RECT *pRect);
     69void vboxVhwaHlpOverlayDstRectGet(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_OVERLAY pOverlay, RECT *pRect);
     70
    6371#endif /* #ifndef ___VBoxVideoVhwa_h___ */
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.cpp

    r32766 r32823  
    578578                    *NumberOfChildren = pContext->u.primary.cDisplays;
    579579                    dprintf(("VBoxVideoWddm: sources(%d), children(%d)\n", *NumberOfVideoPresentSources, *NumberOfChildren));
    580 #ifdef VBOX_WITH_VIDEOHWACCEL
    581                     vboxVhwaInit(pContext);
    582 #endif
     580
     581                    vboxVdmaDdiQueueInit(pContext, &pContext->DdiCmdQueue);
    583582                    vboxVideoCmInit(&pContext->CmMgr);
    584583                    InitializeListHead(&pContext->SwapchainList3D);
     
    586585                    ExInitializeFastMutex(&pContext->ContextMutex);
    587586                    KeInitializeSpinLock(&pContext->SynchLock);
     587
     588#ifdef VBOX_WITH_VIDEOHWACCEL
     589                    vboxVhwaInit(pContext);
     590#endif
    588591                }
    589592                else
     
    907910    VBOXSHGSMILIST VhwaCmdList;
    908911#endif
     912    LIST_ENTRY CompletedDdiCmdQueue;
    909913    BOOL bNotifyDpc;
    910914} VBOXWDDM_DPCDATA, *PVBOXWDDM_DPCDATA;
     
    927931    vboxSHGSMIListDetach2List(&pdc->pDevExt->VhwaCmdList, &pdc->data.VhwaCmdList);
    928932#endif
     933    vboxVdmaDdiCmdGetCompletedListIsr(&pdc->pDevExt->DdiCmdQueue, &pdc->data.CompletedDdiCmdQueue);
     934
    929935    pdc->data.bNotifyDpc = pdc->pDevExt->bNotifyDxDpc;
    930936    pdc->pDevExt->bNotifyDxDpc = FALSE;
     
    974980    }
    975981#endif
     982
     983    vboxVdmaDdiCmdHandleCompletedList(pDevExt, &pDevExt->DdiCmdQueue, &context.data.CompletedDdiCmdQueue);
    976984
    977985    if (context.data.bNotifyDpc)
     
    18871895        {
    18881896            case VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY:
    1889             case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT:
    1890             {
    1891                 VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
     1897            {
     1898                PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY pS2P = (PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY)pPrivateDataBase;
    18921899                Assert(pPatch->PatchLocationListSubmissionLength == 2);
    18931900                const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
     
    18961903                const DXGK_ALLOCATIONLIST *pSrcAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
    18971904                Assert(pSrcAllocationList->SegmentId);
    1898                 pPrivateData->SrcAllocInfo.segmentIdAlloc = pSrcAllocationList->SegmentId;
    1899                 pPrivateData->SrcAllocInfo.offAlloc = (VBOXVIDEOOFFSET)pSrcAllocationList->PhysicalAddress.QuadPart;
     1905                pS2P->Shadow2Primary.ShadowAlloc.segmentIdAlloc = pSrcAllocationList->SegmentId;
     1906                pS2P->Shadow2Primary.ShadowAlloc.offAlloc = (VBOXVIDEOOFFSET)pSrcAllocationList->PhysicalAddress.QuadPart;
     1907//
     1908//                pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart + 1];
     1909//                Assert(pPatchList->AllocationIndex == DXGK_PRESENT_DESTINATION_INDEX);
     1910//                Assert(pPatchList->PatchOffset == 4);
     1911//                const DXGK_ALLOCATIONLIST *pDstAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
     1912//                Assert(pDstAllocationList->SegmentId);
     1913//                pPrivateData->DstAllocInfo.segmentIdAlloc = pDstAllocationList->SegmentId;
     1914//                pPrivateData->DstAllocInfo.offAlloc = (VBOXVIDEOOFFSET)pDstAllocationList->PhysicalAddress.QuadPart;
     1915                break;
     1916            }
     1917            case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT:
     1918            {
     1919                PVBOXWDDM_DMA_PRIVATEDATA_BLT pBlt = (PVBOXWDDM_DMA_PRIVATEDATA_BLT)pPrivateDataBase;
     1920                Assert(pPatch->PatchLocationListSubmissionLength == 2);
     1921                const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
     1922                Assert(pPatchList->AllocationIndex == DXGK_PRESENT_SOURCE_INDEX);
     1923                Assert(pPatchList->PatchOffset == 0);
     1924                const DXGK_ALLOCATIONLIST *pSrcAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
     1925                Assert(pSrcAllocationList->SegmentId);
     1926                pBlt->Blt.SrcAlloc.segmentIdAlloc = pSrcAllocationList->SegmentId;
     1927                pBlt->Blt.SrcAlloc.offAlloc = (VBOXVIDEOOFFSET)pSrcAllocationList->PhysicalAddress.QuadPart;
    19001928
    19011929                pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart + 1];
     
    19041932                const DXGK_ALLOCATIONLIST *pDstAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
    19051933                Assert(pDstAllocationList->SegmentId);
    1906                 pPrivateData->DstAllocInfo.segmentIdAlloc = pDstAllocationList->SegmentId;
    1907                 pPrivateData->DstAllocInfo.offAlloc = (VBOXVIDEOOFFSET)pDstAllocationList->PhysicalAddress.QuadPart;
     1934                pBlt->Blt.DstAlloc.segmentIdAlloc = pDstAllocationList->SegmentId;
     1935                pBlt->Blt.DstAlloc.offAlloc = (VBOXVIDEOOFFSET)pDstAllocationList->PhysicalAddress.QuadPart;
    19081936                break;
    19091937            }
    19101938            case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
    19111939            {
    1912                 VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
     1940                PVBOXWDDM_DMA_PRIVATEDATA_FLIP pFlip = (PVBOXWDDM_DMA_PRIVATEDATA_FLIP)pPrivateDataBase;
    19131941                Assert(pPatch->PatchLocationListSubmissionLength == 1);
    19141942                const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
     
    19171945                const DXGK_ALLOCATIONLIST *pSrcAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
    19181946                Assert(pSrcAllocationList->SegmentId);
    1919                 pPrivateData->SrcAllocInfo.segmentIdAlloc = pSrcAllocationList->SegmentId;
    1920                 pPrivateData->SrcAllocInfo.offAlloc = (VBOXVIDEOOFFSET)pSrcAllocationList->PhysicalAddress.QuadPart;
     1947                pFlip->Flip.Alloc.segmentIdAlloc = pSrcAllocationList->SegmentId;
     1948                pFlip->Flip.Alloc.offAlloc = (VBOXVIDEOOFFSET)pSrcAllocationList->PhysicalAddress.QuadPart;
    19211949                break;
    19221950            }
    19231951            case VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL:
    19241952            {
    1925                 VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
     1953                PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF = (PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL)pPrivateDataBase;
    19261954                Assert(pPatch->PatchLocationListSubmissionLength == 1);
    19271955                const D3DDDI_PATCHLOCATIONLIST* pPatchList = &pPatch->pPatchLocationList[pPatch->PatchLocationListSubmissionStart];
     
    19301958                const DXGK_ALLOCATIONLIST *pDstAllocationList = &pPatch->pAllocationList[pPatchList->AllocationIndex];
    19311959                Assert(pDstAllocationList->SegmentId);
    1932                 pPrivateData->DstAllocInfo.segmentIdAlloc = pDstAllocationList->SegmentId;
    1933                 pPrivateData->DstAllocInfo.offAlloc = (VBOXVIDEOOFFSET)pDstAllocationList->PhysicalAddress.QuadPart;
     1960                pCF->ClrFill.Alloc.segmentIdAlloc = pDstAllocationList->SegmentId;
     1961                pCF->ClrFill.Alloc.offAlloc = (VBOXVIDEOOFFSET)pDstAllocationList->PhysicalAddress.QuadPart;
    19341962                break;
    19351963            }
     
    19752003}
    19762004
    1977 typedef struct VBOXWDDM_SHADOW_UPDATE_COMPLETION
    1978 {
    1979     PDEVICE_EXTENSION pDevExt;
    1980     PVBOXWDDM_CONTEXT pContext;
    1981     UINT SubmissionFenceId;
    1982 } VBOXWDDM_SHADOW_UPDATE_COMPLETION, *PVBOXWDDM_SHADOW_UPDATE_COMPLETION;
    1983 
    1984 BOOLEAN vboxWddmNotifyShadowUpdateCompletion(PVOID Context)
    1985 {
    1986     PVBOXWDDM_SHADOW_UPDATE_COMPLETION pdc = (PVBOXWDDM_SHADOW_UPDATE_COMPLETION)Context;
    1987     PDEVICE_EXTENSION pDevExt = pdc->pDevExt;
    1988     DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
    1989     memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
    1990 
    1991     notify.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED;
    1992     notify.DmaCompleted.SubmissionFenceId = pdc->SubmissionFenceId;
    1993     notify.DmaCompleted.NodeOrdinal = pdc->pContext->NodeOrdinal;
    1994     notify.DmaCompleted.EngineOrdinal = 0;
    1995 
    1996     pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
    1997 
    1998     pDevExt->bNotifyDxDpc = TRUE;
    1999     BOOLEAN bDpcQueued = pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
    2000     Assert(bDpcQueued);
    2001 
    2002     return bDpcQueued;
    2003 }
    2004 
    2005 NTSTATUS vboxWddmDmaCmdNotifyCompletion(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_CONTEXT pContext, UINT SubmissionFenceId)
    2006 {
    2007     VBOXWDDM_SHADOW_UPDATE_COMPLETION context;
    2008     context.pDevExt = pDevExt;
    2009     context.pContext = pContext;
    2010     context.SubmissionFenceId = SubmissionFenceId;
    2011     BOOLEAN bRet;
    2012     NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
    2013             pDevExt->u.primary.DxgkInterface.DeviceHandle,
    2014             vboxWddmNotifyShadowUpdateCompletion,
    2015             &context,
    2016             0, /* IN ULONG MessageNumber */
    2017             &bRet);
    2018     Assert(Status == STATUS_SUCCESS);
    2019     return Status;
    2020 }
    2021 
    20222005typedef struct VBOXWDDM_CALL_ISR
    20232006{
     
    20482031}
    20492032
    2050 static void vboxWddmSubmitBltCmd(PDEVICE_EXTENSION pDevExt, PVBOXWDDM_ALLOCATION pAlloc, PVBOXWDDM_DMA_PRESENT_BLT pBlt)
    2051 {
    2052     PVBOXWDDM_SWAPCHAIN pSwapchain;
    2053     if (pAlloc)
    2054     {
    2055         pSwapchain = vboxWddmSwapchainRetainByAlloc(pDevExt, pAlloc);
    2056         if (!pSwapchain)
    2057             return;
     2033static NTSTATUS vboxWddmSubmitCmd(PDEVICE_EXTENSION pDevExt, VBOXVDMAPIPE_CMD_DMACMD *pCmd)
     2034{
     2035    NTSTATUS Status = vboxVdmaDdiCmdSubmitted(pDevExt, &pDevExt->DdiCmdQueue, &pCmd->DdiCmd);
     2036    Assert(Status == STATUS_SUCCESS);
     2037    if (Status == STATUS_SUCCESS)
     2038    {
     2039        if (pCmd->fFlags.bDecVBVAUnlock)
     2040        {
     2041            uint32_t cNew = ASMAtomicIncU32(&pDevExt->cUnlockedVBVADisabled);
     2042            Assert(cNew < UINT32_MAX/2);
     2043        }
     2044        NTSTATUS submStatus = vboxVdmaGgCmdSubmit(&pDevExt->u.primary.Vdma.DmaGg, &pCmd->Hdr);
     2045        Assert(submStatus == STATUS_SUCCESS);
     2046        if (submStatus != STATUS_SUCCESS)
     2047        {
     2048            if (pCmd->fFlags.bDecVBVAUnlock)
     2049            {
     2050                uint32_t cNew = ASMAtomicDecU32(&pDevExt->cUnlockedVBVADisabled);
     2051                Assert(cNew < UINT32_MAX/2);
     2052            }
     2053            vboxVdmaDdiCmdCompleted(pDevExt, &pDevExt->DdiCmdQueue, &pCmd->DdiCmd);
     2054        }
    20582055    }
    20592056    else
    20602057    {
    2061         pSwapchain = NULL;
    2062     }
    2063 
    2064     PVBOXVDMAPIPE_CMD_RECTSINFO pRectsCmd = (PVBOXVDMAPIPE_CMD_RECTSINFO)vboxVdmaGgCmdCreate(&pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_RECTSINFO, RT_OFFSETOF(VBOXVDMAPIPE_CMD_RECTSINFO, ContextsRects.UpdateRects.aRects[pBlt->DstRects.UpdateRects.cRects]));
    2065     Assert(pRectsCmd);
    2066     if (pRectsCmd)
    2067     {
    2068         VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pBlt->Hdr.DstAllocInfo.srcId];
    2069         VBOXWDDM_CONTEXT *pContext = pBlt->Hdr.pContext;
    2070         pRectsCmd->pContext = pContext;
    2071         pRectsCmd->pSwapchain = pSwapchain;
    2072         memcpy(&pRectsCmd->ContextsRects, &pBlt->DstRects, RT_OFFSETOF(VBOXVDMAPIPE_RECTS, UpdateRects.aRects[pBlt->DstRects.UpdateRects.cRects]));
    2073         vboxWddmRectTranslate(&pRectsCmd->ContextsRects.ContextRect, pSource->VScreenPos.x, pSource->VScreenPos.y);
    2074         for (UINT i = 0; i < pRectsCmd->ContextsRects.UpdateRects.cRects; ++i)
    2075         {
    2076             vboxWddmRectTranslate(&pRectsCmd->ContextsRects.UpdateRects.aRects[i], pSource->VScreenPos.x, pSource->VScreenPos.y);
    2077         }
    2078         NTSTATUS tmpStatus = vboxVdmaGgCmdSubmit(&pDevExt->u.primary.Vdma.DmaGg, &pRectsCmd->Hdr);
    2079         Assert(tmpStatus == STATUS_SUCCESS);
    2080         if (tmpStatus != STATUS_SUCCESS)
    2081             vboxVdmaGgCmdDestroy(&pRectsCmd->Hdr);
    2082     }
     2058        vboxVdmaGgCmdDestroy(&pCmd->Hdr);
     2059    }
     2060    return Status;
     2061}
     2062
     2063static NTSTATUS vboxWddmSubmitBltCmd(PDEVICE_EXTENSION pDevExt, VBOXWDDM_CONTEXT *pContext, UINT u32FenceId, PVBOXWDDM_DMA_PRIVATEDATA_BLT pBlt, VBOXVDMAPIPE_FLAGS_DMACMD fBltFlags)
     2064{
     2065    NTSTATUS Status = STATUS_SUCCESS;
     2066
     2067    PVBOXVDMAPIPE_CMD_DMACMD_BLT pBltCmd = (PVBOXVDMAPIPE_CMD_DMACMD_BLT)vboxVdmaGgCmdCreate(&pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_DMACMD, RT_OFFSETOF(VBOXVDMAPIPE_CMD_DMACMD_BLT, Blt.DstRects.UpdateRects.aRects[pBlt->Blt.DstRects.UpdateRects.cRects]));
     2068    Assert(pBltCmd);
     2069    if (pBltCmd)
     2070    {
     2071        VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pBlt->Blt.DstAlloc.srcId];
     2072        vboxVdmaDdiCmdInit(&pBltCmd->Hdr.DdiCmd, u32FenceId, pContext, vboxVdmaGgDdiCmdDestroy, pBltCmd);
     2073        pBltCmd->Hdr.pDevExt = pDevExt;
     2074        pBltCmd->Hdr.fFlags = fBltFlags;
     2075        pBltCmd->Hdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
     2076        memcpy(&pBltCmd->Blt, &pBlt->Blt, RT_OFFSETOF(VBOXVDMA_BLT, DstRects.UpdateRects.aRects[pBlt->Blt.DstRects.UpdateRects.cRects]));
     2077        vboxWddmSubmitCmd(pDevExt, &pBltCmd->Hdr);
     2078    }
     2079    else
     2080    {
     2081        Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, u32FenceId);
     2082    }
     2083
     2084    return Status;
    20832085}
    20842086
     
    20972099
    20982100    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)hAdapter;
     2101    PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pSubmitCommand->hContext;
     2102    Assert(pContext);
     2103    Assert(pContext->pDevice);
     2104    Assert(pContext->pDevice->pAdapter == pDevExt);
    20992105    Assert(!pSubmitCommand->DmaBufferSegmentId);
    21002106
     
    21182124        case VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY:
    21192125        {
    2120             VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
    2121             VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pPrivateData->SrcAllocInfo.srcId];
    2122             PVBOXWDDM_ALLOCATION pDstAlloc = pPrivateData->DstAllocInfo.pAlloc;
    2123             PVBOXWDDM_ALLOCATION pSrcAlloc = pPrivateData->SrcAllocInfo.pAlloc;
    2124             vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pDstAlloc->SurfDesc.VidPnSourceId);
    2125             vboxWddmCheckUpdateShadowAddress(pDevExt, pSource, pDstAlloc->SurfDesc.VidPnSourceId,
    2126                     pPrivateData->SrcAllocInfo.segmentIdAlloc, pPrivateData->SrcAllocInfo.offAlloc);
    2127             PVBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW pRFS = (PVBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW)pPrivateData;
    2128             uint32_t cDMACmdsOutstanding = ASMAtomicReadU32(&pDevExt->cDMACmdsOutstanding);
    2129             if (!cDMACmdsOutstanding)
    2130                 VBOXVBVA_OP(ReportDirtyRect, pDevExt, pSource, &pRFS->rect);
     2126            PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY pS2P = (PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY)pPrivateDataBase;
     2127            VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pS2P->Shadow2Primary.VidPnSourceId];
     2128            PVBOXWDDM_ALLOCATION pSrcAlloc = pS2P->Shadow2Primary.ShadowAlloc.pAlloc;
     2129            vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pS2P->Shadow2Primary.VidPnSourceId);
     2130            vboxWddmCheckUpdateShadowAddress(pDevExt, pSource, pS2P->Shadow2Primary.VidPnSourceId,
     2131                    pS2P->Shadow2Primary.ShadowAlloc.segmentIdAlloc, pS2P->Shadow2Primary.ShadowAlloc.offAlloc);
     2132            uint32_t cUnlockedVBVADisabled = ASMAtomicReadU32(&pDevExt->cUnlockedVBVADisabled);
     2133            if (!cUnlockedVBVADisabled)
     2134                VBOXVBVA_OP(ReportDirtyRect, pDevExt, pSource, &pS2P->Shadow2Primary.SrcRect);
    21312135            else
    21322136            {
    21332137                Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
    2134                 VBOXVBVA_OP_WITHLOCK_ATDPC(ReportDirtyRect, pDevExt, pSource, &pRFS->rect);
     2138                VBOXVBVA_OP_WITHLOCK_ATDPC(ReportDirtyRect, pDevExt, pSource, &pS2P->Shadow2Primary.SrcRect);
    21352139            }
    21362140            /* get DPC data at IRQL */
    21372141
    2138             Status = vboxWddmDmaCmdNotifyCompletion(pDevExt, pPrivateData->pContext, pSubmitCommand->SubmissionFenceId);
     2142            Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId);
    21392143            break;
    21402144        }
     
    21432147        {
    21442148            VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
    2145             PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pSubmitCommand->hContext;
    2146             Assert(pContext);
    2147             Assert(pContext->pDevice);
    2148             Assert(pContext->pDevice->pAdapter == pDevExt);
    2149             PVBOXWDDM_DMA_PRESENT_BLT pBlt = (PVBOXWDDM_DMA_PRESENT_BLT)pPrivateData;
    2150             PVBOXWDDM_ALLOCATION pDstAlloc = pPrivateData->DstAllocInfo.pAlloc;
    2151             PVBOXWDDM_ALLOCATION pSrcAlloc = pPrivateData->SrcAllocInfo.pAlloc;
     2149            PVBOXWDDM_DMA_PRIVATEDATA_BLT pBlt = (PVBOXWDDM_DMA_PRIVATEDATA_BLT)pPrivateData;
     2150            PVBOXWDDM_ALLOCATION pDstAlloc = pBlt->Blt.DstAlloc.pAlloc;
     2151            PVBOXWDDM_ALLOCATION pSrcAlloc = pBlt->Blt.SrcAlloc.pAlloc;
    21522152            uint32_t cContexts3D = ASMAtomicReadU32(&pDevExt->cContexts3D);
     2153            BOOLEAN bComplete = TRUE;
    21532154            switch (pDstAlloc->enmType)
    21542155            {
     
    21582159                    if (pDstAlloc->bAssigned)
    21592160                    {
    2160                         VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pPrivateData->DstAllocInfo.srcId];
     2161                        VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->SurfDesc.VidPnSourceId];
    21612162                        Assert(pSource->pPrimaryAllocation == pDstAlloc);
    21622163                        switch (pSrcAlloc->enmType)
     
    21642165                            case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
    21652166                            {
    2166                                 RECT rect;
     2167                                VBOXVDMAPIPE_FLAGS_DMACMD fBltFlags;
     2168                                fBltFlags.Value = 0;
     2169                                fBltFlags.b3DRelated = !!cContexts3D;
    21672170                                Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM);
    21682171                                vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pDstAlloc->SurfDesc.VidPnSourceId);
    21692172                                vboxWddmCheckUpdateShadowAddress(pDevExt, pSource,
    2170                                         pDstAlloc->SurfDesc.VidPnSourceId, pPrivateData->SrcAllocInfo.segmentIdAlloc, pPrivateData->SrcAllocInfo.offAlloc);
    2171                                 if (pBlt->DstRects.UpdateRects.cRects)
     2173                                        pDstAlloc->SurfDesc.VidPnSourceId, pBlt->Blt.SrcAlloc.segmentIdAlloc, pBlt->Blt.SrcAlloc.offAlloc);
     2174                                if (vboxVhwaHlpOverlayListIsEmpty(pDevExt, pDstAlloc->SurfDesc.VidPnSourceId))
    21722175                                {
    2173                                     rect = pBlt->DstRects.UpdateRects.aRects[0];
    2174                                     for (UINT i = 1; i < pBlt->DstRects.UpdateRects.cRects; ++i)
     2176                                    RECT rect;
     2177                                    if (pBlt->Blt.DstRects.UpdateRects.cRects)
    21752178                                    {
    2176                                         vboxWddmRectUnited(&rect, &rect, &pBlt->DstRects.UpdateRects.aRects[i]);
     2179                                        rect = pBlt->Blt.DstRects.UpdateRects.aRects[0];
     2180                                        for (UINT i = 1; i < pBlt->Blt.DstRects.UpdateRects.cRects; ++i)
     2181                                        {
     2182                                            vboxWddmRectUnited(&rect, &rect, &pBlt->Blt.DstRects.UpdateRects.aRects[i]);
     2183                                        }
     2184                                    }
     2185                                    else
     2186                                        rect = pBlt->Blt.DstRects.ContextRect;
     2187
     2188                                    uint32_t cUnlockedVBVADisabled = ASMAtomicReadU32(&pDevExt->cUnlockedVBVADisabled);
     2189                                    if (!cUnlockedVBVADisabled)
     2190                                        VBOXVBVA_OP(ReportDirtyRect, pDevExt, pSource, &rect);
     2191                                    else
     2192                                    {
     2193                                        Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
     2194                                        VBOXVBVA_OP_WITHLOCK_ATDPC(ReportDirtyRect, pDevExt, pSource, &rect);
    21772195                                    }
    21782196                                }
    21792197                                else
    2180                                     rect = pBlt->DstRects.ContextRect;
    2181 
    2182                                 uint32_t cDMACmdsOutstanding = ASMAtomicReadU32(&pDevExt->cDMACmdsOutstanding);
    2183                                 if (!cDMACmdsOutstanding)
    2184                                     VBOXVBVA_OP(ReportDirtyRect, pDevExt, pSource, &rect);
    2185                                 else
    21862198                                {
    2187                                     Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
    2188                                     VBOXVBVA_OP_WITHLOCK_ATDPC(ReportDirtyRect, pDevExt, pSource, &rect);
     2199                                    fBltFlags.b2DRelated = 1;
     2200                                    fBltFlags.bDecVBVAUnlock = 1;
    21892201                                }
    2190                                 vboxWddmSubmitBltCmd(pDevExt, NULL, pBlt);
     2202
     2203                                if (fBltFlags.Value)
     2204                                {
     2205                                    Status = vboxWddmSubmitBltCmd(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, pBlt, fBltFlags);
     2206                                    bComplete = FALSE;
     2207                                }
    21912208                                break;
    21922209                            }
     
    21972214                                if (pSrcAlloc->fRcFlags.RenderTarget)
    21982215                                {
    2199                                     vboxWddmSubmitBltCmd(pDevExt, pSrcAlloc, pBlt);
     2216                                    VBOXVDMAPIPE_FLAGS_DMACMD fBltFlags;
     2217                                    fBltFlags.Value = 0;
     2218                                    fBltFlags.b3DRelated = 1;
     2219                                    Status = vboxWddmSubmitBltCmd(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, pBlt, fBltFlags);
     2220                                    bComplete = FALSE;
    22002221                                }
    22012222                                break;
     
    22132234                    Assert(pSrcAlloc->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC);
    22142235                    Assert(pSrcAlloc->fRcFlags.RenderTarget);
    2215                     Assert(vboxWddmRectIsEqual(&pBlt->SrcRect, &pBlt->DstRects.ContextRect));
    2216                     Assert(pBlt->DstRects.UpdateRects.cRects == 1);
    2217                     Assert(vboxWddmRectIsEqual(&pBlt->SrcRect, pBlt->DstRects.UpdateRects.aRects));
     2236                    Assert(vboxWddmRectIsEqual(&pBlt->Blt.SrcRect, &pBlt->Blt.DstRects.ContextRect));
     2237                    Assert(pBlt->Blt.DstRects.UpdateRects.cRects == 1);
     2238                    Assert(vboxWddmRectIsEqual(&pBlt->Blt.SrcRect, pBlt->Blt.DstRects.UpdateRects.aRects));
    22182239                    break;
    22192240                }
     
    22282249            }
    22292250
    2230             Status = vboxWddmDmaCmdNotifyCompletion(pDevExt, pPrivateData->pContext, pSubmitCommand->SubmissionFenceId);
     2251            if (bComplete)
     2252            {
     2253                Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId);
     2254            }
    22312255            break;
    22322256        }
    22332257        case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
    22342258        {
    2235             VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
    2236             PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pSubmitCommand->hContext;
    2237             PVBOXWDDM_ALLOCATION pAlloc = pPrivateData->SrcAllocInfo.pAlloc;
    2238             PVBOXWDDM_SWAPCHAIN pSwapchain = vboxWddmSwapchainRetainByAlloc(pDevExt, pAlloc);
    2239             if (pSwapchain)
    2240             {
    2241                 do
    2242                 {
    2243                     PVBOXVDMAPIPE_CMD_RECTSINFO pRectsCmd = (PVBOXVDMAPIPE_CMD_RECTSINFO)vboxVdmaGgCmdCreate(&pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_RECTSINFO, RT_OFFSETOF(VBOXVDMAPIPE_CMD_RECTSINFO, ContextsRects.UpdateRects.aRects[1]));
    2244                     Assert(pRectsCmd);
    2245                     if (pRectsCmd)
    2246                     {
    2247 
    2248                         VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pPrivateData->SrcAllocInfo.srcId];
    2249                         pRectsCmd->pContext = pContext;
    2250                         pRectsCmd->pSwapchain = pSwapchain;
    2251                         RECT r;
    2252                         r.left = pSource->VScreenPos.x;
    2253                         r.top = pSource->VScreenPos.y;
    2254                         r.right = pAlloc->SurfDesc.width + pSource->VScreenPos.x;
    2255                         r.bottom = pAlloc->SurfDesc.height + pSource->VScreenPos.y;
    2256                         pRectsCmd->ContextsRects.ContextRect = r;
    2257                         pRectsCmd->ContextsRects.UpdateRects.cRects = 1;
    2258                         pRectsCmd->ContextsRects.UpdateRects.aRects[0] = r;
    2259                         NTSTATUS tmpStatus = vboxVdmaGgCmdSubmit(&pDevExt->u.primary.Vdma.DmaGg, &pRectsCmd->Hdr);
    2260                         Assert(tmpStatus == STATUS_SUCCESS);
    2261                         if (tmpStatus == STATUS_SUCCESS)
    2262                             break;
    2263                         vboxVdmaGgCmdDestroy(&pRectsCmd->Hdr);
    2264                     }
    2265                     vboxWddmSwapchainRelease(pSwapchain);
    2266                 } while (0);
    2267             }
    2268             Status = vboxWddmDmaCmdNotifyCompletion(pDevExt, pPrivateData->pContext, pSubmitCommand->SubmissionFenceId);
     2259            VBOXWDDM_DMA_PRIVATEDATA_FLIP *pFlip = (VBOXWDDM_DMA_PRIVATEDATA_FLIP*)pPrivateDataBase;
     2260            PVBOXVDMAPIPE_CMD_DMACMD_FLIP pFlipCmd = (PVBOXVDMAPIPE_CMD_DMACMD_FLIP)vboxVdmaGgCmdCreate(
     2261                    &pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_DMACMD, sizeof (VBOXVDMAPIPE_CMD_DMACMD_FLIP));
     2262            Assert(pFlipCmd);
     2263            if (pFlipCmd)
     2264            {
     2265                VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pFlip->Flip.Alloc.srcId];
     2266                vboxVdmaDdiCmdInit(&pFlipCmd->Hdr.DdiCmd, pSubmitCommand->SubmissionFenceId, pContext, vboxVdmaGgDdiCmdDestroy, pFlipCmd);
     2267                pFlipCmd->Hdr.pDevExt = pDevExt;
     2268                pFlipCmd->Hdr.fFlags.Value = 0;
     2269                pFlipCmd->Hdr.fFlags.b3DRelated = 1;
     2270                pFlipCmd->Hdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP;
     2271                memcpy(&pFlipCmd->Flip, &pFlip->Flip, sizeof (pFlipCmd->Flip));
     2272                Status = vboxWddmSubmitCmd(pDevExt, &pFlipCmd->Hdr);
     2273                Assert(Status == STATUS_SUCCESS);
     2274            }
     2275            else
     2276            {
     2277                Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId);
     2278                Assert(Status == STATUS_SUCCESS);
     2279            }
    22692280            break;
    22702281        }
    22712282        case VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL:
    22722283        {
    2273             VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR *pPrivateData = (VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR*)pPrivateDataBase;
    2274             PVBOXWDDM_DMA_PRESENT_CLRFILL pCF = (PVBOXWDDM_DMA_PRESENT_CLRFILL)pPrivateData;
    2275             PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pSubmitCommand->hContext;
    2276             PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCFCmd = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)vboxVdmaGgCmdCreate(&pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_DMACMD_CLRFILL, RT_OFFSETOF(VBOXVDMAPIPE_CMD_DMACMD_CLRFILL, Rects.aRects[pCF->Rects.cRects]));
    2277             NTSTATUS submStatus = STATUS_UNSUCCESSFUL;
     2284            PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF = (PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL)pPrivateDataBase;
     2285            PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCFCmd = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)vboxVdmaGgCmdCreate(
     2286                    &pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_DMACMD,
     2287                    RT_OFFSETOF(VBOXVDMAPIPE_CMD_DMACMD_CLRFILL, ClrFill.Rects.aRects[pCF->ClrFill.Rects.cRects]));
    22782288            Assert(pCFCmd);
    22792289            if (pCFCmd)
    22802290            {
    2281                 PVBOXWDDM_ALLOCATION pDstAlloc = pPrivateData->DstAllocInfo.pAlloc;
    2282                 Assert(pDstAlloc);
    2283                 D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId;
    2284                 if (pDstAlloc->enmType == VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE
    2285                         && pDstAlloc->bAssigned)
    2286                 {
    2287                     VidPnSourceId = pPrivateData->DstAllocInfo.srcId;
    2288 #ifdef VBOXWDDM_RENDER_FROM_SHADOW
    2289                     VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pPrivateData->DstAllocInfo.srcId];
    2290                     Assert(pSource->pPrimaryAllocation == pDstAlloc);
    2291 
    2292                     Assert(pSource->pShadowAllocation);
    2293                     if (pSource->pShadowAllocation)
    2294                         pDstAlloc = pSource->pShadowAllocation;
    2295 #endif
    2296                 }
    2297                 else
    2298                 {
    2299                     VidPnSourceId = D3DDDI_ID_UNINITIALIZED;
    2300                 }
    2301                 pCFCmd->pContext = pContext;
    2302                 pCFCmd->pAllocation = pDstAlloc;
    2303                 pCFCmd->SubmissionFenceId = pSubmitCommand->SubmissionFenceId;
    2304                 pCFCmd->VidPnSourceId = VidPnSourceId;
    2305                 pCFCmd->Color = pCF->Color;
    2306                 memcpy(&pCFCmd->Rects, &pCF->Rects, RT_OFFSETOF(VBOXWDDM_RECTS_INFO, aRects[pCF->Rects.cRects]));
    2307                 ASMAtomicIncU32(&pDevExt->cDMACmdsOutstanding);
    2308                 submStatus = vboxVdmaGgCmdSubmit(&pDevExt->u.primary.Vdma.DmaGg, &pCFCmd->Hdr);
    2309                 Assert(submStatus == STATUS_SUCCESS);
    2310                 if (submStatus != STATUS_SUCCESS)
    2311                 {
    2312                     uint32_t cNew = ASMAtomicDecU32(&pDevExt->cDMACmdsOutstanding);
    2313                     Assert(cNew < UINT32_MAX/2);
    2314                     vboxVdmaGgCmdDestroy(&pCFCmd->Hdr);
    2315                 }
    2316 
    2317             }
    2318 
    2319             Status = vboxWddmDmaCmdNotifyCompletion(pDevExt, pPrivateData->pContext, pSubmitCommand->SubmissionFenceId);
    2320             Assert(Status == STATUS_SUCCESS);
     2291//                VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pFlip->Flip.Alloc.srcId];
     2292                vboxVdmaDdiCmdInit(&pCFCmd->Hdr.DdiCmd, pSubmitCommand->SubmissionFenceId, pContext, vboxVdmaGgDdiCmdDestroy, pCFCmd);
     2293                pCFCmd->Hdr.pDevExt = pDevExt;
     2294                pCFCmd->Hdr.pDevExt = pDevExt;
     2295                pCFCmd->Hdr.fFlags.Value = 0;
     2296                pCFCmd->Hdr.fFlags.b2DRelated = 1;
     2297                pCFCmd->Hdr.fFlags.bDecVBVAUnlock = 1;
     2298                pCFCmd->Hdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL;
     2299                memcpy(&pCFCmd->ClrFill, &pCF->ClrFill, RT_OFFSETOF(VBOXVDMA_CLRFILL, Rects.aRects[pCF->ClrFill.Rects.cRects]));
     2300                Status = vboxWddmSubmitCmd(pDevExt, &pCFCmd->Hdr);
     2301                Assert(Status == STATUS_SUCCESS);
     2302            }
     2303            else
     2304            {
     2305                Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId);
     2306                Assert(Status == STATUS_SUCCESS);
     2307            }
    23212308
    23222309            break;
     
    23242311        case VBOXVDMACMD_TYPE_DMA_NOP:
    23252312        {
    2326             PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pSubmitCommand->hContext;
    2327             Assert(pContext);
    2328             Status = vboxWddmDmaCmdNotifyCompletion(pDevExt, pContext, pSubmitCommand->SubmissionFenceId);
     2313            Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId);
    23292314            Assert(Status == STATUS_SUCCESS);
    23302315            break;
     
    33913376                        pSource->offVram = VBOXVIDEOOFFSET_VOID;
    33923377#endif
     3378#if 0 /* tmp */
    33933379                        Status = vboxWddmGhDisplaySetInfo(pDevExt, pSource, pSetVidPnSourceVisibility->VidPnSourceId);
    33943380                        Assert(Status == STATUS_SUCCESS);
    33953381                        if (Status != STATUS_SUCCESS)
    33963382                            drprintf((__FUNCTION__": vboxWddmGhDisplaySetInfo failed, Status (0x%x)\n", Status));
     3383#endif
    33973384                    }
    33983385                }
     
    36783665        if (RT_SUCCESS(rc))
    36793666        {
    3680             pCreateOverlay->hOverlay = pOverlay;;
     3667            vboxVhwaHlpOverlayListAdd(pDevExt, pOverlay);
     3668#ifdef VBOXWDDM_RENDER_FROM_SHADOW
     3669            RECT DstRect;
     3670            vboxVhwaHlpOverlayDstRectGet(pDevExt, pOverlay, &DstRect);
     3671            Status = vboxVdmaHlpUpdatePrimary(pDevExt, pCreateOverlay->VidPnSourceId, &DstRect);
     3672            Assert(Status == STATUS_SUCCESS);
     3673            /* ignore primary update failure */
     3674            Status = STATUS_SUCCESS;
     3675#endif
     3676            pCreateOverlay->hOverlay = pOverlay;
    36813677        }
    36823678        else
     
    39613957
    39623958    PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR)pPresent->pDmaBufferPrivateData;
    3963     pPrivateData->pContext = pContext;
    39643959    pPrivateData->BaseHdr.fFlags.Value = 0;
    39653960    uint32_t cContexts3D = ASMAtomicReadU32(&pDevExt->cContexts3D);
     
    40074002                                    && pDstAlloc->bVisible)
    40084003                            {
    4009                                 Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW));
    4010                                 if (pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW))
     4004#ifdef VBOX_WITH_VIDEOHWACCEL
     4005                                if (vboxVhwaHlpOverlayListIsEmpty(pDevExt, pDstAlloc->SurfDesc.VidPnSourceId))
     4006#endif
    40114007                                {
    4012                                     VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->SurfDesc.VidPnSourceId];
    4013                                     vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pDstAlloc->SurfDesc.VidPnSourceId);
    4014                                     Assert(pPresent->SrcRect.left == pPresent->DstRect.left);
    4015                                     Assert(pPresent->SrcRect.right == pPresent->DstRect.right);
    4016                                     Assert(pPresent->SrcRect.top == pPresent->DstRect.top);
    4017                                     Assert(pPresent->SrcRect.bottom == pPresent->DstRect.bottom);
    4018                                     RECT rect;
    4019                                     if (pPresent->SubRectCnt)
     4008                                    Assert(pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY));
     4009                                    if (pPresent->DmaBufferPrivateDataSize >= sizeof (VBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY))
    40204010                                    {
    4021                                         rect = pPresent->pDstSubRects[0];
    4022                                         for (UINT i = 1; i < pPresent->SubRectCnt; ++i)
     4011                                        VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->SurfDesc.VidPnSourceId];
     4012                                        vboxWddmAssignShadow(pDevExt, pSource, pSrcAlloc, pDstAlloc->SurfDesc.VidPnSourceId);
     4013                                        Assert(pPresent->SrcRect.left == pPresent->DstRect.left);
     4014                                        Assert(pPresent->SrcRect.right == pPresent->DstRect.right);
     4015                                        Assert(pPresent->SrcRect.top == pPresent->DstRect.top);
     4016                                        Assert(pPresent->SrcRect.bottom == pPresent->DstRect.bottom);
     4017                                        RECT rect;
     4018                                        if (pPresent->SubRectCnt)
    40234019                                        {
    4024                                             vboxWddmRectUnited(&rect, &rect, &pPresent->pDstSubRects[i]);
     4020                                            rect = pPresent->pDstSubRects[0];
     4021                                            for (UINT i = 1; i < pPresent->SubRectCnt; ++i)
     4022                                            {
     4023                                                vboxWddmRectUnited(&rect, &rect, &pPresent->pDstSubRects[i]);
     4024                                            }
    40254025                                        }
     4026                                        else
     4027                                            rect = pPresent->SrcRect;
     4028
     4029
     4030                                        pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY);
     4031                                        pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     4032                                        Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE);
     4033                                        memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
     4034                                        pPresent->pPatchLocationListOut->PatchOffset = 0;
     4035                                        pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
     4036                                        ++pPresent->pPatchLocationListOut;
     4037                                        pPresent->pPatchLocationListOut->PatchOffset = 4;
     4038                                        pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
     4039                                        ++pPresent->pPatchLocationListOut;
     4040
     4041                                        pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY;
     4042                                        PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY pS2P = (PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY)pPrivateData;
     4043                                        /* we do not know the shadow address yet, perform dummy DMA cycle */
     4044                                        vboxWddmPopulateDmaAllocInfo(&pS2P->Shadow2Primary.ShadowAlloc, pSrcAlloc, pSrc);
     4045//                                        vboxWddmPopulateDmaAllocInfo(&pPrivateData->DstAllocInfo, pDstAlloc, pDst);
     4046                                        pS2P->Shadow2Primary.SrcRect = rect;
     4047                                        pS2P->Shadow2Primary.VidPnSourceId = pDstAlloc->SurfDesc.VidPnSourceId;
     4048                                        break;
    40264049                                    }
    40274050                                    else
    4028                                         rect = pPresent->SrcRect;
    4029 
    4030 
    4031                                     pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW);
    4032                                     pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
    4033                                     Assert(pPresent->DmaSize >= VBOXWDDM_DUMMY_DMABUFFER_SIZE);
    4034                                     memset(pPresent->pPatchLocationListOut, 0, 2*sizeof (D3DDDI_PATCHLOCATIONLIST));
    4035                                     pPresent->pPatchLocationListOut->PatchOffset = 0;
    4036                                     pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_SOURCE_INDEX;
    4037                                     ++pPresent->pPatchLocationListOut;
    4038                                     pPresent->pPatchLocationListOut->PatchOffset = 4;
    4039                                     pPresent->pPatchLocationListOut->AllocationIndex = DXGK_PRESENT_DESTINATION_INDEX;
    4040                                     ++pPresent->pPatchLocationListOut;
    4041 
    4042 
    4043                                     /* we do not know the shadow address yet, perform dummy DMA cycle */
    4044                                     pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_SHADOW2PRIMARY;
    4045                                     vboxWddmPopulateDmaAllocInfo(&pPrivateData->SrcAllocInfo, pSrcAlloc, pSrc);
    4046                                     vboxWddmPopulateDmaAllocInfo(&pPrivateData->DstAllocInfo, pDstAlloc, pDst);
    4047                                     PVBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW pRFS = (PVBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW)pPrivateData;
    4048                                     pRFS->rect = rect;
    4049                                     break;
    4050                                 }
    4051                                 else
    4052                                 {
    4053                                     Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
    4054                                     break;
     4051                                    {
     4052                                        Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
     4053                                        break;
     4054                                    }
    40554055                                }
    40564056                            }
     
    40594059
    40604060                    /* we're here because this is NOT a shadow->primary update
    4061                      * or because there are d3d contexts and we need to report visible rects */
     4061                     * or because there are d3d contexts and we need to report visible rects
     4062                     * or because we have overlays active and we need a special handling for primary */
    40624063#endif
    40634064                    UINT cbCmd = pPresent->DmaBufferPrivateDataSize;
    40644065                    pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
    40654066
    4066                     vboxWddmPopulateDmaAllocInfo(&pPrivateData->SrcAllocInfo, pSrcAlloc, pSrc);
    4067                     vboxWddmPopulateDmaAllocInfo(&pPrivateData->DstAllocInfo, pDstAlloc, pDst);
    4068 
    4069                     PVBOXWDDM_DMA_PRESENT_BLT pBlt = (PVBOXWDDM_DMA_PRESENT_BLT)pPrivateData;
    4070                     pBlt->SrcRect = pPresent->SrcRect;
    4071                     pBlt->DstRects.ContextRect = pPresent->DstRect;
    4072                     pBlt->DstRects.UpdateRects.cRects = 0;
    4073                     UINT cbHead = RT_OFFSETOF(VBOXWDDM_DMA_PRESENT_BLT, DstRects.UpdateRects.aRects[0]);
     4067                    PVBOXWDDM_DMA_PRIVATEDATA_BLT pBlt = (PVBOXWDDM_DMA_PRIVATEDATA_BLT)pPrivateData;
     4068
     4069                    vboxWddmPopulateDmaAllocInfo(&pBlt->Blt.SrcAlloc, pSrcAlloc, pSrc);
     4070                    vboxWddmPopulateDmaAllocInfo(&pBlt->Blt.DstAlloc, pDstAlloc, pDst);
     4071
     4072                    pBlt->Blt.SrcRect = pPresent->SrcRect;
     4073                    pBlt->Blt.DstRects.ContextRect = pPresent->DstRect;
     4074                    pBlt->Blt.DstRects.UpdateRects.cRects = 0;
     4075                    UINT cbHead = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_BLT, Blt.DstRects.UpdateRects.aRects[0]);
    40744076                    Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
    40754077                    UINT cbRects = (pPresent->SubRectCnt - pPresent->MultipassOffset) * sizeof (RECT);
     
    40834085                    {
    40844086                        cbCmd -= cbRects;
    4085                         memcpy(&pBlt->DstRects.UpdateRects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbRects);
    4086                         pBlt->DstRects.UpdateRects.cRects += cbRects/sizeof (RECT);
     4087                        memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbRects);
     4088                        pBlt->Blt.DstRects.UpdateRects.cRects += cbRects/sizeof (RECT);
    40874089                    }
    40884090                    else
     
    40904092                        UINT cbFitingRects = (cbCmd/sizeof (RECT)) * sizeof (RECT);
    40914093                        Assert(cbFitingRects);
    4092                         memcpy(&pBlt->DstRects.UpdateRects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
     4094                        memcpy(&pBlt->Blt.DstRects.UpdateRects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
    40934095                        cbCmd -= cbFitingRects;
    40944096                        pPresent->MultipassOffset += cbFitingRects/sizeof (RECT);
    4095                         pBlt->DstRects.UpdateRects.cRects += cbFitingRects/sizeof (RECT);
     4097                        pBlt->Blt.DstRects.UpdateRects.cRects += cbFitingRects/sizeof (RECT);
    40964098                        Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
    40974099                        Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
     
    42894291            Assert(cContexts3D);
    42904292            pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP;
    4291 
    4292             vboxWddmPopulateDmaAllocInfo(&pPrivateData->SrcAllocInfo, pSrcAlloc, pSrc);
    4293 
    4294             UINT cbCmd = sizeof (VBOXVDMACMD_DMA_PRESENT_FLIP);
     4293            PVBOXWDDM_DMA_PRIVATEDATA_FLIP pFlip = (PVBOXWDDM_DMA_PRIVATEDATA_FLIP)pPrivateData;
     4294
     4295            vboxWddmPopulateDmaAllocInfo(&pFlip->Flip.Alloc, pSrcAlloc, pSrc);
     4296
     4297            UINT cbCmd = sizeof (VBOXWDDM_DMA_PRIVATEDATA_FLIP);
    42954298            pPresent->pDmaBufferPrivateData = (uint8_t*)pPresent->pDmaBufferPrivateData + cbCmd;
    42964299            pPresent->pDmaBuffer = ((uint8_t*)pPresent->pDmaBuffer) + VBOXWDDM_DUMMY_DMABUFFER_SIZE;
     
    43204323            UINT cbCmd = pPresent->DmaBufferPrivateDataSize;
    43214324            pPrivateData->BaseHdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL;
    4322 
    4323             vboxWddmPopulateDmaAllocInfo(&pPrivateData->DstAllocInfo, pDstAlloc, pDst);
    4324 
    4325             PVBOXWDDM_DMA_PRESENT_CLRFILL pClrFill = (PVBOXWDDM_DMA_PRESENT_CLRFILL)pPrivateData;
    4326             pClrFill->Color = pPresent->Color;
    4327             pClrFill->Rects.cRects = 0;
    4328             UINT cbHead = RT_OFFSETOF(VBOXWDDM_DMA_PRESENT_CLRFILL, Rects.aRects[0]);
     4325            PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF = (PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL)pPrivateData;
     4326
     4327            vboxWddmPopulateDmaAllocInfo(&pCF->ClrFill.Alloc, pDstAlloc, pDst);
     4328
     4329            pCF->ClrFill.Color = pPresent->Color;
     4330            pCF->ClrFill.Rects.cRects = 0;
     4331            UINT cbHead = RT_OFFSETOF(VBOXWDDM_DMA_PRIVATEDATA_CLRFILL, ClrFill.Rects.aRects[0]);
    43294332            Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
    43304333            UINT cbRects = (pPresent->SubRectCnt - pPresent->MultipassOffset) * sizeof (RECT);
     
    43384341            {
    43394342                cbCmd -= cbRects;
    4340                 memcpy(&pClrFill->Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbRects);
    4341                 pClrFill->Rects.cRects += cbRects/sizeof (RECT);
     4343                memcpy(&pCF->ClrFill.Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbRects);
     4344                pCF->ClrFill.Rects.cRects += cbRects/sizeof (RECT);
    43424345            }
    43434346            else
     
    43454348                UINT cbFitingRects = (cbCmd/sizeof (RECT)) * sizeof (RECT);
    43464349                Assert(cbFitingRects);
    4347                 memcpy(&pClrFill->Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
     4350                memcpy(&pCF->ClrFill.Rects.aRects[pPresent->MultipassOffset], pPresent->pDstSubRects, cbFitingRects);
    43484351                cbCmd -= cbFitingRects;
    43494352                pPresent->MultipassOffset += cbFitingRects/sizeof (RECT);
    4350                 pClrFill->Rects.cRects += cbFitingRects/sizeof (RECT);
     4353                pCF->ClrFill.Rects.cRects += cbFitingRects/sizeof (RECT);
    43514354                Assert(pPresent->SubRectCnt > pPresent->MultipassOffset);
    43524355                Status = STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER;
     
    44294432    PVBOXWDDM_OVERLAY pOverlay = (PVBOXWDDM_OVERLAY)hOverlay;
    44304433    Assert(pOverlay);
     4434    vboxVhwaHlpOverlayListRemove(pOverlay->pDevExt, pOverlay);
    44314435    int rc = vboxVhwaHlpOverlayDestroy(pOverlay);
    44324436    AssertRC(rc);
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/wddm/VBoxVideoWddm.h

    r32496 r32823  
    2828#endif
    2929
    30 #ifdef VBOXWDDM_WITH_VBVA
    31 # define VBOXWDDM_RENDER_FROM_SHADOW
    32 #endif
    33 
    3430#ifndef VBOXWDDM_RENDER_FROM_SHADOW
    3531# ifndef VBOXVDMA
     
    5753VOID vboxWddmMemFree(PVOID pvMem);
    5854
    59 NTSTATUS vboxWddmDmaCmdNotifyCompletion(PDEVICE_EXTENSION pDevExt, struct VBOXWDDM_CONTEXT *pContext, UINT SubmissionFenceId);
    6055NTSTATUS vboxWddmCallIsr(PDEVICE_EXTENSION pDevExt);
    6156
     
    105100typedef struct VBOXWDDM_OVERLAY
    106101{
     102    LIST_ENTRY ListEntry;
    107103    PDEVICE_EXTENSION pDevExt;
    108104    PVBOXWDDM_RESOURCE pResource;
    109105    PVBOXWDDM_ALLOCATION pCurentAlloc;
    110106    D3DDDI_VIDEO_PRESENT_SOURCE_ID VidPnSourceId;
     107    RECT DstRect;
    111108} VBOXWDDM_OVERLAY, *PVBOXWDDM_OVERLAY;
    112109
     
    167164#define VBOXWDDMENTRY_2_SWAPCHAIN(_pE) ((PVBOXWDDM_SWAPCHAIN)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_SWAPCHAIN, DevExtListEntry)))
    168165
    169 typedef struct VBOXWDDM_DMA_ALLOCINFO
    170 {
    171     PVBOXWDDM_ALLOCATION pAlloc;
    172     VBOXVIDEOOFFSET offAlloc;
    173     UINT segmentIdAlloc;
    174     D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId;
    175 } VBOXWDDM_DMA_ALLOCINFO, *PVBOXWDDM_DMA_ALLOCINFO;
    176 
    177166typedef struct VBOXWDDM_DMA_PRIVATEDATA_FLAFS
    178167{
     
    201190{
    202191    VBOXWDDM_DMA_PRIVATEDATA_BASEHDR BaseHdr;
    203     PVBOXWDDM_CONTEXT pContext;
    204     VBOXWDDM_DMA_ALLOCINFO SrcAllocInfo;
    205     VBOXWDDM_DMA_ALLOCINFO DstAllocInfo;
    206192}VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR, *PVBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR;
    207193
    208194#ifdef VBOXWDDM_RENDER_FROM_SHADOW
    209195
    210 typedef struct VBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW
    211 {
    212     VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR Hdr;
    213     RECT rect;
    214 } VBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW, *PVBOXWDDM_DMA_PRESENT_RENDER_FROM_SHADOW;
    215 
    216 #endif
    217 
    218 typedef struct VBOXWDDM_DMA_PRESENT_BLT
    219 {
    220     VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR Hdr;
    221     RECT SrcRect;
    222     VBOXVDMAPIPE_RECTS DstRects;
    223 }VBOXWDDM_DMA_PRESENT_BLT, *PVBOXWDDM_DMA_PRESENT_BLT;
    224 
    225 typedef struct VBOXVDMACMD_DMA_PRESENT_FLIP
    226 {
    227     VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR Hdr;
    228 } VBOXVDMACMD_DMA_PRESENT_FLIP, *PVBOXVDMACMD_DMA_PRESENT_FLIP;
    229 
    230 typedef struct VBOXWDDM_DMA_PRESENT_CLRFILL
    231 {
    232     VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR Hdr;
    233     UINT Color;
    234     VBOXWDDM_RECTS_INFO Rects;
    235 } VBOXWDDM_DMA_PRESENT_CLRFILL, *PVBOXWDDM_DMA_PRESENT_CLRFILL;
     196typedef struct VBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY
     197{
     198    VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR Hdr;
     199    VBOXVDMA_SHADOW2PRIMARY Shadow2Primary;
     200} VBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY, *PVBOXWDDM_DMA_PRIVATEDATA_SHADOW2PRIMARY;
     201
     202#endif
     203
     204typedef struct VBOXWDDM_DMA_PRIVATEDATA_BLT
     205{
     206    VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR Hdr;
     207    VBOXVDMA_BLT Blt;
     208} VBOXWDDM_DMA_PRIVATEDATA_BLT, *PVBOXWDDM_DMA_PRIVATEDATA_BLT;
     209
     210typedef struct VBOXWDDM_DMA_PRIVATEDATA_FLIP
     211{
     212    VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR Hdr;
     213    VBOXVDMA_FLIP Flip;
     214} VBOXWDDM_DMA_PRIVATEDATA_FLIP, *PVBOXWDDM_DMA_PRIVATEDATA_FLIP;
     215
     216typedef struct VBOXWDDM_DMA_PRIVATEDATA_CLRFILL
     217{
     218    VBOXWDDM_DMA_PRIVATEDATA_PRESENTHDR Hdr;
     219    VBOXVDMA_CLRFILL ClrFill;
     220} VBOXWDDM_DMA_PRIVATEDATA_CLRFILL, *PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL;
    236221
    237222typedef struct VBOXWDDM_OPENALLOCATION
Note: See TracChangeset for help on using the changeset viewer.

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