VirtualBox

Ignore:
Timestamp:
Jun 9, 2012 12:56:51 PM (13 years ago)
Author:
vboxsync
Message:

wddm: fix win8 halt issues

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/Makefile.kmk

    r41570 r41636  
    9090  VBoxVideoWddm_DEFS      += VBOX_WITH_CROGL
    9191 endif
     92 ifdef VBOX_VDMA_WITH_WATCHDOG
     93  VBoxVideoWddm_DEFS      += VBOX_VDMA_WITH_WATCHDOG
     94 endif
     95 
    9296 VBoxVideoWddm_INCS       += ../../../include .. . ../../../../common/VBoxGuestLib $(VBOX_PATH_CROGL_INCLUDE) $(VBOX_PATH_CROGL_GENFILES)
    9397 VBoxVideoWddm_LDFLAGS.x86 += /Entry:DriverEntry@8
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h

    r41337 r41636  
    116116   BOOL bNotifyDxDpc;
    117117
     118#ifdef VBOX_VDMA_WITH_WATCHDOG
     119   PKTHREAD pWdThread;
     120   KEVENT WdEvent;
     121#endif
     122
     123   KTIMER VSyncTimer;
     124   KDPC VSyncDpc;
     125
    118126#if 0
    119127   FAST_MUTEX ShRcTreeMutex;
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp

    r41379 r41636  
    23652365    return Status;
    23662366}
     2367
     2368NTSTATUS vboxWddmThreadCreate(PKTHREAD * ppThread, PKSTART_ROUTINE pStartRoutine, PVOID pStartContext)
     2369{
     2370    NTSTATUS fStatus;
     2371    HANDLE hThread;
     2372    OBJECT_ATTRIBUTES fObjectAttributes;
     2373
     2374    Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
     2375
     2376    InitializeObjectAttributes(&fObjectAttributes, NULL, OBJ_KERNEL_HANDLE,
     2377                        NULL, NULL);
     2378
     2379    fStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS,
     2380                        &fObjectAttributes, NULL, NULL,
     2381                        (PKSTART_ROUTINE) pStartRoutine, pStartContext);
     2382    if (!NT_SUCCESS(fStatus))
     2383      return fStatus;
     2384
     2385    ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL,
     2386                        KernelMode, (PVOID*) ppThread, NULL);
     2387    ZwClose(hThread);
     2388    return STATUS_SUCCESS;
     2389}
     2390
     2391#ifdef VBOX_VDMA_WITH_WATCHDOG
     2392static int vboxWddmWdProgram(PVBOXMP_DEVEXT pDevExt, uint32_t cMillis)
     2393{
     2394    int rc = VINF_SUCCESS;
     2395    PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMICommandAlloc(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, sizeof (VBOXVDMA_CTL), HGSMI_CH_VBVA, VBVA_VDMA_CTL);
     2396    if (pCmd)
     2397    {
     2398        pCmd->enmCtl = VBOXVDMA_CTL_TYPE_WATCHDOG;
     2399        pCmd->u32Offset = cMillis;
     2400        pCmd->i32Result = VERR_NOT_SUPPORTED;
     2401
     2402        const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepSynch(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pCmd);
     2403        Assert(pHdr);
     2404        if (pHdr)
     2405        {
     2406            do
     2407            {
     2408                HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pHdr);
     2409                Assert(offCmd != HGSMIOFFSET_VOID);
     2410                if (offCmd != HGSMIOFFSET_VOID)
     2411                {
     2412                    VBoxVideoCmnPortWriteUlong(VBoxCommonFromDeviceExt(pDevExt)->guestCtx.port, offCmd);
     2413                    rc = VBoxSHGSMICommandDoneSynch(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pHdr);
     2414                    AssertRC(rc);
     2415                    if (RT_SUCCESS(rc))
     2416                    {
     2417                        rc = pCmd->i32Result;
     2418                        AssertRC(rc);
     2419                    }
     2420                    break;
     2421                }
     2422                else
     2423                    rc = VERR_INVALID_PARAMETER;
     2424                /* fail to submit, cancel it */
     2425                VBoxSHGSMICommandCancelSynch(&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pHdr);
     2426            } while (0);
     2427        }
     2428
     2429        VBoxSHGSMICommandFree (&VBoxCommonFromDeviceExt(pDevExt)->guestCtx.heapCtx, pCmd);
     2430    }
     2431    else
     2432    {
     2433        LOGREL(("HGSMIHeapAlloc failed"));
     2434        rc = VERR_OUT_OF_RESOURCES;
     2435    }
     2436    return rc;
     2437}
     2438
     2439static uint32_t g_VBoxWdTimeout = 4000;
     2440/* if null g_VBoxWdTimeout / 2 is used */
     2441static uint32_t g_VBoxWdTimerPeriod = 0;
     2442
     2443static VOID vboxWddmWdThread(PVOID pvUser)
     2444{
     2445    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)pvUser;
     2446    BOOLEAN bExit = FALSE;
     2447    int rc;
     2448    while (1)
     2449    {
     2450        if (!bExit)
     2451        {
     2452            rc = vboxWddmWdProgram(pDevExt, g_VBoxWdTimeout /* ms */);
     2453            AssertRC(rc);
     2454        }
     2455        else
     2456        {
     2457            rc = vboxWddmWdProgram(pDevExt, 0 /* to disable WatchDog */);
     2458            AssertRC(rc);
     2459            break;
     2460        }
     2461        LARGE_INTEGER Timeout;
     2462        uint32_t timerTimeOut = g_VBoxWdTimerPeriod ? g_VBoxWdTimerPeriod : g_VBoxWdTimeout / 2;
     2463        Timeout.QuadPart = 10000ULL * timerTimeOut /* ms */;
     2464        NTSTATUS Status = KeWaitForSingleObject(&pDevExt->WdEvent, Executive, KernelMode, FALSE, &Timeout);
     2465        if (Status != STATUS_TIMEOUT)
     2466            bExit = TRUE;
     2467    }
     2468}
     2469
     2470NTSTATUS vboxWddmWdInit(PVBOXMP_DEVEXT pDevExt)
     2471{
     2472    KeInitializeEvent(&pDevExt->WdEvent, NotificationEvent, FALSE);
     2473
     2474    NTSTATUS Status = vboxWddmThreadCreate(&pDevExt->pWdThread, vboxWddmWdThread, pDevExt);
     2475    if (!NT_SUCCESS(Status))
     2476    {
     2477        WARN(("vboxWddmThreadCreate failed, Status 0x%x", Status));
     2478        pDevExt->pWdThread = NULL;
     2479    }
     2480    return Status;
     2481}
     2482
     2483NTSTATUS vboxWddmWdTerm(PVBOXMP_DEVEXT pDevExt)
     2484{
     2485    if (!pDevExt->pWdThread)
     2486        return STATUS_SUCCESS;
     2487
     2488    KeSetEvent(&pDevExt->WdEvent, 0, FALSE);
     2489
     2490    KeWaitForSingleObject(pDevExt->pWdThread, Executive, KernelMode, FALSE, NULL);
     2491    ObDereferenceObject(pDevExt->pWdThread);
     2492    pDevExt->pWdThread = NULL;
     2493    return STATUS_SUCCESS;
     2494}
     2495#endif
     2496
     2497static int vboxWddmSlConfigure(PVBOXMP_DEVEXT pDevExt, uint32_t fFlags)
     2498{
     2499    PHGSMIGUESTCOMMANDCONTEXT pCtx = &VBoxCommonFromDeviceExt(pDevExt)->guestCtx;
     2500    VBVASCANLINECFG *pCfg;
     2501    int rc = VINF_SUCCESS;
     2502
     2503    /* Allocate the IO buffer. */
     2504    pCfg = (VBVASCANLINECFG *)VBoxHGSMIBufferAlloc(pCtx,
     2505                                       sizeof (VBVASCANLINECFG), HGSMI_CH_VBVA,
     2506                                       VBVA_SCANLINE_CFG);
     2507
     2508    if (pCfg)
     2509    {
     2510        /* Prepare data to be sent to the host. */
     2511        pCfg->rc    = VERR_NOT_IMPLEMENTED;
     2512        pCfg->fFlags = fFlags;
     2513        rc = VBoxHGSMIBufferSubmit(pCtx, pCfg);
     2514        if (RT_SUCCESS(rc))
     2515        {
     2516            AssertRC(pCfg->rc);
     2517            rc = pCfg->rc;
     2518        }
     2519        /* Free the IO buffer. */
     2520        VBoxHGSMIBufferFree(pCtx, pCfg);
     2521    }
     2522    else
     2523        rc = VERR_NO_MEMORY;
     2524    return rc;
     2525}
     2526
     2527NTSTATUS VBoxWddmSlEnableVSyncNotification(PVBOXMP_DEVEXT pDevExt, BOOLEAN fEnable)
     2528{
     2529    if (!fEnable)
     2530    {
     2531        KeCancelTimer(&pDevExt->VSyncTimer);
     2532    }
     2533    else
     2534    {
     2535        LARGE_INTEGER DueTime;
     2536        DueTime.QuadPart = -166666LL; /* 60 Hz */
     2537        KeSetTimerEx(&pDevExt->VSyncTimer, DueTime, 17, &pDevExt->VSyncDpc);
     2538    }
     2539    return STATUS_SUCCESS;
     2540}
     2541
     2542NTSTATUS VBoxWddmSlGetScanLine(PVBOXMP_DEVEXT pDevExt, DXGKARG_GETSCANLINE *pGetScanLine)
     2543{
     2544    Assert((UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays > pGetScanLine->VidPnTargetId);
     2545    VBOXWDDM_TARGET *pTarget = &pDevExt->aTargets[pGetScanLine->VidPnTargetId];
     2546    Assert(pTarget->HeightTotal);
     2547    Assert(pTarget->HeightVisible);
     2548    Assert(pTarget->HeightTotal > pTarget->HeightVisible);
     2549    Assert(pTarget->ScanLineState < pTarget->HeightTotal);
     2550    if (pTarget->HeightTotal)
     2551    {
     2552        uint32_t curScanLine = pTarget->ScanLineState;
     2553        ++pTarget->ScanLineState;
     2554        if (pTarget->ScanLineState >= pTarget->HeightTotal)
     2555            pTarget->ScanLineState = 0;
     2556
     2557
     2558        BOOL bVBlank = (!curScanLine || curScanLine > pTarget->HeightVisible);
     2559        pGetScanLine->ScanLine = curScanLine;
     2560        pGetScanLine->InVerticalBlank = bVBlank;
     2561    }
     2562    else
     2563    {
     2564        pGetScanLine->InVerticalBlank = TRUE;
     2565        pGetScanLine->ScanLine = 0;
     2566    }
     2567    return STATUS_SUCCESS;
     2568}
     2569
     2570static VOID vboxWddmSlVSyncDpc(
     2571  __in      struct _KDPC *Dpc,
     2572  __in_opt  PVOID DeferredContext,
     2573  __in_opt  PVOID SystemArgument1,
     2574  __in_opt  PVOID SystemArgument2
     2575)
     2576{
     2577    PVBOXMP_DEVEXT pDevExt = (PVBOXMP_DEVEXT)DeferredContext;
     2578    DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
     2579    BOOLEAN bNeedDpc = FALSE;
     2580    for (UINT i = 0; i < (UINT)VBoxCommonFromDeviceExt(pDevExt)->cDisplays; ++i)
     2581    {
     2582        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        }
     2595    }
     2596
     2597    if (bNeedDpc)
     2598    {
     2599        pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle);
     2600    }
     2601}
     2602
     2603NTSTATUS VBoxWddmSlInit(PVBOXMP_DEVEXT pDevExt)
     2604{
     2605    KeInitializeTimer(&pDevExt->VSyncTimer);
     2606    KeInitializeDpc(&pDevExt->VSyncDpc, vboxWddmSlVSyncDpc, pDevExt);
     2607    return STATUS_SUCCESS;
     2608}
     2609
     2610NTSTATUS VBoxWddmSlTerm(PVBOXMP_DEVEXT pDevExt)
     2611{
     2612    KeCancelTimer(&pDevExt->VSyncTimer);
     2613    return STATUS_SUCCESS;
     2614}
  • trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.h

    r41379 r41636  
    200200NTSTATUS vboxWddmDrvCfgInit(PUNICODE_STRING pRegStr);
    201201
     202#ifdef VBOX_VDMA_WITH_WATCHDOG
     203NTSTATUS vboxWddmWdInit(PVBOXMP_DEVEXT pDevExt);
     204NTSTATUS vboxWddmWdTerm(PVBOXMP_DEVEXT pDevExt);
     205#endif
     206
     207NTSTATUS VBoxWddmSlEnableVSyncNotification(PVBOXMP_DEVEXT pDevExt, BOOLEAN fEnable);
     208NTSTATUS VBoxWddmSlGetScanLine(PVBOXMP_DEVEXT pDevExt, DXGKARG_GETSCANLINE *pSl);
     209NTSTATUS VBoxWddmSlInit(PVBOXMP_DEVEXT pDevExt);
     210NTSTATUS VBoxWddmSlTerm(PVBOXMP_DEVEXT pDevExt);
     211
    202212#endif /* #ifndef ___VBoxMPMisc_h__ */
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