Changeset 41636 in vbox for trunk/src/VBox/Additions/WINNT/Graphics/Video
- Timestamp:
- Jun 9, 2012 12:56:51 PM (13 years ago)
- 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 90 90 VBoxVideoWddm_DEFS += VBOX_WITH_CROGL 91 91 endif 92 ifdef VBOX_VDMA_WITH_WATCHDOG 93 VBoxVideoWddm_DEFS += VBOX_VDMA_WITH_WATCHDOG 94 endif 95 92 96 VBoxVideoWddm_INCS += ../../../include .. . ../../../../common/VBoxGuestLib $(VBOX_PATH_CROGL_INCLUDE) $(VBOX_PATH_CROGL_GENFILES) 93 97 VBoxVideoWddm_LDFLAGS.x86 += /Entry:DriverEntry@8 -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/common/VBoxMPDevExt.h
r41337 r41636 116 116 BOOL bNotifyDxDpc; 117 117 118 #ifdef VBOX_VDMA_WITH_WATCHDOG 119 PKTHREAD pWdThread; 120 KEVENT WdEvent; 121 #endif 122 123 KTIMER VSyncTimer; 124 KDPC VSyncDpc; 125 118 126 #if 0 119 127 FAST_MUTEX ShRcTreeMutex; -
trunk/src/VBox/Additions/WINNT/Graphics/Video/mp/wddm/VBoxMPMisc.cpp
r41379 r41636 2365 2365 return Status; 2366 2366 } 2367 2368 NTSTATUS 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 2392 static 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 2439 static uint32_t g_VBoxWdTimeout = 4000; 2440 /* if null g_VBoxWdTimeout / 2 is used */ 2441 static uint32_t g_VBoxWdTimerPeriod = 0; 2442 2443 static 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 2470 NTSTATUS 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 2483 NTSTATUS 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 2497 static 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 2527 NTSTATUS 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 2542 NTSTATUS 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 2570 static 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(¬ify, 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, ¬ify); 2593 bNeedDpc = TRUE; 2594 } 2595 } 2596 2597 if (bNeedDpc) 2598 { 2599 pDevExt->u.primary.DxgkInterface.DxgkCbQueueDpc(pDevExt->u.primary.DxgkInterface.DeviceHandle); 2600 } 2601 } 2602 2603 NTSTATUS VBoxWddmSlInit(PVBOXMP_DEVEXT pDevExt) 2604 { 2605 KeInitializeTimer(&pDevExt->VSyncTimer); 2606 KeInitializeDpc(&pDevExt->VSyncDpc, vboxWddmSlVSyncDpc, pDevExt); 2607 return STATUS_SUCCESS; 2608 } 2609 2610 NTSTATUS 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 200 200 NTSTATUS vboxWddmDrvCfgInit(PUNICODE_STRING pRegStr); 201 201 202 #ifdef VBOX_VDMA_WITH_WATCHDOG 203 NTSTATUS vboxWddmWdInit(PVBOXMP_DEVEXT pDevExt); 204 NTSTATUS vboxWddmWdTerm(PVBOXMP_DEVEXT pDevExt); 205 #endif 206 207 NTSTATUS VBoxWddmSlEnableVSyncNotification(PVBOXMP_DEVEXT pDevExt, BOOLEAN fEnable); 208 NTSTATUS VBoxWddmSlGetScanLine(PVBOXMP_DEVEXT pDevExt, DXGKARG_GETSCANLINE *pSl); 209 NTSTATUS VBoxWddmSlInit(PVBOXMP_DEVEXT pDevExt); 210 NTSTATUS VBoxWddmSlTerm(PVBOXMP_DEVEXT pDevExt); 211 202 212 #endif /* #ifndef ___VBoxMPMisc_h__ */
Note:
See TracChangeset
for help on using the changeset viewer.