mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[dxvk] Move surface creation to the backend
This commit is contained in:
parent
c707d9026f
commit
073806df7c
@ -505,17 +505,6 @@ namespace dxvk {
|
||||
|
||||
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)
|
||||
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.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());
|
||||
}
|
||||
|
||||
|
||||
VkResult D3D11SwapChain::CreateSurface(VkSurfaceKHR* pSurface) {
|
||||
Rc<DxvkAdapter> adapter = m_device->adapter();
|
||||
|
||||
return m_surfaceFactory->CreateSurface(
|
||||
adapter->vki()->instance(),
|
||||
adapter->handle(), pSurface);
|
||||
}
|
||||
|
||||
|
||||
void D3D11SwapChain::CreateRenderTargetViews() {
|
||||
PresenterInfo info = m_presenter->info();
|
||||
|
||||
|
@ -147,8 +147,6 @@ namespace dxvk {
|
||||
|
||||
void CreatePresenter();
|
||||
|
||||
VkResult CreateSurface(VkSurfaceKHR* pSurface);
|
||||
|
||||
void CreateRenderTargetViews();
|
||||
|
||||
void CreateBackBuffers();
|
||||
|
@ -946,17 +946,6 @@ namespace dxvk {
|
||||
|
||||
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)
|
||||
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.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();
|
||||
|
||||
|
||||
VkResult D3D9SwapChainEx::CreateSurface(VkSurfaceKHR* pSurface) {
|
||||
auto vki = m_device->adapter()->vki();
|
||||
|
||||
return wsi::createSurface(m_window,
|
||||
vki->getLoaderProc(),
|
||||
vki->instance(),
|
||||
pSurface);
|
||||
return wsi::createSurface(cWindow,
|
||||
vki->getLoaderProc(),
|
||||
vki->instance(),
|
||||
surface);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
@ -199,8 +199,6 @@ namespace dxvk {
|
||||
|
||||
void CreatePresenter();
|
||||
|
||||
VkResult CreateSurface(VkSurfaceKHR* pSurface);
|
||||
|
||||
void CreateRenderTargetViews();
|
||||
|
||||
HRESULT CreateBackBuffers(
|
||||
|
@ -10,10 +10,12 @@ namespace dxvk {
|
||||
Presenter::Presenter(
|
||||
const Rc<DxvkDevice>& device,
|
||||
const Rc<sync::Signal>& signal,
|
||||
const PresenterDesc& desc)
|
||||
const PresenterDesc& desc,
|
||||
PresenterSurfaceProc&& proc)
|
||||
: m_device(device), m_signal(signal),
|
||||
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
|
||||
// is required to support VRR or HDR, but blocks alt-tabbing or
|
||||
// overlapping windows, which breaks a number of games.
|
||||
@ -158,25 +160,31 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
VkResult Presenter::recreateSurface(
|
||||
const std::function<VkResult (VkSurfaceKHR*)>& fn) {
|
||||
VkResult Presenter::recreateSwapChain(const PresenterDesc& desc) {
|
||||
VkResult vr;
|
||||
|
||||
if (m_swapchain)
|
||||
destroySwapchain();
|
||||
|
||||
if (m_surface)
|
||||
destroySurface();
|
||||
if (m_surface) {
|
||||
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) {
|
||||
if (m_swapchain)
|
||||
destroySwapchain();
|
||||
|
||||
if (!m_surface)
|
||||
return VK_ERROR_SURFACE_LOST_KHR;
|
||||
|
||||
VkResult Presenter::createSwapChain(const PresenterDesc& desc) {
|
||||
VkSurfaceFullScreenExclusiveInfoEXT fullScreenExclusiveInfo = { VK_STRUCTURE_TYPE_SURFACE_FULL_SCREEN_EXCLUSIVE_INFO_EXT };
|
||||
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() {
|
||||
if (m_signal != nullptr)
|
||||
m_signal->wait(m_lastFrameId.load(std::memory_order_acquire));
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
||||
#include "../util/log/log.h"
|
||||
@ -18,6 +19,8 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
using PresenterSurfaceProc = std::function<VkResult (VkSurfaceKHR*)>;
|
||||
|
||||
class DxvkDevice;
|
||||
|
||||
/**
|
||||
@ -94,7 +97,8 @@ namespace dxvk {
|
||||
Presenter(
|
||||
const Rc<DxvkDevice>& device,
|
||||
const Rc<sync::Signal>& signal,
|
||||
const PresenterDesc& desc);
|
||||
const PresenterDesc& desc,
|
||||
PresenterSurfaceProc&& proc);
|
||||
|
||||
~Presenter();
|
||||
|
||||
@ -160,15 +164,6 @@ namespace dxvk {
|
||||
VkPresentModeKHR mode,
|
||||
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
|
||||
*
|
||||
@ -227,13 +222,14 @@ namespace dxvk {
|
||||
|
||||
private:
|
||||
|
||||
Rc<DxvkDevice> m_device;
|
||||
Rc<sync::Signal> m_signal;
|
||||
Rc<DxvkDevice> m_device;
|
||||
Rc<sync::Signal> m_signal;
|
||||
|
||||
Rc<vk::InstanceFn> m_vki;
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
Rc<vk::InstanceFn> m_vki;
|
||||
Rc<vk::DeviceFn> m_vkd;
|
||||
|
||||
PresenterInfo m_info = { };
|
||||
PresenterInfo m_info = { };
|
||||
PresenterSurfaceProc m_surfaceProc;
|
||||
|
||||
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
|
||||
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
|
||||
@ -259,7 +255,7 @@ namespace dxvk {
|
||||
|
||||
std::atomic<uint64_t> m_lastFrameId = { 0ull };
|
||||
|
||||
VkResult recreateSwapChainInternal(
|
||||
VkResult createSwapChain(
|
||||
const PresenterDesc& desc);
|
||||
|
||||
VkResult getSupportedFormats(
|
||||
@ -291,6 +287,8 @@ namespace dxvk {
|
||||
uint32_t maxImageCount,
|
||||
uint32_t desired);
|
||||
|
||||
VkResult createSurface();
|
||||
|
||||
void destroySwapchain();
|
||||
|
||||
void destroySurface();
|
||||
|
Loading…
x
Reference in New Issue
Block a user