VirtualBox

Changeset 50947 in vbox


Ignore:
Timestamp:
Apr 1, 2014 5:31:27 PM (11 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
93095
Message:

wddm: preemption fixes

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

Legend:

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

    r50944 r50947  
    771771}
    772772
    773 typedef struct VBOXCMDVBVA_NOTIFYCOMPLETED_CB
     773typedef struct VBOXCMDVBVA_NOTIFYPREEMPT_CB
    774774{
    775775    PVBOXMP_DEVEXT pDevExt;
    776776    VBOXCMDVBVA *pVbva;
    777     volatile UINT *pu32FenceId;
    778     DXGK_INTERRUPT_TYPE enmComplType;
    779 } VBOXCMDVBVA_NOTIFYCOMPLETED_CB, *PVBOXCMDVBVA_NOTIFYCOMPLETED_CB;
    780 
    781 static BOOLEAN vboxCmdVbvaDdiNotifyCompleteCb(PVOID pvContext)
    782 {
    783     PVBOXCMDVBVA_NOTIFYCOMPLETED_CB pData = (PVBOXCMDVBVA_NOTIFYCOMPLETED_CB)pvContext;
    784     if (*pData->pu32FenceId)
    785     {
    786         UINT u32FenceId = *pData->pu32FenceId;
    787         *pData->pu32FenceId = 0;
    788 
    789         vboxCmdVbvaDdiNotifyCompleteIrq(pData->pDevExt, pData->pVbva, u32FenceId, pData->enmComplType);
    790 
    791         pData->pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pData->pDevExt->u.primary.DxgkInterface.DeviceHandle);
    792 
    793         return TRUE;
    794     }
    795 
    796     return FALSE;
    797 }
    798 
    799 static int vboxCmdVbvaDdiNotifyComplete(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, volatile UINT *pu32FenceId, DXGK_INTERRUPT_TYPE enmComplType)
    800 {
    801     VBOXCMDVBVA_NOTIFYCOMPLETED_CB Data;
     777    int rc;
     778    UINT u32SubmitFenceId;
     779    UINT u32PreemptFenceId;
     780} VBOXCMDVBVA_NOTIFYPREEMPT_CB;
     781
     782static BOOLEAN vboxCmdVbvaDdiNotifyPreemptCb(PVOID pvContext)
     783{
     784    VBOXCMDVBVA_NOTIFYPREEMPT_CB* pData = (VBOXCMDVBVA_NOTIFYPREEMPT_CB*)pvContext;
     785    PVBOXMP_DEVEXT pDevExt = pData->pDevExt;
     786    VBOXCMDVBVA *pVbva = pData->pVbva;
     787    if (!pData->u32SubmitFenceId || pVbva->u32FenceCompleted == pData->u32SubmitFenceId)
     788    {
     789        vboxCmdVbvaDdiNotifyCompleteIrq(pDevExt, pVbva, pData->u32PreemptFenceId, DXGK_INTERRUPT_DMA_PREEMPTED);
     790
     791        pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
     792    }
     793    else
     794    {
     795        Assert(pVbva->u32FenceCompleted < pData->u32SubmitFenceId);
     796        Assert(pVbva->cPreempt <= VBOXCMDVBVA_PREEMPT_EL_SIZE);
     797        if (pVbva->cPreempt == VBOXCMDVBVA_PREEMPT_EL_SIZE)
     798        {
     799            WARN(("no more free elements in preempt map"));
     800            pData->rc = VERR_BUFFER_OVERFLOW;
     801            return FALSE;
     802        }
     803        uint32_t iNewEl = (pVbva->iCurPreempt + pVbva->cPreempt) % VBOXCMDVBVA_PREEMPT_EL_SIZE;
     804        Assert(iNewEl < VBOXCMDVBVA_PREEMPT_EL_SIZE);
     805        pVbva->aPreempt[iNewEl].u32SubmitFence = pData->u32SubmitFenceId;
     806        pVbva->aPreempt[iNewEl].u32PreemptFence = pData->u32PreemptFenceId;
     807        ++pVbva->cPreempt;
     808    }
     809
     810    pData->rc = VINF_SUCCESS;
     811    return TRUE;
     812}
     813
     814static int vboxCmdVbvaDdiNotifyPreempt(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, UINT u32SubmitFenceId, UINT u32PreemptFenceId)
     815{
     816    VBOXCMDVBVA_NOTIFYPREEMPT_CB Data;
    802817    Data.pDevExt = pDevExt;
    803818    Data.pVbva = pVbva;
    804     Data.pu32FenceId = pu32FenceId;
    805     Data.enmComplType = enmComplType;
     819    Data.rc = VERR_INTERNAL_ERROR;
     820    Data.u32SubmitFenceId = u32SubmitFenceId;
     821    Data.u32PreemptFenceId = u32PreemptFenceId;
    806822    BOOLEAN bDummy;
    807823    NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution(
    808824            pDevExt->u.primary.DxgkInterface.DeviceHandle,
    809             vboxCmdVbvaDdiNotifyCompleteCb,
     825            vboxCmdVbvaDdiNotifyPreemptCb,
    810826            &Data,
    811827            0, /* IN ULONG MessageNumber */
     
    816832        return VERR_GENERAL_FAILURE;
    817833    }
    818     return Status;
     834
     835    if (!RT_SUCCESS(Data.rc))
     836    {
     837        WARN(("vboxCmdVbvaDdiNotifyPreemptCb failed rc %d", Data.rc));
     838        return Data.rc;
     839    }
     840
     841    return VINF_SUCCESS;
    819842}
    820843
     
    10041027    bool fProcessed;
    10051028    uint8_t* pu8Cmd;
    1006     bool fFenceFound = false;
    1007 
     1029    uint32_t u32SubmitFence = 0;
     1030
     1031    /* we can do it right here */
    10081032    while ((pu8Cmd = (uint8_t*)VBoxVBVAExBIterNext(&Iter, &cbBuffer, &fProcessed)) != NULL)
    10091033    {
     
    10131037        VBOXCMDVBVA_HDR *pCmd = (VBOXCMDVBVA_HDR*)pu8Cmd;
    10141038
    1015         if (pCmd->u32FenceID != u32FenceID)
     1039        if (ASMAtomicCmpXchgU8(&pCmd->u8State, VBOXCMDVBVA_STATE_CANCELLED, VBOXCMDVBVA_STATE_SUBMITTED)
     1040                || pCmd->u8State == VBOXCMDVBVA_STATE_CANCELLED)
    10161041            continue;
    10171042
    1018         fFenceFound = true;
    1019 
    1020         if (!ASMAtomicCmpXchgU8(&pCmd->u8State, VBOXCMDVBVA_STATE_CANCELLED, VBOXCMDVBVA_STATE_SUBMITTED))
    1021         {
    1022             Assert(pCmd->u8State == VBOXCMDVBVA_STATE_IN_PROGRESS);
    1023             break;
    1024         }
    1025 
    1026         /* we have canceled the command successfully */
    1027         vboxCmdVbvaDdiNotifyComplete(pDevExt, pVbva, &pCmd->u32FenceID, DXGK_INTERRUPT_DMA_PREEMPTED);
    1028         return true;
    1029     }
    1030 
    1031     if (!fFenceFound)
    1032         vboxCmdVbvaDdiNotifyComplete(pDevExt, pVbva, &u32FenceID, DXGK_INTERRUPT_DMA_PREEMPTED);
     1043        Assert(pCmd->u8State == VBOXCMDVBVA_STATE_IN_PROGRESS);
     1044
     1045        u32SubmitFence = ASMAtomicUoReadU32(&pCmd->u32FenceID);
     1046        break;
     1047    }
     1048
     1049    vboxCmdVbvaDdiNotifyPreempt(pDevExt, pVbva, u32SubmitFence, u32FenceID);
    10331050
    10341051    return false;
     
    10611078        Assert(u32FenceID);
    10621079        VBoxVBVAExCBufferCompleted(&pVbva->Vbva);
    1063         DXGK_INTERRUPT_TYPE enmDdiNotify;
    10641080
    10651081        if (u8State == VBOXCMDVBVA_STATE_IN_PROGRESS)
    10661082        {
    1067             if (u32FenceID)
     1083            Assert(u32FenceID);
     1084            if (!u32FenceID)
     1085                continue;
     1086
     1087#ifdef DEBUG_misha
     1088            Assert(u32FenceID == pVbva->u32FenceCompleted + 1);
     1089#endif
     1090            pVbva->u32FenceCompleted = u32FenceID;
     1091        }
     1092        else
     1093        {
     1094            Assert(u8State == VBOXCMDVBVA_STATE_CANCELLED);
     1095            continue;
     1096        }
     1097
     1098        Assert(u32FenceID);
     1099        vboxCmdVbvaDdiNotifyCompleteIrq(pDevExt, pVbva, u32FenceID, DXGK_INTERRUPT_DMA_COMPLETED);
     1100
     1101        if (pVbva->cPreempt && pVbva->aPreempt[pVbva->iCurPreempt].u32SubmitFence == u32FenceID)
     1102        {
     1103            Assert(pVbva->aPreempt[pVbva->iCurPreempt].u32PreemptFence);
     1104            vboxCmdVbvaDdiNotifyCompleteIrq(pDevExt, pVbva, pVbva->aPreempt[pVbva->iCurPreempt].u32PreemptFence, DXGK_INTERRUPT_DMA_PREEMPTED);
     1105            --pVbva->cPreempt;
     1106            if (!pVbva->cPreempt)
     1107                pVbva->iCurPreempt = 0;
     1108            else
    10681109            {
    1069 #ifdef DEBUG_misha
    1070                 Assert(u32FenceID == pVbva->u32FenceCompleted + 1);
    1071 #endif
    1072                 pVbva->u32FenceCompleted = u32FenceID;
     1110                ++pVbva->iCurPreempt;
     1111                pVbva->iCurPreempt %= VBOXCMDVBVA_PREEMPT_EL_SIZE;
    10731112            }
    1074             enmDdiNotify = DXGK_INTERRUPT_DMA_COMPLETED;
    1075         }
    1076         else
    1077         {
    1078             Assert(u8State == VBOXCMDVBVA_STATE_CANCELLED);
    1079             enmDdiNotify = DXGK_INTERRUPT_DMA_PREEMPTED;
    1080             /* to prevent concurrent notifications from DdiPreemptCommand */
    1081             pCmd->u32FenceID = 0;
    1082         }
    1083 
    1084         if (u32FenceID)
    1085             vboxCmdVbvaDdiNotifyCompleteIrq(pDevExt, pVbva, u32FenceID, enmDdiNotify);
     1113        }
    10861114
    10871115        fHasCommandsCompletedPreempted = true;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h

    r50940 r50947  
    116116#define VBOXCMDVBVA_BUFFERSIZE(_cbCmdApprox) (RT_OFFSETOF(VBVABUFFER, au8Data) + ((RT_SIZEOFMEMB(VBVABUFFER, aRecords)/RT_SIZEOFMEMB(VBVABUFFER, aRecords[0])) * (_cbCmdApprox)))
    117117
     118typedef struct VBOXCMDVBVA_PREEMPT_EL
     119{
     120    uint32_t u32SubmitFence;
     121    uint32_t u32PreemptFence;
     122} VBOXCMDVBVA_PREEMPT_EL;
     123
     124#define VBOXCMDVBVA_PREEMPT_EL_SIZE 16
     125
    118126typedef struct VBOXCMDVBVA
    119127{
     
    127135    /* node ordinal */
    128136    uint32_t idNode;
     137
     138    uint32_t cPreempt;
     139    uint32_t iCurPreempt;
     140    VBOXCMDVBVA_PREEMPT_EL aPreempt[VBOXCMDVBVA_PREEMPT_EL_SIZE];
    129141} VBOXCMDVBVA;
    130142
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