VirtualBox

Ignore:
Timestamp:
Mar 4, 2014 1:21:14 PM (11 years ago)
Author:
vboxsync
Message:

wddm: misc bugfixes

File:
1 edited

Legend:

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

    r50635 r50677  
    13171317    }
    13181318
     1319    VBOXVTLIST CtlList;
     1320    vboxVtListInit(&CtlList);
     1321#ifdef VBOX_WITH_VIDEOHWACCEL
     1322    VBOXVTLIST VhwaCmdList;
     1323    vboxVtListInit(&VhwaCmdList);
     1324#endif
     1325
    13191326    uint32_t flags = VBoxCommonFromDeviceExt(pDevExt)->hostCtx.pfHostFlags->u32HostFlags;
    13201327    bOur = (flags & HGSMIHOSTFLAGS_IRQ);
     
    13251332    bNeedDpc |= VBoxCmdVbvaCheckCompletedIrq(pDevExt, &pDevExt->CmdVbva);
    13261333
     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(&notify, 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, &notify);
     1424
     1425                    bNeedDpc = TRUE;
     1426                }
     1427            }
     1428        }
     1429    }
     1430
     1431    if (pDevExt->bNotifyDxDpc)
     1432        bNeedDpc = TRUE;
     1433
    13271434    if (bNeedDpc)
    13281435        pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
    1329 
    1330 //    LOGF(("LEAVE, context(0x%p), bOur(0x%x)", MiniportDeviceContext, (ULONG)bOur));
    13311436
    13321437    return bOur;
     
    15541659    pdc->data.bNotifyDpc = pdc->pDevExt->bNotifyDxDpc;
    15551660    pdc->pDevExt->bNotifyDxDpc = FALSE;
     1661
     1662    ASMAtomicWriteU32(&pdc->pDevExt->fCompletingCommands, 0);
     1663
    15561664    return TRUE;
    15571665}
     
    15691677    pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
    15701678
     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    }
    15711712//    LOGF(("LEAVE, context(0x%p)", MiniportDeviceContext));
    15721713}
     
    57385879}
    57395880
     5881static 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}
    57405887
    57415888static NTSTATUS
     
    57525899        WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)",
    57535900                pRender->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
    5754         /* @todo: can this actually happen? what status to return? */
    57555901        return STATUS_INVALID_PARAMETER;
    57565902    }
     
    57595905        WARN(("Present->DmaBufferPrivateDataSize(%d) < sizeof VBOXWDDM_DMA_PRIVATEDATA_BASEHDR (%d)",
    57605906                pRender->DmaBufferPrivateDataSize , sizeof (VBOXWDDM_DMA_PRIVATEDATA_BASEHDR)));
    5761         /* @todo: can this actually happen? what status to return? */
    57625907        return STATUS_INVALID_PARAMETER;
    57635908    }
    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
    57665928    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    }
    57905975//    LOGF(("LEAVE, hContext(0x%x)", hContext));
    57915976
Note: See TracChangeset for help on using the changeset viewer.

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