In case the driver supports VSync control feature the driver maintains timer for VSync interrupt indication. In further commits this timer can be started upon class driver request. Signed-off-by: Yuri Benditovich <yuri.benditovich@xxxxxxxxxx> --- qxldod/QxlDod.cpp | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ qxldod/QxlDod.h | 7 ++++++ 2 files changed, 71 insertions(+) diff --git a/qxldod/QxlDod.cpp b/qxldod/QxlDod.cpp index c956fd5..78d4340 100755 --- a/qxldod/QxlDod.cpp +++ b/qxldod/QxlDod.cpp @@ -82,6 +82,12 @@ QxlDod::QxlDod(_In_ DEVICE_OBJECT* pPhysicalDeviceObject) : m_pPhysicalDevice(pP RtlZeroMemory(m_CurrentModes, sizeof(m_CurrentModes)); RtlZeroMemory(&m_PointerShape, sizeof(m_PointerShape)); m_pHWDevice = NULL; + + KeInitializeDpc(&m_VsyncTimerDpc, VsyncTimerProcGate, this); + KeInitializeTimer(&m_VsyncTimer); + m_VsyncFiredCounter = 0; + m_bVsyncEnabled = FALSE; + DbgPrint(TRACE_LEVEL_INFORMATION, ("<--- %s\n", __FUNCTION__)); } @@ -198,6 +204,7 @@ NTSTATUS QxlDod::StopDevice(VOID) { PAGED_CODE(); m_Flags.DriverStarted = FALSE; + EnableVsync(FALSE); return STATUS_SUCCESS; } @@ -462,6 +469,7 @@ NTSTATUS QxlDod::QueryAdapterInfo(_In_ CONST DXGKARG_QUERYADAPTERINFO* pQueryAda pDriverCaps->PointerCaps.Color = 1; pDriverCaps->SupportNonVGA = m_pHWDevice->IsBIOSCompatible(); + pDriverCaps->SchedulingCaps.VSyncPowerSaveAware = g_bSupportVSync; DbgPrint(TRACE_LEVEL_VERBOSE, ("<--- %s 1\n", __FUNCTION__)); return STATUS_SUCCESS; @@ -4889,3 +4897,59 @@ NTSTATUS HwDeviceInterface::AcquireDisplayInfo(DXGK_DISPLAY_INFORMATION& DispInf } return Status; } + +QXL_NON_PAGED static BOOLEAN VSynchRoutine(PVOID context) +{ + DXGKRNL_INTERFACE *pxface = (DXGKRNL_INTERFACE *)context; + DXGKARGCB_NOTIFY_INTERRUPT_DATA data = {}; + data.InterruptType = DXGK_INTERRUPT_DISPLAYONLY_VSYNC; + pxface->DxgkCbNotifyInterrupt(pxface->DeviceHandle, &data); + pxface->DxgkCbQueueDpc(pxface->DeviceHandle); + return 0; +} + +QXL_NON_PAGED VOID QxlDod::VsyncTimerProc() +{ + BOOLEAN bDummy; + DbgPrint(TRACE_LEVEL_VERBOSE, ("<--- %s\n", __FUNCTION__)); + if (m_bVsyncEnabled && m_AdapterPowerState == PowerDeviceD0) + { + m_DxgkInterface.DxgkCbSynchronizeExecution( + m_DxgkInterface.DeviceHandle, + VSynchRoutine, + &m_DxgkInterface, + 0, + &bDummy + ); + InterlockedIncrement(&m_VsyncFiredCounter); + } +} + +VOID QxlDod::EnableVsync(BOOLEAN bEnable) +{ + PAGED_CODE(); + if (g_bSupportVSync) + { + m_bVsyncEnabled = bEnable; + if (!m_bVsyncEnabled) + { + LONG counter = InterlockedExchange(&m_VsyncFiredCounter, 0); + DbgPrint(TRACE_LEVEL_WARNING, ("Disabled VSync(fired %d)\n", counter)); + KeCancelTimer(&m_VsyncTimer); + } + else + { + LARGE_INTEGER li; + LONG period = 1000 / VSYNC_RATE; + DbgPrint(TRACE_LEVEL_WARNING, ("Enabled VSync(fired %d)\n", m_VsyncFiredCounter)); + li.QuadPart = -10000000 / VSYNC_RATE; + KeSetTimerEx(&m_VsyncTimer, li, period, &m_VsyncTimerDpc); + } + } +} + +QXL_NON_PAGED VOID QxlDod::VsyncTimerProcGate(_In_ _KDPC *dpc, _In_ PVOID context, _In_ PVOID arg1, _In_ PVOID arg2) +{ + QxlDod* pQxl = reinterpret_cast<QxlDod*>(context); + pQxl->VsyncTimerProc(); +} diff --git a/qxldod/QxlDod.h b/qxldod/QxlDod.h index 4598718..005aaed 100755 --- a/qxldod/QxlDod.h +++ b/qxldod/QxlDod.h @@ -624,6 +624,10 @@ private: DXGKARG_SETPOINTERSHAPE m_PointerShape; HwDeviceInterface* m_pHWDevice; + KTIMER m_VsyncTimer; + KDPC m_VsyncTimerDpc; + BOOLEAN m_bVsyncEnabled; + LONG m_VsyncFiredCounter; public: QxlDod(_In_ DEVICE_OBJECT* pPhysicalDeviceObject); ~QxlDod(void); @@ -721,6 +725,7 @@ public: { return m_DxgkInterface.DxgkCbAcquirePostDisplayOwnership(m_DxgkInterface.DeviceHandle, &DispInfo); } + VOID EnableVsync(BOOLEAN bEnable); private: VOID CleanUp(VOID); NTSTATUS CheckHardware(); @@ -746,6 +751,8 @@ private: NTSTATUS IsVidPnSourceModeFieldsValid(CONST D3DKMDT_VIDPN_SOURCE_MODE* pSourceMode) const; NTSTATUS IsVidPnPathFieldsValid(CONST D3DKMDT_VIDPN_PRESENT_PATH* pPath) const; NTSTATUS RegisterHWInfo(_In_ ULONG Id); + QXL_NON_PAGED VOID VsyncTimerProc(); + static QXL_NON_PAGED VOID VsyncTimerProcGate(_In_ _KDPC *dpc, _In_ PVOID context, _In_ PVOID arg1, _In_ PVOID arg2); }; NTSTATUS -- 2.7.0.windows.1 _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel