VirtualBox

Ignore:
Timestamp:
Jul 22, 2011 1:26:19 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73064
Message:

wddm/3d: 1. fix invalid visible rectreporting on swapchain destruction 2. single context for wine (disabled so far), 3 wine & 3d driver bugfixes

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

Legend:

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

    r37734 r38112  
    2929} VBOXVIDEOCM_CMD_DR, *PVBOXVIDEOCM_CMD_DR;
    3030
     31typedef enum
     32{
     33    VBOXVIDEOCM_CMD_CTL_KM_TYPE_POST_INVOKE = 1,
     34    VBOXVIDEOCM_CMD_CTL_KM_TYPE_PRE_INVOKE,
     35    VBOXVIDEOCM_CMD_CTL_KM_TYPE_DUMMY_32BIT = 0x7fffffff
     36} VBOXVIDEOCM_CMD_CTL_KM_TYPE;
     37
     38typedef DECLCALLBACK(VOID) FNVBOXVIDEOCM_CMD_CB(PVBOXVIDEOCM_CTX pContext, struct VBOXVIDEOCM_CMD_CTL_KM *pCmd, PVOID pvContext);
     39typedef FNVBOXVIDEOCM_CMD_CB *PFNVBOXVIDEOCM_CMD_CB;
     40
     41typedef struct VBOXVIDEOCM_CMD_CTL_KM
     42{
     43    VBOXVIDEOCM_CMD_CTL_KM_TYPE enmType;
     44    uint32_t u32Reserved;
     45    PFNVBOXVIDEOCM_CMD_CB pfnCb;
     46    PVOID pvCb;
     47} VBOXVIDEOCM_CMD_CTL_KM, *PVBOXVIDEOCM_CMD_CTL_KM;
     48
    3149AssertCompile(VBOXWDDM_ROUNDBOUND(RT_OFFSETOF(VBOXVIDEOCM_CMD_DR, CmdHdr), 8) == RT_OFFSETOF(VBOXVIDEOCM_CMD_DR, CmdHdr));
    3250
     
    4967    /* commands list  */
    5068    LIST_ENTRY CommandsList;
     69    /* post process commands list  */
     70    LIST_ENTRY PpCommandsList;
    5171    /* event used to notify UMD about pending commands */
    5272    PKEVENT pUmEvent;
     
    95115}
    96116
     117static PVBOXVIDEOCM_CMD_CTL_KM vboxVideoCmCmdCreateKm(PVBOXVIDEOCM_CTX pContext, VBOXVIDEOCM_CMD_CTL_KM_TYPE enmType,
     118        PFNVBOXVIDEOCM_CMD_CB pfnCb, PVOID pvCb,
     119        uint32_t cbSize)
     120{
     121    PVBOXVIDEOCM_CMD_CTL_KM pCmd = (PVBOXVIDEOCM_CMD_CTL_KM)vboxVideoCmCmdCreate(pContext, cbSize + sizeof (*pCmd));
     122    pCmd->enmType = enmType;
     123    pCmd->pfnCb = pfnCb;
     124    pCmd->pvCb = pvCb;
     125    PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pCmd);
     126    pHdr->CmdHdr.enmType = VBOXVIDEOCM_CMD_TYPE_CTL_KM;
     127    return pCmd;
     128}
     129
     130static DECLCALLBACK(VOID) vboxVideoCmCmdCbSetEventAndDereference(PVBOXVIDEOCM_CTX pContext, PVBOXVIDEOCM_CMD_CTL_KM pCmd, PVOID pvContext)
     131{
     132    PKEVENT pEvent = (PKEVENT)pvContext;
     133    KeSetEvent(pEvent, 0, FALSE);
     134    ObDereferenceObject(pEvent);
     135    vboxVideoCmCmdRelease(pCmd);
     136}
     137
     138NTSTATUS vboxVideoCmCmdSubmitCompleteEvent(PVBOXVIDEOCM_CTX pContext, PKEVENT pEvent)
     139{
     140    Assert(pEvent);
     141    PVBOXVIDEOCM_CMD_CTL_KM pCmd = vboxVideoCmCmdCreateKm(pContext, VBOXVIDEOCM_CMD_CTL_KM_TYPE_POST_INVOKE,
     142            vboxVideoCmCmdCbSetEventAndDereference, pEvent, 0);
     143    if (!pCmd)
     144    {
     145        WARN(("vboxVideoCmCmdCreateKm failed"));
     146        return STATUS_NO_MEMORY;
     147    }
     148
     149    vboxVideoCmCmdSubmit(pCmd, VBOXVIDEOCM_SUBMITSIZE_DEFAULT);
     150
     151    return STATUS_SUCCESS;
     152}
     153
    97154DECLINLINE(void) vboxVideoCmCmdRetainByHdr(PVBOXVIDEOCM_CMD_DR pHdr)
    98155{
     
    162219}
    163220
    164 NTSTATUS vboxVideoCmCmdVisit(PVBOXVIDEOCM_CTX pContext, BOOL bEntireSession, PFNVBOXVIDEOCMCMDVISITOR pfnVisitor, PVOID pvVisitor)
     221NTSTATUS vboxVideoCmCmdVisit(PVBOXVIDEOCM_CTX pContext, BOOLEAN bEntireSession, PFNVBOXVIDEOCMCMDVISITOR pfnVisitor, PVOID pvVisitor)
    165222{
    166223    PVBOXVIDEOCM_SESSION pSession = pContext->pSession;
     
    179236            if (bEntireSession || pHdr->pContext == pContext)
    180237            {
    181                 void * pvBody = VBOXVIDEOCM_BODY(pHdr, void);
    182                 UINT fRet = pfnVisitor(pHdr->pContext, pvBody, pHdr->CmdHdr.cbCmd, pvVisitor);
    183                 if (fRet & VBOXVIDEOCMCMDVISITOR_RETURN_RMCMD)
     238                if (pHdr->CmdHdr.enmType == VBOXVIDEOCM_CMD_TYPE_UM)
    184239                {
    185                     RemoveEntryList(&pHdr->QueueList);
     240                    void * pvBody = VBOXVIDEOCM_BODY(pHdr, void);
     241                    UINT fRet = pfnVisitor(pHdr->pContext, pvBody, pHdr->CmdHdr.cbCmd, pvVisitor);
     242                    if (fRet & VBOXVIDEOCMCMDVISITOR_RETURN_RMCMD)
     243                    {
     244                        RemoveEntryList(&pHdr->QueueList);
     245                    }
     246                    if ((fRet & VBOXVIDEOCMCMDVISITOR_RETURN_BREAK))
     247                        break;
    186248                }
    187                 if (!(fRet & VBOXVIDEOCMCMDVISITOR_RETURN_CONTINUE))
    188                     break;
     249                else
     250                {
     251                    WARN(("non-um cmd on visit, skipping"));
     252                }
    189253            }
    190254        }
     
    231295    Assert(IsListEmpty(&pSession->ContextList));
    232296    Assert(IsListEmpty(&pSession->CommandsList));
     297    Assert(IsListEmpty(&pSession->PpCommandsList));
    233298    RemoveEntryList(&pSession->QueueEntry);
    234299    vboxWddmMemFree(pSession);
    235300}
    236301
     302static void vboxVideoCmSessionCtxPpList(PVBOXVIDEOCM_CTX pContext, PLIST_ENTRY pHead)
     303{
     304    LIST_ENTRY *pCur;
     305    for (pCur = pHead->Flink; pCur != pHead; pCur = pHead->Flink)
     306    {
     307        RemoveEntryList(pCur);
     308        PVBOXVIDEOCM_CMD_DR pHdr = VBOXCMENTRY_2_CMD(pCur);
     309        PVBOXVIDEOCM_CMD_CTL_KM pCmd = VBOXVIDEOCM_BODY(pHdr, VBOXVIDEOCM_CMD_CTL_KM);
     310        pCmd->pfnCb(pContext, pCmd, pCmd->pvCb);
     311    }
     312}
     313
     314static void vboxVideoCmSessionCtxDetachCmdsLocked(PLIST_ENTRY pEntriesHead, PVBOXVIDEOCM_CTX pContext, PLIST_ENTRY pDstHead)
     315{
     316    LIST_ENTRY *pCur;
     317    LIST_ENTRY *pPrev;
     318    pCur = pEntriesHead->Flink;
     319    pPrev = pEntriesHead;
     320    while (pCur != pEntriesHead)
     321    {
     322        PVBOXVIDEOCM_CMD_DR pCmd = VBOXCMENTRY_2_CMD(pCur);
     323        if (pCmd->pContext == pContext)
     324        {
     325            RemoveEntryList(pCur);
     326            InsertTailList(pDstHead, pCur);
     327            pCur = pPrev;
     328            /* pPrev - remains unchanged */
     329        }
     330        else
     331        {
     332            pPrev = pCur;
     333        }
     334        pCur = pCur->Flink;
     335    }
     336}
    237337/**
    238338 * @return true iff the given session is destroyed
     
    242342    bool bDestroy;
    243343    LIST_ENTRY RemainedList;
     344    LIST_ENTRY RemainedPpList;
    244345    LIST_ENTRY *pCur;
    245     LIST_ENTRY *pPrev;
    246346    InitializeListHead(&RemainedList);
     347    InitializeListHead(&RemainedPpList);
    247348    Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
    248349    ExAcquireFastMutex(&pSession->Mutex);
     
    254355    {
    255356        vboxVideoLeDetach(&pSession->CommandsList, &RemainedList);
     357        vboxVideoLeDetach(&pSession->PpCommandsList, &RemainedPpList);
    256358    }
    257359    else
    258360    {
    259         pCur = pSession->CommandsList.Flink;
    260         pPrev = &pSession->CommandsList;
    261         while (pCur != &pSession->CommandsList)
    262         {
    263             PVBOXVIDEOCM_CMD_DR pCmd = VBOXCMENTRY_2_CMD(pCur);
    264             if (pCmd->pContext == pContext)
    265             {
    266                 RemoveEntryList(pCur);
    267                 InsertHeadList(&RemainedList, pCur);
    268                 pCur = pPrev;
    269                 /* pPrev - remains unchanged */
    270             }
    271             else
    272             {
    273                 pPrev = pCur;
    274             }
    275             pCur = pCur->Flink;
    276         }
     361        vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->CommandsList, pContext, &RemainedList);
     362        vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->PpCommandsList, pContext, &RemainedPpList);
    277363    }
    278364    ExReleaseFastMutex(&pSession->Mutex);
     
    284370        vboxVideoCmCmdCancel(pCmd);
    285371    }
     372
     373    vboxVideoCmSessionCtxPpList(pContext, &RemainedPpList);
    286374
    287375    if (bDestroy)
     
    303391        InitializeListHead(&pSession->ContextList);
    304392        InitializeListHead(&pSession->CommandsList);
     393        InitializeListHead(&pSession->PpCommandsList);
    305394        pSession->pUmEvent = pUmEvent;
    306395        Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
     
    411500}
    412501
     502VOID vboxVideoCmProcessKm(PVBOXVIDEOCM_CTX pContext, PVBOXVIDEOCM_CMD_CTL_KM pCmd)
     503{
     504    PVBOXVIDEOCM_SESSION pSession = pContext->pSession;
     505
     506    switch (pCmd->enmType)
     507    {
     508        case VBOXVIDEOCM_CMD_CTL_KM_TYPE_PRE_INVOKE:
     509        {
     510            pCmd->pfnCb(pContext, pCmd, pCmd->pvCb);
     511            break;
     512        }
     513
     514        case VBOXVIDEOCM_CMD_CTL_KM_TYPE_POST_INVOKE:
     515        {
     516            PVBOXVIDEOCM_CMD_DR pHdr = VBOXVIDEOCM_HEAD(pCmd);
     517            ExAcquireFastMutex(&pSession->Mutex);
     518            InsertTailList(&pSession->PpCommandsList, &pHdr->QueueList);
     519            ExReleaseFastMutex(&pSession->Mutex);
     520            break;
     521        }
     522
     523        default:
     524        {
     525            WARN(("unsupported cmd type %d", pCmd->enmType));
     526            break;
     527        }
     528    }
     529}
     530
    413531NTSTATUS vboxVideoCmEscape(PVBOXVIDEOCM_CTX pContext, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd)
    414532{
     
    420538    PVBOXVIDEOCM_CMD_DR pHdr;
    421539    LIST_ENTRY DetachedList;
     540    LIST_ENTRY DetachedPpList;
    422541    PLIST_ENTRY pCurEntry = NULL;
    423542    uint32_t cbCmdsReturned = 0;
     
    428547    bool bDetachMode = true;
    429548    InitializeListHead(&DetachedList);
     549    InitializeListHead(&DetachedPpList);
    430550//    PVBOXWDDM_GETVBOXVIDEOCMCMD_HDR *pvCmd
    431551
    432552    Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
    433553    ExAcquireFastMutex(&pSession->Mutex);
     554
     555    vboxVideoCmSessionCtxDetachCmdsLocked(&pSession->PpCommandsList, pContext, &DetachedPpList);
    434556
    435557    do
     
    442564                pHdr = VBOXCMENTRY_2_CMD(pSession->CommandsList.Blink);
    443565                Assert(pHdr->CmdHdr.cbCmd);
    444                 if (cbData >= pHdr->CmdHdr.cbCmd)
     566                uint32_t cbUserCmd = pHdr->CmdHdr.enmType == VBOXVIDEOCM_CMD_TYPE_UM ? pHdr->CmdHdr.cbCmd : 0;
     567                if (cbData >= cbUserCmd)
    445568                {
    446569                    RemoveEntryList(&pHdr->QueueList);
    447570                    InsertHeadList(&DetachedList, &pHdr->QueueList);
    448                     cbData -= pHdr->CmdHdr.cbCmd;
     571                    cbData -= cbUserCmd;
    449572                }
    450573                else
    451574                {
    452                     cbRemainingFirstCmd = pHdr->CmdHdr.cbCmd;
    453                     cbRemainingCmds = pHdr->CmdHdr.cbCmd;
     575                    Assert(cbUserCmd);
     576                    cbRemainingFirstCmd = cbUserCmd;
     577                    cbRemainingCmds = cbUserCmd;
    454578                    pCurEntry = pHdr->QueueList.Blink;
    455579                    bDetachMode = false;
     
    468592            {
    469593                pHdr = VBOXCMENTRY_2_CMD(pCurEntry);
     594                uint32_t cbUserCmd = pHdr->CmdHdr.enmType == VBOXVIDEOCM_CMD_TYPE_UM ? pHdr->CmdHdr.cbCmd : 0;
    470595                Assert(cbRemainingFirstCmd);
    471                 cbRemainingCmds += pHdr->CmdHdr.cbCmd;
     596                cbRemainingCmds += cbUserCmd;
    472597                pCurEntry = pHdr->QueueList.Blink;
    473598            }
     
    483608    ExReleaseFastMutex(&pSession->Mutex);
    484609
     610    vboxVideoCmSessionCtxPpList(pContext, &DetachedPpList);
     611
    485612    pCmd->Hdr.cbCmdsReturned = 0;
    486613    for (pCurEntry = DetachedList.Blink; pCurEntry != &DetachedList; pCurEntry = DetachedList.Blink)
    487614    {
    488615        pHdr = VBOXCMENTRY_2_CMD(pCurEntry);
    489         memcpy(pvData, &pHdr->CmdHdr, pHdr->CmdHdr.cbCmd);
    490         pvData += pHdr->CmdHdr.cbCmd;
    491         pCmd->Hdr.cbCmdsReturned += pHdr->CmdHdr.cbCmd;
    492616        RemoveEntryList(pCurEntry);
    493         vboxVideoCmCmdReleaseByHdr(pHdr);
     617        switch (pHdr->CmdHdr.enmType)
     618        {
     619            case VBOXVIDEOCM_CMD_TYPE_UM:
     620            {
     621                memcpy(pvData, &pHdr->CmdHdr, pHdr->CmdHdr.cbCmd);
     622                pvData += pHdr->CmdHdr.cbCmd;
     623                pCmd->Hdr.cbCmdsReturned += pHdr->CmdHdr.cbCmd;
     624                vboxVideoCmCmdReleaseByHdr(pHdr);
     625                break;
     626            }
     627
     628            case VBOXVIDEOCM_CMD_TYPE_CTL_KM:
     629            {
     630                vboxVideoCmProcessKm(pContext, VBOXVIDEOCM_BODY(pHdr, VBOXVIDEOCM_CMD_CTL_KM));
     631                break;
     632            }
     633
     634            default:
     635            {
     636                WARN(("unsupported cmd type %d", pHdr->CmdHdr.enmType));
     637                break;
     638            }
     639        }
    494640    }
    495641
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPCm.h

    r37734 r38112  
    4242NTSTATUS vboxVideoCmTerm(PVBOXVIDEOCM_MGR pMgr);
    4343
     44NTSTATUS vboxVideoCmCmdSubmitCompleteEvent(PVBOXVIDEOCM_CTX pContext, PKEVENT pEvent);
    4445void* vboxVideoCmCmdCreate(PVBOXVIDEOCM_CTX pContext, uint32_t cbSize);
    4546void* vboxVideoCmCmdReinitForContext(void *pvCmd, PVBOXVIDEOCM_CTX pContext);
     
    4950void vboxVideoCmCmdSubmit(void *pvCmd, uint32_t cbSize);
    5051
    51 #define VBOXVIDEOCMCMDVISITOR_RETURN_CONTINUE 0x00000001
     52#define VBOXVIDEOCMCMDVISITOR_RETURN_BREAK    0x00000001
    5253#define VBOXVIDEOCMCMDVISITOR_RETURN_RMCMD    0x00000002
    5354typedef DECLCALLBACK(UINT) FNVBOXVIDEOCMCMDVISITOR(PVBOXVIDEOCM_CTX pContext, PVOID pvCmd, uint32_t cbCmd, PVOID pvVisitor);
    5455typedef FNVBOXVIDEOCMCMDVISITOR *PFNVBOXVIDEOCMCMDVISITOR;
    55 NTSTATUS vboxVideoCmCmdVisit(PVBOXVIDEOCM_CTX pContext, BOOL bEntireSession, PFNVBOXVIDEOCMCMDVISITOR pfnVisitor, PVOID pvVisitor);
     56NTSTATUS vboxVideoCmCmdVisit(PVBOXVIDEOCM_CTX pContext, BOOLEAN bEntireSession, PFNVBOXVIDEOCMCMDVISITOR pfnVisitor, PVOID pvVisitor);
    5657
    5758NTSTATUS vboxVideoCmEscape(PVBOXVIDEOCM_CTX pContext, PVBOXDISPIFESCAPE_GETVBOXVIDEOCMCMD pCmd, uint32_t cbCmd);
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp

    r37734 r38112  
    216216DECLINLINE(VOID) vboxWddmSwapchainRelease(PVBOXWDDM_SWAPCHAIN pSwapchain)
    217217{
    218     uint32_t cRefs = ASMAtomicDecU32(&pSwapchain->cRefs);
     218    const uint32_t cRefs = ASMAtomicDecU32(&pSwapchain->cRefs);
    219219    Assert(cRefs < UINT32_MAX/2);
    220220    if (!cRefs)
    221221    {
    222         Assert(pSwapchain->pContext);
    223         if (pSwapchain->pContext)
    224         {
    225             NTSTATUS tmpStatus = vboxVdmaPostHideSwapchain(pSwapchain);
    226             Assert(tmpStatus == STATUS_SUCCESS);
    227         }
    228222        vboxWddmMemFree(pSwapchain);
    229223    }
     
    312306{
    313307    vboxWddmSwapchainAllocRemoveAllInternal(pDevExt, pSwapchain, TRUE);
     308
     309    Assert(pSwapchain->pContext);
     310    if (pSwapchain->pContext)
     311    {
     312        NTSTATUS tmpStatus = vboxVdmaGgCmdCancel(pDevExt, pSwapchain->pContext, pSwapchain);
     313        if (tmpStatus != STATUS_SUCCESS)
     314        {
     315            WARN(("vboxVdmaGgCmdCancel returned Status (0x%x)", tmpStatus));
     316        }
     317    }
     318
    314319    vboxWddmSwapchainRelease(pSwapchain);
    315320}
     
    397402        return STATUS_INVALID_PARAMETER;
    398403
    399     PVBOXWDDM_SWAPCHAIN pSwapchain;
     404    PVBOXWDDM_SWAPCHAIN pSwapchain = NULL;
    400405    PVBOXWDDM_ALLOCATION *apAlloc = NULL;
    401     if (pSwapchainInfo->SwapchainInfo.cAllocs)
    402     {
    403         apAlloc = (PVBOXWDDM_ALLOCATION *)vboxWddmMemAlloc(sizeof (PVBOXWDDM_ALLOCATION) * pSwapchainInfo->SwapchainInfo.cAllocs);
    404         Assert(apAlloc);
    405         if (!apAlloc)
    406             return STATUS_NO_MEMORY;
    407         for (UINT i = 0; i < pSwapchainInfo->SwapchainInfo.cAllocs; ++i)
    408         {
    409             DXGKARGCB_GETHANDLEDATA GhData;
    410             GhData.hObject = pSwapchainInfo->SwapchainInfo.ahAllocs[i];
    411             GhData.Type = DXGK_HANDLE_ALLOCATION;
    412             GhData.Flags.Value = 0;
    413             PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pDevExt->u.primary.DxgkInterface.DxgkCbGetHandleData(&GhData);
    414             Assert(pAlloc);
    415             if (!pAlloc)
    416                 return STATUS_INVALID_PARAMETER;
    417             apAlloc[i] = pAlloc;
    418         }
    419     }
    420 
    421     if (pSwapchainInfo->SwapchainInfo.hSwapchainKm)
    422     {
    423         ExAcquireFastMutex(&pDevExt->ContextMutex);
    424         pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmHTableGet(&pContext->Swapchains, (VBOXWDDM_HANDLE)pSwapchainInfo->SwapchainInfo.hSwapchainKm);
    425         Assert(pSwapchain);
    426         if (!pSwapchain)
    427         {
    428             ExReleaseFastMutex(&pDevExt->ContextMutex);
    429             return STATUS_INVALID_PARAMETER;
    430         }
    431         Assert(pSwapchain->hSwapchainKm == pSwapchainInfo->SwapchainInfo.hSwapchainKm);
    432         Assert(pSwapchain->pContext == pContext);
    433         if (pSwapchain->pContext != pContext)
    434         {
    435             ExReleaseFastMutex(&pDevExt->ContextMutex);
    436             return STATUS_INVALID_PARAMETER;
    437         }
    438     }
    439     else if (pSwapchainInfo->SwapchainInfo.cAllocs)
    440     {
    441         pSwapchain = vboxWddmSwapchainCreate();
    442         if (!pSwapchain)
    443             return STATUS_NO_MEMORY;
    444 
    445         ExAcquireFastMutex(&pDevExt->ContextMutex);
    446         BOOLEAN bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain);
    447         Assert(bRc);
    448     }
    449     else
    450         return STATUS_INVALID_PARAMETER;
    451 
    452     memset(&pSwapchain->ViewRect, 0, sizeof (pSwapchain->ViewRect));
    453     if (pSwapchain->pLastReportedRects)
    454     {
    455         vboxVideoCmCmdRelease(pSwapchain->pLastReportedRects);
    456         pSwapchain->pLastReportedRects = NULL;
    457     }
    458 
    459     vboxWddmSwapchainAllocRemoveAll(pDevExt, pSwapchain);
    460 
    461     if (pSwapchainInfo->SwapchainInfo.cAllocs)
    462     {
    463         for (UINT i = 0; i < pSwapchainInfo->SwapchainInfo.cAllocs; ++i)
    464         {
    465             vboxWddmSwapchainAllocAdd(pDevExt, pSwapchain, apAlloc[i]);
    466         }
    467         pSwapchain->hSwapchainUm = pSwapchainInfo->SwapchainInfo.hSwapchainUm;
    468     }
    469     else
    470     {
    471         vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
    472     }
    473 
    474     ExReleaseFastMutex(&pDevExt->ContextMutex);
    475 
    476     if (pSwapchainInfo->SwapchainInfo.cAllocs)
    477     {
    478         Assert(pSwapchain->pContext);
    479         Assert(pSwapchain->hSwapchainKm);
    480         pSwapchainInfo->SwapchainInfo.hSwapchainKm = pSwapchain->hSwapchainKm;
    481     }
    482     else
    483     {
    484         vboxWddmSwapchainDestroy(pDevExt, pSwapchain);
    485         pSwapchainInfo->SwapchainInfo.hSwapchainKm = 0;
    486     }
    487 
    488     return STATUS_SUCCESS;
     406    Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
     407    NTSTATUS Status = STATUS_SUCCESS;
     408
     409    do {
     410        if (pSwapchainInfo->SwapchainInfo.cAllocs)
     411        {
     412            apAlloc = (PVBOXWDDM_ALLOCATION *)vboxWddmMemAlloc(sizeof (PVBOXWDDM_ALLOCATION) * pSwapchainInfo->SwapchainInfo.cAllocs);
     413            Assert(apAlloc);
     414            if (!apAlloc)
     415            {
     416                Status = STATUS_NO_MEMORY;
     417                break;
     418            }
     419            for (UINT i = 0; i < pSwapchainInfo->SwapchainInfo.cAllocs; ++i)
     420            {
     421                DXGKARGCB_GETHANDLEDATA GhData;
     422                GhData.hObject = pSwapchainInfo->SwapchainInfo.ahAllocs[i];
     423                GhData.Type = DXGK_HANDLE_ALLOCATION;
     424                GhData.Flags.Value = 0;
     425                PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pDevExt->u.primary.DxgkInterface.DxgkCbGetHandleData(&GhData);
     426                Assert(pAlloc);
     427                if (!pAlloc)
     428                {
     429                    Status = STATUS_INVALID_PARAMETER;
     430                    break;
     431                }
     432                apAlloc[i] = pAlloc;
     433            }
     434
     435            if (!NT_SUCCESS(Status))
     436                break;
     437        }
     438
     439        if (pSwapchainInfo->SwapchainInfo.hSwapchainKm)
     440        {
     441            ExAcquireFastMutex(&pDevExt->ContextMutex);
     442            pSwapchain = (PVBOXWDDM_SWAPCHAIN)vboxWddmHTableGet(&pContext->Swapchains, (VBOXWDDM_HANDLE)pSwapchainInfo->SwapchainInfo.hSwapchainKm);
     443            Assert(pSwapchain);
     444            if (!pSwapchain)
     445            {
     446                ExReleaseFastMutex(&pDevExt->ContextMutex);
     447                Status = STATUS_INVALID_PARAMETER;
     448                break;
     449            }
     450            Assert(pSwapchain->hSwapchainKm == pSwapchainInfo->SwapchainInfo.hSwapchainKm);
     451            Assert(pSwapchain->pContext == pContext);
     452            if (pSwapchain->pContext != pContext)
     453            {
     454                ExReleaseFastMutex(&pDevExt->ContextMutex);
     455                Status = STATUS_INVALID_PARAMETER;
     456                break;
     457            }
     458        }
     459        else if (pSwapchainInfo->SwapchainInfo.cAllocs)
     460        {
     461            pSwapchain = vboxWddmSwapchainCreate();
     462            if (!pSwapchain)
     463            {
     464                Status = STATUS_NO_MEMORY;
     465                break;
     466            }
     467
     468            ExAcquireFastMutex(&pDevExt->ContextMutex);
     469            BOOLEAN bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain);
     470            Assert(bRc);
     471        }
     472        else
     473        {
     474            Status = STATUS_INVALID_PARAMETER;
     475            break;
     476        }
     477
     478        memset(&pSwapchain->ViewRect, 0, sizeof (pSwapchain->ViewRect));
     479        if (pSwapchain->pLastReportedRects)
     480        {
     481            vboxVideoCmCmdRelease(pSwapchain->pLastReportedRects);
     482            pSwapchain->pLastReportedRects = NULL;
     483        }
     484
     485        vboxWddmSwapchainAllocRemoveAll(pDevExt, pSwapchain);
     486
     487        if (pSwapchainInfo->SwapchainInfo.cAllocs)
     488        {
     489            for (UINT i = 0; i < pSwapchainInfo->SwapchainInfo.cAllocs; ++i)
     490            {
     491                vboxWddmSwapchainAllocAdd(pDevExt, pSwapchain, apAlloc[i]);
     492            }
     493            pSwapchain->hSwapchainUm = pSwapchainInfo->SwapchainInfo.hSwapchainUm;
     494        }
     495        else
     496        {
     497            vboxWddmSwapchainCtxRemoveLocked(pDevExt, pContext, pSwapchain);
     498        }
     499
     500        ExReleaseFastMutex(&pDevExt->ContextMutex);
     501
     502        if (pSwapchainInfo->SwapchainInfo.cAllocs)
     503        {
     504            Assert(pSwapchain->pContext);
     505            Assert(pSwapchain->hSwapchainKm);
     506            pSwapchainInfo->SwapchainInfo.hSwapchainKm = pSwapchain->hSwapchainKm;
     507        }
     508        else
     509        {
     510            vboxWddmSwapchainDestroy(pDevExt, pSwapchain);
     511            pSwapchainInfo->SwapchainInfo.hSwapchainKm = 0;
     512        }
     513
     514        Assert(Status == STATUS_SUCCESS);
     515    } while (0);
     516
     517    /* cleanup */
     518    if (apAlloc)
     519        vboxWddmMemFree(apAlloc);
     520
     521    return Status;
    489522}
    490523
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp

    r37736 r38112  
    927927            break;
    928928        }
     929
    929930        default:
    930931            Assert(0);
     
    10641065
    10651066    return Status;
     1067}
     1068
     1069static DECLCALLBACK(UINT) vboxVdmaGgCmdCancelVisitor(PVBOXVIDEOCM_CTX pContext, PVOID pvCmd, uint32_t cbCmd, PVOID pvVisitor)
     1070{
     1071    PVBOXWDDM_SWAPCHAIN pSwapchain = (PVBOXWDDM_SWAPCHAIN)pvVisitor;
     1072    if (!pSwapchain)
     1073        return VBOXVIDEOCMCMDVISITOR_RETURN_RMCMD;
     1074    PVBOXVIDEOCM_CMD_RECTS_INTERNAL pCmdInternal = (PVBOXVIDEOCM_CMD_RECTS_INTERNAL)pvCmd;
     1075    if (pCmdInternal->hSwapchainUm == pSwapchain->hSwapchainUm)
     1076        return VBOXVIDEOCMCMDVISITOR_RETURN_RMCMD;
     1077    return 0;
    10661078}
    10671079
     
    11031115                            break;
    11041116                        }
     1117                        case VBOXVDMAPIPE_CMD_TYPE_FINISH:
     1118                        {
     1119                            PVBOXVDMAPIPE_CMD_FINISH pCmd = (PVBOXVDMAPIPE_CMD_FINISH)pDr;
     1120                            PVBOXWDDM_CONTEXT pContext = pCmd->pContext;
     1121                            Assert(pCmd->pEvent);
     1122                            Status = vboxVideoCmCmdSubmitCompleteEvent(&pContext->CmContext, pCmd->pEvent);
     1123                            if (Status != STATUS_SUCCESS)
     1124                            {
     1125                                WARN(("vboxVideoCmCmdWaitCompleted failedm Status (0x%x)", Status));
     1126                            }
     1127                            vboxVdmaGgCmdDestroy(pDevExt, &pCmd->Hdr);
     1128                            break;
     1129                        }
     1130                        case VBOXVDMAPIPE_CMD_TYPE_CANCEL:
     1131                        {
     1132                            PVBOXVDMAPIPE_CMD_CANCEL pCmd = (PVBOXVDMAPIPE_CMD_CANCEL)pDr;
     1133                            PVBOXWDDM_CONTEXT pContext = pCmd->pContext;
     1134                            Status = vboxVideoCmCmdVisit(&pContext->CmContext, FALSE, vboxVdmaGgCmdCancelVisitor, pCmd->pSwapchain);
     1135                            if (Status != STATUS_SUCCESS)
     1136                            {
     1137                                WARN(("vboxVideoCmCmdWaitCompleted failedm Status (0x%x)", Status));
     1138                            }
     1139                            Assert(pCmd->pEvent);
     1140                            KeSetEvent(pCmd->pEvent, 0, FALSE);
     1141                            vboxVdmaGgCmdDestroy(pDevExt, &pCmd->Hdr);
     1142                            break;
     1143                        }
    11051144                        default:
    11061145                            AssertBreakpoint();
     
    12171256#endif
    12181257    vboxVdmaDdiCmdInit(pDdiCmd, u32NodeOrdinal, u32FenceId, pfnComplete, pvComplete);
     1258}
     1259
     1260NTSTATUS vboxVdmaGgCmdFinish(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, PKEVENT pEvent)
     1261{
     1262    NTSTATUS Status = STATUS_SUCCESS;
     1263
     1264    PVBOXVDMAPIPE_CMD_FINISH pCmd = (PVBOXVDMAPIPE_CMD_FINISH)vboxVdmaGgCmdCreate(pDevExt, VBOXVDMAPIPE_CMD_TYPE_FINISH, sizeof (*pCmd));
     1265    if (pCmd)
     1266    {
     1267        pCmd->pContext = pContext;
     1268        pCmd->pEvent = pEvent;
     1269        Status = vboxVdmaGgCmdSubmit(pDevExt, &pCmd->Hdr);
     1270        if (!NT_SUCCESS(Status))
     1271        {
     1272            WARN(("vboxVdmaGgCmdSubmit returned 0x%x", Status));
     1273        }
     1274    }
     1275    else
     1276    {
     1277        WARN(("vboxVdmaGgCmdCreate failed"));
     1278        Status = STATUS_NO_MEMORY;
     1279    }
     1280    return Status;
     1281}
     1282
     1283NTSTATUS vboxVdmaGgCmdCancel(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, PVBOXWDDM_SWAPCHAIN pSwapchain)
     1284{
     1285    NTSTATUS Status = STATUS_SUCCESS;
     1286
     1287    PVBOXVDMAPIPE_CMD_CANCEL pCmd = (PVBOXVDMAPIPE_CMD_CANCEL)vboxVdmaGgCmdCreate(pDevExt, VBOXVDMAPIPE_CMD_TYPE_CANCEL, sizeof (*pCmd));
     1288    if (pCmd)
     1289    {
     1290        KEVENT Event;
     1291        KeInitializeEvent(&Event, NotificationEvent, FALSE);
     1292        pCmd->pContext = pContext;
     1293        pCmd->pSwapchain = pSwapchain;
     1294        pCmd->pEvent = &Event;
     1295        Status = vboxVdmaGgCmdSubmit(pDevExt, &pCmd->Hdr);
     1296        if (NT_SUCCESS(Status))
     1297        {
     1298            Status = KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
     1299            Assert(Status == STATUS_SUCCESS);
     1300        }
     1301        else
     1302        {
     1303            WARN(("vboxVdmaGgCmdSubmit returned 0x%x", Status));
     1304        }
     1305    }
     1306    else
     1307    {
     1308        WARN(("vboxVdmaGgCmdCreate failed"));
     1309        Status = STATUS_NO_MEMORY;
     1310    }
     1311    return Status;
    12191312}
    12201313
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.h

    r37626 r38112  
    161161    VBOXVDMAPIPE_CMD_TYPE_UNDEFINED = 0,
    162162    VBOXVDMAPIPE_CMD_TYPE_RECTSINFO,
    163     VBOXVDMAPIPE_CMD_TYPE_DMACMD
     163    VBOXVDMAPIPE_CMD_TYPE_DMACMD,
     164    VBOXVDMAPIPE_CMD_TYPE_FINISH, /* ensures all previously submitted commands are completed */
     165    VBOXVDMAPIPE_CMD_TYPE_CANCEL
    164166} VBOXVDMAPIPE_CMD_TYPE;
    165167
     
    193195    VBOXVDMAPIPE_RECTS ContextsRects;
    194196} VBOXVDMAPIPE_CMD_RECTSINFO, *PVBOXVDMAPIPE_CMD_RECTSINFO;
     197
     198typedef struct VBOXVDMAPIPE_CMD_FINISH
     199{
     200    VBOXVDMAPIPE_CMD_DR Hdr;
     201    PVBOXWDDM_CONTEXT pContext;
     202    PKEVENT pEvent;
     203} VBOXVDMAPIPE_CMD_FINISH, *PVBOXVDMAPIPE_CMD_FINISH;
     204
     205typedef struct VBOXVDMAPIPE_CMD_CANCEL
     206{
     207    VBOXVDMAPIPE_CMD_DR Hdr;
     208    PVBOXWDDM_CONTEXT pContext;
     209    PVBOXWDDM_SWAPCHAIN pSwapchain;
     210    PKEVENT pEvent;
     211} VBOXVDMAPIPE_CMD_CANCEL, *PVBOXVDMAPIPE_CMD_CANCEL;
    195212
    196213typedef struct VBOXVDMAPIPE_FLAGS_DMACMD
     
    313330PVBOXVDMAPIPE_CMD_DR vboxVdmaGgCmdCreate(PVBOXMP_DEVEXT pDevExt, VBOXVDMAPIPE_CMD_TYPE enmType, uint32_t cbCmd);
    314331void vboxVdmaGgCmdDestroy(PVBOXMP_DEVEXT pDevExt, PVBOXVDMAPIPE_CMD_DR pDr);
     332NTSTATUS vboxVdmaGgCmdFinish(PVBOXMP_DEVEXT pDevExt, struct VBOXWDDM_CONTEXT *pContext, PKEVENT pEvent);
     333NTSTATUS vboxVdmaGgCmdCancel(PVBOXMP_DEVEXT pDevExt, VBOXWDDM_CONTEXT *pContext, PVBOXWDDM_SWAPCHAIN pSwapchain);
    315334
    316335NTSTATUS vboxVdmaPostHideSwapchain(PVBOXWDDM_SWAPCHAIN pSwapchain);
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