Changeset 50677 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm
- Timestamp:
- Mar 4, 2014 1:21:14 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp
r50635 r50677 1317 1317 } 1318 1318 1319 VBOXVTLIST CtlList; 1320 vboxVtListInit(&CtlList); 1321 #ifdef VBOX_WITH_VIDEOHWACCEL 1322 VBOXVTLIST VhwaCmdList; 1323 vboxVtListInit(&VhwaCmdList); 1324 #endif 1325 1319 1326 uint32_t flags = VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags->u32HostFlags; 1320 1327 bOur = (flags & HGSMIHOSTFLAGS_IRQ); … … 1325 1332 bNeedDpc |= VBoxCmdVbvaCheckCompletedIrq(pDevExt, &pDevExt->CmdVbva); 1326 1333 1334 do { 1335 if (flags & HGSMIHOSTFLAGS_GCOMMAND_COMPLETED) 1336 { 1337 /* read the command offset */ 1338 HGSMIOFFSET offCmd = VBoxVideoCmnPortReadUlong(VBoxCommonFromDeviceExt(pDevExt)->guestCtx.port); 1339 if (offCmd == HGSMIOFFSET_VOID) 1340 { 1341 WARN(("void command offset!")); 1342 continue; 1343 } 1344 1345 uint16_t chInfo; 1346 uint8_t *pvCmd = HGSMIBufferDataAndChInfoFromOffset (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx.Heap.area, offCmd, &chInfo); 1347 if (!pvCmd) 1348 { 1349 WARN(("zero cmd")); 1350 continue; 1351 } 1352 1353 switch (chInfo) 1354 { 1355 case VBVA_VBVACMD_CTL: 1356 { 1357 int rc = VBoxSHGSMICommandProcessCompletion (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, (VBOXSHGSMIHEADER*)pvCmd, TRUE /*bool bIrq*/ , &CtlList); 1358 AssertRC(rc); 1359 break; 1360 } 1361 #ifdef VBOX_WITH_VIDEOHWACCEL 1362 case VBVA_VHWA_CMD: 1363 { 1364 vboxVhwaPutList(&VhwaCmdList, (VBOXVHWACMD*)pvCmd); 1365 break; 1366 } 1367 #endif /* # ifdef VBOX_WITH_VIDEOHWACCEL */ 1368 default: 1369 AssertBreakpoint(); 1370 } 1371 } 1372 else if (flags & HGSMIHOSTFLAGS_COMMANDS_PENDING) 1373 { 1374 AssertBreakpoint(); 1375 /* @todo: FIXME: implement !!! */ 1376 } 1377 else 1378 break; 1379 1380 flags = VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags->u32HostFlags; 1381 1382 } while (1); 1383 1384 if (!vboxVtListIsEmpty(&CtlList)) 1385 { 1386 vboxVtListCat(&pDevExt->CtlList, &CtlList); 1387 bNeedDpc = TRUE; 1388 ASMAtomicWriteU32(&pDevExt->fCompletingCommands, 1); 1389 } 1390 1391 if (!vboxVtListIsEmpty(&VhwaCmdList)) 1392 { 1393 vboxVtListCat(&pDevExt->VhwaCmdList, &VhwaCmdList); 1394 bNeedDpc = TRUE; 1395 ASMAtomicWriteU32(&pDevExt->fCompletingCommands, 1); 1396 } 1397 1398 bNeedDpc |= !vboxVdmaDdiCmdIsCompletedListEmptyIsr(pDevExt); 1399 1400 if (bOur) 1401 { 1402 #ifdef VBOX_VDMA_WITH_WATCHDOG 1403 if (flags & HGSMIHOSTFLAGS_WATCHDOG) 1404 { 1405 Assert(0); 1406 } 1407 #endif 1408 if (flags & HGSMIHOSTFLAGS_VSYNC) 1409 { 1410 Assert(0); 1411 DXGKARGCB_NOTIFY_INTERRUPT_DATA notify; 1412 for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i) 1413 { 1414 PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i]; 1415 PVBOXWDDM_ALLOCATION pPrimary = pSource->pPrimaryAllocation; 1416 if (pPrimary && pPrimary->AllocData.Addr.offVram != VBOXVIDEOOFFSET_VOID) 1417 { 1418 memset(¬ify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA)); 1419 notify.InterruptType = DXGK_INTERRUPT_CRTC_VSYNC; 1420 /* @todo: !!!this is not correct in case we want source[i]->target[i!=j] mapping */ 1421 notify.CrtcVsync.VidPnTargetId = i; 1422 notify.CrtcVsync.PhysicalAddress.QuadPart = pPrimary->AllocData.Addr.offVram; 1423 pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, ¬ify); 1424 1425 bNeedDpc = TRUE; 1426 } 1427 } 1428 } 1429 } 1430 1431 if (pDevExt->bNotifyDxDpc) 1432 bNeedDpc = TRUE; 1433 1327 1434 if (bNeedDpc) 1328 1435 pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle); 1329 1330 // LOGF(("LEAVE, context(0x%p), bOur(0x%x)", MiniportDeviceContext, (ULONG)bOur));1331 1436 1332 1437 return bOur; … … 1554 1659 pdc->data.bNotifyDpc = pdc->pDevExt->bNotifyDxDpc; 1555 1660 pdc->pDevExt->bNotifyDxDpc = FALSE; 1661 1662 ASMAtomicWriteU32(&pdc->pDevExt->fCompletingCommands, 0); 1663 1556 1664 return TRUE; 1557 1665 } … … 1569 1677 pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle); 1570 1678 1679 if (ASMAtomicReadU32(&pDevExt->fCompletingCommands)) 1680 { 1681 VBOXWDDM_GETDPCDATA_CONTEXT context = {0}; 1682 BOOLEAN bRet; 1683 1684 context.pDevExt = pDevExt; 1685 1686 /* get DPC data at IRQL */ 1687 NTSTATUS Status = pDevExt->u.primary.DxgkInterface.DxgkCbSynchronizeExecution( 1688 pDevExt->u.primary.DxgkInterface.DeviceHandle, 1689 vboxWddmGetDPCDataCallback, 1690 &context, 1691 0, /* IN ULONG MessageNumber */ 1692 &bRet); 1693 Assert(Status == STATUS_SUCCESS); 1694 1695 // if (context.data.bNotifyDpc) 1696 pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle); 1697 1698 if (!vboxVtListIsEmpty(&context.data.CtlList)) 1699 { 1700 int rc = VBoxSHGSMICommandPostprocessCompletion (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, &context.data.CtlList); 1701 AssertRC(rc); 1702 } 1703 #ifdef VBOX_WITH_VIDEOHWACCEL 1704 if (!vboxVtListIsEmpty(&context.data.VhwaCmdList)) 1705 { 1706 vboxVhwaCompletionListProcess(pDevExt, &context.data.VhwaCmdList); 1707 } 1708 #endif 1709 1710 vboxVdmaDdiCmdHandleCompletedList(pDevExt, &context.data.CompletedDdiCmdQueue); 1711 } 1571 1712 // LOGF(("LEAVE, context(0x%p)", MiniportDeviceContext)); 1572 1713 } … … 5738 5879 } 5739 5880 5881 static void vboxWddmPatchLocationInit(D3DDDI_PATCHLOCATIONLIST *pPatchLocationListOut, UINT idx, UINT offPatch) 5882 { 5883 memset(pPatchLocationListOut, 0, sizeof (*pPatchLocationListOut)); 5884 pPatchLocationListOut->AllocationIndex = idx; 5885 pPatchLocationListOut->PatchOffset = offPatch; 5886 } 5740 5887 5741 5888 static NTSTATUS … … 5752 5899 WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)", 5753 5900 pRender->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))); 5754 /* @todo: can this actually happen? what status to return? */5755 5901 return STATUS_INVALID_PARAMETER; 5756 5902 } … … 5759 5905 WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)", 5760 5906 pRender->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR))); 5761 /* @todo: can this actually happen? what status to return? */5762 5907 return STATUS_INVALID_PARAMETER; 5763 5908 } 5764 5765 PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pInputHdr = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pCommand; 5909 if (pRender->DmaSize < pRender->CommandLength) 5910 { 5911 WARN(("pRender->DmaSize(%d) < pRender->CommandLength(%d)", 5912 pRender->DmaSize, pRender->CommandLength)); 5913 return STATUS_INVALID_PARAMETER; 5914 } 5915 if (pRender->PatchLocationListOutSize < pRender->PatchLocationListInSize) 5916 { 5917 WARN(("pRender->PatchLocationListOutSize(%d) < pRender->PatchLocationListInSize(%d)", 5918 pRender->PatchLocationListOutSize, pRender->PatchLocationListInSize)); 5919 return STATUS_INVALID_PARAMETER; 5920 } 5921 if (pRender->AllocationListSize != pRender->PatchLocationListInSize) 5922 { 5923 WARN(("pRender->AllocationListSize(%d) != pRender->PatchLocationListInSize(%d)", 5924 pRender->AllocationListSize, pRender->PatchLocationListInSize)); 5925 return STATUS_INVALID_PARAMETER; 5926 } 5927 5766 5928 NTSTATUS Status = STATUS_SUCCESS; 5767 switch (pInputHdr->enmCmd) 5768 { 5769 case VBOXVDMACMD_TYPE_DMA_NOP: 5770 { 5771 PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pDmaBufferPrivateData; 5772 pPrivateData->enmCmd = VBOXVDMACMD_TYPE_DMA_NOP; 5773 5774 pRender->pDmaBufferPrivateData = (uint8_t*)pRender->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR); 5775 pRender->pDmaBuffer = ((uint8_t*)pRender->pDmaBuffer) + pRender->CommandLength; 5776 Assert(pRender->DmaSize >= pRender->CommandLength); 5777 Assert(pRender->PatchLocationListOutSize >= pRender->PatchLocationListInSize); 5778 UINT cbPLL = pRender->PatchLocationListInSize * sizeof (pRender->pPatchLocationListOut[0]); 5779 memcpy(pRender->pPatchLocationListOut, pRender->pPatchLocationListIn, cbPLL); 5780 pRender->pPatchLocationListOut += pRender->PatchLocationListInSize; 5781 break; 5782 } 5783 default: 5784 { 5785 WARN(("unsupported command %d", pInputHdr->enmCmd)); 5786 return STATUS_INVALID_PARAMETER; 5787 } 5788 } 5789 5929 5930 __try 5931 { 5932 PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pInputHdr = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pCommand; 5933 switch (pInputHdr->enmCmd) 5934 { 5935 case VBOXVDMACMD_TYPE_DMA_NOP: 5936 { 5937 PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR pPrivateData = (PVBOXWDDM_DMA_PRIVATEDATA_BASEHDR)pRender->pDmaBufferPrivateData; 5938 pPrivateData->enmCmd = VBOXVDMACMD_TYPE_DMA_NOP; 5939 pRender->pDmaBufferPrivateData = (uint8_t*)pRender->pDmaBufferPrivateData + sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR); 5940 pRender->pDmaBuffer = ((uint8_t*)pRender->pDmaBuffer) + pRender->CommandLength; 5941 for (UINT i = 0; i < pRender->PatchLocationListInSize; ++i) 5942 { 5943 UINT offPatch = i * 4; 5944 if (offPatch + 4 > pRender->CommandLength) 5945 { 5946 WARN(("wrong offPatch")); 5947 return STATUS_INVALID_PARAMETER; 5948 } 5949 if (offPatch != pRender->pPatchLocationListIn[i].PatchOffset) 5950 { 5951 WARN(("wrong PatchOffset")); 5952 return STATUS_INVALID_PARAMETER; 5953 } 5954 if (i != pRender->pPatchLocationListIn[i].AllocationIndex) 5955 { 5956 WARN(("wrong AllocationIndex")); 5957 return STATUS_INVALID_PARAMETER; 5958 } 5959 vboxWddmPatchLocationInit(&pRender->pPatchLocationListOut[i], i, offPatch); 5960 } 5961 break; 5962 } 5963 default: 5964 { 5965 WARN(("unsupported command %d", pInputHdr->enmCmd)); 5966 return STATUS_INVALID_PARAMETER; 5967 } 5968 } 5969 } 5970 __except (EXCEPTION_EXECUTE_HANDLER) 5971 { 5972 Status = STATUS_INVALID_PARAMETER; 5973 WARN(("invalid parameter")); 5974 } 5790 5975 // LOGF(("LEAVE, hContext(0x%x)", hContext)); 5791 5976
Note:
See TracChangeset
for help on using the changeset viewer.