1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-07 16:54:14 +01:00

[dxvk] Move surface creation to the backend

This commit is contained in:
Philip Rebohle 2025-01-12 15:58:58 +01:00 committed by Philip Rebohle
parent c707d9026f
commit 073806df7c
6 changed files with 66 additions and 76 deletions

View File

@ -505,17 +505,6 @@ namespace dxvk {
VkResult vr = m_presenter->recreateSwapChain(presenterDesc); VkResult vr = m_presenter->recreateSwapChain(presenterDesc);
if (vr == VK_ERROR_SURFACE_LOST_KHR) {
vr = m_presenter->recreateSurface([this] (VkSurfaceKHR* surface) {
return CreateSurface(surface);
});
if (vr)
throw DxvkError(str::format("D3D11SwapChain: Failed to recreate surface: ", vr));
vr = m_presenter->recreateSwapChain(presenterDesc);
}
if (vr) if (vr)
throw DxvkError(str::format("D3D11SwapChain: Failed to recreate swap chain: ", vr)); throw DxvkError(str::format("D3D11SwapChain: Failed to recreate swap chain: ", vr));
@ -537,20 +526,19 @@ namespace dxvk {
presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1); presenterDesc.imageCount = PickImageCount(m_desc.BufferCount + 1);
presenterDesc.numFormats = PickFormats(m_desc.Format, presenterDesc.formats); presenterDesc.numFormats = PickFormats(m_desc.Format, presenterDesc.formats);
m_presenter = new Presenter(m_device, m_frameLatencySignal, presenterDesc); m_presenter = new Presenter(m_device, m_frameLatencySignal, presenterDesc, [
cAdapter = m_device->adapter(),
cFactory = m_surfaceFactory
] (VkSurfaceKHR* surface) {
return cFactory->CreateSurface(
cAdapter->vki()->instance(),
cAdapter->handle(), surface);
});
m_presenter->setFrameRateLimit(m_targetFrameRate, GetActualFrameLatency()); m_presenter->setFrameRateLimit(m_targetFrameRate, GetActualFrameLatency());
} }
VkResult D3D11SwapChain::CreateSurface(VkSurfaceKHR* pSurface) {
Rc<DxvkAdapter> adapter = m_device->adapter();
return m_surfaceFactory->CreateSurface(
adapter->vki()->instance(),
adapter->handle(), pSurface);
}
void D3D11SwapChain::CreateRenderTargetViews() { void D3D11SwapChain::CreateRenderTargetViews() {
PresenterInfo info = m_presenter->info(); PresenterInfo info = m_presenter->info();

View File

@ -147,8 +147,6 @@ namespace dxvk {
void CreatePresenter(); void CreatePresenter();
VkResult CreateSurface(VkSurfaceKHR* pSurface);
void CreateRenderTargetViews(); void CreateRenderTargetViews();
void CreateBackBuffers(); void CreateBackBuffers();

View File

@ -946,17 +946,6 @@ namespace dxvk {
VkResult vr = m_wctx->presenter->recreateSwapChain(presenterDesc); VkResult vr = m_wctx->presenter->recreateSwapChain(presenterDesc);
if (vr == VK_ERROR_SURFACE_LOST_KHR) {
vr = m_wctx->presenter->recreateSurface([this] (VkSurfaceKHR* surface) {
return CreateSurface(surface);
});
if (vr)
throw DxvkError(str::format("D3D9SwapChainEx: Failed to recreate surface: ", vr));
vr = m_wctx->presenter->recreateSwapChain(presenterDesc);
}
if (vr) if (vr)
throw DxvkError(str::format("D3D9SwapChainEx: Failed to recreate swap chain: ", vr)); throw DxvkError(str::format("D3D9SwapChainEx: Failed to recreate swap chain: ", vr));
@ -976,17 +965,18 @@ namespace dxvk {
presenterDesc.imageCount = PickImageCount(m_presentParams.BackBufferCount + 1); presenterDesc.imageCount = PickImageCount(m_presentParams.BackBufferCount + 1);
presenterDesc.numFormats = PickFormats(EnumerateFormat(m_presentParams.BackBufferFormat), presenterDesc.formats); presenterDesc.numFormats = PickFormats(EnumerateFormat(m_presentParams.BackBufferFormat), presenterDesc.formats);
m_wctx->presenter = new Presenter(m_device, m_wctx->frameLatencySignal, presenterDesc); m_wctx->presenter = new Presenter(m_device,
} m_wctx->frameLatencySignal, presenterDesc, [
cDevice = m_device,
cWindow = m_window
] (VkSurfaceKHR* surface) {
auto vki = cDevice->adapter()->vki();
return wsi::createSurface(cWindow,
VkResult D3D9SwapChainEx::CreateSurface(VkSurfaceKHR* pSurface) {
auto vki = m_device->adapter()->vki();
return wsi::createSurface(m_window,
vki->getLoaderProc(), vki->getLoaderProc(),
vki->instance(), vki->instance(),
pSurface); surface);
});
} }

View File

@ -199,8 +199,6 @@ namespace dxvk {
void CreatePresenter(); void CreatePresenter();
VkResult CreateSurface(VkSurfaceKHR* pSurface);
void CreateRenderTargetViews(); void CreateRenderTargetViews();
HRESULT CreateBackBuffers( HRESULT CreateBackBuffers(

View File

@ -10,10 +10,12 @@ namespace dxvk {
Presenter::Presenter( Presenter::Presenter(
const Rc<DxvkDevice>& device, const Rc<DxvkDevice>& device,
const Rc<sync::Signal>& signal, const Rc<sync::Signal>& signal,
const PresenterDesc& desc) const PresenterDesc& desc,
PresenterSurfaceProc&& proc)
: m_device(device), m_signal(signal), : m_device(device), m_signal(signal),
m_vki(device->instance()->vki()), m_vki(device->instance()->vki()),
m_vkd(device->vkd()) { m_vkd(device->vkd()),
m_surfaceProc(std::move(proc)) {
// Only enable FSE if the user explicitly opts in. On Windows, FSE // Only enable FSE if the user explicitly opts in. On Windows, FSE
// is required to support VRR or HDR, but blocks alt-tabbing or // is required to support VRR or HDR, but blocks alt-tabbing or
// overlapping windows, which breaks a number of games. // overlapping windows, which breaks a number of games.
@ -158,25 +160,31 @@ namespace dxvk {
} }
VkResult Presenter::recreateSurface( VkResult Presenter::recreateSwapChain(const PresenterDesc& desc) {
const std::function<VkResult (VkSurfaceKHR*)>& fn) { VkResult vr;
if (m_swapchain) if (m_swapchain)
destroySwapchain(); destroySwapchain();
if (m_surface) if (m_surface) {
destroySurface(); vr = createSwapChain(desc);
return fn(&m_surface); if (vr == VK_ERROR_SURFACE_LOST_KHR)
destroySurface();
}
if (!m_surface) {
vr = createSurface();
if (vr == VK_SUCCESS)
vr = createSwapChain(desc);
}
return vr;
} }
VkResult Presenter::recreateSwapChain(const PresenterDesc& desc) { VkResult Presenter::createSwapChain(const PresenterDesc& desc) {
if (m_swapchain)
destroySwapchain();
if (!m_surface)
return VK_ERROR_SURFACE_LOST_KHR;
VkSurfaceFullScreenExclusiveInfoEXT fullScreenExclusiveInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT }; VkSurfaceFullScreenExclusiveInfoEXT fullScreenExclusiveInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT };
fullScreenExclusiveInfo.fullScreenExclusive = m_fullscreenMode; fullScreenExclusiveInfo.fullScreenExclusive = m_fullscreenMode;
@ -653,6 +661,16 @@ namespace dxvk {
} }
VkResult Presenter::createSurface() {
VkResult vr = m_surfaceProc(&m_surface);
if (vr != VK_SUCCESS)
Logger::err(str::format("Failed to create Vulkan surface: ", vr));
return vr;
}
void Presenter::destroySwapchain() { void Presenter::destroySwapchain() {
if (m_signal != nullptr) if (m_signal != nullptr)
m_signal->wait(m_lastFrameId.load(std::memory_order_acquire)); m_signal->wait(m_lastFrameId.load(std::memory_order_acquire));

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <functional> #include <functional>
#include <queue>
#include <vector> #include <vector>
#include "../util/log/log.h" #include "../util/log/log.h"
@ -18,6 +19,8 @@
namespace dxvk { namespace dxvk {
using PresenterSurfaceProc = std::function<VkResult (VkSurfaceKHR*)>;
class DxvkDevice; class DxvkDevice;
/** /**
@ -94,7 +97,8 @@ namespace dxvk {
Presenter( Presenter(
const Rc<DxvkDevice>& device, const Rc<DxvkDevice>& device,
const Rc<sync::Signal>& signal, const Rc<sync::Signal>& signal,
const PresenterDesc& desc); const PresenterDesc& desc,
PresenterSurfaceProc&& proc);
~Presenter(); ~Presenter();
@ -160,15 +164,6 @@ namespace dxvk {
VkPresentModeKHR mode, VkPresentModeKHR mode,
uint64_t frameId); uint64_t frameId);
/**
* \brief Changes and takes ownership of surface
*
* The presenter will destroy the surface as necessary.
* \param [in] fn Surface create function
*/
VkResult recreateSurface(
const std::function<VkResult (VkSurfaceKHR*)>& fn);
/** /**
* \brief Changes presenter properties * \brief Changes presenter properties
* *
@ -234,6 +229,7 @@ namespace dxvk {
Rc<vk::DeviceFn> m_vkd; Rc<vk::DeviceFn> m_vkd;
PresenterInfo m_info = { }; PresenterInfo m_info = { };
PresenterSurfaceProc m_surfaceProc;
VkSurfaceKHR m_surface = VK_NULL_HANDLE; VkSurfaceKHR m_surface = VK_NULL_HANDLE;
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE; VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
@ -259,7 +255,7 @@ namespace dxvk {
std::atomic<uint64_t> m_lastFrameId = { 0ull }; std::atomic<uint64_t> m_lastFrameId = { 0ull };
VkResult recreateSwapChainInternal( VkResult createSwapChain(
const PresenterDesc& desc); const PresenterDesc& desc);
VkResult getSupportedFormats( VkResult getSupportedFormats(
@ -291,6 +287,8 @@ namespace dxvk {
uint32_t maxImageCount, uint32_t maxImageCount,
uint32_t desired); uint32_t desired);
VkResult createSurface();
void destroySwapchain(); void destroySwapchain();
void destroySurface(); void destroySurface();