diff --git a/OptiScaler.ini b/OptiScaler.ini index a312ce5c..75f50e7a 100644 --- a/OptiScaler.ini +++ b/OptiScaler.ini @@ -670,7 +670,7 @@ RenderPresetUltraPerformance=auto ; Fix broken visuals in some games (mostly non-UE) on AMD GPUs under Windows ; Can cause stutters, so best to use only when necessary and mentioned ; true or false - Default (auto) is false -MakeDepthCopy=auto +MakeResourceCopy=auto diff --git a/OptiScaler/Config.cpp b/OptiScaler/Config.cpp index f05661a3..f342fe66 100644 --- a/OptiScaler/Config.cpp +++ b/OptiScaler/Config.cpp @@ -330,7 +330,7 @@ bool Config::Reload(std::filesystem::path iniPath) // Nukems { - MakeDepthCopy.set_from_config(readBool("Nukems", "MakeDepthCopy")); + NukemMakeResourceCopy.set_from_config(readBool("Nukems", "MakeResourceCopy")); } // Logging @@ -1003,7 +1003,8 @@ bool Config::SaveIni() // Nukems { - ini.SetValue("Nukems", "MakeDepthCopy", GetBoolValue(Instance()->MakeDepthCopy.value_for_config()).c_str()); + ini.SetValue("Nukems", "MakeResourceCopy", + GetBoolValue(Instance()->NukemMakeResourceCopy.value_for_config()).c_str()); } // Sharpness diff --git a/OptiScaler/Config.h b/OptiScaler/Config.h index cdec363f..4727eaeb 100644 --- a/OptiScaler/Config.h +++ b/OptiScaler/Config.h @@ -243,7 +243,7 @@ class Config CustomOptional DLSSDRenderPresetUltraPerformance { 0 }; // Nukems - CustomOptional MakeDepthCopy { false }; + CustomOptional NukemMakeResourceCopy { false }; // CAS CustomOptional RcasEnabled { false }; diff --git a/OptiScaler/inputs/FG/DLSSG_Mod.h b/OptiScaler/inputs/FG/DLSSG_Mod.h index 9f533924..92ec49df 100644 --- a/OptiScaler/inputs/FG/DLSSG_Mod.h +++ b/OptiScaler/inputs/FG/DLSSG_Mod.h @@ -10,11 +10,17 @@ typedef void (*PFN_RefreshGlobalConfiguration)(); typedef void (*PFN_EnableDebugView)(bool enable); +#define FRAMES_IN_FLIGHT 2 + class DLSSGMod { private: inline static HMODULE _dll = nullptr; + inline static ID3D12Resource* _copiedDlssgDepth[FRAMES_IN_FLIGHT] = { nullptr, nullptr }; + inline static ID3D12Resource* _copiedDlssgMV[FRAMES_IN_FLIGHT] = { nullptr, nullptr }; + inline static UINT64 _frameCount = 0; + inline static PFN_RefreshGlobalConfiguration _refreshGlobalConfiguration = nullptr; inline static PFN_EnableDebugView _fsrDebugView = nullptr; // for now keep compatibility with the patched 0.110 @@ -58,6 +64,68 @@ class DLSSGMod } } + static bool CreateBufferResource(ID3D12Device* InDevice, ID3D12Resource* InResource, D3D12_RESOURCE_STATES InState, + ID3D12Resource** OutResource) + { + if (InDevice == nullptr || InResource == nullptr) + return false; + + auto inDesc = InResource->GetDesc(); + + if (*OutResource != nullptr) + { + auto bufDesc = (*OutResource)->GetDesc(); + + if (bufDesc.Width != inDesc.Width || bufDesc.Height != inDesc.Height || bufDesc.Format != inDesc.Format) + { + (*OutResource)->Release(); + (*OutResource) = nullptr; + LOG_WARN("Release {}x{}, new one: {}x{}", bufDesc.Width, bufDesc.Height, inDesc.Width, inDesc.Height); + } + else + { + return true; + } + } + + D3D12_HEAP_PROPERTIES heapProperties; + D3D12_HEAP_FLAGS heapFlags; + HRESULT hr = InResource->GetHeapProperties(&heapProperties, &heapFlags); + + if (hr != S_OK) + { + LOG_ERROR("GetHeapProperties result: {:X}", (UINT64) hr); + return false; + } + + hr = InDevice->CreateCommittedResource(&heapProperties, D3D12_HEAP_FLAG_NONE, &inDesc, InState, nullptr, + IID_PPV_ARGS(OutResource)); + + if (hr != S_OK) + { + LOG_ERROR("CreateCommittedResource result: {:X}", (UINT64) hr); + return false; + } + + LOG_DEBUG("Created new one: {}x{}", inDesc.Width, inDesc.Height); + return true; + } + + static inline void ResourceBarrier(ID3D12GraphicsCommandList* InCommandList, ID3D12Resource* InResource, + D3D12_RESOURCE_STATES InBeforeState, D3D12_RESOURCE_STATES InAfterState) + { + if (InBeforeState == InAfterState) + return; + + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = InResource; + barrier.Transition.StateBefore = InBeforeState; + barrier.Transition.StateAfter = InAfterState; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + InCommandList->ResourceBarrier(1, &barrier); + } + public: static void InitDLSSGMod_Dx12() { @@ -296,48 +364,56 @@ class DLSSGMod //} } + _frameCount++; + auto index = _frameCount % FRAMES_IN_FLIGHT; + // Make a copy of the depth going to the frame generator // Fixes an issue with the depth being corrupted on AMD under Windows ID3D12Resource* dlssgDepth = nullptr; - if (Config::Instance()->MakeDepthCopy.value_or_default()) + if (Config::Instance()->NukemMakeResourceCopy.value_or_default()) InParameters->Get("DLSSG.Depth", &dlssgDepth); if (dlssgDepth) { - D3D12_RESOURCE_DESC desc = dlssgDepth->GetDesc(); - - D3D12_HEAP_PROPERTIES heapProperties; - D3D12_HEAP_FLAGS heapFlags; - - static ID3D12Resource* copiedDlssgDepth = nullptr; - if (copiedDlssgDepth != nullptr) + if (CreateBufferResource(State::Instance().currentD3D12Device, dlssgDepth, + D3D12_RESOURCE_STATE_COPY_DEST, &_copiedDlssgDepth[index])) { - copiedDlssgDepth->Release(); - copiedDlssgDepth = nullptr; + ResourceBarrier(InCmdList, dlssgDepth, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, + D3D12_RESOURCE_STATE_COPY_SOURCE); + + InCmdList->CopyResource(_copiedDlssgDepth[index], dlssgDepth); + + ResourceBarrier(InCmdList, dlssgDepth, D3D12_RESOURCE_STATE_COPY_SOURCE, + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + + // cast to make sure it's void*, otherwise dlssg cries + InParameters->Set("DLSSG.Depth", (void*) _copiedDlssgDepth[index]); } + } - if (dlssgDepth->GetHeapProperties(&heapProperties, &heapFlags) == S_OK) - { - auto result = State::Instance().currentD3D12Device->CreateCommittedResource( - &heapProperties, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, - IID_PPV_ARGS(&copiedDlssgDepth)); + // Make a copy of the MV going to the frame generator + // Fixes an issue with the MV being corrupted on AMD under Windows + ID3D12Resource* dlssgMV = nullptr; - if (result == S_OK) - { - InCmdList->CopyResource(copiedDlssgDepth, dlssgDepth); - InParameters->Set( - "DLSSG.Depth", - (void*) copiedDlssgDepth); // cast to make sure it's void*, otherwise dlssg cries - } - else - { - LOG_ERROR("Making a new resource for DLSSG Depth has failed"); - } - } - else + if (Config::Instance()->NukemMakeResourceCopy.value_or_default()) + InParameters->Get("DLSSG.MVecs", &dlssgMV); + + if (dlssgMV) + { + if (CreateBufferResource(State::Instance().currentD3D12Device, dlssgMV, D3D12_RESOURCE_STATE_COPY_DEST, + &_copiedDlssgMV[index])) { - LOG_ERROR("Getting heap properties has failed"); + ResourceBarrier(InCmdList, dlssgMV, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, + D3D12_RESOURCE_STATE_COPY_SOURCE); + + InCmdList->CopyResource(_copiedDlssgMV[index], dlssgMV); + + ResourceBarrier(InCmdList, dlssgMV, D3D12_RESOURCE_STATE_COPY_SOURCE, + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + + // cast to make sure it's void*, otherwise dlssg cries + InParameters->Set("DLSSG.MVecs", (void*) _copiedDlssgMV[index]); } } diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp index 62fefe14..9176851d 100644 --- a/OptiScaler/menu/menu_common.cpp +++ b/OptiScaler/menu/menu_common.cpp @@ -4168,11 +4168,13 @@ bool MenuCommon::RenderMenu() else ImGui::TextColored(ImVec4(1.f, 0.f, 0.f, 1.f), "OFF"); - if (bool makeDepthCopy = config->MakeDepthCopy.value_or_default(); - ImGui::Checkbox("Fix broken visuals", &makeDepthCopy)) - config->MakeDepthCopy = makeDepthCopy; - ShowHelpMarker("Makes a copy of the depth buffer\nCan fix broken visuals in some games on AMD " - "GPUs under Windows\nCan cause stutters, so best to use only when necessary"); + if (bool makeResourceCopy = config->NukemMakeResourceCopy.value_or_default(); + ImGui::Checkbox("Fix broken visuals", &makeResourceCopy)) + config->NukemMakeResourceCopy = makeResourceCopy; + + ShowHelpMarker( + "Makes a copy of the depth and MV buffer\nCan fix broken visuals in some games on AMD " + "GPUs under Windows\nCan cause stutters, so best to use only when necessary"); } else if (state.swapchainApi == Vulkan) { diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h index 0357a831..df627952 100644 --- a/OptiScaler/resource.h +++ b/OptiScaler/resource.h @@ -38,7 +38,6 @@ STRINGIZE(VER_MAJOR_VERSION) "." STRINGIZE(VER_MINOR_VERSION) "." STRINGIZE(VER_HOTFIX_VERSION) "." STRINGIZE(VER_BUILD_NUMBER) #define OPTI_VERSION STRINGIZE(VER_MAJOR_VERSION) "." STRINGIZE(VER_MINOR_VERSION) "." STRINGIZE(VER_HOTFIX_VERSION) - #define VER_PRODUCT_VERSION VER_FILE_VERSION #ifdef VER_PRE_RELEASE