Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/doitsujin/dxvk.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Rebohle <philip.rebohle@tu-dortmund.de>2018-05-23 14:03:12 +0300
committerPhilip Rebohle <philip.rebohle@tu-dortmund.de>2018-05-23 14:03:12 +0300
commit38c5e570257e8cd9dcb78ab227baa2a2c877bd0f (patch)
tree088d360609b3a6a897f7a449027fb64fc002897c
parent531732fe91fe59ed94447eac1e922be45fbf0bf9 (diff)
[dxgi] Refactor Vulkan swap chain and surface creationv0.52
Creating the Vulkan surface at the latest possible moment fixes an issue with Frostpunk, which renders to a D3D9 swap chain before presenting to the GXGI swap chain.
-rw-r--r--src/dxgi/dxgi_presenter.cpp75
-rw-r--r--src/dxgi/dxgi_presenter.h34
-rw-r--r--src/dxgi/dxgi_swapchain.cpp14
3 files changed, 62 insertions, 61 deletions
diff --git a/src/dxgi/dxgi_presenter.cpp b/src/dxgi/dxgi_presenter.cpp
index 116ea212..431cca37 100644
--- a/src/dxgi/dxgi_presenter.cpp
+++ b/src/dxgi/dxgi_presenter.cpp
@@ -10,15 +10,10 @@ namespace dxvk {
DxgiVkPresenter::DxgiVkPresenter(
const Rc<DxvkDevice>& device,
HWND window)
- : m_device (device),
+ : m_window (window),
+ m_device (device),
m_context (device->createContext()) {
- // Create Vulkan surface for the window
- HINSTANCE instance = reinterpret_cast<HINSTANCE>(
- GetWindowLongPtr(window, GWLP_HINSTANCE));
-
- m_surface = m_device->adapter()->createSurface(instance, window);
-
// Reset options for the swap chain itself. We will
// create a swap chain object before presentation.
m_options.preferredSurfaceFormat = { VK_FORMAT_UNDEFINED, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR };
@@ -275,27 +270,52 @@ namespace dxvk {
}
- void DxgiVkPresenter::RecreateSwapchain(const DxvkSwapchainProperties* pOptions) {
+ void DxgiVkPresenter::SetGammaControl(
+ const DXGI_VK_GAMMA_CURVE* pGammaCurve) {
+ m_context->beginRecording(
+ m_device->createCommandList());
+
+ m_context->updateImage(m_gammaTexture,
+ VkImageSubresourceLayers { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 },
+ VkOffset3D { 0, 0, 0 },
+ VkExtent3D { DXGI_VK_GAMMA_CP_COUNT, 1, 1 },
+ pGammaCurve, 0, 0);
+
+ m_device->submitCommandList(
+ m_context->endRecording(),
+ nullptr, nullptr);
+ }
+
+
+ void DxgiVkPresenter::RecreateSwapchain(DXGI_FORMAT Format, VkPresentModeKHR PresentMode, VkExtent2D WindowSize) {
+ if (m_surface == nullptr)
+ m_surface = CreateSurface();
+
+ DxvkSwapchainProperties options;
+ options.preferredSurfaceFormat = PickSurfaceFormat(Format);
+ options.preferredPresentMode = PickPresentMode(PresentMode);
+ options.preferredBufferSize = WindowSize;
+
const bool doRecreate =
- pOptions->preferredSurfaceFormat.format != m_options.preferredSurfaceFormat.format
- || pOptions->preferredSurfaceFormat.colorSpace != m_options.preferredSurfaceFormat.colorSpace
- || pOptions->preferredPresentMode != m_options.preferredPresentMode
- || pOptions->preferredBufferSize.width != m_options.preferredBufferSize.width
- || pOptions->preferredBufferSize.height != m_options.preferredBufferSize.height;
+ options.preferredSurfaceFormat.format != m_options.preferredSurfaceFormat.format
+ || options.preferredSurfaceFormat.colorSpace != m_options.preferredSurfaceFormat.colorSpace
+ || options.preferredPresentMode != m_options.preferredPresentMode
+ || options.preferredBufferSize.width != m_options.preferredBufferSize.width
+ || options.preferredBufferSize.height != m_options.preferredBufferSize.height;
if (doRecreate) {
Logger::info(str::format(
"DxgiVkPresenter: Recreating swap chain: ",
- "\n Format: ", pOptions->preferredSurfaceFormat.format,
- "\n Present mode: ", pOptions->preferredPresentMode,
- "\n Buffer size: ", pOptions->preferredBufferSize.width, "x", pOptions->preferredBufferSize.height));
+ "\n Format: ", options.preferredSurfaceFormat.format,
+ "\n Present mode: ", options.preferredPresentMode,
+ "\n Buffer size: ", options.preferredBufferSize.width, "x", options.preferredBufferSize.height));
if (m_swapchain == nullptr)
- m_swapchain = m_device->createSwapchain(m_surface, *pOptions);
+ m_swapchain = m_device->createSwapchain(m_surface, options);
else
- m_swapchain->changeProperties(*pOptions);
+ m_swapchain->changeProperties(options);
- m_options = *pOptions;
+ m_options = options;
}
}
@@ -339,20 +359,11 @@ namespace dxvk {
}
- void DxgiVkPresenter::SetGammaControl(
- const DXGI_VK_GAMMA_CURVE* pGammaCurve) {
- m_context->beginRecording(
- m_device->createCommandList());
-
- m_context->updateImage(m_gammaTexture,
- VkImageSubresourceLayers { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 },
- VkOffset3D { 0, 0, 0 },
- VkExtent3D { DXGI_VK_GAMMA_CP_COUNT, 1, 1 },
- pGammaCurve, 0, 0);
+ Rc<DxvkSurface> DxgiVkPresenter::CreateSurface() {
+ HINSTANCE instance = reinterpret_cast<HINSTANCE>(
+ GetWindowLongPtr(m_window, GWLP_HINSTANCE));
- m_device->submitCommandList(
- m_context->endRecording(),
- nullptr, nullptr);
+ return m_device->adapter()->createSurface(instance, m_window);
}
diff --git a/src/dxgi/dxgi_presenter.h b/src/dxgi/dxgi_presenter.h
index 1ce32606..8709849c 100644
--- a/src/dxgi/dxgi_presenter.h
+++ b/src/dxgi/dxgi_presenter.h
@@ -100,28 +100,14 @@ namespace dxvk {
* Only actually recreates the swap chain object
* if any of the properties have changed. If no
* properties have changed, this is a no-op.
- * \param [in] options New swap chain options
+ * \param [in] Format New surface format
+ * \param [in] PresentMode Present mode
+ * \param [in] WindowSize Window size
*/
void RecreateSwapchain(
- const DxvkSwapchainProperties* pOptions);
-
- /**
- * \brief Picks a surface format based on a DXGI format
- *
- * This will return a supported format that, if possible,
- * has properties similar to those of the DXGI format.
- * \param [in] fmt The DXGI format
- * \returns The Vulkan format
- */
- VkSurfaceFormatKHR PickSurfaceFormat(DXGI_FORMAT Fmt) const;
-
- /**
- * \brief Picks a supported present mode
- *
- * \param [in] preferred Preferred present mode
- * \returns An actually supported present mode
- */
- VkPresentModeKHR PickPresentMode(VkPresentModeKHR Preferred) const;
+ DXGI_FORMAT Format,
+ VkPresentModeKHR PresentMode,
+ VkExtent2D WindowSize);
/**
* \brief Sets gamma curve
@@ -142,6 +128,8 @@ namespace dxvk {
GammaTex = 3,
};
+ HWND m_window;
+
Rc<DxvkDevice> m_device;
Rc<DxvkContext> m_context;
@@ -164,6 +152,12 @@ namespace dxvk {
DxvkBlendMode m_blendMode;
DxvkSwapchainProperties m_options;
+ VkSurfaceFormatKHR PickSurfaceFormat(DXGI_FORMAT Fmt) const;
+
+ VkPresentModeKHR PickPresentMode(VkPresentModeKHR Preferred) const;
+
+ Rc<DxvkSurface> CreateSurface();
+
Rc<DxvkSampler> CreateSampler(
VkFilter Filter,
VkSamplerAddressMode AddressMode);
diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp
index ceca91b0..343cbc04 100644
--- a/src/dxgi/dxgi_swapchain.cpp
+++ b/src/dxgi/dxgi_swapchain.cpp
@@ -306,15 +306,11 @@ namespace dxvk {
// up vertical synchronization properly, but also apply
// changes that were made to the window size even if the
// Vulkan swap chain itself remains valid.
- DxvkSwapchainProperties swapchainProps;
- swapchainProps.preferredSurfaceFormat
- = m_presenter->PickSurfaceFormat(m_desc.Format);
- swapchainProps.preferredPresentMode = SyncInterval == 0
- ? m_presenter->PickPresentMode(VK_PRESENT_MODE_IMMEDIATE_KHR)
- : m_presenter->PickPresentMode(VK_PRESENT_MODE_FIFO_KHR);
- swapchainProps.preferredBufferSize = GetWindowSize();
-
- m_presenter->RecreateSwapchain(&swapchainProps);
+ VkPresentModeKHR presentMode = SyncInterval == 0
+ ? VK_PRESENT_MODE_IMMEDIATE_KHR
+ : VK_PRESENT_MODE_FIFO_KHR;
+
+ m_presenter->RecreateSwapchain(m_desc.Format, presentMode, GetWindowSize());
m_presenter->PresentImage();
return S_OK;
} catch (const DxvkError& err) {