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:
parent
c707d9026f
commit
073806df7c
@ -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();
|
||||||
|
|
||||||
|
@ -147,8 +147,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
void CreatePresenter();
|
void CreatePresenter();
|
||||||
|
|
||||||
VkResult CreateSurface(VkSurfaceKHR* pSurface);
|
|
||||||
|
|
||||||
void CreateRenderTargetViews();
|
void CreateRenderTargetViews();
|
||||||
|
|
||||||
void CreateBackBuffers();
|
void CreateBackBuffers();
|
||||||
|
@ -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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -199,8 +199,6 @@ namespace dxvk {
|
|||||||
|
|
||||||
void CreatePresenter();
|
void CreatePresenter();
|
||||||
|
|
||||||
VkResult CreateSurface(VkSurfaceKHR* pSurface);
|
|
||||||
|
|
||||||
void CreateRenderTargetViews();
|
void CreateRenderTargetViews();
|
||||||
|
|
||||||
HRESULT CreateBackBuffers(
|
HRESULT CreateBackBuffers(
|
||||||
|
@ -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));
|
||||||
|
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user