VirtualBox

Ignore:
Timestamp:
Jun 9, 2012 4:58:09 PM (12 years ago)
Author:
vboxsync
Message:

wddm: vsync support fixes + missing commit

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/VBoxMPMisc.cpp

    r41636 r41638  
    25352535        LARGE_INTEGER DueTime;
    25362536        DueTime.QuadPart = -166666LL; /* 60 Hz */
    2537         KeSetTimerEx(&pDevExt->VSyncTimer, DueTime, 17, &pDevExt->VSyncDpc);
     2537        KeSetTimerEx(&pDevExt->VSyncTimer, DueTime, 16, &pDevExt->VSyncDpc);
    25382538    }
    25392539    return STATUS_SUCCESS;
     
    25812581    {
    25822582        PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
    2583         PVBOXWDDM_ALLOCATION pPrimary = pSource->pPrimaryAllocation;
    2584         if (pPrimary && pPrimary->offVram != VBOXVIDEOOFFSET_VOID)
    2585         {
    2586             memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
    2587             notify.InterruptType = DXGK_INTERRUPT_CRTC_VSYNC;
    2588             /* @todo: !!!this is not correct in case we want source[i]->target[i!=j] mapping */
    2589             notify.CrtcVsync.VidPnTargetId = i;
    2590             notify.CrtcVsync.PhysicalAddress.QuadPart = pPrimary->offVram;
    2591             /* yes, we can report VSync at dispatch */
    2592             pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
    2593             bNeedDpc = TRUE;
    2594         }
     2583        PVBOXWDDM_ALLOCATION pPrimary = vboxWddmAquirePrimary(pDevExt, pSource, i);
     2584        if (pPrimary)
     2585        {
     2586            VBOXVIDEOOFFSET offVram = pPrimary->offVram;
     2587            if (offVram != VBOXVIDEOOFFSET_VOID)
     2588            {
     2589                memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
     2590                notify.InterruptType = DXGK_INTERRUPT_CRTC_VSYNC;
     2591                /* @todo: !!!this is not correct in case we want source[i]->target[i!=j] mapping */
     2592                notify.CrtcVsync.VidPnTargetId = i;
     2593                notify.CrtcVsync.PhysicalAddress.QuadPart = pPrimary->offVram;
     2594                /* yes, we can report VSync at dispatch */
     2595                pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
     2596                bNeedDpc = TRUE;
     2597            }
     2598#ifdef DEBUG_misha
     2599            else
     2600                Assert(0);
     2601#endif
     2602            vboxWddmAllocationRelease(pPrimary);
     2603        }
     2604#ifdef DEBUG_misha
     2605        else
     2606            Assert(0);
     2607#endif
    25952608    }
    25962609
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPTypes.h

    r41058 r41638  
    104104    KSPIN_LOCK OverlayListLock;
    105105#endif
     106    KSPIN_LOCK AllocationLock;
    106107    POINT VScreenPos;
    107108    VBOXWDDM_POINTER_INFO PointerInfo;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPVdma.cpp

    r41233 r41638  
    809809            Assert(pFlip->Hdr.fFlags.fVisibleRegions);
    810810            Assert(!pFlip->Hdr.fFlags.fRealOp);
     811            PVBOXWDDM_ALLOCATION pAlloc = pFlip->Flip.Alloc.pAlloc;
     812            VBOXWDDM_SOURCE *pSource = &pDevExt->aSources[pAlloc->SurfDesc.VidPnSourceId];
     813            vboxWddmAssignPrimary(pDevExt, pSource, pAlloc, pAlloc->SurfDesc.VidPnSourceId);
    811814            if (pFlip->Hdr.fFlags.fVisibleRegions)
    812815            {
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.cpp

    r41374 r41638  
    879879        if (RT_SUCCESS(rc))
    880880        {
     881#ifdef VBOX_VDMA_WITH_WATCHDOG
     882            vboxWddmWdInit(pDevExt);
     883#endif
    881884            /* can enable it right away since the host does not need any screen/FB info
    882885             * for basic DMA functionality */
     
    982985    if (RT_SUCCESS(rc))
    983986    {
     987#ifdef VBOX_VDMA_WITH_WATCHDOG
     988        vboxWddmWdTerm(pDevExt);
     989#endif
    984990        rc = vboxVdmaDestroy(pDevExt, &pDevExt->u.primary.Vdma);
    985991        AssertRC(rc);
     
    11151121                    vboxVhwaInit(pDevExt);
    11161122#endif
     1123                    VBoxWddmSlInit(pDevExt);
     1124
     1125                    for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     1126                    {
     1127                        PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
     1128                        KeInitializeSpinLock(&pSource->AllocationLock);
     1129                    }
    11171130                }
    11181131                else
     
    11591172    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)MiniportDeviceContext;
    11601173    NTSTATUS Status = STATUS_SUCCESS;
     1174
     1175    VBoxWddmSlTerm(pDevExt);
    11611176
    11621177    vboxVideoCmTerm(&pDevExt->CmMgr);
     
    14021417        if (pDevExt->bNotifyDxDpc)
    14031418        {
    1404 //            Assert(bNeedDpc == TRUE);
    1405 //            pDevExt->bNotifyDxDpc = TRUE;
    1406 //            pDevExt->bSetNotifyDxDpc = FALSE;
    14071419            bNeedDpc = TRUE;
    14081420        }
     
    14101422        if (bOur)
    14111423        {
     1424#ifdef VBOX_VDMA_WITH_WATCHDOG
     1425            if (flags & HGSMIHOSTFLAGS_WATCHDOG)
     1426            {
     1427                Assert(0);
     1428            }
     1429#endif
     1430            if (flags & HGSMIHOSTFLAGS_VSYNC)
     1431            {
     1432                Assert(0);
     1433                DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
     1434                for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     1435                {
     1436                    PVBOXWDDM_SOURCE pSource = &pDevExt->aSources[i];
     1437                    PVBOXWDDM_ALLOCATION pPrimary = pSource->pPrimaryAllocation;
     1438                    if (pPrimary && pPrimary->offVram != VBOXVIDEOOFFSET_VOID)
     1439                    {
     1440                        memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
     1441                        notify.InterruptType = DXGK_INTERRUPT_CRTC_VSYNC;
     1442                        /* @todo: !!!this is not correct in case we want source[i]->target[i!=j] mapping */
     1443                        notify.CrtcVsync.VidPnTargetId = i;
     1444                        notify.CrtcVsync.PhysicalAddress.QuadPart = pPrimary->offVram;
     1445                        pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
     1446
     1447                        pDevExt->bNotifyDxDpc = TRUE;
     1448                    }
     1449                }
     1450            }
     1451
     1452            if (pDevExt->bNotifyDxDpc)
     1453            {
     1454                bNeedDpc = TRUE;
     1455            }
     1456
    14121457            VBoxHGSMIClearIrq(&VBoxCommonFromDeviceExt(pDevExt)->hostCtx);
    14131458#if 0 //def DEBUG_misha
     
    14931538    Assert(Status == STATUS_SUCCESS);
    14941539
    1495     if (context.data.bNotifyDpc)
    1496         pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
     1540//    if (context.data.bNotifyDpc)
     1541    pDevExt->u.primary.DxgkInterface.DxgkCbNotifyDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
    14971542
    14981543    if (!vboxVtListIsEmpty(&context.data.CtlList))
     
    19371982}
    19381983
    1939 VOID vboxWddmAllocationCleanup(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
     1984VOID vboxWddmAllocationCleanupAssignment(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
    19401985{
    19411986    switch (pAllocation->enmType)
     
    19491994                vboxWddmAssignPrimary(pDevExt, &pDevExt->aSources[pAllocation->SurfDesc.VidPnSourceId], NULL, pAllocation->SurfDesc.VidPnSourceId);
    19501995            }
    1951 
     1996            break;
     1997        }
     1998#ifdef VBOXWDDM_RENDER_FROM_SHADOW
     1999        case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
     2000        {
     2001            if (pAllocation->bAssigned)
     2002            {
     2003                Assert(pAllocation->SurfDesc.VidPnSourceId != D3DDDI_ID_UNINITIALIZED);
     2004                /* @todo: do we need to notify host? */
     2005                vboxWddmAssignShadow(pDevExt, &pDevExt->aSources[pAllocation->SurfDesc.VidPnSourceId], NULL, pAllocation->SurfDesc.VidPnSourceId);
     2006            }
     2007            break;
     2008        }
     2009#endif
     2010        default:
     2011            break;
     2012    }
     2013}
     2014
     2015VOID vboxWddmAllocationCleanup(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_ALLOCATION pAllocation)
     2016{
     2017    switch (pAllocation->enmType)
     2018    {
     2019        case VBOXWDDM_ALLOC_TYPE_STD_SHAREDPRIMARYSURFACE:
     2020        case VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC:
     2021        {
    19522022#if 0
    19532023            if (pAllocation->enmType == VBOXWDDM_ALLOC_TYPE_UMD_RC_GENERIC)
     
    19612031            break;
    19622032        }
    1963 #ifdef VBOXWDDM_RENDER_FROM_SHADOW
    1964         case VBOXWDDM_ALLOC_TYPE_STD_SHADOWSURFACE:
    1965         {
    1966             if (pAllocation->bAssigned)
    1967             {
    1968                 Assert(pAllocation->SurfDesc.VidPnSourceId != D3DDDI_ID_UNINITIALIZED);
    1969                 /* @todo: do we need to notify host? */
    1970                 vboxWddmAssignShadow(pDevExt, &pDevExt->aSources[pAllocation->SurfDesc.VidPnSourceId], NULL, pAllocation->SurfDesc.VidPnSourceId);
    1971             }
    1972             break;
    1973         }
    1974 #endif
    19752033        case VBOXWDDM_ALLOC_TYPE_UMD_HGSMI_BUFFER:
    19762034        {
     
    23102368        PVBOXWDDM_ALLOCATION pAlloc = (PVBOXWDDM_ALLOCATION)pDestroyAllocation->pAllocationList[i];
    23112369        Assert(pAlloc->pResource == pRc);
     2370        vboxWddmAllocationCleanupAssignment(pDevExt, pAlloc);
    23122371        /* wait for all current allocation-related ops are completed */
    23132372        vboxWddmAllocationWaitDereference(pAlloc);
     
    30423101        {
    30433102            VBOXWDDM_DMA_PRIVATEDATA_FLIP *pFlip = (VBOXWDDM_DMA_PRIVATEDATA_FLIP*)pPrivateDataBase;
     3103            vboxWddmAllocUpdateAddress(pFlip->Flip.Alloc.pAlloc, pFlip->Flip.Alloc.segmentIdAlloc, pFlip->Flip.Alloc.offAlloc);
    30443104            PVBOXVDMAPIPE_CMD_DMACMD_FLIP pFlipCmd = (PVBOXVDMAPIPE_CMD_DMACMD_FLIP)vboxVdmaGgCmdCreate(pDevExt,
    30453105                    VBOXVDMAPIPE_CMD_TYPE_DMACMD, sizeof (VBOXVDMAPIPE_CMD_DMACMD_FLIP));
     
    30693129        {
    30703130            PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL pCF = (PVBOXWDDM_DMA_PRIVATEDATA_CLRFILL)pPrivateDataBase;
     3131            vboxWddmAllocUpdateAddress(pCF->ClrFill.Alloc.pAlloc, pCF->ClrFill.Alloc.segmentIdAlloc, pCF->ClrFill.Alloc.offAlloc);
    30713132            PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL pCFCmd = (PVBOXVDMAPIPE_CMD_DMACMD_CLRFILL)vboxVdmaGgCmdCreate(pDevExt,
    30723133                    VBOXVDMAPIPE_CMD_TYPE_DMACMD, RT_OFFSETOF(VBOXVDMAPIPE_CMD_DMACMD_CLRFILL, ClrFill.Rects.aRects[pCF->ClrFill.Rects.cRects]));
     
    48534914    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
    48544915
    4855     Assert((UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays > pGetScanLine->VidPnTargetId);
    4856     VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[pGetScanLine->VidPnTargetId];
    4857     Assert(pTarget->HeightTotal);
    4858     Assert(pTarget->HeightVisible);
    4859     Assert(pTarget->HeightTotal > pTarget->HeightVisible);
    4860     Assert(pTarget->ScanLineState < pTarget->HeightTotal);
    4861     if (pTarget->HeightTotal)
    4862     {
    4863         uint32_t curScanLine = pTarget->ScanLineState;
    4864         ++pTarget->ScanLineState;
    4865         if (pTarget->ScanLineState >= pTarget->HeightTotal)
    4866             pTarget->ScanLineState = 0;
    4867 
    4868 
    4869         BOOL bVBlank = (!curScanLine || curScanLine > pTarget->HeightVisible);
    4870         pGetScanLine->ScanLine = curScanLine;
    4871         pGetScanLine->InVerticalBlank = bVBlank;
    4872     }
    4873     else
    4874     {
    4875         pGetScanLine->InVerticalBlank = TRUE;
    4876         pGetScanLine->ScanLine = 0;
    4877     }
     4916#ifdef DEBUG_misha
     4917    RT_BREAKPOINT();
     4918#endif
     4919
     4920    NTSTATUS Status = VBoxWddmSlGetScanLine(pDevExt, pGetScanLine);
    48784921
    48794922    LOGF(("LEAVE, hAdapter(0x%x)", hAdapter));
    48804923
    4881     return STATUS_SUCCESS;
     4924    return Status;
    48824925}
    48834926
     
    49074950    LOGF(("ENTER, hAdapter(0x%x)", hAdapter));
    49084951
    4909 //    AssertBreakpoint();
     4952    NTSTATUS Status = STATUS_SUCCESS;
     4953    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)hAdapter;
     4954
     4955    switch (InterruptType)
     4956    {
     4957        case DXGK_INTERRUPT_CRTC_VSYNC:
     4958        {
     4959            Status = VBoxWddmSlEnableVSyncNotification(pDevExt, Enable);
     4960            if (!NT_SUCCESS(Status))
     4961                WARN(("VSYNC Interrupt control failed Enable(%d), Status(0x%x)", Enable, Status));
     4962            break;
     4963        }
     4964        case DXGK_INTERRUPT_DMA_COMPLETED:
     4965        case DXGK_INTERRUPT_DMA_PREEMPTED:
     4966        case DXGK_INTERRUPT_DMA_FAULTED:
     4967            WARN(("Unexpected interrupt type! %d", InterruptType));
     4968            break;
     4969        default:
     4970            WARN(("UNSUPPORTED interrupt type! %d", InterruptType));
     4971            break;
     4972    }
    49104973
    49114974    LOGF(("LEAVE, hAdapter(0x%x)", hAdapter));
    49124975
    4913     /* @todo: STATUS_NOT_IMPLEMENTED ?? */
    4914     return STATUS_SUCCESS;
     4976    return Status;
    49154977}
    49164978
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPWddm.h

    r41379 r41638  
    7575}
    7676
     77#ifdef VBOXWDDM_RENDER_FROM_SHADOW
     78DECLINLINE(void) vboxWddmAssignShadow(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_ALLOCATION pAllocation, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
     79{
     80    if (pSource->pShadowAllocation == pAllocation)
     81    {
     82        Assert(pAllocation->bAssigned);
     83        return;
     84    }
     85
     86    if (pSource->pShadowAllocation)
     87    {
     88        PVBOXWDDM_ALLOCATION pOldAlloc = pSource->pShadowAllocation;
     89        /* clear the visibility info fo the current primary */
     90        pOldAlloc->bVisible = FALSE;
     91        pOldAlloc->bAssigned = FALSE;
     92        Assert(pOldAlloc->SurfDesc.VidPnSourceId == srcId);
     93        /* release the shadow surface */
     94        pOldAlloc->SurfDesc.VidPnSourceId = D3DDDI_ID_UNINITIALIZED;
     95    }
     96
     97    if (pAllocation)
     98    {
     99        Assert(!pAllocation->bAssigned);
     100        Assert(!pAllocation->bVisible);
     101        pAllocation->bVisible = FALSE;
     102        /* this check ensures the shadow is not used for other source simultaneously */
     103        Assert(pAllocation->SurfDesc.VidPnSourceId == D3DDDI_ID_UNINITIALIZED);
     104        pAllocation->SurfDesc.VidPnSourceId = srcId;
     105        pAllocation->bAssigned = TRUE;
     106        if (!vboxWddmCmpSurfDescsBase(&pSource->SurfDesc, &pAllocation->SurfDesc))
     107            pSource->offVram = VBOXVIDEOOFFSET_VOID; /* force guest->host notification */
     108        pSource->SurfDesc = pAllocation->SurfDesc;
     109    }
     110
     111    pSource->pShadowAllocation = pAllocation;
     112}
     113#endif
     114
     115DECLINLINE(VOID) vboxWddmAssignPrimary(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, PVBOXWDDM_ALLOCATION pAllocation, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
     116{
     117    /* vboxWddmAssignPrimary can not be run in reentrant order, so safely do a direct unlocked check here */
     118    if (pSource->pPrimaryAllocation == pAllocation)
     119        return;
     120
     121    if (pSource->pPrimaryAllocation)
     122    {
     123        PVBOXWDDM_ALLOCATION pOldAlloc = pSource->pPrimaryAllocation;
     124        /* clear the visibility info fo the current primary */
     125        pOldAlloc->bVisible = FALSE;
     126        pOldAlloc->bAssigned = FALSE;
     127        Assert(pOldAlloc->SurfDesc.VidPnSourceId == srcId);
     128
     129        vboxWddmAllocationRelease(pOldAlloc);
     130    }
     131
     132    if (pAllocation)
     133    {
     134        pAllocation->bVisible = FALSE;
     135        Assert(pAllocation->SurfDesc.VidPnSourceId == srcId);
     136        pAllocation->bAssigned = TRUE;
     137
     138        vboxWddmAllocationRetain(pAllocation);
     139    }
     140
     141    KIRQL OldIrql;
     142    KeAcquireSpinLock(&pSource->AllocationLock, &OldIrql);
     143    pSource->pPrimaryAllocation = pAllocation;
     144    KeReleaseSpinLock(&pSource->AllocationLock, OldIrql);
     145}
     146
     147DECLINLINE(PVBOXWDDM_ALLOCATION) vboxWddmAquirePrimary(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_SOURCE pSource, D3DDDI_VIDEO_PRESENT_SOURCE_ID srcId)
     148{
     149    PVBOXWDDM_ALLOCATION pPrimary;
     150    KIRQL OldIrql;
     151    KeAcquireSpinLock(&pSource->AllocationLock, &OldIrql);
     152    pPrimary = pSource->pPrimaryAllocation;
     153    if (pPrimary)
     154        vboxWddmAllocationRetain(pPrimary);
     155    KeReleaseSpinLock(&pSource->AllocationLock, OldIrql);
     156    return pPrimary;
     157}
     158
    77159
    78160#define VBOXWDDMENTRY_2_SWAPCHAIN(_pE) ((PVBOXWDDM_SWAPCHAIN)((uint8_t*)(_pE) - RT_OFFSETOF(VBOXWDDM_SWAPCHAIN, DevExtListEntry)))
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