diff --git a/OptiScaler.ini b/OptiScaler.ini
index d1d7c200..c1ddab16 100644
--- a/OptiScaler.ini
+++ b/OptiScaler.ini
@@ -91,6 +91,11 @@ RectHeight=auto
; true or false - Default (auto) is false
AlwaysTrackHeaps=auto
+; Track resource release
+; Most probably will tanks performance!!!
+; true or false - Default (auto) is false
+HudfixTrackRelease=auto
+
; Makes a copy of Depth to be used with Hudfix FG call
; Setting it false most probably cause occasional garbling
; true or false - Default (auto) is true
diff --git a/OptiScaler/Config.cpp b/OptiScaler/Config.cpp
index b65183bb..19eb7110 100644
--- a/OptiScaler/Config.cpp
+++ b/OptiScaler/Config.cpp
@@ -95,6 +95,7 @@ bool Config::Reload(std::filesystem::path iniPath)
FGHudfixHalfSync.set_from_config(readBool("OptiFG", "HudfixHalfSync"));
FGHudfixFullSync.set_from_config(readBool("OptiFG", "HudfixFullSync"));
+ FGHudfixTrackRelease.set_from_config(readBool("OptiFG", "HudfixTrackRelease"));
}
// Framerate
@@ -607,6 +608,7 @@ bool Config::SaveIni()
ini.SetValue("OptiFG", "HudfixHalfSync", GetBoolValue(Instance()->FGHudfixHalfSync.value_for_config()).c_str());
ini.SetValue("OptiFG", "HudfixFullSync", GetBoolValue(Instance()->FGHudfixFullSync.value_for_config()).c_str());
+ ini.SetValue("OptiFG", "HudfixTrackRelease", GetBoolValue(Instance()->FGHudfixTrackRelease.value_for_config()).c_str());
}
// Framerate
diff --git a/OptiScaler/OptiScaler.vcxproj b/OptiScaler/OptiScaler.vcxproj
index a6947dff..6ab8185c 100644
--- a/OptiScaler/OptiScaler.vcxproj
+++ b/OptiScaler/OptiScaler.vcxproj
@@ -226,9 +226,7 @@
true
stdcpplatest
NotUsing
- true
Speed
- true
Windows
@@ -275,9 +273,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
true
stdcpplatest
NotUsing
- true
Speed
- true
Windows
diff --git a/OptiScaler/OptiScaler.vcxproj.filters b/OptiScaler/OptiScaler.vcxproj.filters
index 383580b9..f87e7cab 100644
--- a/OptiScaler/OptiScaler.vcxproj.filters
+++ b/OptiScaler/OptiScaler.vcxproj.filters
@@ -467,6 +467,21 @@
Header Files
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
@@ -734,6 +749,21 @@
Source Files
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
diff --git a/OptiScaler/dllmain.cpp b/OptiScaler/dllmain.cpp
index 78220cf9..8b0dd5de 100644
--- a/OptiScaler/dllmain.cpp
+++ b/OptiScaler/dllmain.cpp
@@ -1044,7 +1044,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserv
break;
case DLL_THREAD_DETACH:
- //LOG_DEBUG_ONLY("DLL_THREAD_DETACH from module: {0:X}, count: {1}", (UINT64)hModule, loadCount);
+ //LOG_DEBUG_ONLY("DLL_THREAD_DETACH from module: {0:X}, count: {1}", (UINT64)hModule, loadCount);
break;
default:
diff --git a/OptiScaler/hooks/HooksDx.cpp b/OptiScaler/hooks/HooksDx.cpp
index 84c9ec89..a3421546 100644
--- a/OptiScaler/hooks/HooksDx.cpp
+++ b/OptiScaler/hooks/HooksDx.cpp
@@ -158,7 +158,7 @@ static HRESULT hkFGPresent(void* This, UINT SyncInterval, UINT Flags)
auto lockAccuired = false;
if (!(Flags & DXGI_PRESENT_TEST || Flags & DXGI_PRESENT_RESTART) && fg != nullptr && fg->IsActive() &&
- fg->TargetFrame() < fg->FrameCount() && Config::Instance()->FGUseMutexForSwaphain.value_or_default()) // && fg->Mutex.getOwner() != 2)
+ fg->TargetFrame() < fg->FrameCount() && Config::Instance()->FGUseMutexForSwaphain.value_or_default() && fg->Mutex.getOwner() != 2)
{
LOG_TRACE("Waiting FG->Mutex 2, current: {}", fg->Mutex.getOwner());
fg->Mutex.lock(2);
diff --git a/OptiScaler/menu/menu_common.cpp b/OptiScaler/menu/menu_common.cpp
index f23541ba..f57bb7c6 100644
--- a/OptiScaler/menu/menu_common.cpp
+++ b/OptiScaler/menu/menu_common.cpp
@@ -1690,6 +1690,14 @@ bool MenuCommon::RenderMenu()
}
ShowHelpMarker("Always track resources, might cause performace issues\nbut also might fix HudFix related crashes!");
+ auto tr = Config::Instance()->FGHudfixTrackRelease.value_or_default();
+ if (ImGui::Checkbox("Track Resource Release", &tr))
+ {
+ Config::Instance()->FGHudfixTrackRelease = tr;
+ LOG_DEBUG("Enabled set FGHudfixTrackRelease: {}", tr);
+ }
+ ShowHelpMarker("Track resource releases\nMost probably WILL TANK PERFORMANCE");
+
ImGui::TreePop();
}
diff --git a/OptiScaler/resource.h b/OptiScaler/resource.h
index 063b523d..a0badeec 100644
--- a/OptiScaler/resource.h
+++ b/OptiScaler/resource.h
@@ -28,7 +28,7 @@
#define VER_MAJOR_VERSION 0
#define VER_MINOR_VERSION 7
#define VER_HOTFIX_VERSION 7
-#define VER_BUILD_NUMBER 10
+#define VER_BUILD_NUMBER 11
#define VER_PRE_RELEASE
diff --git a/OptiScaler/resource_tracking/ResTrack_dx12.cpp b/OptiScaler/resource_tracking/ResTrack_dx12.cpp
index 9dfc0e0e..4b138d19 100644
--- a/OptiScaler/resource_tracking/ResTrack_dx12.cpp
+++ b/OptiScaler/resource_tracking/ResTrack_dx12.cpp
@@ -28,6 +28,10 @@ static UINT _trackMark = 1;
typedef void(*PFN_CreateRenderTargetView)(ID3D12Device* This, ID3D12Resource* pResource, D3D12_RENDER_TARGET_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
typedef void(*PFN_CreateShaderResourceView)(ID3D12Device* This, ID3D12Resource* pResource, D3D12_SHADER_RESOURCE_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
typedef void(*PFN_CreateUnorderedAccessView)(ID3D12Device* This, ID3D12Resource* pResource, ID3D12Resource* pCounterResource, D3D12_UNORDERED_ACCESS_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
+typedef void(*PFN_CreateDepthStencilView)(ID3D12Device* This, ID3D12Resource* pResource, const D3D12_DEPTH_STENCIL_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
+typedef void(*PFN_CreateConstantBufferView)(ID3D12Device* This, const D3D12_CONSTANT_BUFFER_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
+
+typedef void(*PFN_CreateSampler)(ID3D12Device* This, const D3D12_SAMPLER_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor);
typedef HRESULT(*PFN_CreateDescriptorHeap)(ID3D12Device* This, D3D12_DESCRIPTOR_HEAP_DESC* pDescriptorHeapDesc, REFIID riid, void** ppvHeap);
typedef void(*PFN_CopyDescriptors)(ID3D12Device* This, UINT NumDestDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pDestDescriptorRangeStarts, UINT* pDestDescriptorRangeSizes, UINT NumSrcDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pSrcDescriptorRangeStarts, UINT* pSrcDescriptorRangeSizes, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType);
@@ -59,6 +63,10 @@ typedef void(*PFN_DiscardResource)(ID3D12GraphicsCommandList* This, ID3D12Resour
static PFN_CreateRenderTargetView o_CreateRenderTargetView = nullptr;
static PFN_CreateShaderResourceView o_CreateShaderResourceView = nullptr;
static PFN_CreateUnorderedAccessView o_CreateUnorderedAccessView = nullptr;
+static PFN_CreateDepthStencilView o_CreateDepthStencilView = nullptr;
+static PFN_CreateConstantBufferView o_CreateConstantBufferView = nullptr;
+static PFN_CreateSampler o_CreateSampler = nullptr;
+
static PFN_CreateDescriptorHeap o_CreateDescriptorHeap = nullptr;
static PFN_CopyDescriptors o_CopyDescriptors = nullptr;
static PFN_CopyDescriptorsSimple o_CopyDescriptorsSimple = nullptr;
@@ -89,6 +97,19 @@ static std::mutex _resourceMutex;
// heaps
static std::vector fgHeaps;
+struct HeapCacheTLS
+{
+ HeapInfo* ptr = nullptr;
+ unsigned genSeen = 0;
+};
+
+static thread_local HeapCacheTLS cache;
+static thread_local HeapCacheTLS cacheRTV;
+static thread_local HeapCacheTLS cacheCBV;
+static thread_local HeapCacheTLS cacheSRV;
+static thread_local HeapCacheTLS cacheUAV;
+static std::atomic gHeapGeneration{ 1 };
+
#ifdef USE_RESOURCE_DISCARD
// created resources
static ankerl::unordered_dense::map > fgHandlesByResources;
@@ -253,13 +274,101 @@ static SIZE_T GetCPUHandle(ID3D12Device* This, SIZE_T gpuHandle, D3D12_DESCRIPTO
return NULL;
}
-static HeapInfo* GetHeapByCpuHandle(SIZE_T cpuHandle)
+static HeapInfo* GetHeapByCpuHandleCBV(SIZE_T cpuHandle)
{
- std::shared_lock lock(heapMutex);
+ unsigned currentGen = gHeapGeneration.load(std::memory_order_relaxed);
+
+ if (cacheCBV.genSeen == currentGen && cacheCBV.ptr && cacheCBV.ptr->cpuStart <= cpuHandle && cpuHandle < cacheCBV.ptr->cpuEnd)
+ return cacheCBV.ptr;
+
for (size_t i = 0; i < fgHeaps.size(); i++)
{
if (fgHeaps[i].cpuStart <= cpuHandle && fgHeaps[i].cpuEnd > cpuHandle)
- return &fgHeaps[i];
+ {
+ cacheCBV.ptr = &fgHeaps[i];
+ cacheCBV.genSeen = currentGen;
+ return cacheCBV.ptr;
+ }
+ }
+
+ return nullptr;
+}
+
+static HeapInfo* GetHeapByCpuHandleRTV(SIZE_T cpuHandle)
+{
+ unsigned currentGen = gHeapGeneration.load(std::memory_order_relaxed);
+
+ if (cacheRTV.genSeen == currentGen && cacheRTV.ptr && cacheRTV.ptr->cpuStart <= cpuHandle && cpuHandle < cacheRTV.ptr->cpuEnd)
+ return cacheRTV.ptr;
+
+ for (size_t i = 0; i < fgHeaps.size(); i++)
+ {
+ if (fgHeaps[i].cpuStart <= cpuHandle && fgHeaps[i].cpuEnd > cpuHandle)
+ {
+ cacheRTV.ptr = &fgHeaps[i];
+ cacheRTV.genSeen = currentGen;
+ return cacheRTV.ptr;
+ }
+ }
+
+ return nullptr;
+}
+
+static HeapInfo* GetHeapByCpuHandleSRV(SIZE_T cpuHandle)
+{
+ unsigned currentGen = gHeapGeneration.load(std::memory_order_relaxed);
+
+ if (cacheSRV.genSeen == currentGen && cacheSRV.ptr && cacheSRV.ptr->cpuStart <= cpuHandle && cpuHandle < cacheSRV.ptr->cpuEnd)
+ return cacheSRV.ptr;
+
+ for (size_t i = 0; i < fgHeaps.size(); i++)
+ {
+ if (fgHeaps[i].cpuStart <= cpuHandle && fgHeaps[i].cpuEnd > cpuHandle)
+ {
+ cacheSRV.ptr = &fgHeaps[i];
+ cacheSRV.genSeen = currentGen;
+ return cacheSRV.ptr;
+ }
+ }
+
+ return nullptr;
+}
+
+static HeapInfo* GetHeapByCpuHandleUAV(SIZE_T cpuHandle)
+{
+ unsigned currentGen = gHeapGeneration.load(std::memory_order_relaxed);
+
+ if (cacheUAV.genSeen == currentGen && cacheUAV.ptr && cacheUAV.ptr->cpuStart <= cpuHandle && cpuHandle < cacheUAV.ptr->cpuEnd)
+ return cacheUAV.ptr;
+
+ for (size_t i = 0; i < fgHeaps.size(); i++)
+ {
+ if (fgHeaps[i].cpuStart <= cpuHandle && fgHeaps[i].cpuEnd > cpuHandle)
+ {
+ cacheUAV.ptr = &fgHeaps[i];
+ cacheUAV.genSeen = currentGen;
+ return cacheUAV.ptr;
+ }
+ }
+
+ return nullptr;
+}
+
+static HeapInfo* GetHeapByCpuHandle(SIZE_T cpuHandle)
+{
+ unsigned currentGen = gHeapGeneration.load(std::memory_order_relaxed);
+
+ if (cache.genSeen == currentGen && cache.ptr && cache.ptr->cpuStart <= cpuHandle && cpuHandle < cache.ptr->cpuEnd)
+ return cache.ptr;
+
+ for (size_t i = 0; i < fgHeaps.size(); i++)
+ {
+ if (fgHeaps[i].cpuStart <= cpuHandle && fgHeaps[i].cpuEnd > cpuHandle)
+ {
+ cache.ptr = &fgHeaps[i];
+ cache.genSeen = currentGen;
+ return cache.ptr;
+ }
}
return nullptr;
@@ -267,7 +376,6 @@ static HeapInfo* GetHeapByCpuHandle(SIZE_T cpuHandle)
static HeapInfo* GetHeapByGpuHandle(SIZE_T gpuHandle)
{
- std::shared_lock lock(heapMutex);
for (size_t i = 0; i < fgHeaps.size(); i++)
{
if (fgHeaps[i].gpuStart <= gpuHandle && fgHeaps[i].gpuEnd >= gpuHandle)
@@ -433,6 +541,45 @@ static void hkDiscardResource(ID3D12GraphicsCommandList* This, ID3D12Resource* p
#pragma region Resource input hooks
+static void hkCreateSampler(ID3D12Device* This, const D3D12_SAMPLER_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
+{
+ o_CreateSampler(This, pDesc, DestDescriptor);
+
+ //if (DestDescriptor.ptr != 0)
+ //{
+ // auto heap = GetHeapByCpuHandle(DestDescriptor.ptr);
+
+ // if (heap != nullptr)
+ // heap->SetByCpuHandle(DestDescriptor.ptr, {});
+ //}
+}
+
+static void hkCreateDepthStencilView(ID3D12Device* This, ID3D12Resource* pResource, const D3D12_DEPTH_STENCIL_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
+{
+ o_CreateDepthStencilView(This, pResource, pDesc, DestDescriptor);
+
+ //if (DestDescriptor.ptr != 0)
+ //{
+ // auto heap = GetHeapByCpuHandle(DestDescriptor.ptr);
+
+ // if (heap != nullptr)
+ // heap->SetByCpuHandle(DestDescriptor.ptr, {});
+ //}
+}
+
+static void hkCreateConstantBufferView(ID3D12Device* This, const D3D12_CONSTANT_BUFFER_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
+{
+ o_CreateConstantBufferView(This, pDesc, DestDescriptor);
+
+ if (DestDescriptor.ptr != 0)
+ {
+ auto heap = GetHeapByCpuHandleCBV(DestDescriptor.ptr);
+
+ if (heap != nullptr)
+ heap->ClearByCpuHandle(DestDescriptor.ptr);
+ }
+}
+
static void hkCreateRenderTargetView(ID3D12Device* This, ID3D12Resource* pResource, D3D12_RENDER_TARGET_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor)
{
// force hdr for swapchain buffer
@@ -454,26 +601,24 @@ static void hkCreateRenderTargetView(ID3D12Device* This, ID3D12Resource* pResour
o_CreateRenderTargetView(This, pResource, pDesc, DestDescriptor);
- if (pResource == nullptr)
+ if (pResource == nullptr || (pDesc != nullptr && pDesc->ViewDimension != D3D12_RTV_DIMENSION_TEXTURE2D))
{
- LOG_TRACE("Unbind: {:X}", DestDescriptor.ptr);
+ LOG_DEBUG_ONLY("Unbind: {:X}", DestDescriptor.ptr);
- auto heap = GetHeapByCpuHandle(DestDescriptor.ptr);
-
-#ifdef USE_RESOURCE_DISCARD
- {
- std::lock_guard lock(_resourceMutex);
- auto temp = heap->GetByCpuHandle(DestDescriptor.ptr);
-
- if (temp != nullptr && temp->buffer != nullptr)
- RemoveResourceHeap(temp->buffer, DestDescriptor.ptr);
- }
-#endif
+ auto heap = GetHeapByCpuHandleRTV(DestDescriptor.ptr);
if (heap != nullptr)
- heap->SetByCpuHandle(DestDescriptor.ptr, {});
+ {
+#ifdef USE_RESOURCE_DISCARD
+ if (heap->buffer != nullptr)
+ {
+ std::lock_guard lock(_resourceMutex);
+ RemoveResourceHeap(heap->buffer, DestDescriptor.ptr);
+ }
+#endif
- return;
+ heap->ClearByCpuHandle(DestDescriptor.ptr);
+ }
}
if (pResource == nullptr || pDesc == nullptr || pDesc->ViewDimension != D3D12_RTV_DIMENSION_TEXTURE2D)
@@ -503,7 +648,7 @@ static void hkCreateRenderTargetView(ID3D12Device* This, ID3D12Resource* pResour
#endif // _DEBUG
- auto heap = GetHeapByCpuHandle(DestDescriptor.ptr);
+ auto heap = GetHeapByCpuHandleRTV(DestDescriptor.ptr);
if (heap != nullptr)
{
#ifdef USE_RESOURCE_DISCARD
@@ -543,11 +688,11 @@ static void hkCreateShaderResourceView(ID3D12Device* This, ID3D12Resource* pReso
o_CreateShaderResourceView(This, pResource, pDesc, DestDescriptor);
- if (pResource == nullptr)
+ if (pResource == nullptr || (pDesc != nullptr && pDesc->ViewDimension != D3D12_SRV_DIMENSION_TEXTURE2D))
{
- LOG_TRACE("Unbind: {:X}", DestDescriptor.ptr);
+ LOG_DEBUG_ONLY("Unbind: {:X}", DestDescriptor.ptr);
- auto heap = GetHeapByCpuHandle(DestDescriptor.ptr);
+ auto heap = GetHeapByCpuHandleSRV(DestDescriptor.ptr);
#ifdef USE_RESOURCE_DISCARD
{
@@ -560,9 +705,7 @@ static void hkCreateShaderResourceView(ID3D12Device* This, ID3D12Resource* pReso
#endif
if (heap != nullptr)
- heap->SetByCpuHandle(DestDescriptor.ptr, {});
-
- return;
+ heap->ClearByCpuHandle(DestDescriptor.ptr);
}
if (pResource == nullptr || pDesc == nullptr || pDesc->ViewDimension != D3D12_SRV_DIMENSION_TEXTURE2D)
@@ -592,7 +735,7 @@ static void hkCreateShaderResourceView(ID3D12Device* This, ID3D12Resource* pReso
#endif // _DEBUG
- auto heap = GetHeapByCpuHandle(DestDescriptor.ptr);
+ auto heap = GetHeapByCpuHandleSRV(DestDescriptor.ptr);
if (heap != nullptr)
{
#ifdef USE_RESOURCE_DISCARD
@@ -631,11 +774,11 @@ static void hkCreateUnorderedAccessView(ID3D12Device* This, ID3D12Resource* pRes
o_CreateUnorderedAccessView(This, pResource, pCounterResource, pDesc, DestDescriptor);
- if (pResource == nullptr)
+ if (pResource == nullptr || (pDesc != nullptr && pDesc->ViewDimension != D3D12_UAV_DIMENSION_TEXTURE2D))
{
- LOG_TRACE("Unbind: {:X}", DestDescriptor.ptr);
+ LOG_DEBUG_ONLY("Unbind: {:X}", DestDescriptor.ptr);
- auto heap = GetHeapByCpuHandle(DestDescriptor.ptr);
+ auto heap = GetHeapByCpuHandleUAV(DestDescriptor.ptr);
#ifdef USE_RESOURCE_DISCARD
{
@@ -648,9 +791,7 @@ static void hkCreateUnorderedAccessView(ID3D12Device* This, ID3D12Resource* pRes
#endif
if (heap != nullptr)
- heap->SetByCpuHandle(DestDescriptor.ptr, {});
-
- return;
+ heap->ClearByCpuHandle(DestDescriptor.ptr);
}
if (pResource == nullptr || pDesc == nullptr || pDesc->ViewDimension != D3D12_UAV_DIMENSION_TEXTURE2D)
@@ -680,8 +821,7 @@ static void hkCreateUnorderedAccessView(ID3D12Device* This, ID3D12Resource* pRes
#endif // _DEBUG
-
- auto heap = GetHeapByCpuHandle(DestDescriptor.ptr);
+ auto heap = GetHeapByCpuHandleUAV(DestDescriptor.ptr);
if (heap != nullptr)
{
#ifdef USE_RESOURCE_DISCARD
@@ -803,6 +943,7 @@ static HRESULT hkCreateDescriptorHeap(ID3D12Device* This, D3D12_DESCRIPTOR_HEAP_
{
std::unique_lock lock(heapMutex);
fgHeaps.push_back(info);
+ gHeapGeneration.fetch_add(1, std::memory_order_relaxed);
}
}
else
@@ -821,7 +962,7 @@ static HRESULT hkCreateDescriptorHeap(ID3D12Device* This, D3D12_DESCRIPTOR_HEAP_
ULONG ResTrack_Dx12::hkRelease(ID3D12Resource* This)
{
#ifndef USE_RESOURCE_DISCARD
- if(!Config::Instance()->FGHudfixTrackRelease.value_or_default())
+ if (!Config::Instance()->FGHudfixTrackRelease.value_or_default())
return o_Release(This);
#endif
@@ -905,10 +1046,7 @@ void ResTrack_Dx12::hkCopyDescriptors(ID3D12Device* This,
if (DescriptorHeapsType != D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV && DescriptorHeapsType != D3D12_DESCRIPTOR_HEAP_TYPE_RTV)
return;
- if (pDestDescriptorRangeStarts == nullptr || pSrcDescriptorRangeStarts == nullptr)
- return;
-
- if (pDestDescriptorRangeSizes == nullptr && pSrcDescriptorRangeSizes == nullptr)
+ if (pDestDescriptorRangeStarts == nullptr || (*pDestDescriptorRangeStarts).ptr == 0 || pDestDescriptorRangeSizes == nullptr)
return;
if (!Config::Instance()->FGAlwaysTrackHeaps.value_or_default() && !IsHudFixActive())
@@ -930,7 +1068,7 @@ void ResTrack_Dx12::hkCopyDescriptors(ID3D12Device* This,
auto size = This->GetDescriptorHandleIncrementSize(DescriptorHeapsType);
- if (srcRangeSizes != nullptr)
+ if (srcRangeStarts != nullptr && (*srcRangeStarts).ptr != 0 && srcRangeSizes != nullptr)
{
LOG_DEBUG_ONLY("Src based loop");
@@ -972,7 +1110,7 @@ void ResTrack_Dx12::hkCopyDescriptors(ID3D12Device* This,
}
#endif
- dstHeap->SetByCpuHandle(destHandle, {});
+ dstHeap->ClearByCpuHandle(destHandle);
}
if (destRangeSizes == nullptr || destRangeSizes[destRangeIndex] == destIndex)
@@ -1017,7 +1155,7 @@ void ResTrack_Dx12::hkCopyDescriptors(ID3D12Device* This,
RemoveResourceHeap(temp->buffer, destHandle);
}
#endif
- dstHeap->SetByCpuHandle(destHandle, {});
+ dstHeap->ClearByCpuHandle(destHandle);
if (destRangeSizes == nullptr || destRangeSizes[destRangeIndex] == destIndex)
{
@@ -1079,9 +1217,16 @@ void ResTrack_Dx12::hkCopyDescriptors(ID3D12Device* This,
{
LOG_DEBUG_ONLY("dstRangeIndex: {}, dstIndex: {}, srcRangeIndex: {}, srcIndex: {}", i, j, srcRangeIndex, srcIndex);
+ HeapInfo* srcHeap = nullptr;
+ unsigned long long srcHandle = 0;
+
// source
- auto srcHandle = srcRangeStarts[srcRangeIndex].ptr + srcIndex * size;
- auto srcHeap = GetHeapByCpuHandle(srcHandle);
+ if (srcRangeStarts != nullptr && (*srcRangeStarts).ptr != 0)
+ {
+ srcHandle = srcRangeStarts[srcRangeIndex].ptr + srcIndex * size;
+ srcHeap = GetHeapByCpuHandle(srcHandle);
+ }
+
auto destHandle = destRangeStarts[i].ptr + j * size;
auto dstHeap = GetHeapByCpuHandle(destHandle);
@@ -1102,7 +1247,7 @@ void ResTrack_Dx12::hkCopyDescriptors(ID3D12Device* This,
}
#endif
- dstHeap->SetByCpuHandle(destHandle, {});
+ dstHeap->ClearByCpuHandle(destHandle);
}
if (srcRangeSizes == nullptr || srcRangeSizes[srcRangeIndex] == srcIndex)
@@ -1148,7 +1293,7 @@ void ResTrack_Dx12::hkCopyDescriptors(ID3D12Device* This,
}
#endif
- dstHeap->SetByCpuHandle(destHandle, {});
+ dstHeap->ClearByCpuHandle(destHandle);
if (srcRangeSizes == nullptr || srcRangeSizes[srcRangeIndex] == srcIndex)
{
@@ -1208,38 +1353,41 @@ void ResTrack_Dx12::hkCopyDescriptorsSimple(ID3D12Device* This, UINT NumDescript
for (size_t i = 0; i < NumDescriptors; i++)
{
+ HeapInfo* srcHeap = nullptr;
+ unsigned long long srcHandle = 0;
+
// source
- auto srcHandle = SrcDescriptorRangeStart.ptr + i * size;
- auto srcHeap = GetHeapByCpuHandle(srcHandle);
- auto destHandle = DestDescriptorRangeStart.ptr + i * size;
- auto dstHeap = GetHeapByCpuHandle(destHandle);
-
- if (srcHeap == nullptr)
+ if (SrcDescriptorRangeStart.ptr != 0)
{
- if (dstHeap != nullptr)
- {
-#ifdef USE_RESOURCE_DISCARD
- {
- std::lock_guard lock(_resourceMutex);
- auto temp = dstHeap->GetByCpuHandle(destHandle);
-
- if (temp != nullptr && temp->buffer != nullptr)
- RemoveResourceHeap(temp->buffer, destHandle);
- }
-#endif
-
- dstHeap->SetByCpuHandle(destHandle, {});
- }
-
- continue;
+ srcHandle = SrcDescriptorRangeStart.ptr + i * size;
+ srcHeap = GetHeapByCpuHandle(srcHandle);
}
- auto buffer = srcHeap->GetByCpuHandle(srcHandle);
+ auto destHandle = DestDescriptorRangeStart.ptr + i * size;
+ auto dstHeap = GetHeapByCpuHandle(destHandle);
// destination
if (dstHeap == nullptr)
continue;
+ if (srcHeap == nullptr)
+ {
+#ifdef USE_RESOURCE_DISCARD
+ {
+ std::lock_guard lock(_resourceMutex);
+ auto temp = dstHeap->GetByCpuHandle(destHandle);
+
+ if (temp != nullptr && temp->buffer != nullptr)
+ RemoveResourceHeap(temp->buffer, destHandle);
+ }
+#endif
+
+ dstHeap->ClearByCpuHandle(destHandle);
+ continue;
+ }
+
+ auto buffer = srcHeap->GetByCpuHandle(srcHandle);
+
if (buffer == nullptr)
{
#ifdef USE_RESOURCE_DISCARD
@@ -1252,7 +1400,7 @@ void ResTrack_Dx12::hkCopyDescriptorsSimple(ID3D12Device* This, UINT NumDescript
}
#endif
- dstHeap->SetByCpuHandle(destHandle, {});
+ dstHeap->ClearByCpuHandle(destHandle);
continue;
}
@@ -1367,7 +1515,7 @@ void ResTrack_Dx12::hkOMSetRenderTargets(ID3D12GraphicsCommandList* This, UINT N
if (RTsSingleHandleToDescriptorRange)
{
- heap = GetHeapByCpuHandle(pRenderTargetDescriptors[0].ptr);
+ heap = GetHeapByCpuHandleRTV(pRenderTargetDescriptors[0].ptr);
if (heap == nullptr)
{
LOG_DEBUG_ONLY("No heap!");
@@ -1380,7 +1528,7 @@ void ResTrack_Dx12::hkOMSetRenderTargets(ID3D12GraphicsCommandList* This, UINT N
{
handle = pRenderTargetDescriptors[i];
- heap = GetHeapByCpuHandle(handle.ptr);
+ heap = GetHeapByCpuHandleRTV(handle.ptr);
if (heap == nullptr)
{
LOG_DEBUG_ONLY("No heap!");
@@ -1873,12 +2021,15 @@ void ResTrack_Dx12::HookDevice(ID3D12Device* device)
PVOID* pVTable = *(PVOID**)realDevice;
// hudless
- o_CreateRenderTargetView = (PFN_CreateRenderTargetView)pVTable[20];
o_CreateDescriptorHeap = (PFN_CreateDescriptorHeap)pVTable[14];
- o_CopyDescriptors = (PFN_CopyDescriptors)pVTable[23];
- o_CopyDescriptorsSimple = (PFN_CopyDescriptorsSimple)pVTable[24];
+ o_CreateConstantBufferView = (PFN_CreateConstantBufferView)pVTable[17];
o_CreateShaderResourceView = (PFN_CreateShaderResourceView)pVTable[18];
o_CreateUnorderedAccessView = (PFN_CreateUnorderedAccessView)pVTable[19];
+ o_CreateRenderTargetView = (PFN_CreateRenderTargetView)pVTable[20];
+ o_CreateDepthStencilView = (PFN_CreateDepthStencilView)pVTable[21];
+ o_CreateSampler = (PFN_CreateSampler)pVTable[22];
+ o_CopyDescriptors = (PFN_CopyDescriptors)pVTable[23];
+ o_CopyDescriptorsSimple = (PFN_CopyDescriptorsSimple)pVTable[24];
// Apply the detour
if (o_CreateDescriptorHeap != nullptr || o_CreateRenderTargetView != nullptr)
@@ -1891,9 +2042,18 @@ void ResTrack_Dx12::HookDevice(ID3D12Device* device)
if (Config::Instance()->FGType.value_or_default() == OptiFG && Config::Instance()->OverlayMenu.value_or_default())
{
+ if (o_CreateConstantBufferView != nullptr)
+ DetourAttach(&(PVOID&)o_CreateConstantBufferView, hkCreateConstantBufferView);
+
if (o_CreateRenderTargetView != nullptr)
DetourAttach(&(PVOID&)o_CreateRenderTargetView, hkCreateRenderTargetView);
+ //if (o_CreateDepthStencilView != nullptr)
+ // DetourAttach(&(PVOID&)o_CreateDepthStencilView, hkCreateDepthStencilView);
+
+ //if (o_CreateSampler != nullptr)
+ // DetourAttach(&(PVOID&)o_CreateSampler, hkCreateSampler);
+
if (o_CreateShaderResourceView != nullptr)
DetourAttach(&(PVOID&)o_CreateShaderResourceView, hkCreateShaderResourceView);
@@ -1905,6 +2065,7 @@ void ResTrack_Dx12::HookDevice(ID3D12Device* device)
if (o_CopyDescriptorsSimple != nullptr)
DetourAttach(&(PVOID&)o_CopyDescriptorsSimple, hkCopyDescriptorsSimple);
+
}
DetourTransactionCommit();
diff --git a/OptiScaler/resource_tracking/ResTrack_dx12.h b/OptiScaler/resource_tracking/ResTrack_dx12.h
index d56f8cf3..33a07289 100644
--- a/OptiScaler/resource_tracking/ResTrack_dx12.h
+++ b/OptiScaler/resource_tracking/ResTrack_dx12.h
@@ -35,16 +35,14 @@ typedef struct HeapInfo
HeapInfo(SIZE_T cpuStart, SIZE_T cpuEnd, SIZE_T gpuStart, SIZE_T gpuEnd, UINT numResources, UINT increment, UINT type)
: cpuStart(cpuStart), cpuEnd(cpuEnd), gpuStart(gpuStart), gpuEnd(gpuEnd), numDescriptors(numResources), increment(increment), info(new ResourceInfo[numResources]), type(type)
- {}
+ {
+ }
ResourceInfo* GetByCpuHandle(SIZE_T cpuHandle) const
{
- if (cpuStart > cpuHandle || cpuEnd < cpuHandle)
- return nullptr;
-
auto index = (cpuHandle - cpuStart) / increment;
- if (index >= numDescriptors || info[index].buffer == nullptr)
+ if (info[index].buffer == nullptr)
return nullptr;
return &info[index];
@@ -52,12 +50,9 @@ typedef struct HeapInfo
ResourceInfo* GetByGpuHandle(SIZE_T gpuHandle) const
{
- if (gpuStart > gpuHandle || gpuEnd < gpuHandle)
- return nullptr;
-
auto index = (gpuHandle - gpuStart) / increment;
- if (index >= numDescriptors || info[index].buffer == nullptr)
+ if (info[index].buffer == nullptr)
return nullptr;
return &info[index];
@@ -65,30 +60,33 @@ typedef struct HeapInfo
void SetByCpuHandle(SIZE_T cpuHandle, ResourceInfo setInfo) const
{
- if (cpuStart > cpuHandle || cpuEnd < cpuHandle)
- return;
-
auto index = (cpuHandle - cpuStart) / increment;
-
- if (index >= numDescriptors)
- return;
-
info[index] = setInfo;
}
void SetByGpuHandle(SIZE_T gpuHandle, ResourceInfo setInfo) const
{
- if (gpuStart > gpuHandle || gpuEnd < gpuHandle)
- return;
-
auto index = (gpuHandle - gpuStart) / increment;
-
- if (index >= numDescriptors)
- return;
-
info[index] = setInfo;
}
-} heap_info;
+
+ void ClearByCpuHandle(SIZE_T cpuHandle) const
+ {
+ auto index = (cpuHandle - cpuStart) / increment;
+
+ if (info[index].buffer != nullptr)
+ info[index].buffer = nullptr;
+ }
+
+ void ClearByGpuHandle(SIZE_T gpuHandle) const
+ {
+ auto index = (gpuHandle - gpuStart) / increment;
+
+ if (info[index].buffer != nullptr)
+ info[index].buffer = nullptr;
+ }
+
+} heap_info;
#else
// Vector version for lower heap usage
typedef struct HeapInfo
@@ -103,7 +101,8 @@ typedef struct HeapInfo
std::vector info;
HeapInfo(SIZE_T cpuStart, SIZE_T cpuEnd, SIZE_T gpuStart, SIZE_T gpuEnd, UINT numResources, UINT increment, UINT type)
- : cpuStart(cpuStart), cpuEnd(cpuEnd), gpuStart(gpuStart), gpuEnd(gpuEnd), numDescriptors(numResources), increment(increment), info(numResources), type(type) {}
+ : cpuStart(cpuStart), cpuEnd(cpuEnd), gpuStart(gpuStart), gpuEnd(gpuEnd), numDescriptors(numResources), increment(increment), info(numResources), type(type) {
+ }
ResourceInfo* GetByCpuHandle(SIZE_T cpuHandle)
{
@@ -161,14 +160,14 @@ private:
inline static std::mutex _drawMutex;
static bool IsHudFixActive();
-
+
static void hkCopyDescriptors(ID3D12Device* This,
UINT NumDestDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pDestDescriptorRangeStarts, UINT* pDestDescriptorRangeSizes,
UINT NumSrcDescriptorRanges, D3D12_CPU_DESCRIPTOR_HANDLE* pSrcDescriptorRangeStarts, UINT* pSrcDescriptorRangeSizes,
D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType);
static void hkCopyDescriptorsSimple(ID3D12Device* This, UINT NumDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart,
D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType);
-
+
static void hkSetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList* This, UINT RootParameterIndex, D3D12_GPU_DESCRIPTOR_HANDLE BaseDescriptor);
static void hkOMSetRenderTargets(ID3D12GraphicsCommandList* This, UINT NumRenderTargetDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE* pRenderTargetDescriptors,
BOOL RTsSingleHandleToDescriptorRange, D3D12_CPU_DESCRIPTOR_HANDLE* pDepthStencilDescriptor);