mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-14 22:29:15 +01:00
[vulkan,d3d9,d3d11] Move surface creation to swap chain implementation
This commit is contained in:
parent
49cf0ecf54
commit
03dca539cb
@ -2,6 +2,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "../dxgi/dxgi_monitor.h"
|
#include "../dxgi/dxgi_monitor.h"
|
||||||
|
#include "../dxgi/dxgi_surface.h"
|
||||||
#include "../dxgi/dxgi_swapchain.h"
|
#include "../dxgi/dxgi_swapchain.h"
|
||||||
|
|
||||||
#include "../dxvk/dxvk_adapter.h"
|
#include "../dxvk/dxvk_adapter.h"
|
||||||
@ -3002,8 +3003,12 @@ namespace dxvk {
|
|||||||
InitReturnPtr(ppSwapChain);
|
InitReturnPtr(ppSwapChain);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
auto vki = m_device->GetDXVKDevice()->adapter()->vki();
|
||||||
|
|
||||||
|
Com<IDXGIVkSurfaceFactory> surfaceFactory = new DxgiSurfaceFactory(vki->getLoaderProc(), hWnd);
|
||||||
|
|
||||||
Com<D3D11SwapChain> presenter = new D3D11SwapChain(
|
Com<D3D11SwapChain> presenter = new D3D11SwapChain(
|
||||||
m_container, m_device, hWnd, pDesc);
|
m_container, m_device, surfaceFactory.ptr(), pDesc);
|
||||||
|
|
||||||
*ppSwapChain = presenter.ref();
|
*ppSwapChain = presenter.ref();
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@ -3074,9 +3079,14 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
auto vki = m_device->GetDXVKDevice()->adapter()->vki();
|
||||||
|
|
||||||
|
// Create surface factory for the window
|
||||||
|
Com<IDXGIVkSurfaceFactory> surfaceFactory = new DxgiSurfaceFactory(vki->getLoaderProc(), hWnd);
|
||||||
|
|
||||||
// Create presenter for the device
|
// Create presenter for the device
|
||||||
Com<D3D11SwapChain> presenter = new D3D11SwapChain(
|
Com<D3D11SwapChain> presenter = new D3D11SwapChain(
|
||||||
m_container, m_device, hWnd, &desc);
|
m_container, m_device, surfaceFactory.ptr(), &desc);
|
||||||
|
|
||||||
// Create the actual swap chain
|
// Create the actual swap chain
|
||||||
*ppSwapChain = ref(new DxgiSwapChain(
|
*ppSwapChain = ref(new DxgiSwapChain(
|
||||||
|
@ -16,23 +16,23 @@ namespace dxvk {
|
|||||||
D3D11SwapChain::D3D11SwapChain(
|
D3D11SwapChain::D3D11SwapChain(
|
||||||
D3D11DXGIDevice* pContainer,
|
D3D11DXGIDevice* pContainer,
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
HWND hWnd,
|
IDXGIVkSurfaceFactory* pSurfaceFactory,
|
||||||
const DXGI_SWAP_CHAIN_DESC1* pDesc)
|
const DXGI_SWAP_CHAIN_DESC1* pDesc)
|
||||||
: m_dxgiDevice(pContainer),
|
: m_dxgiDevice(pContainer),
|
||||||
m_parent (pDevice),
|
m_parent(pDevice),
|
||||||
m_window (hWnd),
|
m_surfaceFactory(pSurfaceFactory),
|
||||||
m_desc (*pDesc),
|
m_desc(*pDesc),
|
||||||
m_device (pDevice->GetDXVKDevice()),
|
m_device(pDevice->GetDXVKDevice()),
|
||||||
m_context (m_device->createContext(DxvkContextType::Supplementary)),
|
m_context(m_device->createContext(DxvkContextType::Supplementary)),
|
||||||
m_frameLatencyCap(pDevice->GetOptions()->maxFrameLatency) {
|
m_frameLatencyCap(pDevice->GetOptions()->maxFrameLatency) {
|
||||||
CreateFrameLatencyEvent();
|
CreateFrameLatencyEvent();
|
||||||
|
CreatePresenter();
|
||||||
if (!pDevice->GetOptions()->deferSurfaceCreation)
|
|
||||||
CreatePresenter();
|
|
||||||
|
|
||||||
CreateBackBuffer();
|
CreateBackBuffer();
|
||||||
CreateBlitter();
|
CreateBlitter();
|
||||||
CreateHud();
|
CreateHud();
|
||||||
|
|
||||||
|
if (!pDevice->GetOptions()->deferSurfaceCreation)
|
||||||
|
RecreateSwapChain(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -223,9 +223,6 @@ namespace dxvk {
|
|||||||
m_vsync = vsync;
|
m_vsync = vsync;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_presenter == nullptr)
|
|
||||||
CreatePresenter();
|
|
||||||
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
if (!m_presenter->hasSwapChain()) {
|
if (!m_presenter->hasSwapChain()) {
|
||||||
@ -395,8 +392,21 @@ namespace dxvk {
|
|||||||
presenterDesc.numPresentModes = PickPresentModes(Vsync, presenterDesc.presentModes);
|
presenterDesc.numPresentModes = PickPresentModes(Vsync, presenterDesc.presentModes);
|
||||||
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
||||||
|
|
||||||
if (m_presenter->recreateSwapChain(presenterDesc) != VK_SUCCESS)
|
VkResult vr = m_presenter->recreateSwapChain(presenterDesc);
|
||||||
throw DxvkError("D3D11SwapChain: Failed to recreate swap chain");
|
|
||||||
|
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));
|
||||||
|
|
||||||
CreateRenderTargetViews();
|
CreateRenderTargetViews();
|
||||||
}
|
}
|
||||||
@ -426,15 +436,22 @@ namespace dxvk {
|
|||||||
presenterDesc.numPresentModes = PickPresentModes(false, presenterDesc.presentModes);
|
presenterDesc.numPresentModes = PickPresentModes(false, presenterDesc.presentModes);
|
||||||
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
||||||
|
|
||||||
m_presenter = new vk::Presenter(m_window,
|
m_presenter = new vk::Presenter(
|
||||||
m_device->adapter()->vki(),
|
m_device->adapter()->vki(),
|
||||||
m_device->vkd(),
|
m_device->vkd(),
|
||||||
presenterDevice,
|
presenterDevice,
|
||||||
presenterDesc);
|
presenterDesc);
|
||||||
|
|
||||||
m_presenter->setFrameRateLimit(m_parent->GetOptions()->maxFrameRate);
|
m_presenter->setFrameRateLimit(m_parent->GetOptions()->maxFrameRate);
|
||||||
|
}
|
||||||
|
|
||||||
CreateRenderTargetViews();
|
|
||||||
|
VkResult D3D11SwapChain::CreateSurface(VkSurfaceKHR* pSurface) {
|
||||||
|
Rc<DxvkAdapter> adapter = m_device->adapter();
|
||||||
|
|
||||||
|
return m_surfaceFactory->CreateSurface(
|
||||||
|
adapter->vki()->instance(),
|
||||||
|
adapter->handle(), pSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ namespace dxvk {
|
|||||||
D3D11SwapChain(
|
D3D11SwapChain(
|
||||||
D3D11DXGIDevice* pContainer,
|
D3D11DXGIDevice* pContainer,
|
||||||
D3D11Device* pDevice,
|
D3D11Device* pDevice,
|
||||||
HWND hWnd,
|
IDXGIVkSurfaceFactory* pSurfaceFactory,
|
||||||
const DXGI_SWAP_CHAIN_DESC1* pDesc);
|
const DXGI_SWAP_CHAIN_DESC1* pDesc);
|
||||||
|
|
||||||
~D3D11SwapChain();
|
~D3D11SwapChain();
|
||||||
@ -90,7 +90,7 @@ namespace dxvk {
|
|||||||
Com<D3D11DXGIDevice, false> m_dxgiDevice;
|
Com<D3D11DXGIDevice, false> m_dxgiDevice;
|
||||||
|
|
||||||
D3D11Device* m_parent;
|
D3D11Device* m_parent;
|
||||||
HWND m_window;
|
Com<IDXGIVkSurfaceFactory> m_surfaceFactory;
|
||||||
|
|
||||||
DXGI_SWAP_CHAIN_DESC1 m_desc;
|
DXGI_SWAP_CHAIN_DESC1 m_desc;
|
||||||
|
|
||||||
@ -137,6 +137,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
void CreatePresenter();
|
void CreatePresenter();
|
||||||
|
|
||||||
|
VkResult CreateSurface(VkSurfaceKHR* pSurface);
|
||||||
|
|
||||||
void CreateRenderTargetViews();
|
void CreateRenderTargetViews();
|
||||||
|
|
||||||
void CreateBackBuffer();
|
void CreateBackBuffer();
|
||||||
|
@ -35,9 +35,14 @@ namespace dxvk {
|
|||||||
m_window = m_presentParams.hDeviceWindow;
|
m_window = m_presentParams.hDeviceWindow;
|
||||||
|
|
||||||
UpdatePresentRegion(nullptr, nullptr);
|
UpdatePresentRegion(nullptr, nullptr);
|
||||||
if (m_window && !pDevice->GetOptions()->deferSurfaceCreation)
|
|
||||||
|
if (m_window) {
|
||||||
CreatePresenter();
|
CreatePresenter();
|
||||||
|
|
||||||
|
if (!pDevice->GetOptions()->deferSurfaceCreation)
|
||||||
|
RecreateSwapChain(false);
|
||||||
|
}
|
||||||
|
|
||||||
CreateBackBuffers(m_presentParams.BackBufferCount);
|
CreateBackBuffers(m_presentParams.BackBufferCount);
|
||||||
CreateBlitter();
|
CreateBlitter();
|
||||||
CreateHud();
|
CreateHud();
|
||||||
@ -116,7 +121,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
bool recreate = false;
|
bool recreate = false;
|
||||||
recreate |= m_presenter == nullptr;
|
recreate |= m_presenter == nullptr;
|
||||||
recreate |= window != m_window;
|
recreate |= window != m_window;
|
||||||
recreate |= m_dialog != m_lastDialog;
|
recreate |= m_dialog != m_lastDialog;
|
||||||
|
|
||||||
m_window = window;
|
m_window = window;
|
||||||
@ -757,8 +762,21 @@ namespace dxvk {
|
|||||||
presenterDesc.numPresentModes = PickPresentModes(Vsync, presenterDesc.presentModes);
|
presenterDesc.numPresentModes = PickPresentModes(Vsync, presenterDesc.presentModes);
|
||||||
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
||||||
|
|
||||||
if (m_presenter->recreateSwapChain(presenterDesc) != VK_SUCCESS)
|
VkResult vr = m_presenter->recreateSwapChain(presenterDesc);
|
||||||
throw DxvkError("D3D9SwapChainEx: Failed to recreate swap chain");
|
|
||||||
|
if (vr == VK_ERROR_SURFACE_LOST_KHR) {
|
||||||
|
vr = m_presenter->recreateSurface([this] (VkSurfaceKHR* surface) {
|
||||||
|
return CreateSurface(surface);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (vr)
|
||||||
|
throw DxvkError(str::format("D3D9SwapChainEx: Failed to recreate surface: ", vr));
|
||||||
|
|
||||||
|
vr = m_presenter->recreateSwapChain(presenterDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vr)
|
||||||
|
throw DxvkError(str::format("D3D9SwapChainEx: Failed to recreate swap chain: ", vr));
|
||||||
|
|
||||||
CreateRenderTargetViews();
|
CreateRenderTargetViews();
|
||||||
}
|
}
|
||||||
@ -785,15 +803,23 @@ namespace dxvk {
|
|||||||
presenterDesc.numPresentModes = PickPresentModes(false, presenterDesc.presentModes);
|
presenterDesc.numPresentModes = PickPresentModes(false, presenterDesc.presentModes);
|
||||||
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
presenterDesc.fullScreenExclusive = PickFullscreenMode();
|
||||||
|
|
||||||
m_presenter = new vk::Presenter(m_window,
|
m_presenter = new vk::Presenter(
|
||||||
m_device->adapter()->vki(),
|
m_device->adapter()->vki(),
|
||||||
m_device->vkd(),
|
m_device->vkd(),
|
||||||
presenterDevice,
|
presenterDevice,
|
||||||
presenterDesc);
|
presenterDesc);
|
||||||
|
|
||||||
m_presenter->setFrameRateLimit(m_parent->GetOptions()->maxFrameRate);
|
m_presenter->setFrameRateLimit(m_parent->GetOptions()->maxFrameRate);
|
||||||
|
}
|
||||||
|
|
||||||
CreateRenderTargetViews();
|
|
||||||
|
VkResult D3D9SwapChainEx::CreateSurface(VkSurfaceKHR* pSurface) {
|
||||||
|
auto vki = m_device->adapter()->vki();
|
||||||
|
|
||||||
|
return wsi::createSurface(m_window,
|
||||||
|
vki->getLoaderProc(),
|
||||||
|
vki->instance(),
|
||||||
|
pSurface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -137,6 +137,8 @@ namespace dxvk {
|
|||||||
|
|
||||||
void CreatePresenter();
|
void CreatePresenter();
|
||||||
|
|
||||||
|
VkResult CreateSurface(VkSurfaceKHR* pSurface);
|
||||||
|
|
||||||
void CreateRenderTargetViews();
|
void CreateRenderTargetViews();
|
||||||
|
|
||||||
void DestroyBackBuffers();
|
void DestroyBackBuffers();
|
||||||
|
@ -23,6 +23,7 @@ namespace dxvk::vk {
|
|||||||
~LibraryLoader();
|
~LibraryLoader();
|
||||||
PFN_vkVoidFunction sym(VkInstance instance, const char* name) const;
|
PFN_vkVoidFunction sym(VkInstance instance, const char* name) const;
|
||||||
PFN_vkVoidFunction sym(const char* name) const;
|
PFN_vkVoidFunction sym(const char* name) const;
|
||||||
|
PFN_vkGetInstanceProcAddr getLoaderProc() const { return m_getInstanceProcAddr; }
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
protected:
|
protected:
|
||||||
const HMODULE m_library;
|
const HMODULE m_library;
|
||||||
@ -39,6 +40,7 @@ namespace dxvk::vk {
|
|||||||
struct InstanceLoader : public RcObject {
|
struct InstanceLoader : public RcObject {
|
||||||
InstanceLoader(const Rc<LibraryLoader>& library, bool owned, VkInstance instance);
|
InstanceLoader(const Rc<LibraryLoader>& library, bool owned, VkInstance instance);
|
||||||
PFN_vkVoidFunction sym(const char* name) const;
|
PFN_vkVoidFunction sym(const char* name) const;
|
||||||
|
PFN_vkGetInstanceProcAddr getLoaderProc() const { return m_library->getLoaderProc(); }
|
||||||
VkInstance instance() const { return m_instance; }
|
VkInstance instance() const { return m_instance; }
|
||||||
protected:
|
protected:
|
||||||
Rc<LibraryLoader> m_library;
|
Rc<LibraryLoader> m_library;
|
||||||
|
@ -7,17 +7,12 @@
|
|||||||
namespace dxvk::vk {
|
namespace dxvk::vk {
|
||||||
|
|
||||||
Presenter::Presenter(
|
Presenter::Presenter(
|
||||||
HWND window,
|
|
||||||
const Rc<InstanceFn>& vki,
|
const Rc<InstanceFn>& vki,
|
||||||
const Rc<DeviceFn>& vkd,
|
const Rc<DeviceFn>& vkd,
|
||||||
PresenterDevice device,
|
PresenterDevice device,
|
||||||
const PresenterDesc& desc)
|
const PresenterDesc& desc)
|
||||||
: m_vki(vki), m_vkd(vkd), m_device(device), m_window(window) {
|
: m_vki(vki), m_vkd(vkd), m_device(device) {
|
||||||
if (createSurface() != VK_SUCCESS)
|
|
||||||
throw DxvkError("Failed to create surface");
|
|
||||||
|
|
||||||
if (recreateSwapChain(desc) != VK_SUCCESS)
|
|
||||||
throw DxvkError("Failed to create swap chain");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +41,7 @@ namespace dxvk::vk {
|
|||||||
m_swapchain, std::numeric_limits<uint64_t>::max(),
|
m_swapchain, std::numeric_limits<uint64_t>::max(),
|
||||||
sync.acquire, VK_NULL_HANDLE, &m_imageIndex);
|
sync.acquire, VK_NULL_HANDLE, &m_imageIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_acquireStatus != VK_SUCCESS && m_acquireStatus != VK_SUBOPTIMAL_KHR)
|
if (m_acquireStatus != VK_SUCCESS && m_acquireStatus != VK_SUBOPTIMAL_KHR)
|
||||||
return m_acquireStatus;
|
return m_acquireStatus;
|
||||||
|
|
||||||
@ -88,11 +83,26 @@ namespace dxvk::vk {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VkResult Presenter::recreateSurface(
|
||||||
|
const std::function<VkResult (VkSurfaceKHR*)>& fn) {
|
||||||
|
if (m_swapchain)
|
||||||
|
destroySwapchain();
|
||||||
|
|
||||||
|
if (m_surface)
|
||||||
|
destroySurface();
|
||||||
|
|
||||||
|
return fn(&m_surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
VkResult Presenter::recreateSwapChain(const PresenterDesc& desc) {
|
VkResult Presenter::recreateSwapChain(const PresenterDesc& desc) {
|
||||||
if (m_swapchain)
|
if (m_swapchain)
|
||||||
destroySwapchain();
|
destroySwapchain();
|
||||||
|
|
||||||
|
if (!m_surface)
|
||||||
|
return VK_ERROR_SURFACE_LOST_KHR;
|
||||||
|
|
||||||
// Query surface capabilities. Some properties might
|
// Query surface capabilities. Some properties might
|
||||||
// have changed, including the size limits and supported
|
// have changed, including the size limits and supported
|
||||||
// present modes, so we'll just query everything again.
|
// present modes, so we'll just query everything again.
|
||||||
@ -103,13 +113,13 @@ namespace dxvk::vk {
|
|||||||
VkResult status;
|
VkResult status;
|
||||||
|
|
||||||
if ((status = m_vki->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
if ((status = m_vki->vkGetPhysicalDeviceSurfaceCapabilitiesKHR(
|
||||||
m_device.adapter, m_surface, &caps)) != VK_SUCCESS)
|
m_device.adapter, m_surface, &caps)))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if ((status = getSupportedFormats(formats, desc)) != VK_SUCCESS)
|
if ((status = getSupportedFormats(formats, desc)))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if ((status = getSupportedPresentModes(modes, desc)) != VK_SUCCESS)
|
if ((status = getSupportedPresentModes(modes, desc)))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// Select actual swap chain properties and create swap chain
|
// Select actual swap chain properties and create swap chain
|
||||||
@ -155,13 +165,13 @@ namespace dxvk::vk {
|
|||||||
"\n Exclusive FS: ", desc.fullScreenExclusive));
|
"\n Exclusive FS: ", desc.fullScreenExclusive));
|
||||||
|
|
||||||
if ((status = m_vkd->vkCreateSwapchainKHR(m_vkd->device(),
|
if ((status = m_vkd->vkCreateSwapchainKHR(m_vkd->device(),
|
||||||
&swapInfo, nullptr, &m_swapchain)) != VK_SUCCESS)
|
&swapInfo, nullptr, &m_swapchain)))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// Acquire images and create views
|
// Acquire images and create views
|
||||||
std::vector<VkImage> images;
|
std::vector<VkImage> images;
|
||||||
|
|
||||||
if ((status = getSwapImages(images)) != VK_SUCCESS)
|
if ((status = getSwapImages(images)))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// Update actual image count
|
// Update actual image count
|
||||||
@ -183,7 +193,7 @@ namespace dxvk::vk {
|
|||||||
0, 1, 0, 1 };
|
0, 1, 0, 1 };
|
||||||
|
|
||||||
if ((status = m_vkd->vkCreateImageView(m_vkd->device(),
|
if ((status = m_vkd->vkCreateImageView(m_vkd->device(),
|
||||||
&viewInfo, nullptr, &m_images[i].view)) != VK_SUCCESS)
|
&viewInfo, nullptr, &m_images[i].view)))
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,11 +204,11 @@ namespace dxvk::vk {
|
|||||||
VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
|
VkSemaphoreCreateInfo semInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
|
||||||
|
|
||||||
if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(),
|
if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(),
|
||||||
&semInfo, nullptr, &m_semaphores[i].acquire)) != VK_SUCCESS)
|
&semInfo, nullptr, &m_semaphores[i].acquire)))
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(),
|
if ((status = m_vkd->vkCreateSemaphore(m_vkd->device(),
|
||||||
&semInfo, nullptr, &m_semaphores[i].present)) != VK_SUCCESS)
|
&semInfo, nullptr, &m_semaphores[i].present)))
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -398,28 +408,6 @@ namespace dxvk::vk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VkResult Presenter::createSurface() {
|
|
||||||
/* TODO fix */
|
|
||||||
VkResult status = wsi::createSurface(m_window, nullptr, m_vki->instance(), &m_surface);
|
|
||||||
|
|
||||||
if (status != VK_SUCCESS)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
VkBool32 supportStatus = VK_FALSE;
|
|
||||||
|
|
||||||
if ((status = m_vki->vkGetPhysicalDeviceSurfaceSupportKHR(m_device.adapter,
|
|
||||||
m_device.queueFamily, m_surface, &supportStatus)) != VK_SUCCESS)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
if (!supportStatus) {
|
|
||||||
m_vki->vkDestroySurfaceKHR(m_vki->instance(), m_surface, nullptr);
|
|
||||||
return VK_ERROR_OUT_OF_HOST_MEMORY; // just abuse this
|
|
||||||
}
|
|
||||||
|
|
||||||
return VK_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Presenter::destroySwapchain() {
|
void Presenter::destroySwapchain() {
|
||||||
for (const auto& img : m_images)
|
for (const auto& img : m_images)
|
||||||
m_vkd->vkDestroyImageView(m_vkd->device(), img.view, nullptr);
|
m_vkd->vkDestroyImageView(m_vkd->device(), img.view, nullptr);
|
||||||
@ -440,6 +428,8 @@ namespace dxvk::vk {
|
|||||||
|
|
||||||
void Presenter::destroySurface() {
|
void Presenter::destroySurface() {
|
||||||
m_vki->vkDestroySurfaceKHR(m_vki->instance(), m_surface, nullptr);
|
m_vki->vkDestroySurfaceKHR(m_vki->instance(), m_surface, nullptr);
|
||||||
|
|
||||||
|
m_surface = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "../util/log/log.h"
|
#include "../util/log/log.h"
|
||||||
@ -93,7 +94,6 @@ namespace dxvk::vk {
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Presenter(
|
Presenter(
|
||||||
HWND window,
|
|
||||||
const Rc<InstanceFn>& vki,
|
const Rc<InstanceFn>& vki,
|
||||||
const Rc<DeviceFn>& vkd,
|
const Rc<DeviceFn>& vkd,
|
||||||
PresenterDevice device,
|
PresenterDevice device,
|
||||||
@ -141,7 +141,16 @@ namespace dxvk::vk {
|
|||||||
* \returns Status of the operation
|
* \returns Status of the operation
|
||||||
*/
|
*/
|
||||||
VkResult presentImage();
|
VkResult presentImage();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \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
|
||||||
*
|
*
|
||||||
@ -149,6 +158,7 @@ namespace dxvk::vk {
|
|||||||
* no swap chain resources must be in use by the
|
* no swap chain resources must be in use by the
|
||||||
* GPU at the time this is called.
|
* GPU at the time this is called.
|
||||||
* \param [in] desc Swap chain description
|
* \param [in] desc Swap chain description
|
||||||
|
* \param [in] surface New Vulkan surface
|
||||||
*/
|
*/
|
||||||
VkResult recreateSwapChain(
|
VkResult recreateSwapChain(
|
||||||
const PresenterDesc& desc);
|
const PresenterDesc& desc);
|
||||||
@ -181,7 +191,6 @@ namespace dxvk::vk {
|
|||||||
PresenterDevice m_device;
|
PresenterDevice m_device;
|
||||||
PresenterInfo m_info;
|
PresenterInfo m_info;
|
||||||
|
|
||||||
HWND m_window = nullptr;
|
|
||||||
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
|
VkSurfaceKHR m_surface = VK_NULL_HANDLE;
|
||||||
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
|
VkSwapchainKHR m_swapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
@ -195,6 +204,9 @@ namespace dxvk::vk {
|
|||||||
|
|
||||||
FpsLimiter m_fpsLimiter;
|
FpsLimiter m_fpsLimiter;
|
||||||
|
|
||||||
|
VkResult recreateSwapChainInternal(
|
||||||
|
const PresenterDesc& desc);
|
||||||
|
|
||||||
VkResult getSupportedFormats(
|
VkResult getSupportedFormats(
|
||||||
std::vector<VkSurfaceFormatKHR>& formats,
|
std::vector<VkSurfaceFormatKHR>& formats,
|
||||||
const PresenterDesc& desc);
|
const PresenterDesc& desc);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user