From d9772b0ffd6fda8dfa05ec7df7cf89849ab8cfdc Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 24 May 2018 11:44:04 +0200 Subject: [PATCH 1/6] [dxvk] Create image views for all supported view types Rather than creating just one image view per DxvkImageView, we create views for all compatible types in an attempt to work around game bugs in Diablo 3, Far Cry 5, Nier Automata, Dishonored 2, Trackmania etc., which bind incompatible resource views to some resource slots. --- src/dxvk/dxvk_context.cpp | 4 +- src/dxvk/dxvk_image.cpp | 96 ++++++++++++++++++++++++++++----------- src/dxvk/dxvk_image.h | 31 +++++++++---- 3 files changed, 95 insertions(+), 36 deletions(-) diff --git a/src/dxvk/dxvk_context.cpp b/src/dxvk/dxvk_context.cpp index bb966228..afad9756 100644 --- a/src/dxvk/dxvk_context.cpp +++ b/src/dxvk/dxvk_context.cpp @@ -1822,11 +1822,11 @@ namespace dxvk { case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: - if (res.imageView != nullptr && res.imageView->type() == binding.view) { + if (res.imageView != nullptr && res.imageView->handle(binding.view) != VK_NULL_HANDLE) { updatePipelineState |= bindingState.setBound(i); m_descInfos[i].image.sampler = VK_NULL_HANDLE; - m_descInfos[i].image.imageView = res.imageView->handle(); + m_descInfos[i].image.imageView = res.imageView->handle(binding.view); m_descInfos[i].image.imageLayout = res.imageView->imageInfo().layout; if (depthAttachment.view != nullptr diff --git a/src/dxvk/dxvk_image.cpp b/src/dxvk/dxvk_image.cpp index 3f9937dc..3227c9da 100644 --- a/src/dxvk/dxvk_image.cpp +++ b/src/dxvk/dxvk_image.cpp @@ -87,25 +87,75 @@ namespace dxvk { const Rc& image, const DxvkImageViewCreateInfo& info) : m_vkd(vkd), m_image(image), m_info(info) { + // Since applications tend to bind views + for (uint32_t i = 0; i < ViewCount; i++) + m_views[i] = VK_NULL_HANDLE; + + switch (info.type) { + case VK_IMAGE_VIEW_TYPE_1D: + case VK_IMAGE_VIEW_TYPE_1D_ARRAY: { + this->createView(VK_IMAGE_VIEW_TYPE_1D, 1); + this->createView(VK_IMAGE_VIEW_TYPE_1D_ARRAY, info.numLayers); + } break; + + case VK_IMAGE_VIEW_TYPE_2D: + case VK_IMAGE_VIEW_TYPE_2D_ARRAY: + case VK_IMAGE_VIEW_TYPE_CUBE: + case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: { + this->createView(VK_IMAGE_VIEW_TYPE_2D, 1); + this->createView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, info.numLayers); + + if (m_image->info().flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) { + uint32_t cubeCount = info.numLayers / 6; + + if (cubeCount > 0) { + this->createView(VK_IMAGE_VIEW_TYPE_CUBE, 6); + this->createView(VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, 6 * cubeCount); + } + } + } break; + + case VK_IMAGE_VIEW_TYPE_3D: { + this->createView(VK_IMAGE_VIEW_TYPE_3D, 1); + + if (m_image->info().flags & VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT_KHR) { + this->createView(VK_IMAGE_VIEW_TYPE_2D, 1); + this->createView(VK_IMAGE_VIEW_TYPE_2D_ARRAY, m_image->info().extent.depth); + } + } break; + + default: + throw DxvkError(str::format("DxvkImageView: Invalid view type: ", info.type)); + } + } + + + DxvkImageView::~DxvkImageView() { + for (uint32_t i = 0; i < ViewCount; i++) + m_vkd->vkDestroyImageView(m_vkd->device(), m_views[i], nullptr); + } + + + void DxvkImageView::createView(VkImageViewType type, uint32_t numLayers) { VkImageSubresourceRange subresourceRange; - subresourceRange.aspectMask = info.aspect; - subresourceRange.baseMipLevel = info.minLevel; - subresourceRange.levelCount = info.numLevels; - subresourceRange.baseArrayLayer = info.minLayer; - subresourceRange.layerCount = info.numLayers; + subresourceRange.aspectMask = m_info.aspect; + subresourceRange.baseMipLevel = m_info.minLevel; + subresourceRange.levelCount = m_info.numLevels; + subresourceRange.baseArrayLayer = m_info.minLayer; + subresourceRange.layerCount = numLayers; VkImageViewCreateInfo viewInfo; viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; viewInfo.pNext = nullptr; viewInfo.flags = 0; - viewInfo.image = image->handle(); - viewInfo.viewType = info.type; - viewInfo.format = info.format; - viewInfo.components = info.swizzle; + viewInfo.image = m_image->handle(); + viewInfo.viewType = type; + viewInfo.format = m_info.format; + viewInfo.components = m_info.swizzle; viewInfo.subresourceRange = subresourceRange; if (m_vkd->vkCreateImageView(m_vkd->device(), - &viewInfo, nullptr, &m_view) != VK_SUCCESS) { + &viewInfo, nullptr, &m_views[type]) != VK_SUCCESS) { throw DxvkError(str::format( "DxvkImageView: Failed to create image view:" "\n View type: ", viewInfo.viewType, @@ -117,23 +167,17 @@ namespace dxvk { "\n Array layers: ", viewInfo.subresourceRange.baseArrayLayer, " - ", viewInfo.subresourceRange.layerCount, "\n Image properties:", - "\n Type: ", image->info().type, - "\n Format: ", image->info().format, - "\n Extent: ", "(", image->info().extent.width, - ",", image->info().extent.height, - ",", image->info().extent.depth, ")", - "\n Mip levels: ", image->info().mipLevels, - "\n Array layers: ", image->info().numLayers, - "\n Samples: ", image->info().sampleCount, - "\n Usage: ", std::hex, image->info().usage, - "\n Tiling: ", image->info().tiling)); + "\n Type: ", m_image->info().type, + "\n Format: ", m_image->info().format, + "\n Extent: ", "(", m_image->info().extent.width, + ",", m_image->info().extent.height, + ",", m_image->info().extent.depth, ")", + "\n Mip levels: ", m_image->info().mipLevels, + "\n Array layers: ", m_image->info().numLayers, + "\n Samples: ", m_image->info().sampleCount, + "\n Usage: ", std::hex, m_image->info().usage, + "\n Tiling: ", m_image->info().tiling)); } } - - DxvkImageView::~DxvkImageView() { - m_vkd->vkDestroyImageView( - m_vkd->device(), m_view, nullptr); - } - } \ No newline at end of file diff --git a/src/dxvk/dxvk_image.h b/src/dxvk/dxvk_image.h index 9802d81e..395213bc 100644 --- a/src/dxvk/dxvk_image.h +++ b/src/dxvk/dxvk_image.h @@ -232,7 +232,7 @@ namespace dxvk { * \brief DXVK image view */ class DxvkImageView : public DxvkResource { - + constexpr static uint32_t ViewCount = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY + 1; public: DxvkImageView( @@ -243,21 +243,34 @@ namespace dxvk { ~DxvkImageView(); /** - * \brief Image view handle + * \brief Image view handle for the default type * - * Internal use only. + * The default view type is guaranteed to be + * supported by the image view, and should be + * preferred over picking a different type. * \returns Image view handle */ VkImageView handle() const { - return m_view; + return handle(m_info.type); + } + + /** + * \brief Image view handle for a given view type + * + * If the view does not support the requested image + * view type, \c VK_NULL_HANDLE will be returned. + * \param [in] viewType The requested view type + * \returns The image view handle + */ + VkImageView handle(VkImageViewType viewType) const { + return m_views[viewType]; } /** * \brief Image view type * - * Convenience method to query the - * view type in order to check for - * resource compatibility. + * Convenience method to query the view type + * in order to check for resource compatibility. * \returns Image view type */ VkImageViewType type() const { @@ -336,7 +349,9 @@ namespace dxvk { Rc m_image; DxvkImageViewCreateInfo m_info; - VkImageView m_view; + VkImageView m_views[ViewCount]; + + void createView(VkImageViewType type, uint32_t numLayers); }; From 58e9280891b8a07a66bef2243b69bab6e9e4930f Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 24 May 2018 11:49:12 +0200 Subject: [PATCH 2/6] [dxbc] Remove Tex2D -> Tex2DArray workaround --- src/d3d11/d3d11_device.cpp | 9 --------- src/dxbc/dxbc_compiler.cpp | 5 ----- src/dxbc/dxbc_options.cpp | 3 +-- src/dxbc/dxbc_options.h | 5 ----- 4 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index f58cc02c..b576143e 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -413,9 +413,6 @@ namespace dxvk { viewInfo.numLevels = desc.Texture2D.MipLevels; viewInfo.minLayer = 0; viewInfo.numLayers = 1; - - if (m_dxbcOptions.test(DxbcOption::ForceTex2DArray)) - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; break; case D3D11_SRV_DIMENSION_TEXTURE2DARRAY: @@ -432,9 +429,6 @@ namespace dxvk { viewInfo.numLevels = 1; viewInfo.minLayer = 0; viewInfo.numLayers = 1; - - if (m_dxbcOptions.test(DxbcOption::ForceTex2DArray)) - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; break; case D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY: @@ -624,9 +618,6 @@ namespace dxvk { viewInfo.numLevels = 1; viewInfo.minLayer = 0; viewInfo.numLayers = 1; - - if (m_dxbcOptions.test(DxbcOption::ForceTex2DArray)) - viewInfo.type = VK_IMAGE_VIEW_TYPE_2D_ARRAY; break; case D3D11_UAV_DIMENSION_TEXTURE2DARRAY: diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index 73c7bba1..f3c3b8bf 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -6290,11 +6290,6 @@ namespace dxvk { } }(); - if (typeInfo.dim == spv::Dim2D && m_options.test(DxbcOption::ForceTex2DArray)) { - typeInfo.array = 1; - typeInfo.vtype = VK_IMAGE_VIEW_TYPE_2D_ARRAY; - } - return typeInfo; } diff --git a/src/dxbc/dxbc_options.cpp b/src/dxbc/dxbc_options.cpp index 22b925b7..6ccfd565 100644 --- a/src/dxbc/dxbc_options.cpp +++ b/src/dxbc/dxbc_options.cpp @@ -5,8 +5,7 @@ namespace dxvk { const static std::unordered_map g_dxbcAppOptions = {{ - { "Dishonored2.exe", DxbcOptions(DxbcOption::ForceTex2DArray) }, - { "ManiaPlanet.exe", DxbcOptions(DxbcOption::ForceTex2DArray) }, + }}; diff --git a/src/dxbc/dxbc_options.h b/src/dxbc/dxbc_options.h index abe29521..1a8e575c 100644 --- a/src/dxbc/dxbc_options.h +++ b/src/dxbc/dxbc_options.h @@ -17,11 +17,6 @@ namespace dxvk { /// Use FMin/FMax/FClamp instead of NMin/NMax/NClamp. /// Workaround for bugs in older Nvidia drivers. UseSimpleMinMaxClamp, - - /// Enforces the use of array views even when dealing - /// with non-array texture types. Some games do not - /// bind the correct texture type to the pipeline. - ForceTex2DArray, }; using DxbcOptions = Flags; From 12d79257be273d42e853329ed3f10d9f2f013fee Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 24 May 2018 12:00:31 +0200 Subject: [PATCH 3/6] [dxbc] Remove TexCube -> TexCubeArray workaround --- src/dxbc/dxbc_compiler.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index f3c3b8bf..fe28f6fe 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -828,7 +828,6 @@ namespace dxvk { case DxbcResourceDim::Buffer: m_module.enableCapability(spv::CapabilityImageBuffer); break; case DxbcResourceDim::Texture1D: m_module.enableCapability(spv::CapabilityImage1D); break; case DxbcResourceDim::Texture1DArr: m_module.enableCapability(spv::CapabilityImage1D); break; - case DxbcResourceDim::TextureCube: m_module.enableCapability(spv::CapabilityImageCubeArray); break; case DxbcResourceDim::TextureCubeArr: m_module.enableCapability(spv::CapabilityImageCubeArray); break; case DxbcResourceDim::Texture2DMs: m_module.enableCapability(spv::CapabilityImageMSArray); break; case DxbcResourceDim::Texture2DMsArr: m_module.enableCapability(spv::CapabilityImageMSArray); break; @@ -6284,7 +6283,7 @@ namespace dxvk { case DxbcResourceDim::Texture2DMs: return { spv::Dim2D, 0, 1, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_2D }; case DxbcResourceDim::Texture2DMsArr: return { spv::Dim2D, 1, 1, isUav ? 2u : 1u, 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; case DxbcResourceDim::Texture3D: return { spv::Dim3D, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_3D }; - case DxbcResourceDim::TextureCube: return { spv::DimCube, 1, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY }; + case DxbcResourceDim::TextureCube: return { spv::DimCube, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_CUBE }; case DxbcResourceDim::TextureCubeArr: return { spv::DimCube, 1, 0, isUav ? 2u : 1u, 1u, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY }; default: throw DxvkError(str::format("DxbcCompiler: Unsupported resource type: ", resourceType)); } From a43025294aae1ae166b6d17efe419ffd7d5930a0 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 24 May 2018 12:07:03 +0200 Subject: [PATCH 4/6] [dxbc] Remove DxbcImageInfo::layered property --- src/dxbc/dxbc_compiler.cpp | 47 +++++++++----------------------------- src/dxbc/dxbc_decoder.h | 1 - 2 files changed, 11 insertions(+), 37 deletions(-) diff --git a/src/dxbc/dxbc_compiler.cpp b/src/dxbc/dxbc_compiler.cpp index fe28f6fe..8d918b24 100644 --- a/src/dxbc/dxbc_compiler.cpp +++ b/src/dxbc/dxbc_compiler.cpp @@ -963,7 +963,7 @@ namespace dxvk { const DxbcScalarType sampledType = DxbcScalarType::Uint32; const uint32_t sampledTypeId = getScalarTypeId(sampledType); - const DxbcImageInfo typeInfo = { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_MAX_ENUM }; + const DxbcImageInfo typeInfo = { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_MAX_ENUM }; // Declare the resource type const uint32_t resTypeId = m_module.defImageType(sampledTypeId, @@ -4589,15 +4589,6 @@ namespace dxvk { m_module.opLoad(info.typeId, info.varId)); } - if (info.image.array && !info.image.layered) { - const uint32_t index = result.type.ccount - 1; - const uint32_t zero = m_module.constu32(0); - - result.id = m_module.opCompositeInsert( - getVectorTypeId(result.type), - zero, result.id, 1, &index); - } - return result; } @@ -4642,22 +4633,6 @@ namespace dxvk { coordVector, DxbcRegMask::firstN(dim)); } - if (imageInfo.array && !imageInfo.layered) { - const uint32_t index = dim - 1; - const uint32_t zero = [&] { - switch (coordVector.type.ctype) { - case DxbcScalarType::Sint32: return m_module.consti32(0); - case DxbcScalarType::Uint32: return m_module.constu32(0); - case DxbcScalarType::Float32: return m_module.constf32(0.0f); - default: throw DxvkError("Dxbc: Invalid tex coord type"); - } - }(); - - coordVector.id = m_module.opCompositeInsert( - getVectorTypeId(coordVector.type), - zero, coordVector.id, 1, &index); - } - return coordVector; } @@ -6275,16 +6250,16 @@ namespace dxvk { bool isUav) const { DxbcImageInfo typeInfo = [resourceType, isUav] () -> DxbcImageInfo { switch (resourceType) { - case DxbcResourceDim::Buffer: return { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_MAX_ENUM }; - case DxbcResourceDim::Texture1D: return { spv::Dim1D, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_1D }; - case DxbcResourceDim::Texture1DArr: return { spv::Dim1D, 1, 0, isUav ? 2u : 1u, 1u, VK_IMAGE_VIEW_TYPE_1D_ARRAY }; - case DxbcResourceDim::Texture2D: return { spv::Dim2D, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_2D }; - case DxbcResourceDim::Texture2DArr: return { spv::Dim2D, 1, 0, isUav ? 2u : 1u, 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; - case DxbcResourceDim::Texture2DMs: return { spv::Dim2D, 0, 1, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_2D }; - case DxbcResourceDim::Texture2DMsArr: return { spv::Dim2D, 1, 1, isUav ? 2u : 1u, 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; - case DxbcResourceDim::Texture3D: return { spv::Dim3D, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_3D }; - case DxbcResourceDim::TextureCube: return { spv::DimCube, 0, 0, isUav ? 2u : 1u, 0u, VK_IMAGE_VIEW_TYPE_CUBE }; - case DxbcResourceDim::TextureCubeArr: return { spv::DimCube, 1, 0, isUav ? 2u : 1u, 1u, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY }; + case DxbcResourceDim::Buffer: return { spv::DimBuffer, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_MAX_ENUM }; + case DxbcResourceDim::Texture1D: return { spv::Dim1D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_1D }; + case DxbcResourceDim::Texture1DArr: return { spv::Dim1D, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_1D_ARRAY }; + case DxbcResourceDim::Texture2D: return { spv::Dim2D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D }; + case DxbcResourceDim::Texture2DArr: return { spv::Dim2D, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; + case DxbcResourceDim::Texture2DMs: return { spv::Dim2D, 0, 1, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D }; + case DxbcResourceDim::Texture2DMsArr: return { spv::Dim2D, 1, 1, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_2D_ARRAY }; + case DxbcResourceDim::Texture3D: return { spv::Dim3D, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_3D }; + case DxbcResourceDim::TextureCube: return { spv::DimCube, 0, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_CUBE }; + case DxbcResourceDim::TextureCubeArr: return { spv::DimCube, 1, 0, isUav ? 2u : 1u, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY }; default: throw DxvkError(str::format("DxbcCompiler: Unsupported resource type: ", resourceType)); } }(); diff --git a/src/dxbc/dxbc_decoder.h b/src/dxbc/dxbc_decoder.h index e0b15e4d..df21fcbc 100644 --- a/src/dxbc/dxbc_decoder.h +++ b/src/dxbc/dxbc_decoder.h @@ -60,7 +60,6 @@ namespace dxvk { uint32_t array = 0; uint32_t ms = 0; uint32_t sampled = 0; - uint32_t layered = 0; VkImageViewType vtype = VK_IMAGE_VIEW_TYPE_MAX_ENUM; }; From f087016e77a5fe574905b625f344b62eac070c96 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 24 May 2018 12:31:04 +0200 Subject: [PATCH 5/6] [dxgi] Add app-specific DXGI options --- src/dxgi/dxgi_options.cpp | 20 ++++++++++++++++++++ src/dxgi/dxgi_options.h | 30 ++++++++++++++++++++++++++++++ src/dxgi/meson.build | 1 + 3 files changed, 51 insertions(+) create mode 100644 src/dxgi/dxgi_options.cpp create mode 100644 src/dxgi/dxgi_options.h diff --git a/src/dxgi/dxgi_options.cpp b/src/dxgi/dxgi_options.cpp new file mode 100644 index 00000000..94df5f80 --- /dev/null +++ b/src/dxgi/dxgi_options.cpp @@ -0,0 +1,20 @@ +#include "dxgi_options.h" + +#include + +namespace dxvk { + + const static std::unordered_map g_dxgiAppOptions = {{ + { "Frostpunk.exe", DxgiOptions(DxgiOption::DeferSurfaceCreation) }, + }}; + + + DxgiOptions getDxgiAppOptions(const std::string& appName) { + auto appOptions = g_dxgiAppOptions.find(appName); + + return appOptions != g_dxgiAppOptions.end() + ? appOptions->second + : DxgiOptions(); + } + +} \ No newline at end of file diff --git a/src/dxgi/dxgi_options.h b/src/dxgi/dxgi_options.h new file mode 100644 index 00000000..11c8c999 --- /dev/null +++ b/src/dxgi/dxgi_options.h @@ -0,0 +1,30 @@ +#pragma once + +#include "dxgi_include.h" + +namespace dxvk { + + /** + * \brief DXGI options + * + * Per-app options that control the + * behaviour of some DXGI classes. + */ + enum class DxgiOption : uint64_t { + /// Defer surface creation until first present call. This + /// fixes issues with games that create multiple swap chains + /// for a single window that may interfere with each other. + DeferSurfaceCreation, + }; + + using DxgiOptions = Flags; + + /** + * \brief Gets app-specific DXGI options + * + * \param [in] appName Application name + * \returns DXGI options for this application + */ + DxgiOptions getDxgiAppOptions(const std::string& appName); + +} diff --git a/src/dxgi/meson.build b/src/dxgi/meson.build index cc76baeb..5dfc3347 100644 --- a/src/dxgi/meson.build +++ b/src/dxgi/meson.build @@ -10,6 +10,7 @@ dxgi_src = [ 'dxgi_factory.cpp', 'dxgi_format.cpp', 'dxgi_main.cpp', + 'dxgi_options.cpp', 'dxgi_output.cpp', 'dxgi_presenter.cpp', 'dxgi_swapchain.cpp', From d844ddfdfa41872e77516746cb1e8cd2dfacb669 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 24 May 2018 12:31:21 +0200 Subject: [PATCH 6/6] [dxgi] Add option for deferred surface creation Deferred surface creation is required for Frostpunk due to conflicts with the D3D9 swap chain created by the game before it presents the first frame to the DXGI swap chain, but breaks NieR:Automata due to threading issues. --- src/dxgi/dxgi_presenter.cpp | 7 +++++++ src/dxgi/dxgi_presenter.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/dxgi/dxgi_presenter.cpp b/src/dxgi/dxgi_presenter.cpp index 431cca37..f041ab6a 100644 --- a/src/dxgi/dxgi_presenter.cpp +++ b/src/dxgi/dxgi_presenter.cpp @@ -14,6 +14,13 @@ namespace dxvk { m_device (device), m_context (device->createContext()) { + // Some games don't work with deferred surface creation, + // so we should default to initializing it immediately. + DxgiOptions dxgiOptions = getDxgiAppOptions(env::getExeName()); + + if (!dxgiOptions.test(DxgiOption::DeferSurfaceCreation)) + m_surface = CreateSurface(); + // 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 }; diff --git a/src/dxgi/dxgi_presenter.h b/src/dxgi/dxgi_presenter.h index 8709849c..a497ab34 100644 --- a/src/dxgi/dxgi_presenter.h +++ b/src/dxgi/dxgi_presenter.h @@ -8,7 +8,7 @@ #include "../spirv/spirv_module.h" -#include "dxgi_include.h" +#include "dxgi_options.h" namespace dxvk {