VirtualBox

Ignore:
Timestamp:
Jun 24, 2011 12:01:33 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
72472
Message:

wddm/3d: fix card resets

Location:
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp

    r37490 r37626  
    12601260        {
    12611261            PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
    1262             vboxVdmaDdiCmdInit(pDdiCmd, 0, NULL, vboxVideoAMgrAllocSubmitCompletion, pDr);
     1262            vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxVideoAMgrAllocSubmitCompletion, pDr);
    12631263            /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
    12641264            vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
     
    13811381}
    13821382
     1383VOID vboxWddmCounterU32Wait(uint32_t volatile * pu32, uint32_t u32Val)
     1384{
     1385    LARGE_INTEGER Interval;
     1386    Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;
     1387    uint32_t u32CurVal;
     1388
     1389    while ((u32CurVal = ASMAtomicReadU32(pu32)) != u32Val)
     1390    {
     1391        Assert(u32CurVal >= u32Val);
     1392        Assert(u32CurVal < UINT32_MAX/2);
     1393
     1394        KeDelayExecutionThread(KernelMode, FALSE, &Interval);
     1395    }
     1396}
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h

    r37300 r37626  
    148148#endif
    149149
     150
     151VOID vboxWddmCounterU32Wait(uint32_t volatile * pu32, uint32_t u32Val);
     152
    150153#endif /* #ifndef ___VBoxMPMisc_h__ */
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h

    r37490 r37626  
    116116    struct VBOXWDDM_SWAPCHAIN *pSwapchain;
    117117    VBOXWDDM_ALLOC_TYPE enmType;
     118    volatile uint32_t cRefs;
    118119//    VBOXWDDM_ALLOCUSAGE_TYPE enmCurrentUsage;
    119120    D3DDDI_RESOURCEFLAGS fRcFlags;
     
    123124    VBOXVHWA_SURFHANDLE hHostHandle;
    124125#endif
     126    BOOLEAN fDeleted;
    125127    BOOLEAN bVisible;
    126128    BOOLEAN bAssigned;
     
    141143{
    142144    uint32_t fFlags;
     145    volatile uint32_t cRefs;
    143146    VBOXWDDM_RC_DESC RcDesc;
     147    BOOLEAN fDeleted;
    144148    uint32_t cAllocations;
    145149    VBOXWDDM_ALLOCATION aAllocations[1];
     
    190194typedef struct VBOXWDDM_CONTEXT
    191195{
    192 //    LIST_ENTRY ListEntry;
    193196    struct VBOXWDDM_DEVICE * pDevice;
    194197    HANDLE hContext;
     
    196199    UINT  NodeOrdinal;
    197200    UINT  EngineAffinity;
    198 //    UINT uLastCompletedCmdFenceId;
    199201    VBOXWDDM_HTABLE Swapchains;
    200202    VBOXVIDEOCM_CTX CmContext;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h

    r36867 r37626  
    5151#define VBOXVBVA_OP_WITHLOCK_ATDPC(_op, _pdext, _psrc, _arg) \
    5252        do { \
     53            Assert(KeGetCurrentIrql() == DISPATCH_LEVEL); \
    5354            KeAcquireSpinLockAtDpcLevel(&(_psrc)->Vbva.Lock);  \
    5455            VBOXVBVA_OP(_op, _pdext, _psrc, _arg);        \
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp

    r36867 r37626  
    213213}
    214214
    215 PVBOXVDMAPIPE_CMD_DR vboxVdmaGgCmdCreate(PVBOXVDMAGG pVdma, VBOXVDMAPIPE_CMD_TYPE enmType, uint32_t cbCmd)
    216 {
    217     PVBOXVDMAPIPE_CMD_DR pHdr = (PVBOXVDMAPIPE_CMD_DR)vboxWddmMemAllocZero(cbCmd);
    218     Assert(pHdr);
    219     if (pHdr)
    220     {
    221         pHdr->enmType = enmType;
    222         return pHdr;
    223     }
    224     return NULL;
    225 }
    226 
    227 void vboxVdmaGgCmdDestroy(PVBOXVDMAPIPE_CMD_DR pDr)
    228 {
     215PVBOXVDMAPIPE_CMD_DR vboxVdmaGgCmdCreate(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_TYPE enmType, uint32_t cbCmd)
     216{
     217    PVBOXVDMAPIPE_CMD_DR pHdr;
     218#ifdef VBOX_WDDM_IRQ_COMPLETION
     219    if (enmType == VBOXVDMAPIPE_CMD_TYPE_DMACMD)
     220    {
     221        UINT cbAlloc = VBOXVDMACMD_SIZE_FROMBODYSIZE(cbCmd);
     222        VBOXVDMACBUF_DR* pDr = vboxVdmaCBufDrCreate(&pDevExt->u.primary.Vdma, cbAlloc);
     223        if (!pDr)
     224        {
     225            WARN(("dr allocation failed"));
     226            return NULL;
     227        }
     228        pDr->fFlags = VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR;
     229        pDr->cbBuf = VBOXVDMACMD_HEADER_SIZE();
     230        pDr->rc = VINF_SUCCESS;
     231
     232
     233        PVBOXVDMACMD pDmaHdr = VBOXVDMACBUF_DR_TAIL(pDr, VBOXVDMACMD);
     234        pDmaHdr->enmType = VBOXVDMACMD_TYPE_DMA_NOP;
     235        pDmaHdr->u32CmdSpecific = 0;
     236
     237        pHdr = VBOXVDMACMD_BODY(pDmaHdr, VBOXVDMAPIPE_CMD_DR);
     238    }
     239    else
     240#endif
     241    {
     242        pHdr = (PVBOXVDMAPIPE_CMD_DR)vboxWddmMemAllocZero(cbCmd);
     243        if (!pHdr)
     244        {
     245            WARN(("cmd allocation failed"));
     246            return NULL;
     247        }
     248    }
     249    pHdr->enmType = enmType;
     250    return pHdr;
     251}
     252
     253#ifdef VBOX_WDDM_IRQ_COMPLETION
     254DECLINLINE(VBOXVDMACBUF_DR*) vboxVdmaGgCmdDmaGetDr(PVBOXVDMAPIPE_CMD_DMACMD pDr)
     255{
     256    VBOXVDMACMD* pDmaCmd = VBOXVDMACMD_FROM_BODY(pDr);
     257    VBOXVDMACBUF_DR* pDmaDr = VBOXVDMACBUF_DR_FROM_TAIL(pDmaCmd);
     258    return pDmaDr;
     259}
     260
     261DECLINLINE(PVBOXVDMADDI_CMD) vboxVdmaGgCmdDmaGetDdiCmd(PVBOXVDMAPIPE_CMD_DMACMD pDr)
     262{
     263    VBOXVDMACBUF_DR* pDmaDr = vboxVdmaGgCmdDmaGetDr(pDr);
     264    return VBOXVDMADDI_CMD_FROM_BUF_DR(pDmaDr);
     265}
     266
     267#endif
     268
     269void vboxVdmaGgCmdDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pDr)
     270{
     271#ifdef VBOX_WDDM_IRQ_COMPLETION
     272    if (pDr->enmType == VBOXVDMAPIPE_CMD_TYPE_DMACMD)
     273    {
     274        VBOXVDMACBUF_DR* pDmaDr = vboxVdmaGgCmdDmaGetDr((PVBOXVDMAPIPE_CMD_DMACMD)pDr);
     275        vboxVdmaCBufDrFree(&pDevExt->u.primary.Vdma, pDmaDr);
     276        return;
     277    }
     278#endif
    229279    vboxWddmMemFree(pDr);
    230280}
     
    232282DECLCALLBACK(VOID) vboxVdmaGgDdiCmdDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext)
    233283{
    234     vboxVdmaGgCmdDestroy((PVBOXVDMAPIPE_CMD_DR)pvContext);
     284    vboxVdmaGgCmdDestroy(pDevExt, (PVBOXVDMAPIPE_CMD_DR)pvContext);
    235285}
    236286
     
    528578}
    529579
    530 static NTSTATUS vboxVdmaGgDmaColorFill(PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCF)
     580static NTSTATUS vboxVdmaGgDmaColorFill(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCF)
    531581{
    532582    NTSTATUS Status = STATUS_UNSUCCESSFUL;
    533     PVBOXWDDM_CONTEXT pContext = pCF->Hdr.DdiCmd.pContext;
    534     PVBOXMP_DEVEXT pDevExt = pContext->pDevice->pAdapter;
    535583    Assert (pDevExt->pvVisibleVram);
    536584    if (pDevExt->pvVisibleVram)
     
    593641                    {
    594642                        PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[pCF->ClrFill.Alloc.pAlloc->SurfDesc.VidPnSourceId];
    595                         VBOXVBVA_OP_WITHLOCK(ReportDirtyRect, pDevExt, pSource, &UnionRect);
     643                        uint32_t cUnlockedVBVADisabled = ASMAtomicReadU32(&pDevExt->cUnlockedVBVADisabled);
     644                        if (!cUnlockedVBVADisabled)
     645                        {
     646                            VBOXVBVA_OP(ReportDirtyRect, pDevExt, pSource, &UnionRect);
     647                        }
     648                        else
     649                        {
     650                            VBOXVBVA_OP_WITHLOCK(ReportDirtyRect, pDevExt, pSource, &UnionRect);
     651                        }
    596652                    }
    597653                }
     
    682738 * @return on success the number of bytes the command contained, otherwise - VERR_xxx error code
    683739 */
    684 static NTSTATUS vboxVdmaGgDmaBlt(PVBOXVDMAPIPE_CMD_DMACMD_BLT pBlt)
     740static NTSTATUS vboxVdmaGgDmaBlt(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD_BLT pBlt)
    685741{
    686742    /* we do not support stretching for now */
     
    694750
    695751    NTSTATUS Status = STATUS_SUCCESS;
    696     PVBOXMP_DEVEXT pDevExt = pBlt->Hdr.pDevExt;
    697752
    698753    if (pBlt->Blt.DstRects.UpdateRects.cRects)
     
    734789}
    735790
    736 static NTSTATUS vboxVdmaGgDmaCmdProcess(VBOXVDMAPIPE_CMD_DMACMD *pDmaCmd)
    737 {
    738     PVBOXMP_DEVEXT pDevExt = pDmaCmd->pDevExt;
    739     PVBOXWDDM_CONTEXT pContext = pDmaCmd->DdiCmd.pContext;
     791static NTSTATUS vboxVdmaGgDmaCmdProcessFast(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_DMACMD *pDmaCmd)
     792{
    740793    NTSTATUS Status = STATUS_SUCCESS;
     794    PVBOXWDDM_CONTEXT pContext = pDmaCmd->pContext;
    741795    DXGK_INTERRUPT_TYPE enmComplType = DXGK_INTERRUPT_DMA_COMPLETED;
    742796    switch (pDmaCmd->enmCmd)
     
    763817                                Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM);
    764818
    765                                 if (pBlt->Hdr.fFlags.b2DRelated || pBlt->Hdr.fFlags.b3DRelated)
     819                                if (pBlt->Hdr.fFlags.b2DRelated)
    766820                                {
    767                                     POINT pos;
    768                                     BOOLEAN bPosMoved = FALSE;
    769                                     if (pBlt->Hdr.fFlags.b3DRelated)
     821                                    RECT OverlayUnionRect;
     822                                    RECT UpdateRect;
     823                                    UpdateRect = pBlt->Blt.DstRects.UpdateRects.aRects[0];
     824                                    for (UINT i = 1; i < pBlt->Blt.DstRects.UpdateRects.cRects; ++i)
    770825                                    {
    771                                         pos = pSource->VScreenPos;
    772                                         if (pos.x || pos.y)
    773                                         {
    774                                             vboxWddmBltPipeRectsTranslate(&pBlt->Blt.DstRects, pos.x, pos.y);
    775                                             bPosMoved = TRUE;
    776                                         }
    777                                         Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, NULL, &pBlt->Blt.DstRects);
    778                                         Assert(Status == STATUS_SUCCESS);
     826                                        vboxWddmRectUnite(&UpdateRect, &pBlt->Blt.DstRects.UpdateRects.aRects[i]);
    779827                                    }
    780 
    781 
    782                                     if (pBlt->Hdr.fFlags.b2DRelated)
     828                                    vboxVhwaHlpOverlayDstRectUnion(pDevExt, pDstAlloc->SurfDesc.VidPnSourceId, &OverlayUnionRect);
     829                                    Assert(pBlt->Blt.DstRects.ContextRect.left == 0); /* <-| otherwise we would probably need to translate the UpdateRects to left;top first??*/
     830                                    Assert(pBlt->Blt.DstRects.ContextRect.top == 0); /* <--| */
     831                                    vboxVdmaDirtyRectsCalcIntersection(&OverlayUnionRect, &pBlt->Blt.DstRects.UpdateRects, &pBlt->Blt.DstRects.UpdateRects);
     832                                    if (pBlt->Blt.DstRects.UpdateRects.cRects)
    783833                                    {
    784                                         if (bPosMoved)
    785                                         {
    786                                             vboxWddmBltPipeRectsTranslate(&pBlt->Blt.DstRects, -pos.x, -pos.y);
    787                                         }
    788 
    789                                         RECT OverlayUnionRect;
    790                                         RECT UpdateRect;
    791                                         UpdateRect = pBlt->Blt.DstRects.UpdateRects.aRects[0];
    792                                         for (UINT i = 1; i < pBlt->Blt.DstRects.UpdateRects.cRects; ++i)
    793                                         {
    794                                             vboxWddmRectUnite(&UpdateRect, &pBlt->Blt.DstRects.UpdateRects.aRects[i]);
    795                                         }
    796                                         vboxVhwaHlpOverlayDstRectUnion(pDevExt, pDstAlloc->SurfDesc.VidPnSourceId, &OverlayUnionRect);
    797                                         Assert(pBlt->Blt.DstRects.ContextRect.left == 0); /* <-| otherwise we would probably need to translate the UpdateRects to left;top first??*/
    798                                         Assert(pBlt->Blt.DstRects.ContextRect.top == 0); /* <--| */
    799                                         vboxVdmaDirtyRectsCalcIntersection(&OverlayUnionRect, &pBlt->Blt.DstRects.UpdateRects, &pBlt->Blt.DstRects.UpdateRects);
    800                                         if (pBlt->Blt.DstRects.UpdateRects.cRects)
    801                                         {
    802                                             vboxVdmaGgDmaBlt(pBlt);
    803                                         }
     834                                        vboxVdmaGgDmaBlt(pDevExt, pBlt);
     835                                    }
     836
     837                                    uint32_t cUnlockedVBVADisabled = ASMAtomicReadU32(&pDevExt->cUnlockedVBVADisabled);
     838                                    if (!cUnlockedVBVADisabled)
     839                                    {
     840                                        VBOXVBVA_OP(ReportDirtyRect, pDevExt, pSource, &UpdateRect);
     841                                    }
     842                                    else
     843                                    {
    804844                                        VBOXVBVA_OP_WITHLOCK(ReportDirtyRect, pDevExt, pSource, &UpdateRect);
    805845                                    }
     846
     847                                }
     848
     849                                if (pBlt->Hdr.fFlags.b3DRelated)
     850                                {
     851                                    Status = STATUS_MORE_PROCESSING_REQUIRED;
    806852                                }
    807853
     
    816862                                    if (pBlt->Hdr.fFlags.b3DRelated)
    817863                                    {
    818                                         PVBOXWDDM_SWAPCHAIN pSwapchain;
    819                                         pSwapchain = vboxWddmSwapchainRetainByAlloc(pDevExt, pSrcAlloc);
    820                                         if (pSwapchain)
    821                                         {
    822                                             Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, pSwapchain, &pBlt->Blt.DstRects);
    823                                             Assert(Status == STATUS_SUCCESS);
    824                                             vboxWddmSwapchainRelease(pSwapchain);
    825                                         }
     864                                        Status = STATUS_MORE_PROCESSING_REQUIRED;
    826865                                    }
    827866                                }
     
    846885                        if (pBlt->Blt.DstRects.UpdateRects.cRects)
    847886                        {
    848                             vboxVdmaGgDmaBlt(pBlt);
     887                            vboxVdmaGgDmaBlt(pDevExt, pBlt);
    849888                        }
    850889                    }
     
    859898            }
    860899
     900            if (Status == STATUS_MORE_PROCESSING_REQUIRED)
     901            {
     902                vboxWddmAllocationRetain(pDstAlloc);
     903                vboxWddmAllocationRetain(pSrcAlloc);
     904            }
    861905            break;
    862906        }
     
    865909            PVBOXVDMAPIPE_CMD_DMACMD_FLIP pFlip = (PVBOXVDMAPIPE_CMD_DMACMD_FLIP)pDmaCmd;
    866910            Assert(pFlip->Hdr.fFlags.b3DRelated);
    867             Assert(!pFlip->Hdr.fFlags.bDecVBVAUnlock);
     911            Assert(!pFlip->Hdr.fFlags.b2DRelated);
     912            if (pFlip->Hdr.fFlags.b3DRelated)
     913            {
     914                Status = STATUS_MORE_PROCESSING_REQUIRED;
     915                vboxWddmAllocationRetain(pFlip->Flip.Alloc.pAlloc);
     916            }
     917
     918            break;
     919        }
     920        case VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL:
     921        {
     922            PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCF = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)pDmaCmd;
     923            Assert(pCF->Hdr.fFlags.b2DRelated);
     924            Assert(!pCF->Hdr.fFlags.b3DRelated);
     925            Status = vboxVdmaGgDmaColorFill(pDevExt, pCF);
     926            Assert(Status == STATUS_SUCCESS);
     927            break;
     928        }
     929        default:
     930            Assert(0);
     931            break;
     932    }
     933
     934    NTSTATUS tmpStatus = vboxVdmaGgCmdDmaNotifyCompleted(pDevExt, pDmaCmd, enmComplType);
     935    Assert(tmpStatus == STATUS_SUCCESS);
     936    if (Status != STATUS_MORE_PROCESSING_REQUIRED)
     937    {
     938        vboxVdmaGgCmdDestroy(pDevExt, &pDmaCmd->Hdr);
     939    }
     940
     941    return Status;
     942}
     943
     944static NTSTATUS vboxVdmaGgDmaCmdProcessSlow(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_DMACMD *pDmaCmd)
     945{
     946    NTSTATUS Status = STATUS_SUCCESS;
     947    PVBOXWDDM_CONTEXT pContext = pDmaCmd->pContext;
     948    DXGK_INTERRUPT_TYPE enmComplType = DXGK_INTERRUPT_DMA_COMPLETED;
     949    switch (pDmaCmd->enmCmd)
     950    {
     951        case VBOXVDMACMD_TYPE_DMA_PRESENT_BLT:
     952        {
     953            PVBOXVDMAPIPE_CMD_DMACMD_BLT pBlt = (PVBOXVDMAPIPE_CMD_DMACMD_BLT)pDmaCmd;
     954            PVBOXWDDM_ALLOCATION pDstAlloc = pBlt->Blt.DstAlloc.pAlloc;
     955            PVBOXWDDM_ALLOCATION pSrcAlloc = pBlt->Blt.SrcAlloc.pAlloc;
     956            BOOLEAN bComplete = TRUE;
     957            switch (pDstAlloc->enmType)
     958            {
     959                case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
     960                case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
     961                {
     962                    if (pDstAlloc->bAssigned)
     963                    {
     964                        VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pDstAlloc->SurfDesc.VidPnSourceId];
     965                        Assert(pSource->pPrimaryAllocation == pDstAlloc);
     966                        switch (pSrcAlloc->enmType)
     967                        {
     968                            case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
     969                            {
     970                                Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_SYSTEM);
     971
     972                                if (pBlt->Hdr.fFlags.b3DRelated)
     973                                {
     974                                    POINT pos = pSource->VScreenPos;
     975                                    if (pos.x || pos.y)
     976                                    {
     977                                        vboxWddmBltPipeRectsTranslate(&pBlt->Blt.DstRects, pos.x, pos.y);
     978                                    }
     979
     980                                    Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, NULL, &pBlt->Blt.DstRects);
     981                                    Assert(Status == STATUS_SUCCESS);
     982                                }
     983
     984                                break;
     985                            }
     986                            case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
     987                            {
     988                                Assert(pContext->enmType == VBOXWDDM_CONTEXT_TYPE_CUSTOM_3D);
     989                                Assert(pSrcAlloc->fRcFlags.RenderTarget);
     990                                if (pSrcAlloc->fRcFlags.RenderTarget)
     991                                {
     992                                    if (pBlt->Hdr.fFlags.b3DRelated)
     993                                    {
     994                                        POINT pos = pSource->VScreenPos;
     995                                        if (pos.x || pos.y)
     996                                        {
     997                                            vboxWddmBltPipeRectsTranslate(&pBlt->Blt.DstRects, pos.x, pos.y);
     998                                        }
     999
     1000                                        PVBOXWDDM_SWAPCHAIN pSwapchain;
     1001                                        pSwapchain = vboxWddmSwapchainRetainByAlloc(pDevExt, pSrcAlloc);
     1002                                        if (pSwapchain)
     1003                                        {
     1004                                            Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pContext, pSwapchain, &pBlt->Blt.DstRects);
     1005                                            Assert(Status == STATUS_SUCCESS);
     1006                                            vboxWddmSwapchainRelease(pSwapchain);
     1007                                        }
     1008                                    }
     1009                                }
     1010                                break;
     1011                            }
     1012                            default:
     1013                                AssertBreakpoint();
     1014                                break;
     1015                        }
     1016                    }
     1017                    break;
     1018                }
     1019                default:
     1020                    Assert(0);
     1021            }
     1022
     1023            vboxWddmAllocationRelease(pDstAlloc);
     1024            vboxWddmAllocationRelease(pSrcAlloc);
     1025            break;
     1026        }
     1027        case VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP:
     1028        {
     1029            PVBOXVDMAPIPE_CMD_DMACMD_FLIP pFlip = (PVBOXVDMAPIPE_CMD_DMACMD_FLIP)pDmaCmd;
     1030            Assert(pFlip->Hdr.fFlags.b3DRelated);
    8681031            Assert(!pFlip->Hdr.fFlags.b2DRelated);
    8691032            PVBOXWDDM_ALLOCATION pAlloc = pFlip->Flip.Alloc.pAlloc;
     
    8891052            }
    8901053
    891             break;
    892         }
    893         case VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL:
    894         {
    895             PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCF = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)pDmaCmd;
    896             Assert(pCF->Hdr.fFlags.b2DRelated);
    897             Assert(pCF->Hdr.fFlags.bDecVBVAUnlock);
    898             Assert(!pCF->Hdr.fFlags.b3DRelated);
    899             Status = vboxVdmaGgDmaColorFill(pCF);
    900             Assert(Status == STATUS_SUCCESS);
     1054            vboxWddmAllocationRelease(pAlloc);
     1055
    9011056            break;
    9021057        }
     
    9061061    }
    9071062
    908     if (pDmaCmd->fFlags.bDecVBVAUnlock)
    909     {
    910         uint32_t cNew = ASMAtomicDecU32(&pDevExt->cUnlockedVBVADisabled);
    911         Assert(cNew < UINT32_MAX/2);
    912     }
    913 
    914     Status = vboxVdmaDdiCmdCompleted(pDevExt, &pDevExt->DdiCmdQueue, &pDmaCmd->DdiCmd, enmComplType);
    915     Assert(Status == STATUS_SUCCESS);
     1063    vboxVdmaGgCmdDestroy(pDevExt, &pDmaCmd->Hdr);
    9161064
    9171065    return Status;
     
    9201068static VOID vboxVdmaGgWorkerThread(PVOID pvUser)
    9211069{
    922     PVBOXVDMAGG pVdma = (PVBOXVDMAGG)pvUser;
     1070    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)pvUser;
     1071    PVBOXVDMAGG pVdma = &pDevExt->u.primary.Vdma.DmaGg;
    9231072
    9241073    NTSTATUS Status = vboxVdmaPipeSvrOpen(&pVdma->CmdPipe);
     
    9401089                    switch (pDr->enmType)
    9411090                    {
    942 #if 0
    943                         case VBOXVDMAPIPE_CMD_TYPE_RECTSINFO:
    944                         {
    945                             PVBOXVDMAPIPE_CMD_RECTSINFO pRects = (PVBOXVDMAPIPE_CMD_RECTSINFO)pDr;
    946                             Status = vboxVdmaGgDirtyRectsProcess(pRects);
    947                             Assert(Status == STATUS_SUCCESS);
    948                             vboxVdmaGgCmdDestroy(pDr);
    949                             break;
    950                         }
    951 #endif
    9521091                        case VBOXVDMAPIPE_CMD_TYPE_DMACMD:
    9531092                        {
    9541093                            PVBOXVDMAPIPE_CMD_DMACMD pDmaCmd = (PVBOXVDMAPIPE_CMD_DMACMD)pDr;
    955                             Status = vboxVdmaGgDmaCmdProcess(pDmaCmd);
     1094                            Status = vboxVdmaGgDmaCmdProcessSlow(pDevExt, pDmaCmd);
    9561095                            Assert(Status == STATUS_SUCCESS);
    9571096                        } break;
     
    9591098                        {
    9601099                            PVBOXVDMAPIPE_CMD_RECTSINFO pRects = (PVBOXVDMAPIPE_CMD_RECTSINFO)pDr;
    961                             Status = vboxVdmaGgDirtyRectsProcess(pRects->pDevExt, pRects->pContext, pRects->pSwapchain, &pRects->ContextsRects);
     1100                            Status = vboxVdmaGgDirtyRectsProcess(pDevExt, pRects->pContext, pRects->pSwapchain, &pRects->ContextsRects);
    9621101                            Assert(Status == STATUS_SUCCESS);
    963                             vboxVdmaGgCmdDestroy(pDr);
     1102                            vboxVdmaGgCmdDestroy(pDevExt, pDr);
    9641103                            break;
    9651104                        }
     
    9791118}
    9801119
    981 NTSTATUS vboxVdmaGgConstruct(PVBOXVDMAGG pVdma)
    982 {
     1120NTSTATUS vboxVdmaGgConstruct(PVBOXMP_DEVEXT pDevExt)
     1121{
     1122    PVBOXVDMAGG pVdma = &pDevExt->u.primary.Vdma.DmaGg;
    9831123    NTSTATUS Status = vboxVdmaPipeConstruct(&pVdma->CmdPipe);
    9841124    Assert(Status == STATUS_SUCCESS);
    9851125    if (Status == STATUS_SUCCESS)
    9861126    {
    987         Status = vboxVdmaGgThreadCreate(&pVdma->pThread, vboxVdmaGgWorkerThread, pVdma);
     1127        Status = vboxVdmaGgThreadCreate(&pVdma->pThread, vboxVdmaGgWorkerThread, pDevExt);
    9881128        Assert(Status == STATUS_SUCCESS);
    9891129        if (Status == STATUS_SUCCESS)
     
    9991139}
    10001140
    1001 NTSTATUS vboxVdmaGgDestruct(PVBOXVDMAGG pVdma)
    1002 {
     1141NTSTATUS vboxVdmaGgDestruct(PVBOXMP_DEVEXT pDevExt)
     1142{
     1143    PVBOXVDMAGG pVdma = &pDevExt->u.primary.Vdma.DmaGg;
    10031144    /* this informs the server thread that it should complete all current commands and exit */
    10041145    NTSTATUS Status = vboxVdmaPipeCltClose(&pVdma->CmdPipe);
     
    10181159}
    10191160
    1020 NTSTATUS vboxVdmaGgCmdSubmit(PVBOXVDMAGG pVdma, PVBOXVDMAPIPE_CMD_DR pCmd)
    1021 {
    1022     return vboxVdmaPipeCltCmdPut(&pVdma->CmdPipe, &pCmd->PipeHdr);
     1161NTSTATUS vboxVdmaGgCmdSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pCmd)
     1162{
     1163    switch (pCmd->enmType)
     1164    {
     1165        case VBOXVDMAPIPE_CMD_TYPE_DMACMD:
     1166        {
     1167            PVBOXVDMAPIPE_CMD_DMACMD pDmaCmd = (PVBOXVDMAPIPE_CMD_DMACMD)pCmd;
     1168            NTSTATUS Status = vboxVdmaGgDmaCmdProcessFast(pDevExt, pDmaCmd);
     1169            if (Status == STATUS_MORE_PROCESSING_REQUIRED)
     1170                break;
     1171            return Status;
     1172        }
     1173        default:
     1174            break;
     1175    }
     1176    return vboxVdmaPipeCltCmdPut(&pDevExt->u.primary.Vdma.DmaGg.CmdPipe, &pCmd->PipeHdr);
     1177}
     1178
     1179NTSTATUS vboxVdmaGgCmdDmaNotifySubmitted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD pCmd)
     1180{
     1181    PVBOXVDMADDI_CMD pDdiCmd;
     1182#ifdef VBOX_WDDM_IRQ_COMPLETION
     1183    pDdiCmd = vboxVdmaGgCmdDmaGetDdiCmd(pCmd);
     1184#else
     1185    pDdiCmd = &pCmd->DdiCmd;
     1186#endif
     1187    NTSTATUS Status = vboxVdmaDdiCmdSubmitted(pDevExt, pDdiCmd);
     1188    Assert(Status == STATUS_SUCCESS);
     1189    return Status;
     1190}
     1191
     1192NTSTATUS vboxVdmaGgCmdDmaNotifyCompleted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD pCmd, DXGK_INTERRUPT_TYPE enmComplType)
     1193{
     1194#ifdef VBOX_WDDM_IRQ_COMPLETION
     1195    VBOXVDMACBUF_DR* pDr = vboxVdmaGgCmdDmaGetDr(pCmd);
     1196    int rc = vboxVdmaCBufDrSubmit(pDevExt, &pDevExt->u.primary.Vdma, pDr);
     1197    Assert(rc == VINF_SUCCESS);
     1198    if (RT_SUCCESS(rc))
     1199    {
     1200        return STATUS_SUCCESS;
     1201    }
     1202    return STATUS_UNSUCCESSFUL;
     1203#else
     1204    return vboxVdmaDdiCmdCompleted(pDevExt, &pCmd->DdiCmd, enmComplType);
     1205#endif
     1206}
     1207
     1208VOID vboxVdmaGgCmdDmaNotifyInit(PVBOXVDMAPIPE_CMD_DMACMD pCmd,
     1209        uint32_t u32NodeOrdinal, uint32_t u32FenceId,
     1210        PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete, PVOID pvComplete)
     1211{
     1212    PVBOXVDMADDI_CMD pDdiCmd;
     1213#ifdef VBOX_WDDM_IRQ_COMPLETION
     1214    pDdiCmd = vboxVdmaGgCmdDmaGetDdiCmd(pCmd);
     1215#else
     1216    pDdiCmd = &pCmd->DdiCmd;
     1217#endif
     1218    vboxVdmaDdiCmdInit(pDdiCmd, u32NodeOrdinal, u32FenceId, pfnComplete, pvComplete);
    10231219}
    10241220
     
    11561352#endif
    11571353        {
    1158             NTSTATUS Status = vboxVdmaGgConstruct(&pInfo->DmaGg);
     1354            NTSTATUS Status = vboxVdmaGgConstruct(pDevExt);
    11591355            Assert(Status == STATUS_SUCCESS);
    11601356            if (Status == STATUS_SUCCESS)
     
    12311427{
    12321428    int rc = VINF_SUCCESS;
    1233     NTSTATUS Status = vboxVdmaGgDestruct(&pInfo->DmaGg);
     1429    NTSTATUS Status = vboxVdmaGgDestruct(pDevExt);
    12341430    Assert(Status == STATUS_SUCCESS);
    12351431    if (Status == STATUS_SUCCESS)
     
    13041500    }
    13051501
    1306     if (vboxVdmaDdiCmdCompletedIrq(pDevExt, &pDevExt->DdiCmdQueue, VBOXVDMADDI_CMD_FROM_BUF_DR(pDr), enmComplType))
     1502    if (vboxVdmaDdiCmdCompletedIrq(pDevExt, VBOXVDMADDI_CMD_FROM_BUF_DR(pDr), enmComplType))
    13071503    {
    13081504        pDevExt->bNotifyDxDpc = TRUE;
     
    13831579
    13841580/* ddi dma command queue */
    1385 DECLINLINE(BOOLEAN) vboxVdmaDdiCmdCanComplete(PVBOXVDMADDI_CMD_QUEUE pQueue)
    1386 {
     1581
     1582VOID vboxVdmaDdiCmdGetCompletedListIsr(PVBOXMP_DEVEXT pDevExt, LIST_ENTRY *pList)
     1583{
     1584    vboxVideoLeDetach(&pDevExt->DpcCmdQueue, pList);
     1585}
     1586
     1587BOOLEAN vboxVdmaDdiCmdIsCompletedListEmptyIsr(PVBOXMP_DEVEXT pDevExt)
     1588{
     1589    return IsListEmpty(&pDevExt->DpcCmdQueue);
     1590}
     1591
     1592DECLINLINE(BOOLEAN) vboxVdmaDdiCmdCanComplete(PVBOXMP_DEVEXT pDevExt, UINT u32NodeOrdinal)
     1593{
     1594    PVBOXVDMADDI_CMD_QUEUE pQueue = &pDevExt->aNodes[u32NodeOrdinal].CmdQueue;
    13871595    return ASMAtomicUoReadU32(&pQueue->cQueuedCmds) == 0;
    13881596}
     
    13931601}
    13941602
    1395 static VOID vboxVdmaDdiCmdNotifyCompletedIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType)
    1396 {
     1603static VOID vboxVdmaDdiCmdNotifyCompletedIrq(PVBOXMP_DEVEXT pDevExt, UINT u32NodeOrdinal, UINT u32FenceId, DXGK_INTERRUPT_TYPE enmComplType)
     1604{
     1605    PVBOXVDMADDI_NODE pNode = &pDevExt->aNodes[u32NodeOrdinal];
    13971606    DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
    13981607    memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
     
    14011610        case DXGK_INTERRUPT_DMA_COMPLETED:
    14021611            notify.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED;
    1403             notify.DmaCompleted.SubmissionFenceId = pCmd->u32FenceId;
    1404 //            if (pCmd->pContext)
    1405 //            {
    1406 //                notify.DmaCompleted.NodeOrdinal = pCmd->pContext->NodeOrdinal;
    1407 //                pCmd->pContext->uLastCompletedCmdFenceId = pCmd->u32FenceId;
    1408 //            }
    1409 //            else
    1410             {
    1411                 pDevExt->u.primary.Vdma.uLastCompletedPagingBufferCmdFenceId = pCmd->u32FenceId;
    1412             }
    1413 
    1414             InsertTailList(&pQueue->DpcCmdQueue, &pCmd->QueueEntry);
    1415 
    1416             break;
     1612            notify.DmaCompleted.SubmissionFenceId = u32FenceId;
     1613            notify.DmaCompleted.NodeOrdinal = u32NodeOrdinal;
     1614            pNode->uLastCompletedFenceId = u32FenceId;
     1615            break;
     1616
    14171617        case DXGK_INTERRUPT_DMA_PREEMPTED:
    14181618            Assert(0);
    14191619            notify.InterruptType = DXGK_INTERRUPT_DMA_PREEMPTED;
    1420             notify.DmaPreempted.PreemptionFenceId = pCmd->u32FenceId;
    1421 //            if (pCmd->pContext)
    1422 //            {
    1423 //                notify.DmaPreempted.LastCompletedFenceId = pCmd->pContext->uLastCompletedCmdFenceId;
    1424 //                notify.DmaPreempted.NodeOrdinal = pCmd->pContext->NodeOrdinal;
    1425 //            }
    1426 //            else
    1427             {
    1428                 notify.DmaPreempted.LastCompletedFenceId = pDevExt->u.primary.Vdma.uLastCompletedPagingBufferCmdFenceId;
    1429             }
     1620            notify.DmaPreempted.PreemptionFenceId = u32FenceId;
     1621            notify.DmaPreempted.NodeOrdinal = u32NodeOrdinal;
     1622            notify.DmaPreempted.LastCompletedFenceId = pNode->uLastCompletedFenceId;
    14301623            break;
    14311624
     
    14331626            Assert(0);
    14341627            notify.InterruptType = DXGK_INTERRUPT_DMA_FAULTED;
    1435             notify.DmaFaulted.FaultedFenceId = pCmd->u32FenceId;
     1628            notify.DmaFaulted.FaultedFenceId = u32FenceId;
    14361629            notify.DmaFaulted.Status = STATUS_UNSUCCESSFUL; /* @todo: better status ? */
    1437             if (pCmd->pContext)
    1438             {
    1439                 notify.DmaFaulted.NodeOrdinal = pCmd->pContext->NodeOrdinal;
    1440             }
    1441             break;
     1630            notify.DmaFaulted.NodeOrdinal = u32NodeOrdinal;
     1631            break;
     1632
    14421633        default:
    14431634            Assert(0);
     
    14481639}
    14491640
    1450 DECLINLINE(VOID) vboxVdmaDdiCmdDequeueIrq(PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
    1451 {
     1641static VOID vboxVdmaDdiCmdProcessCompletedIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType)
     1642{
     1643    vboxVdmaDdiCmdNotifyCompletedIrq(pDevExt, pCmd->u32NodeOrdinal, pCmd->u32FenceId, enmComplType);
     1644    switch (enmComplType)
     1645    {
     1646        case DXGK_INTERRUPT_DMA_COMPLETED:
     1647            InsertTailList(&pDevExt->DpcCmdQueue, &pCmd->QueueEntry);
     1648            break;
     1649        default:
     1650            AssertFailed();
     1651            break;
     1652    }
     1653}
     1654
     1655DECLINLINE(VOID) vboxVdmaDdiCmdDequeueIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd)
     1656{
     1657    PVBOXVDMADDI_CMD_QUEUE pQueue = &pDevExt->aNodes[pCmd->u32NodeOrdinal].CmdQueue;
    14521658    ASMAtomicDecU32(&pQueue->cQueuedCmds);
    14531659    RemoveEntryList(&pCmd->QueueEntry);
    14541660}
    14551661
    1456 DECLINLINE(VOID) vboxVdmaDdiCmdEnqueueIrq(PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
    1457 {
     1662DECLINLINE(VOID) vboxVdmaDdiCmdEnqueueIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd)
     1663{
     1664    PVBOXVDMADDI_CMD_QUEUE pQueue = &pDevExt->aNodes[pCmd->u32NodeOrdinal].CmdQueue;
    14581665    ASMAtomicIncU32(&pQueue->cQueuedCmds);
    14591666    InsertTailList(&pQueue->CmdQueue, &pCmd->QueueEntry);
    14601667}
    14611668
    1462 VOID vboxVdmaDdiQueueInit(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue)
    1463 {
    1464     pQueue->cQueuedCmds = 0;
    1465     InitializeListHead(&pQueue->CmdQueue);
    1466     InitializeListHead(&pQueue->DpcCmdQueue);
    1467 }
    1468 
    1469 BOOLEAN vboxVdmaDdiCmdCompletedIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType)
     1669VOID vboxVdmaDdiNodesInit(PVBOXMP_DEVEXT pDevExt)
     1670{
     1671    for (UINT i = 0; i < RT_ELEMENTS(pDevExt->aNodes); ++i)
     1672    {
     1673        pDevExt->aNodes[i].uLastCompletedFenceId = 0;
     1674        PVBOXVDMADDI_CMD_QUEUE pQueue = &pDevExt->aNodes[i].CmdQueue;
     1675        pQueue->cQueuedCmds = 0;
     1676        InitializeListHead(&pQueue->CmdQueue);
     1677    }
     1678    InitializeListHead(&pDevExt->DpcCmdQueue);
     1679}
     1680
     1681BOOLEAN vboxVdmaDdiCmdCompletedIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType)
    14701682{
    14711683    if (VBOXVDMADDI_STATE_NOT_DX_CMD == pCmd->enmState)
    14721684    {
    1473         InsertTailList(&pQueue->DpcCmdQueue, &pCmd->QueueEntry);
     1685        InsertTailList(&pDevExt->DpcCmdQueue, &pCmd->QueueEntry);
    14741686        return FALSE;
    14751687    }
    14761688
     1689    PVBOXVDMADDI_CMD_QUEUE pQueue = &pDevExt->aNodes[pCmd->u32NodeOrdinal].CmdQueue;
    14771690    BOOLEAN bQueued = pCmd->enmState > VBOXVDMADDI_STATE_NOT_QUEUED;
    14781691    BOOLEAN bComplete = FALSE;
     
    14841697        if (pQueue->CmdQueue.Flink == &pCmd->QueueEntry)
    14851698        {
    1486             vboxVdmaDdiCmdDequeueIrq(pQueue, pCmd);
     1699            vboxVdmaDdiCmdDequeueIrq(pDevExt, pCmd);
    14871700            bComplete = TRUE;
    14881701        }
     
    14941707    else
    14951708    {
    1496         vboxVdmaDdiCmdEnqueueIrq(pQueue, pCmd);
     1709        vboxVdmaDdiCmdEnqueueIrq(pDevExt, pCmd);
    14971710    }
    14981711
    14991712    if (bComplete)
    15001713    {
    1501         vboxVdmaDdiCmdNotifyCompletedIrq(pDevExt, pQueue, pCmd, enmComplType);
     1714        vboxVdmaDdiCmdProcessCompletedIrq(pDevExt, pCmd, enmComplType);
    15021715
    15031716        while (!IsListEmpty(&pQueue->CmdQueue))
     
    15061719            if (pCmd->enmState == VBOXVDMADDI_STATE_COMPLETED)
    15071720            {
    1508                 vboxVdmaDdiCmdDequeueIrq(pQueue, pCmd);
    1509                 vboxVdmaDdiCmdNotifyCompletedIrq(pDevExt, pQueue, pCmd, pCmd->enmComplType);
     1721                vboxVdmaDdiCmdDequeueIrq(pDevExt, pCmd);
     1722                vboxVdmaDdiCmdProcessCompletedIrq(pDevExt, pCmd, pCmd->enmComplType);
    15101723            }
    15111724            else
     
    15221735}
    15231736
    1524 VOID vboxVdmaDdiCmdSubmittedIrq(PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
     1737VOID vboxVdmaDdiCmdSubmittedIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd)
    15251738{
    15261739    BOOLEAN bQueued = pCmd->enmState >= VBOXVDMADDI_STATE_PENDING;
     
    15281741    pCmd->enmState = VBOXVDMADDI_STATE_SUBMITTED;
    15291742    if (!bQueued)
    1530         vboxVdmaDdiCmdEnqueueIrq(pQueue, pCmd);
     1743        vboxVdmaDdiCmdEnqueueIrq(pDevExt, pCmd);
    15311744}
    15321745
     
    15341747{
    15351748    PVBOXMP_DEVEXT pDevExt;
    1536     PVBOXVDMADDI_CMD_QUEUE pQueue;
    15371749    PVBOXVDMADDI_CMD pCmd;
    15381750    DXGK_INTERRUPT_TYPE enmComplType;
     
    15421754{
    15431755    PVBOXVDMADDI_CMD_COMPLETED_CB pdc = (PVBOXVDMADDI_CMD_COMPLETED_CB)Context;
    1544     BOOLEAN bNeedDpc = vboxVdmaDdiCmdCompletedIrq(pdc->pDevExt, pdc->pQueue, pdc->pCmd, pdc->enmComplType);
    1545     pdc->pDevExt->bNotifyDxDpc |= bNeedDpc;
     1756    PVBOXMP_DEVEXT pDevExt = pdc->pDevExt;
     1757    BOOLEAN bNeedDpc = vboxVdmaDdiCmdCompletedIrq(pDevExt, pdc->pCmd, pdc->enmComplType);
     1758    pDevExt->bNotifyDxDpc |= bNeedDpc;
     1759
     1760    if (bNeedDpc)
     1761    {
     1762        BOOLEAN bRc = pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
     1763        Assert(bRc);
     1764    }
    15461765
    15471766    return bNeedDpc;
    15481767}
    15491768
    1550 NTSTATUS vboxVdmaDdiCmdCompleted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType)
     1769NTSTATUS vboxVdmaDdiCmdCompleted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType)
    15511770{
    15521771    VBOXVDMADDI_CMD_COMPLETED_CB context;
    15531772    context.pDevExt = pDevExt;
    1554     context.pQueue = pQueue;
    15551773    context.pCmd = pCmd;
    15561774    context.enmComplType = enmComplType;
     
    15631781            &bNeedDps);
    15641782    Assert(Status == STATUS_SUCCESS);
    1565     if (Status == STATUS_SUCCESS && bNeedDps)
    1566     {
    1567         BOOLEAN bRc = pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
    1568         Assert(bRc);
    1569     }
    15701783    return Status;
    15711784}
     
    15731786typedef struct VBOXVDMADDI_CMD_SUBMITTED_CB
    15741787{
    1575 //    PVBOXMP_DEVEXT pDevExt;
    1576     PVBOXVDMADDI_CMD_QUEUE pQueue;
     1788    PVBOXMP_DEVEXT pDevExt;
    15771789    PVBOXVDMADDI_CMD pCmd;
    15781790} VBOXVDMADDI_CMD_SUBMITTED_CB, *PVBOXVDMADDI_CMD_SUBMITTED_CB;
     
    15811793{
    15821794    PVBOXVDMADDI_CMD_SUBMITTED_CB pdc = (PVBOXVDMADDI_CMD_SUBMITTED_CB)Context;
    1583     vboxVdmaDdiCmdSubmittedIrq(pdc->pQueue, pdc->pCmd);
     1795    vboxVdmaDdiCmdSubmittedIrq(pdc->pDevExt, pdc->pCmd);
    15841796
    15851797    return FALSE;
    15861798}
    15871799
    1588 NTSTATUS vboxVdmaDdiCmdSubmitted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd)
     1800NTSTATUS vboxVdmaDdiCmdSubmitted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd)
    15891801{
    15901802    VBOXVDMADDI_CMD_SUBMITTED_CB context;
    1591     context.pQueue = pQueue;
     1803    context.pDevExt = pDevExt;
    15921804    context.pCmd = pCmd;
    15931805    BOOLEAN bRc;
     
    16051817{
    16061818    PVBOXMP_DEVEXT pDevExt;
    1607     PVBOXWDDM_CONTEXT pContext;
     1819    UINT u32NodeOrdinal;
    16081820    uint32_t u32FenceId;
    16091821} VBOXVDMADDI_CMD_COMPLETE_CB, *PVBOXVDMADDI_CMD_COMPLETE_CB;
     
    16131825    PVBOXVDMADDI_CMD_COMPLETE_CB pdc = (PVBOXVDMADDI_CMD_COMPLETE_CB)Context;
    16141826    PVBOXMP_DEVEXT pDevExt = pdc->pDevExt;
    1615     DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
    1616     memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
    1617 
    1618     notify.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED;
    1619     notify.DmaCompleted.SubmissionFenceId = pdc->u32FenceId;
    1620     notify.DmaCompleted.NodeOrdinal = pdc->pContext->NodeOrdinal;
    1621     notify.DmaCompleted.EngineOrdinal = 0;
    1622 
    1623     pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
     1827
     1828    vboxVdmaDdiCmdNotifyCompletedIrq(pDevExt, pdc->u32NodeOrdinal, pdc->u32FenceId, DXGK_INTERRUPT_DMA_COMPLETED);
    16241829
    16251830    pDevExt->bNotifyDxDpc = TRUE;
     
    16291834}
    16301835
    1631 static NTSTATUS vboxVdmaDdiCmdFenceNotifyComplete(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, uint32_t u32FenceId)
     1836static NTSTATUS vboxVdmaDdiCmdFenceNotifyComplete(PVBOXMP_DEVEXT pDevExt, uint32_t u32NodeOrdinal, uint32_t u32FenceId)
    16321837{
    16331838    VBOXVDMADDI_CMD_COMPLETE_CB context;
    16341839    context.pDevExt = pDevExt;
    1635     context.pContext = pContext;
     1840    context.u32NodeOrdinal = u32NodeOrdinal;
    16361841    context.u32FenceId = u32FenceId;
    16371842    BOOLEAN bRet;
     
    16461851}
    16471852
    1648 NTSTATUS vboxVdmaDdiCmdFenceComplete(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, uint32_t u32FenceId, DXGK_INTERRUPT_TYPE enmComplType)
    1649 {
    1650     if (vboxVdmaDdiCmdCanComplete(&pDevExt->DdiCmdQueue))
    1651         return vboxVdmaDdiCmdFenceNotifyComplete(pDevExt, pContext, u32FenceId);
     1853NTSTATUS vboxVdmaDdiCmdFenceComplete(PVBOXMP_DEVEXT pDevExt, uint32_t u32NodeOrdinal, uint32_t u32FenceId, DXGK_INTERRUPT_TYPE enmComplType)
     1854{
     1855    if (vboxVdmaDdiCmdCanComplete(pDevExt, u32NodeOrdinal))
     1856        return vboxVdmaDdiCmdFenceNotifyComplete(pDevExt, u32NodeOrdinal, u32FenceId);
    16521857
    16531858    PVBOXVDMADDI_CMD pCmd = (PVBOXVDMADDI_CMD)vboxWddmMemAlloc(sizeof (VBOXVDMADDI_CMD));
     
    16551860    if (pCmd)
    16561861    {
    1657         vboxVdmaDdiCmdInit(pCmd, u32FenceId, pContext, vboxVdmaDdiCmdCompletionCbFree, NULL);
    1658         NTSTATUS Status = vboxVdmaDdiCmdCompleted(pDevExt, &pDevExt->DdiCmdQueue, pCmd, enmComplType);
     1862        vboxVdmaDdiCmdInit(pCmd, u32NodeOrdinal, u32FenceId, vboxVdmaDdiCmdCompletionCbFree, NULL);
     1863        NTSTATUS Status = vboxVdmaDdiCmdCompleted(pDevExt, pCmd, enmComplType);
    16591864        Assert(Status == STATUS_SUCCESS);
    16601865        if (Status == STATUS_SUCCESS)
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h

    r37490 r37626  
    2525#include <VBox/HGSMI/HGSMI.h>
    2626
     27typedef struct _VBOXMP_DEVEXT *PVBOXMP_DEVEXT;
     28
    2729/* ddi dma command queue handling */
    2830typedef enum
     
    4446    LIST_ENTRY QueueEntry;
    4547    VBOXVDMADDI_STATE enmState;
     48    uint32_t u32NodeOrdinal;
    4649    uint32_t u32FenceId;
    4750    DXGK_INTERRUPT_TYPE enmComplType;
    48     PVBOXWDDM_CONTEXT pContext;
    4951    PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete;
    5052    PVOID pvComplete;
     
    5557    volatile uint32_t cQueuedCmds;
    5658    LIST_ENTRY CmdQueue;
    57     LIST_ENTRY DpcCmdQueue;
    5859} VBOXVDMADDI_CMD_QUEUE, *PVBOXVDMADDI_CMD_QUEUE;
    5960
    60 VOID vboxVdmaDdiQueueInit(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue);
    61 BOOLEAN vboxVdmaDdiCmdCompletedIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType);
    62 VOID vboxVdmaDdiCmdSubmittedIrq(PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd);
    63 
    64 NTSTATUS vboxVdmaDdiCmdCompleted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType);
    65 NTSTATUS vboxVdmaDdiCmdSubmitted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, PVBOXVDMADDI_CMD pCmd);
     61typedef struct VBOXVDMADDI_NODE
     62{
     63    VBOXVDMADDI_CMD_QUEUE CmdQueue;
     64    UINT uLastCompletedFenceId;
     65} VBOXVDMADDI_NODE, *PVBOXVDMADDI_NODE;
     66
     67VOID vboxVdmaDdiNodesInit(PVBOXMP_DEVEXT pDevExt);
     68BOOLEAN vboxVdmaDdiCmdCompletedIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType);
     69VOID vboxVdmaDdiCmdSubmittedIrq(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd);
     70
     71NTSTATUS vboxVdmaDdiCmdCompleted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, DXGK_INTERRUPT_TYPE enmComplType);
     72NTSTATUS vboxVdmaDdiCmdSubmitted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd);
    6673
    6774DECLINLINE(VOID) vboxVdmaDdiCmdInit(PVBOXVDMADDI_CMD pCmd,
    68         uint32_t u32FenceId, PVBOXWDDM_CONTEXT pContext,
     75        uint32_t u32NodeOrdinal, uint32_t u32FenceId,
    6976        PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete, PVOID pvComplete)
    7077{
     
    7279    pCmd->QueueEntry.Flink = NULL;
    7380    pCmd->enmState = VBOXVDMADDI_STATE_NOT_QUEUED;
     81    pCmd->u32NodeOrdinal = u32NodeOrdinal;
    7482    pCmd->u32FenceId = u32FenceId;
    75     pCmd->pContext = pContext;
    7683    pCmd->pfnComplete = pfnComplete;
    7784    pCmd->pvComplete = pvComplete;
     
    8794}
    8895
    89 NTSTATUS vboxVdmaDdiCmdFenceComplete(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, uint32_t u32FenceId, DXGK_INTERRUPT_TYPE enmComplType);
     96NTSTATUS vboxVdmaDdiCmdFenceComplete(PVBOXMP_DEVEXT pDevExt, uint32_t u32NodeOrdinal, uint32_t u32FenceId, DXGK_INTERRUPT_TYPE enmComplType);
    9097
    9198DECLCALLBACK(VOID) vboxVdmaDdiCmdCompletionCbFree(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD pCmd, PVOID pvContext);
    9299
    93 DECLINLINE(VOID) vboxVdmaDdiCmdGetCompletedListIsr(PVBOXVDMADDI_CMD_QUEUE pQueue, LIST_ENTRY *pList)
    94 {
    95     vboxVideoLeDetach(&pQueue->DpcCmdQueue, pList);
    96 }
    97 
    98 DECLINLINE(BOOLEAN) vboxVdmaDdiCmdIsCompletedListEmptyIsr(PVBOXVDMADDI_CMD_QUEUE pQueue)
    99 {
    100     return IsListEmpty(&pQueue->DpcCmdQueue);
    101 }
     100VOID vboxVdmaDdiCmdGetCompletedListIsr(PVBOXMP_DEVEXT pDevExt, LIST_ENTRY *pList);
     101
     102BOOLEAN vboxVdmaDdiCmdIsCompletedListEmptyIsr(PVBOXMP_DEVEXT pDevExt);
    102103
    103104#define VBOXVDMADDI_CMD_FROM_ENTRY(_pEntry) ((PVBOXVDMADDI_CMD)(((uint8_t*)(_pEntry)) - RT_OFFSETOF(VBOXVDMADDI_CMD, QueueEntry)))
    104105
    105 DECLINLINE(VOID) vboxVdmaDdiCmdHandleCompletedList(PVBOXMP_DEVEXT pDevExt, PVBOXVDMADDI_CMD_QUEUE pQueue, LIST_ENTRY *pList)
     106DECLINLINE(VOID) vboxVdmaDdiCmdHandleCompletedList(PVBOXMP_DEVEXT pDevExt, LIST_ENTRY *pList)
    106107{
    107108    LIST_ENTRY *pEntry = pList->Flink;
     
    188189{
    189190    VBOXVDMAPIPE_CMD_DR Hdr;
    190     PVBOXMP_DEVEXT pDevExt;
    191191    PVBOXWDDM_CONTEXT pContext;
    192192    struct VBOXWDDM_SWAPCHAIN *pSwapchain;
     
    202202            UINT b2DRelated     : 1;
    203203            UINT b3DRelated     : 1;
    204             UINT bDecVBVAUnlock : 1;
    205             UINT Reserved       : 29;
     204            UINT Reserved       : 30;
    206205        };
    207206        UINT Value;
     
    211210{
    212211    VBOXVDMAPIPE_CMD_DR Hdr;
     212#ifndef VBOX_WDDM_IRQ_COMPLETION
    213213    VBOXVDMADDI_CMD DdiCmd;
    214     PVBOXMP_DEVEXT pDevExt;
     214#endif
     215    PVBOXWDDM_CONTEXT pContext;
    215216    VBOXVDMACMD_TYPE enmCmd;
    216217    VBOXVDMAPIPE_FLAGS_DMACMD fFlags;
     
    309310
    310311#endif
    311 NTSTATUS vboxVdmaGgCmdSubmit(PVBOXVDMAGG pVdma, PVBOXVDMAPIPE_CMD_DR pCmd);
    312 PVBOXVDMAPIPE_CMD_DR vboxVdmaGgCmdCreate(PVBOXVDMAGG pVdma, VBOXVDMAPIPE_CMD_TYPE enmType, uint32_t cbCmd);
    313 void vboxVdmaGgCmdDestroy(PVBOXVDMAPIPE_CMD_DR pDr);
     312NTSTATUS vboxVdmaGgCmdSubmit(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pCmd);
     313PVBOXVDMAPIPE_CMD_DR vboxVdmaGgCmdCreate(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_TYPE enmType, uint32_t cbCmd);
     314void vboxVdmaGgCmdDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pDr);
    314315
    315316NTSTATUS vboxVdmaPostHideSwapchain(PVBOXWDDM_SWAPCHAIN pSwapchain);
     317
     318NTSTATUS vboxVdmaGgCmdDmaNotifyCompleted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD pCmd, DXGK_INTERRUPT_TYPE enmComplType);
     319NTSTATUS vboxVdmaGgCmdDmaNotifySubmitted(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DMACMD pCmd);
     320VOID vboxVdmaGgCmdDmaNotifyInit(PVBOXVDMAPIPE_CMD_DMACMD pCmd,
     321        uint32_t u32NodeOrdinal, uint32_t u32FenceId,
     322        PFNVBOXVDMADDICMDCOMPLETE_DPC pfnComplete, PVOID pvComplete);
    316323
    317324#define VBOXVDMAPIPE_CMD_DR_FROM_DDI_CMD(_pCmd) ((PVBOXVDMAPIPE_CMD_DR)(((uint8_t*)(_pCmd)) - RT_OFFSETOF(VBOXVDMAPIPE_CMD_DR, DdiCmd)))
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp

    r37490 r37626  
    487487        Ctx.pDr = pDr;
    488488        Ctx.pEvent = &Event;
    489         vboxVdmaDdiCmdInit(pDdiCmd, 0, NULL, vboxWddmChildStatusReportCompletion, &Ctx);
     489        vboxVdmaDdiCmdInit(pDdiCmd, 0, 0, vboxWddmChildStatusReportCompletion, &Ctx);
    490490        /* mark command as submitted & invisible for the dx runtime since dx did not originate it */
    491491        vboxVdmaDdiCmdSubmittedNotDx(pDdiCmd);
     
    946946                    LOG(("sources(%d), children(%d)", *NumberOfVideoPresentSources, *NumberOfChildren));
    947947
    948                     vboxVdmaDdiQueueInit(pContext, &pContext->DdiCmdQueue);
     948                    vboxVdmaDdiNodesInit(pContext);
    949949                    vboxVideoCmInit(&pContext->CmMgr);
    950950                    InitializeListHead(&pContext->SwapchainList3D);
     
    12421242        }
    12431243
    1244         bNeedDpc |= !vboxVdmaDdiCmdIsCompletedListEmptyIsr(&pDevExt->DdiCmdQueue);
     1244        bNeedDpc |= !vboxVdmaDdiCmdIsCompletedListEmptyIsr(pDevExt);
    12451245
    12461246        if (pDevExt->bNotifyDxDpc)
     
    13061306    vboxSHGSMIListDetach2List(&pdc->pDevExt->VhwaCmdList, &pdc->data.VhwaCmdList);
    13071307#endif
    1308     vboxVdmaDdiCmdGetCompletedListIsr(&pdc->pDevExt->DdiCmdQueue, &pdc->data.CompletedDdiCmdQueue);
     1308    vboxVdmaDdiCmdGetCompletedListIsr(pdc->pDevExt, &pdc->data.CompletedDdiCmdQueue);
    13091309
    13101310    pdc->data.bNotifyDpc = pdc->pDevExt->bNotifyDxDpc;
     
    13591359#endif
    13601360
    1361     vboxVdmaDdiCmdHandleCompletedList(pDevExt, &pDevExt->DdiCmdQueue, &context.data.CompletedDdiCmdQueue);
     1361    vboxVdmaDdiCmdHandleCompletedList(pDevExt, &context.data.CompletedDdiCmdQueue);
    13621362
    13631363//    LOGF(("LEAVE, context(0x%p)", MiniportDeviceContext));
     
    16021602            pCaps->MemoryManagementCaps.PagingNode = 0;
    16031603            /* @todo: this correlates with pCaps->SchedulingCaps.MultiEngineAware */
    1604             pCaps->GpuEngineTopology.NbAsymetricProcessingNodes = 1;
     1604            pCaps->GpuEngineTopology.NbAsymetricProcessingNodes = VBOXWDDM_NUM_NODES;
    16051605
    16061606            break;
     
    17291729}
    17301730
    1731 PVBOXWDDM_ALLOCATION vboxWddmAllocationCreateFromResource(PVBOXWDDM_RESOURCE pResource, uint32_t iIndex)
    1732 {
    1733     PVBOXWDDM_ALLOCATION pAllocation = NULL;
    1734     if (pResource)
    1735     {
    1736         Assert(iIndex < pResource->cAllocations);
    1737         if (iIndex < pResource->cAllocations)
    1738         {
    1739             pAllocation = &pResource->aAllocations[iIndex];
    1740             memset(pAllocation, 0, sizeof (VBOXWDDM_ALLOCATION));
    1741         }
    1742     }
    1743     else
    1744         pAllocation = (PVBOXWDDM_ALLOCATION)vboxWddmMemAllocZero(sizeof (VBOXWDDM_ALLOCATION));
    1745 
    1746     if (pAllocation)
    1747     {
    1748         if (pResource)
    1749         {
    1750             pAllocation->pResource = pResource;
    1751             pAllocation->iIndex = iIndex;
    1752         }
    1753     }
    1754 
    1755     return pAllocation;
     1731PVBOXWDDM_RESOURCE vboxWddmResourceCreate(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_RCINFO pRcInfo)
     1732{
     1733    PVBOXWDDM_RESOURCE pResource = (PVBOXWDDM_RESOURCE)vboxWddmMemAllocZero(RT_OFFSETOF(VBOXWDDM_RESOURCE, aAllocations[pRcInfo->cAllocInfos]));
     1734    if (!pResource)
     1735    {
     1736        AssertFailed();
     1737        return NULL;
     1738    }
     1739    pResource->cRefs = 1;
     1740    pResource->cAllocations = pRcInfo->cAllocInfos;
     1741    pResource->fFlags = pRcInfo->fFlags;
     1742    pResource->RcDesc = pRcInfo->RcDesc;
     1743    return pResource;
     1744}
     1745
     1746VOID vboxWddmResourceRetain(PVBOXWDDM_RESOURCE pResource)
     1747{
     1748    ASMAtomicIncU32(&pResource->cRefs);
     1749}
     1750
     1751static VOID vboxWddmResourceDestroy(PVBOXWDDM_RESOURCE pResource)
     1752{
     1753    vboxWddmMemFree(pResource);
     1754}
     1755
     1756VOID vboxWddmResourceWaitDereference(PVBOXWDDM_RESOURCE pResource)
     1757{
     1758    vboxWddmCounterU32Wait(&pResource->cRefs, 1);
     1759}
     1760
     1761VOID vboxWddmResourceRelease(PVBOXWDDM_RESOURCE pResource)
     1762{
     1763    uint32_t cRefs = ASMAtomicDecU32(&pResource->cRefs);
     1764    Assert(cRefs < UINT32_MAX/2);
     1765    if (!cRefs)
     1766    {
     1767        vboxWddmResourceDestroy(pResource);
     1768    }
    17561769}
    17571770
     
    17621775    {
    17631776        Assert(&pResource->aAllocations[pAllocation->iIndex] == pAllocation);
     1777        vboxWddmResourceRelease(pResource);
    17641778    }
    17651779    else
     
    17691783}
    17701784
    1771 NTSTATUS vboxWddmDestroyAllocation(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
    1772 {
    1773     PAGED_CODE();
    1774 
     1785VOID vboxWddmAllocationCleanup(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
     1786{
    17751787    switch (pAllocation->enmType)
    17761788    {
     
    17971809        }
    17981810#endif
    1799 //#ifdef VBOX_WITH_VIDEOHWACCEL
    1800 //        case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
    1801 //        {
    1802 //            if (pAllocation->fRcFlags.Overlay)
    1803 //            {
    1804 //                vboxVhwaHlpDestroyOverlay(pDevExt, pAllocation);
    1805 //            }
    1806 //            break;
    1807 //        }
    1808 //#endif
    18091811        case VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER:
    18101812        {
     
    18251827        vboxWddmSwapchainRelease(pSwapchain);
    18261828    }
     1829}
     1830
     1831VOID vboxWddmAllocationDestroy(PVBOXWDDM_ALLOCATION pAllocation)
     1832{
     1833    PAGED_CODE();
    18271834
    18281835    vboxWddmAllocationDeleteFromResource(pAllocation->pResource, pAllocation);
    1829 
    1830     return STATUS_SUCCESS;
    1831 }
    1832 
    1833 NTSTATUS vboxWddmCreateAllocation(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_RESOURCE pResource, uint32_t iIndex, DXGK_ALLOCATIONINFO* pAllocationInfo)
     1836}
     1837
     1838PVBOXWDDM_ALLOCATION vboxWddmAllocationCreateFromResource(PVBOXWDDM_RESOURCE pResource, uint32_t iIndex)
     1839{
     1840    PVBOXWDDM_ALLOCATION pAllocation = NULL;
     1841    if (pResource)
     1842    {
     1843        Assert(iIndex < pResource->cAllocations);
     1844        if (iIndex < pResource->cAllocations)
     1845        {
     1846            pAllocation = &pResource->aAllocations[iIndex];
     1847            memset(pAllocation, 0, sizeof (VBOXWDDM_ALLOCATION));
     1848        }
     1849        vboxWddmResourceRetain(pResource);
     1850    }
     1851    else
     1852        pAllocation = (PVBOXWDDM_ALLOCATION)vboxWddmMemAllocZero(sizeof (VBOXWDDM_ALLOCATION));
     1853
     1854    if (pAllocation)
     1855    {
     1856        if (pResource)
     1857        {
     1858            pAllocation->pResource = pResource;
     1859            pAllocation->iIndex = iIndex;
     1860        }
     1861    }
     1862
     1863    return pAllocation;
     1864}
     1865
     1866VOID vboxWddmAllocationWaitDereference(PVBOXWDDM_ALLOCATION pAllocation)
     1867{
     1868    vboxWddmCounterU32Wait(&pAllocation->cRefs, 1);
     1869}
     1870
     1871
     1872NTSTATUS vboxWddmAllocationCreate(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_RESOURCE pResource, uint32_t iIndex, DXGK_ALLOCATIONINFO* pAllocationInfo)
    18341873{
    18351874    PAGED_CODE();
     
    18621901            pAllocation->enmType = pAllocInfo->enmType;
    18631902            pAllocation->offVram = VBOXVIDEOOFFSET_VOID;
     1903            pAllocation->cRefs = 1;
    18641904            pAllocation->bVisible = FALSE;
    18651905            pAllocation->bAssigned = FALSE;
     
    20362076            if (pResource)
    20372077            {
     2078                pResource->cRefs = 1;
    20382079                pResource->cAllocations = pRcInfo->cAllocInfos;
    20392080                pResource->fFlags = pRcInfo->fFlags;
     
    20532094        for (UINT i = 0; i < pCreateAllocation->NumAllocations; ++i)
    20542095        {
    2055             Status = vboxWddmCreateAllocation(pDevExt, pResource, i, &pCreateAllocation->pAllocationInfo[i]);
     2096            Status = vboxWddmAllocationCreate(pDevExt, pResource, i, &pCreateAllocation->pAllocationInfo[i]);
    20562097            Assert(Status == STATUS_SUCCESS);
    20572098            if (Status != STATUS_SUCCESS)
    20582099            {
    2059                 LOGREL(("ERROR: vboxWddmCreateAllocation error (0x%x)", Status));
     2100                LOGREL(("ERROR: vboxWddmAllocationCreate error (0x%x)", Status));
    20602101                /* note: i-th allocation is expected to be cleared in a fail handling code above */
    20612102                for (UINT j = 0; j < i; ++j)
    20622103                {
    2063                     vboxWddmDestroyAllocation(pDevExt, (PVBOXWDDM_ALLOCATION)pCreateAllocation->pAllocationInfo[j].hAllocation);
     2104                    vboxWddmAllocationCleanup(pDevExt, (PVBOXWDDM_ALLOCATION)pCreateAllocation->pAllocationInfo[j].hAllocation);
     2105                    vboxWddmAllocationRelease((PVBOXWDDM_ALLOCATION)pCreateAllocation->pAllocationInfo[j].hAllocation);
    20642106                }
    20652107            }
     
    20682110        pCreateAllocation->hResource = pResource;
    20692111        if (pResource && Status != STATUS_SUCCESS)
    2070             vboxWddmMemFree(pResource);
     2112            vboxWddmResourceRelease(pResource);
    20712113    }
    20722114    LOGF(("LEAVE, status(0x%x), context(0x%x)", Status, hAdapter));
     
    20912133
    20922134    PVBOXWDDM_RESOURCE pRc = (PVBOXWDDM_RESOURCE)pDestroyAllocation->hResource;
     2135    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
    20932136
    20942137    if (pRc)
     
    21012144        PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pDestroyAllocation->pAllocationList[i];
    21022145        Assert(pAlloc->pResource == pRc);
    2103         vboxWddmDestroyAllocation((PVBOXMP_DEVEXT)hAdapter, pAlloc);
     2146        /* wait for all current allocation-related ops are completed */
     2147        vboxWddmAllocationWaitDereference(pAlloc);
     2148        vboxWddmAllocationCleanup(pDevExt, pAlloc);
     2149        vboxWddmAllocationRelease(pAlloc);
    21042150    }
    21052151
    21062152    if (pRc)
    21072153    {
    2108         vboxWddmMemFree(pRc);
     2154        /* wait for all current resource-related ops are completed */
     2155        vboxWddmResourceWaitDereference(pRc);
     2156        vboxWddmResourceRelease(pRc);
    21092157    }
    21102158
     
    24832531static NTSTATUS vboxWddmSubmitCmd(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_DMACMD *pCmd)
    24842532{
    2485     NTSTATUS Status = vboxVdmaDdiCmdSubmitted(pDevExt, &pDevExt->DdiCmdQueue, &pCmd->DdiCmd);
     2533    NTSTATUS Status = vboxVdmaGgCmdDmaNotifySubmitted(pDevExt, pCmd);
    24862534    Assert(Status == STATUS_SUCCESS);
    24872535    if (Status == STATUS_SUCCESS)
    24882536    {
    2489         if (pCmd->fFlags.bDecVBVAUnlock)
    2490         {
    2491             uint32_t cNew = ASMAtomicIncU32(&pDevExt->cUnlockedVBVADisabled);
    2492             Assert(cNew < UINT32_MAX/2);
    2493         }
    2494         NTSTATUS submStatus = vboxVdmaGgCmdSubmit(&pDevExt->u.primary.Vdma.DmaGg, &pCmd->Hdr);
     2537        NTSTATUS submStatus = vboxVdmaGgCmdSubmit(pDevExt, &pCmd->Hdr);
    24952538        Assert(submStatus == STATUS_SUCCESS);
    24962539        if (submStatus != STATUS_SUCCESS)
    24972540        {
    2498             if (pCmd->fFlags.bDecVBVAUnlock)
    2499             {
    2500                 uint32_t cNew = ASMAtomicDecU32(&pDevExt->cUnlockedVBVADisabled);
    2501                 Assert(cNew < UINT32_MAX/2);
    2502             }
    2503             vboxVdmaDdiCmdCompleted(pDevExt, &pDevExt->DdiCmdQueue, &pCmd->DdiCmd, DXGK_INTERRUPT_DMA_FAULTED);
     2541            vboxVdmaGgCmdDmaNotifyCompleted(pDevExt, pCmd, DXGK_INTERRUPT_DMA_FAULTED);
    25042542        }
    25052543    }
    25062544    else
    25072545    {
    2508         vboxVdmaGgCmdDestroy(&pCmd->Hdr);
     2546        vboxVdmaGgCmdDestroy(pDevExt, &pCmd->Hdr);
    25092547    }
    25102548    return Status;
     
    25142552{
    25152553    NTSTATUS Status = STATUS_SUCCESS;
    2516 
    2517     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]));
     2554    PVBOXVDMAPIPE_CMD_DMACMD_BLT pBltCmd = (PVBOXVDMAPIPE_CMD_DMACMD_BLT)vboxVdmaGgCmdCreate(pDevExt, VBOXVDMAPIPE_CMD_TYPE_DMACMD, RT_OFFSETOF(VBOXVDMAPIPE_CMD_DMACMD_BLT, Blt.DstRects.UpdateRects.aRects[pBlt->Blt.DstRects.UpdateRects.cRects]));
    25182555    Assert(pBltCmd);
    25192556    if (pBltCmd)
    25202557    {
    25212558        VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pBlt->Blt.DstAlloc.srcId];
    2522         vboxVdmaDdiCmdInit(&pBltCmd->Hdr.DdiCmd, u32FenceId, pContext, vboxVdmaGgDdiCmdDestroy, pBltCmd);
    2523         pBltCmd->Hdr.pDevExt = pDevExt;
     2559        vboxVdmaGgCmdDmaNotifyInit(&pBltCmd->Hdr, pContext->NodeOrdinal, u32FenceId, NULL, NULL);
    25242560        pBltCmd->Hdr.fFlags = fBltFlags;
     2561        pBltCmd->Hdr.pContext = pContext;
    25252562        pBltCmd->Hdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_BLT;
    25262563        memcpy(&pBltCmd->Blt, &pBlt->Blt, RT_OFFSETOF(VBOXVDMA_BLT, DstRects.UpdateRects.aRects[pBlt->Blt.DstRects.UpdateRects.cRects]));
     
    25292566    else
    25302567    {
    2531         Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, u32FenceId, DXGK_INTERRUPT_DMA_FAULTED);
    2532     }
    2533 
     2568        Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, u32FenceId, DXGK_INTERRUPT_DMA_FAULTED);
     2569    }
    25342570    return Status;
    25352571}
     
    26272663            /* get DPC data at IRQL */
    26282664
    2629             Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
     2665            Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
    26302666            break;
    26312667        }
     
    26752711                                    uint32_t cUnlockedVBVADisabled = ASMAtomicReadU32(&pDevExt->cUnlockedVBVADisabled);
    26762712                                    if (!cUnlockedVBVADisabled)
     2713                                    {
    26772714                                        VBOXVBVA_OP(ReportDirtyRect, pDevExt, pSource, &rect);
     2715                                    }
    26782716                                    else
    26792717                                    {
    2680                                         Assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
    26812718                                        VBOXVBVA_OP_WITHLOCK_ATDPC(ReportDirtyRect, pDevExt, pSource, &rect);
    26822719                                    }
     
    26852722                                {
    26862723                                    fBltFlags.b2DRelated = 1;
    2687                                     fBltFlags.bDecVBVAUnlock = 1;
    26882724                                }
    26892725
     
    27482784            if (bComplete)
    27492785            {
    2750                 Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
     2786                Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
    27512787            }
    27522788            break;
     
    27872823
    27882824            PVBOXVDMADDI_CMD pDdiCmd = VBOXVDMADDI_CMD_FROM_BUF_DR(pDr);
    2789             vboxVdmaDdiCmdInit(pDdiCmd, pSubmitCommand->SubmissionFenceId, pContext, vboxWddmDmaCompleteChromiumCmd, pDr);
    2790             NTSTATUS Status = vboxVdmaDdiCmdSubmitted(pDevExt, &pDevExt->DdiCmdQueue, pDdiCmd);
     2825            vboxVdmaDdiCmdInit(pDdiCmd, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, vboxWddmDmaCompleteChromiumCmd, pDr);
     2826            NTSTATUS Status = vboxVdmaDdiCmdSubmitted(pDevExt, pDdiCmd);
    27912827            Assert(Status == STATUS_SUCCESS);
    27922828            if (Status == STATUS_SUCCESS)
     
    28002836            }
    28012837#else
    2802             Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
     2838            Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
    28032839            Assert(Status == STATUS_SUCCESS);
    28042840#endif
     
    28082844        {
    28092845            VBOXWDDM_DMA_PRIVATEDATA_FLIP *pFlip = (VBOXWDDM_DMA_PRIVATEDATA_FLIP*)pPrivateDataBase;
    2810             PVBOXVDMAPIPE_CMD_DMACMD_FLIP pFlipCmd = (PVBOXVDMAPIPE_CMD_DMACMD_FLIP)vboxVdmaGgCmdCreate(
    2811                     &pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_DMACMD, sizeof (VBOXVDMAPIPE_CMD_DMACMD_FLIP));
     2846            PVBOXVDMAPIPE_CMD_DMACMD_FLIP pFlipCmd = (PVBOXVDMAPIPE_CMD_DMACMD_FLIP)vboxVdmaGgCmdCreate(pDevExt,
     2847                    VBOXVDMAPIPE_CMD_TYPE_DMACMD, sizeof (VBOXVDMAPIPE_CMD_DMACMD_FLIP));
    28122848            Assert(pFlipCmd);
    28132849            if (pFlipCmd)
    28142850            {
    28152851                VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pFlip->Flip.Alloc.srcId];
    2816                 vboxVdmaDdiCmdInit(&pFlipCmd->Hdr.DdiCmd, pSubmitCommand->SubmissionFenceId, pContext, vboxVdmaGgDdiCmdDestroy, pFlipCmd);
    2817                 pFlipCmd->Hdr.pDevExt = pDevExt;
     2852                vboxVdmaGgCmdDmaNotifyInit(&pFlipCmd->Hdr, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, NULL, NULL);
    28182853                pFlipCmd->Hdr.fFlags.Value = 0;
    28192854                pFlipCmd->Hdr.fFlags.b3DRelated = 1;
     2855                pFlipCmd->Hdr.pContext = pContext;
    28202856                pFlipCmd->Hdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_FLIP;
    28212857                memcpy(&pFlipCmd->Flip, &pFlip->Flip, sizeof (pFlipCmd->Flip));
     
    28252861            else
    28262862            {
    2827                 Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_FAULTED);
     2863                Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_FAULTED);
    28282864                Assert(Status == STATUS_SUCCESS);
    28292865            }
     
    28332869        {
    28342870            PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF = (PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL)pPrivateDataBase;
    2835             PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCFCmd = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)vboxVdmaGgCmdCreate(
    2836                     &pDevExt->u.primary.Vdma.DmaGg, VBOXVDMAPIPE_CMD_TYPE_DMACMD,
    2837                     RT_OFFSETOF(VBOXVDMAPIPE_CMD_DMACMD_CLRFILL, ClrFill.Rects.aRects[pCF->ClrFill.Rects.cRects]));
     2871            PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCFCmd = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)vboxVdmaGgCmdCreate(pDevExt,
     2872                    VBOXVDMAPIPE_CMD_TYPE_DMACMD, RT_OFFSETOF(VBOXVDMAPIPE_CMD_DMACMD_CLRFILL, ClrFill.Rects.aRects[pCF->ClrFill.Rects.cRects]));
    28382873            Assert(pCFCmd);
    28392874            if (pCFCmd)
    28402875            {
    28412876//                VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pFlip->Flip.Alloc.srcId];
    2842                 vboxVdmaDdiCmdInit(&pCFCmd->Hdr.DdiCmd, pSubmitCommand->SubmissionFenceId, pContext, vboxVdmaGgDdiCmdDestroy, pCFCmd);
    2843                 pCFCmd->Hdr.pDevExt = pDevExt;
    2844                 pCFCmd->Hdr.pDevExt = pDevExt;
     2877                vboxVdmaGgCmdDmaNotifyInit(&pCFCmd->Hdr, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, NULL, NULL);
    28452878                pCFCmd->Hdr.fFlags.Value = 0;
    28462879                pCFCmd->Hdr.fFlags.b2DRelated = 1;
    2847                 pCFCmd->Hdr.fFlags.bDecVBVAUnlock = 1;
     2880                pCFCmd->Hdr.pContext = pContext;
    28482881                pCFCmd->Hdr.enmCmd = VBOXVDMACMD_TYPE_DMA_PRESENT_CLRFILL;
    28492882                memcpy(&pCFCmd->ClrFill, &pCF->ClrFill, RT_OFFSETOF(VBOXVDMA_CLRFILL, Rects.aRects[pCF->ClrFill.Rects.cRects]));
     
    28532886            else
    28542887            {
    2855                 Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_FAULTED);
     2888                Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_FAULTED);
    28562889                Assert(Status == STATUS_SUCCESS);
    28572890            }
     
    28612894        case VBOXVDMACMD_TYPE_DMA_NOP:
    28622895        {
    2863             Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
     2896            Status = vboxVdmaDdiCmdFenceComplete(pDevExt, pContext->NodeOrdinal, pSubmitCommand->SubmissionFenceId, DXGK_INTERRUPT_DMA_COMPLETED);
    28642897            Assert(Status == STATUS_SUCCESS);
    28652898            break;
     
    29062939    LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
    29072940
    2908 //    AssertBreakpoint();
     2941    AssertFailed();
    29092942    /* @todo: fixme: implement */
    29102943
     
    53185351    vboxVDbgBreakFv();
    53195352
     5353    if (pCreateContext->NodeOrdinal >= VBOXWDDM_NUM_NODES)
     5354    {
     5355        WARN(("Invalid NodeOrdinal (%d), expected to be less that (%d)\n", pCreateContext->NodeOrdinal, VBOXWDDM_NUM_NODES));
     5356        return STATUS_INVALID_PARAMETER;
     5357    }
     5358
    53205359    NTSTATUS Status = STATUS_SUCCESS;
    53215360    PVBOXWDDM_DEVICE pDevice = (PVBOXWDDM_DEVICE)hDevice;
     
    55215560    }
    55225561*/
     5562
     5563#ifdef DEBUG_misha
     5564    RTLogGroupSettings(0, "+default.e.l.f.l2.l3");
     5565#endif
    55235566
    55245567    LOGREL(("Built %s %s", __DATE__, __TIME__));
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h

    r36867 r37626  
    6262}
    6363
     64VOID vboxWddmAllocationDestroy(PVBOXWDDM_ALLOCATION pAllocation);
     65
     66DECLINLINE(VOID) vboxWddmAllocationRelease(PVBOXWDDM_ALLOCATION pAllocation)
     67{
     68    uint32_t cRefs = ASMAtomicDecU32(&pAllocation->cRefs);
     69    Assert(cRefs < UINT32_MAX/2);
     70    if (!cRefs)
     71    {
     72        vboxWddmAllocationDestroy(pAllocation);
     73    }
     74}
     75
     76DECLINLINE(VOID) vboxWddmAllocationRetain(PVBOXWDDM_ALLOCATION pAllocation)
     77{
     78    ASMAtomicIncU32(&pAllocation->cRefs);
     79}
     80
     81
    6482#define VBOXWDDMENTRY_2_SWAPCHAIN(_pE) ((PVBOXWDDM_SWAPCHAIN)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_SWAPCHAIN, DevExtListEntry)))
    6583
Note: See TracChangeset for help on using the changeset viewer.

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