Changeset 50947 in vbox
- Timestamp:
- Apr 1, 2014 5:31:27 PM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 93095
- 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 771 771 } 772 772 773 typedef struct VBOXCMDVBVA_NOTIFY COMPLETED_CB773 typedef struct VBOXCMDVBVA_NOTIFYPREEMPT_CB 774 774 { 775 775 PVBOXMP_DEVEXT pDevExt; 776 776 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 782 static 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 814 static int vboxCmdVbvaDdiNotifyPreempt(PVBOXMP_DEVEXT pDevExt, VBOXCMDVBVA *pVbva, UINT u32SubmitFenceId, UINT u32PreemptFenceId) 815 { 816 VBOXCMDVBVA_NOTIFYPREEMPT_CB Data; 802 817 Data.pDevExt = pDevExt; 803 818 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; 806 822 BOOLEAN bDummy; 807 823 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution( 808 824 pDevExt->u.primary.DxgkInterface.DeviceHandle, 809 vboxCmdVbvaDdiNotify CompleteCb,825 vboxCmdVbvaDdiNotifyPreemptCb, 810 826 &Data, 811 827 0, /* IN ULONG MessageNumber */ … … 816 832 return VERR_GENERAL_FAILURE; 817 833 } 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; 819 842 } 820 843 … … 1004 1027 bool fProcessed; 1005 1028 uint8_t* pu8Cmd; 1006 bool fFenceFound = false; 1007 1029 uint32_t u32SubmitFence = 0; 1030 1031 /* we can do it right here */ 1008 1032 while ((pu8Cmd = (uint8_t*)VBoxVBVAExBIterNext(&Iter, &cbBuffer, &fProcessed)) != NULL) 1009 1033 { … … 1013 1037 VBOXCMDVBVA_HDR *pCmd = (VBOXCMDVBVA_HDR*)pu8Cmd; 1014 1038 1015 if (pCmd->u32FenceID != u32FenceID) 1039 if (ASMAtomicCmpXchgU8(&pCmd->u8State, VBOXCMDVBVA_STATE_CANCELLED, VBOXCMDVBVA_STATE_SUBMITTED) 1040 || pCmd->u8State == VBOXCMDVBVA_STATE_CANCELLED) 1016 1041 continue; 1017 1042 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); 1033 1050 1034 1051 return false; … … 1061 1078 Assert(u32FenceID); 1062 1079 VBoxVBVAExCBufferCompleted(&pVbva->Vbva); 1063 DXGK_INTERRUPT_TYPE enmDdiNotify;1064 1080 1065 1081 if (u8State == VBOXCMDVBVA_STATE_IN_PROGRESS) 1066 1082 { 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 1068 1109 { 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; 1073 1112 } 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 } 1086 1114 1087 1115 fHasCommandsCompletedPreempted = true; -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVbva.h
r50940 r50947 116 116 #define VBOXCMDVBVA_BUFFERSIZE(_cbCmdApprox) (RT_OFFSETOF(VBVABUFFER, au8Data) + ((RT_SIZEOFMEMB(VBVABUFFER, aRecords)/RT_SIZEOFMEMB(VBVABUFFER, aRecords[0])) * (_cbCmdApprox))) 117 117 118 typedef 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 118 126 typedef struct VBOXCMDVBVA 119 127 { … … 127 135 /* node ordinal */ 128 136 uint32_t idNode; 137 138 uint32_t cPreempt; 139 uint32_t iCurPreempt; 140 VBOXCMDVBVA_PREEMPT_EL aPreempt[VBOXCMDVBVA_PREEMPT_EL_SIZE]; 129 141 } VBOXCMDVBVA; 130 142
Note:
See TracChangeset
for help on using the changeset viewer.