From 2bceeff5f2a9bf999963f148a0a2c6521a7b4666 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 28 Feb 2022 22:44:10 +0100 Subject: [PATCH] [d3d11] Replace apitrace mode option with something more granular And enable it only for vertex and index buffers in Nier Replicant. --- src/d3d11/d3d11_buffer.cpp | 5 ++++- src/d3d11/d3d11_options.cpp | 26 +++++++++++++++++++------- src/d3d11/d3d11_options.h | 9 +++++---- src/d3d11/d3d11_texture.cpp | 9 +++++++-- src/util/config/config.cpp | 18 +++++++++--------- 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/d3d11/d3d11_buffer.cpp b/src/d3d11/d3d11_buffer.cpp index 9b1ee35a..eb72fc1b 100644 --- a/src/d3d11/d3d11_buffer.cpp +++ b/src/d3d11/d3d11_buffer.cpp @@ -247,7 +247,10 @@ namespace dxvk { break; } - if (memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT && m_parent->GetOptions()->apitraceMode) { + bool useCached = (m_parent->GetOptions()->cachedDynamicResources == ~0u) + || (m_parent->GetOptions()->cachedDynamicResources & m_desc.BindFlags); + + if ((memoryFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) && useCached) { memoryFlags |= VK_MEMORY_PROPERTY_HOST_COHERENT_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT; } diff --git a/src/d3d11/d3d11_options.cpp b/src/d3d11/d3d11_options.cpp index 09db0159..e78c5198 100644 --- a/src/d3d11/d3d11_options.cpp +++ b/src/d3d11/d3d11_options.cpp @@ -38,15 +38,27 @@ namespace dxvk { this->constantBufferRangeCheck = config.getOption("d3d11.constantBufferRangeCheck", false) && DxvkGpuVendor(devInfo.core.properties.vendorID) != DxvkGpuVendor::Amd; - bool apitraceAttached = false; - apitraceAttached = ::GetModuleHandle("dxgitrace.dll") != nullptr; + auto cachedDynamicResources = config.getOption("d3d11.cachedDynamicResources", std::string()); - this->apitraceMode = config.getOption("d3d11.apitraceMode", apitraceAttached); + if (::GetModuleHandle("dxgitrace.dll")) { + // apitrace reads back all mapped resources on the CPU, so + // allocating everything in cached memory is necessary to + // achieve acceptable performance + this->cachedDynamicResources = ~0u; + } else { + this->cachedDynamicResources = 0u; - // Inform user in case they have the option enabled or a game - // ships a file called dxgitrace.dll for whatever reason. - if (this->apitraceMode) - Logger::warn("D3D11: Apitrace mode enabled, may affect performance!"); + for (char c : cachedDynamicResources) { + switch (c) { + case 'c': this->cachedDynamicResources |= D3D11_BIND_CONSTANT_BUFFER; break; + case 'v': this->cachedDynamicResources |= D3D11_BIND_VERTEX_BUFFER; break; + case 'i': this->cachedDynamicResources |= D3D11_BIND_INDEX_BUFFER; break; + case 'r': this->cachedDynamicResources |= D3D11_BIND_SHADER_RESOURCE; break; + case 'a': this->cachedDynamicResources = ~0u; break; + default: Logger::warn(str::format("Unknown flag for d3d11.cachedDynamicResources option: ", c)); + } + } + } } } \ No newline at end of file diff --git a/src/d3d11/d3d11_options.h b/src/d3d11/d3d11_options.h index 6ec0b5a3..99353b30 100644 --- a/src/d3d11/d3d11_options.h +++ b/src/d3d11/d3d11_options.h @@ -9,7 +9,7 @@ #include "d3d11_include.h" namespace dxvk { - + struct D3D11Options { D3D11Options(const Config& config, const Rc& device); @@ -107,9 +107,10 @@ namespace dxvk { /// performs the required shader and resolve fixups. bool disableMsaa; - /// Apitrace mode: Maps all buffers in cached memory. - /// Enabled automatically if dxgitrace.dll is attached. - bool apitraceMode; + /// Dynamic resources with the given bind flags will be allocated + /// in cached system memory. Enabled automatically when recording + /// an api trace. + uint32_t cachedDynamicResources; }; } \ No newline at end of file diff --git a/src/d3d11/d3d11_texture.cpp b/src/d3d11/d3d11_texture.cpp index 1f8f978c..ee1cc5f4 100644 --- a/src/d3d11/d3d11_texture.cpp +++ b/src/d3d11/d3d11_texture.cpp @@ -532,7 +532,10 @@ namespace dxvk { VkMemoryPropertyFlags memoryFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - if ((m_desc.CPUAccessFlags & D3D11_CPU_ACCESS_READ) || m_device->GetOptions()->apitraceMode) + bool useCached = (m_device->GetOptions()->cachedDynamicResources == ~0u) + || (m_device->GetOptions()->cachedDynamicResources & m_desc.BindFlags); + + if (m_desc.Usage == D3D11_USAGE_STAGING || useCached) memoryFlags |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; else if (m_desc.Usage == D3D11_USAGE_DEFAULT || m_desc.BindFlags) memoryFlags |= VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT; @@ -609,7 +612,9 @@ namespace dxvk { VkMemoryPropertyFlags memType = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT; - if (m_desc.Usage == D3D11_USAGE_STAGING || m_device->GetOptions()->apitraceMode) + bool useCached = m_device->GetOptions()->cachedDynamicResources == ~0u; + + if (m_desc.Usage == D3D11_USAGE_STAGING || useCached) memType |= VK_MEMORY_PROPERTY_HOST_CACHED_BIT; MappedBuffer result; diff --git a/src/util/config/config.cpp b/src/util/config/config.cpp index 64c2b563..c49cae1f 100644 --- a/src/util/config/config.cpp +++ b/src/util/config/config.cpp @@ -117,7 +117,7 @@ namespace dxvk { { R"(\\NieR Replicant ver\.1\.22474487139\.exe)", {{ { "dxgi.syncInterval", "1" }, { "dxgi.maxFrameRate", "60" }, - { "d3d11.apitraceMode", "True" }, + { "d3d11.cachedDynamicResources", "vi" }, }} }, /* SteamVR performance test */ { R"(\\vr\.exe$)", {{ @@ -148,13 +148,13 @@ namespace dxvk { * game parts */ { R"(\\Crysis3\.exe$)", {{ { "dxgi.customVendorId", "10de" }, - { "d3d11.apitraceMode", "True" }, + { "d3d11.cachedDynamicResources", "a" }, }} }, /* Crysis 3 Remastered * * Apitrace mode helps massively in cpu bound * * game parts */ { R"(\\Crysis3Remastered\.exe$)", {{ - { "d3d11.apitraceMode", "True" }, + { "d3d11.cachedDynamicResources", "a" }, }} }, /* Atelier series - games try to render video * * with a D3D9 swap chain over the DXGI swap * @@ -202,23 +202,23 @@ namespace dxvk { /* Darksiders Warmastered - apparently reads * * from write-only mapped buffers */ { R"(\\darksiders1\.exe$)", {{ - { "d3d11.apitraceMode", "True" }, + { "d3d11.cachedDynamicResources", "a" }, }} }, /* Monster Hunter World */ { R"(\\MonsterHunterWorld\.exe$)", {{ - { "d3d11.apitraceMode", "True" }, + { "d3d11.cachedDynamicResources", "a" }, }} }, /* Kingdome Come: Deliverance */ { R"(\\KingdomCome\.exe$)", {{ - { "d3d11.apitraceMode", "True" }, + { "d3d11.cachedDynamicResources", "a" }, }} }, /* Homefront: The Revolution */ { R"(\\Homefront2_Release\.exe$)", {{ - { "d3d11.apitraceMode", "True" }, + { "d3d11.cachedDynamicResources", "a" }, }} }, /* Sniper Ghost Warrior Contracts */ { R"(\\SGWContracts\.exe$)", {{ - { "d3d11.apitraceMode", "True" }, + { "d3d11.cachedDynamicResources", "a" }, }} }, /* Shadow of the Tomb Raider - invariant * * position breaks character rendering on NV */ @@ -258,7 +258,7 @@ namespace dxvk { }} }, /* AoE 2 DE - runs poorly for some users */ { R"(\\AoE2DE_s\.exe$)", {{ - { "d3d11.apitraceMode", "True" }, + { "d3d11.cachedDynamicResources", "a" }, }} }, /* Total War: Warhammer III */ { R"(\\Warhammer3\.exe$)", {{