Ответ 1
Извините за поздний ответ, но я заметил, что до сих пор нет принятого ответа, поэтому, возможно, вы не нашли того, что сработало. В настоящее время в Windows служба DesktopWindowManager (dwm.exe) координирует все и не может быть обойдена. Начиная с Windows 8, эта служба не может быть отключена.
Итак, DWM всегда будет управлять частотой кадров, отображать управление очередью и окончательную композицию для всех различных IDXGISurface (n) объекты и IDXGIOutput (n) контролирует, и, если я не пропущу что-то, использование отслеживания VSync очень мало, если ваша цель рендеринга закадровый. Что касается вашего вопроса, я не был уверен, была ли ваша цель:
- получить чрезвычайно точную информацию о времени, но только для диагностики, профилирования или использования информации или
- было ли приложение затем (пытаться) использовать эти результаты для (планировать) расписание своих текущих циклов.
Если это последнее, я считаю, что вы можете эффективно это сделать только в том случае, если приложение D3D работает в режиме полноэкранного эксклюзивного. Единственный случай, когда DWM - под видом DXGI - по-настоящему доверяет клиенту обрабатывать свои собственные Present
время.
Хорошая новость заключается в том, что вы можете получить все данные синхронизации, которые вы когда-либо хотели, и в разрешение QueryPerformanceFrequency, которое обычно вокруг 320 нс. Как вы, наверное, знаете, разрешение QPC является фактором в 20 000 000 (да, двадцать миллионов) улучшений по сравнению с тиком DateTime
, несмотря на предположение о его 100 нс. span (DateTime.Now.Ticks
имеет в основном идентичное разрешение для миллисекунды Environment.TickCount
).
Здесь, как получить информацию о времени видео с высоким разрешением:
Задает информацию о времени составления списка Desktop Window Manager (DWM). Используется функцией DwmGetCompositionTimingInfo.
typedef struct _DWM_TIMING_INFO
{
UINT32 cbSize; // size of this DWM_TIMING_INFO structure
URATIO rateRefresh; // monitor refresh rate
QPC_TIME qpcRefreshPeriod; // monitor refresh period
URATIO rateCompose; // composition rate
QPC_TIME qpcVBlank; // query performance counter value before the vertical blank
CFRAMES cRefresh; // DWM refresh counter
UINT cDXRefresh; // DirectX refresh counter
QPC_TIME qpcCompose; // query performance counter value for a frame composition
CFRAMES cFrame; // frame number that was composed at qpcCompose
UINT cDXPresent; // DirectX present number used to identify rendering frames
CFRAMES cRefreshFrame; // refresh count of the frame that was composed at qpcCompose
CFRAMES cFrameSubmitted; // DWM frame number that was last submitted
UINT cDXPresentSubmitted; // DirectX present number that was last submitted
CFRAMES cFrameConfirmed; // DWM frame number that was last confirmed as presented
UINT cDXPresentConfirmed; // DirectX present number that was last confirmed as presented
CFRAMES cRefreshConfirmed; // target refresh count of the last frame confirmed as completed by the GPU
UINT cDXRefreshConfirmed; // DirectX refresh count when the frame was confirmed as presented
CFRAMES cFramesLate; // number of frames the DWM presented late
UINT cFramesOutstanding; // number of composition frames that have been issued but have not been confirmed as completed
CFRAMES cFrameDisplayed; // last frame displayed
QPC_TIME qpcFrameDisplayed; // QPC time of the composition pass when the frame was displayed
CFRAMES cRefreshFrameDisplayed; // vertical refresh count when the frame should have become visible
CFRAMES cFrameComplete; // ID of the last frame marked as completed
QPC_TIME qpcFrameComplete; // QPC time when the last frame was marked as completed
CFRAMES cFramePending; // ID of the last frame marked as pending
QPC_TIME qpcFramePending; // QPC time when the last frame was marked as pending
CFRAMES cFramesDisplayed; // number of unique frames displayed
CFRAMES cFramesComplete; // number of new completed frames that have been received
CFRAMES cFramesPending; // number of new frames submitted to DirectX but not yet completed
CFRAMES cFramesAvailable; // number of frames available but not displayed, used, or dropped
CFRAMES cFramesDropped; // number of rendered frames that were never displayed because composition occurred too late
CFRAMES cFramesMissed; // number of times an old frame was composed when a new frame should have been used but was not available
CFRAMES cRefreshNextDisplayed; // frame count at which the next frame is scheduled to be displayed
CFRAMES cRefreshNextPresented; // frame count at which the next DirectX present is scheduled to be displayed
CFRAMES cRefreshesDisplayed; // total number of refreshes that have been displayed for the application since the DwmSetPresentParameters function was last called
CFRAMES cRefreshesPresented; // total number of refreshes that have been presented by the application since DwmSetPresentParameters was last called
CFRAMES cRefreshStarted; // refresh number when content for this window started to be displayed
ULONGLONG cPixelsReceived; // total number of pixels DirectX redirected to the DWM
ULONGLONG cPixelsDrawn; // number of pixels drawn
CFRAMES cBuffersEmpty; // number of empty buffers in the flip chain
}
DWM_TIMING_INFO;
(Примечание. Чтобы горизонтально сжать приведенный выше исходный код для отображения на этом веб-сайте, предположим, что следующие аббревиатуры добавлены:)
typedef UNSIGNED_RATIO URATIO;
typedef DWM_FRAME_COUNT DWMFC;
typedef QPC_TIME QPCT;
Теперь для приложений, работающих в оконном режиме, вы можете, конечно, получить эту подробную информацию так часто, как вам нравится. Если вам это нужно только для пассивного профилирования, то получение данных из DwmGetCompositionTimingInfo - это современный способ сделать это.
И говоря о современном, поскольку вопрос, намеченный на модернизацию, вы захотите рассмотреть возможность использования IDXGISwapChain1, полученного из IDXGIFactory2:: CreateSwapChainForComposition, чтобы включить использование нового компонента DirectComposition.
DirectComposition обеспечивает богатые и текучие переходы путем достижения высокой частоты кадров, использования графического оборудования и работы независимо от потока пользовательского интерфейса. DirectComposition может принимать содержимое растрового изображения, нарисованное различными библиотеками рендеринга, включая растровые изображения Microsoft DirectX, и растровые изображения, отображаемые в окне (растровые изображения HWND). Кроме того, DirectComposition поддерживает множество преобразований, таких как 2D аффинные преобразования и 3D-перспективы, а также основные эффекты, такие как отсечение и непрозрачность.
В любом случае представляется менее вероятным, что подробная информация о сроках может с пользой информировать поведение среды выполнения приложения; может быть, это поможет вам предсказать ваш следующий VSync, но кто-то задается вопросом, какое значение имеет "повышенная осведомленность о периоде гашения", для какой-то определенной DWM-покоренной вне сети подкачки.
Поскольку ваша поверхность приложения является лишь одним из многих, которые DWM жонглирует, DWM будет делать все виды своей собственной динамической адаптации, при условии, что каждый клиент будет вести себя последовательно. Непредсказуемые адаптации несовместимы в таком режиме и, скорее всего, просто в конечном итоге нарушают обе стороны.