Разрыв с VSYNC только в полноэкранном режиме (оконный режим работает нормально) в Windows 10 / DirectX

Я думаю, что мое приложение DirectX 11 отлично работало на предыдущей системе (я уверен примерно на 70%). Но теперь в Windows 10 (ноутбук) проблема с разрывом только в полноэкранном режиме (в оконном режиме разрыва нет).

Сцена довольно «тяжелая» (предполагается, что она будет протестирована на производительность для моего приложения). Когда DirectX рендерит более «тяжелые» части, на короткое время частота кадров снижается примерно до 50 кадров в секунду (мои измерения могут быть немного неточными), а затем возвращается к 60-61 кадрам в секунду. Что странно, я не вижу разрывов в "более тяжелых" частях (около 50фпс).

Я слышал, что это может быть как-то связано с DWM, который обеспечивает свою синхронизацию для оконных приложений (поэтому моя программа отлично работает в оконном режиме?).

Что я могу с этим сделать?

Цепочка обмена:

DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = numerator;
sd.BufferDesc.RefreshRate.Denominator = denominator;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = *hwnd;
sd.SampleDesc.Count = sampleCount; //1 (and 0 for quality) to turn off multisampling
sd.SampleDesc.Quality = maxQualityLevel;
sd.Windowed = fullScreen ? FALSE : TRUE;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; //allow full-screen switchin

// Set the scan line ordering and scaling to unspecified.
sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
// Discard the back buffer contents after presenting.
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

Где numerator и denominator рассчитываются на основе этого руководства:

...
numerator = displayModeList[i].RefreshRate.Numerator;
denominator = displayModeList[i].RefreshRate.Denominator;

Который возвращает два очень высоких значения, которые дают около 60 при делении друг на друга (получу ли я тот же эффект, просто установив их в 60 и 1?):

введите здесь описание изображения

Я также визуализирую с помощью:

if(VSYNC){
    swapChain->Present(1, 0); //lock to screen refresh rate
}else{
    swapChain->Present(0, 0); //present as fast as possible
}

Я что-то пропустил? Или я что-то не так сделал?


person PolGraphic    schedule 01.08.2015    source источник
comment
Вы пытались обнулить числитель и знаменатель? Затем DXGI автоматически рассчитает нужные значения. (msdn.microsoft.com/ en-us/library/windows/desktop/) Ссылка также объясняет, почему 60/1 не следует жестко кодировать (может привести к проблемам на некоторых системах).   -  person Gnietschow    schedule 02.08.2015
comment
@Gnietschow Я почти уверен, что не использую DXGI (насколько мне известно, я использую только DirectX 11 в своем приложении на С++, без DXGI, который является дополнительной оболочкой для некоторых задач, но, возможно, я ошибаюсь). В любом случае, спасибо за ссылку. Теперь я знаю, почему бы не жестко закодировать 60/1, но почему мой подход к его вычислению вызывает проблемы? Я предпочитаю не начинать использовать DXGI только для получения значений числителя/знаменателя (сложности и т. д.).   -  person PolGraphic    schedule 02.08.2015
comment
DXGI — это API, который обрабатывает цепочку обмена и перечисление устройств для Windows Vista+ и явно используется с Direct3D 10, 11 и 12. Вам следует прочитать эту статью.   -  person Chuck Walbourn    schedule 03.08.2015
comment
Я думаю, вы путаете DXGI с вспомогательными методами D3DX. Как сказал Чак Уолборн, вы уже используете DXGI, потому что это мета-API для всех связанных с графикой API-интерфейсов в окнах, таких как Direct3D, Direct2D, DirectWrite и т. д.   -  person Gnietschow    schedule 05.08.2015
comment
@Gnietschow Действительно, ты прав. И установка значений 0/0 делает свое дело - можете ли вы дать ответ из своего комментария? В любом случае, почему мой метод получения этих значений (тот, который был взят из учебника) меня не устраивает?   -  person PolGraphic    schedule 05.08.2015
comment
К сожалению, я понятия не имею. Я также пытался получить частоту обновления адаптера, но он не работал должным образом, пока я не использовал автоматический 0/0. Может кто просветит нас :)   -  person Gnietschow    schedule 10.08.2015
comment
Синхронизация с произвольной частотой кадров устройства отображения (Vsync) – это базовая функция компьютерной графики, которая должна легко поддерживаться и обеспечиваться всеми API и фреймворками на всех платформах, использующих любые язык для разработки, а также должен быть по умолчанию. Мы не эволюционировали, и это безумие. Все это означает, что я сочувствую, а также задаюсь вопросом, как мы дошли до этого момента.   -  person Henrik Erlandsson    schedule 09.09.2017
comment
Vsync был понят в 1960-х годах, использовался в 1970-х, в 1981 году мы свернули не туда, и люди, не занимающиеся компьютерной графикой, делали видеокарты, в 90-х аналоговые дисплеи все еще держались, и был возврат до DVI и далее, где этого, по-видимому, нет. снова понимается как основная функция. На этом мой исторический обзор заканчивается, обещаю.   -  person Henrik Erlandsson    schedule 09.09.2017


Ответы (1)


Мой комментарий в качестве ответа:

Вы пытались обнулить числитель и знаменатель? Затем DXGI автоматически рассчитает нужные значения. (документ) ссылка также объясняет, почему 60/1 не следует жестко кодировать (может привести к проблемам на некоторых системах).

person Gnietschow    schedule 09.08.2015