1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-15 07:29:17 +01:00

[d3d11] Don't present if the presenter has no swap chain.

Also fixes DXGI_PRESENT_TEST handling for zero-sized windows.
This commit is contained in:
Philip Rebohle 2019-12-15 11:33:17 +01:00
parent 2d0c9127f3
commit aa40decc23
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 46 additions and 31 deletions

View File

@ -208,11 +208,25 @@ namespace dxvk {
if (m_presenter == nullptr)
CreatePresenter();
HRESULT hr = S_OK;
if (!m_presenter->hasSwapChain()) {
RecreateSwapChain(vsync);
m_dirty = false;
}
if (!m_presenter->hasSwapChain())
hr = DXGI_STATUS_OCCLUDED;
if (m_device->getDeviceStatus() != VK_SUCCESS)
hr = DXGI_ERROR_DEVICE_RESET;
if ((PresentFlags & DXGI_PRESENT_TEST) || hr != S_OK)
return hr;
if (std::exchange(m_dirty, false))
RecreateSwapChain(vsync);
HRESULT hr = S_OK;
try {
PresentImage(SyncInterval);
} catch (const DxvkError& e) {
@ -220,14 +234,11 @@ namespace dxvk {
hr = E_FAIL;
}
if (m_device->getDeviceStatus() != VK_SUCCESS)
hr = DXGI_ERROR_DEVICE_RESET;
return hr;
}
void D3D11SwapChain::PresentImage(UINT SyncInterval) {
HRESULT D3D11SwapChain::PresentImage(UINT SyncInterval) {
Com<ID3D11DeviceContext> deviceContext = nullptr;
m_parent->GetImmediateContext(&deviceContext);
@ -242,11 +253,36 @@ namespace dxvk {
for (uint32_t i = 0; i < SyncInterval || i < 1; i++) {
SynchronizePresent();
if (!m_presenter->hasSwapChain())
return DXGI_STATUS_OCCLUDED;
// Presentation semaphores and WSI swap chain image
vk::PresenterInfo info = m_presenter->info();
vk::PresenterSync sync = m_presenter->getSyncSemaphores();
uint32_t imageIndex = 0;
VkResult status = m_presenter->acquireNextImage(
sync.acquire, VK_NULL_HANDLE, imageIndex);
while (status != VK_SUCCESS && status != VK_SUBOPTIMAL_KHR) {
RecreateSwapChain(m_vsync);
if (!m_presenter->hasSwapChain())
return DXGI_STATUS_OCCLUDED;
info = m_presenter->info();
sync = m_presenter->getSyncSemaphores();
status = m_presenter->acquireNextImage(
sync.acquire, VK_NULL_HANDLE, imageIndex);
}
// Resolve back buffer if it is multisampled. We
// only have to do it only for the first frame.
m_context->beginRecording(
m_device->createCommandList());
// Resolve back buffer if it is multisampled. We
// only have to do it only for the first frame.
if (m_swapImageResolve != nullptr && i == 0) {
VkImageSubresourceLayers resolveSubresource;
resolveSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -266,25 +302,6 @@ namespace dxvk {
resolveRegion, VK_FORMAT_UNDEFINED);
}
// Presentation semaphores and WSI swap chain image
vk::PresenterInfo info = m_presenter->info();
vk::PresenterSync sync = m_presenter->getSyncSemaphores();
uint32_t imageIndex = 0;
VkResult status = m_presenter->acquireNextImage(
sync.acquire, VK_NULL_HANDLE, imageIndex);
while (status != VK_SUCCESS && status != VK_SUBOPTIMAL_KHR) {
RecreateSwapChain(m_vsync);
info = m_presenter->info();
sync = m_presenter->getSyncSemaphores();
status = m_presenter->acquireNextImage(
sync.acquire, VK_NULL_HANDLE, imageIndex);
}
// Use an appropriate texture filter depending on whether
// the back buffer size matches the swap image size
bool fitSize = m_swapImage->info().extent.width == info.imageExtent.width
@ -341,6 +358,7 @@ namespace dxvk {
}
SignalFrameLatencyEvent();
return S_OK;
}

View File

@ -135,7 +135,7 @@ namespace dxvk {
bool m_dirty = true;
bool m_vsync = true;
void PresentImage(UINT SyncInterval);
HRESULT PresentImage(UINT SyncInterval);
void SubmitPresent(
D3D11ImmediateContext* pContext,

View File

@ -258,9 +258,6 @@ namespace dxvk {
if (SyncInterval > 4)
return DXGI_ERROR_INVALID_CALL;
if (PresentFlags & DXGI_PRESENT_TEST)
return S_OK;
std::lock_guard<std::recursive_mutex> lockWin(m_lockWindow);
std::lock_guard<std::mutex> lockBuf(m_lockBuffer);