mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-08-26 08:06:33 +00:00
refactor vk & dx hooks
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
||||
#include "imgui/imgui_overlay_dx.h"
|
||||
#include "hooks/HooksDx.h"
|
||||
|
||||
|
||||
inline ID3D11Device* D3D11Device = nullptr;
|
||||
@@ -95,11 +95,11 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Init_Ext(unsigned long long InApp
|
||||
D3D11_QUERY_DESC timestampQueryDesc = {};
|
||||
timestampQueryDesc.Query = D3D11_QUERY_TIMESTAMP;
|
||||
|
||||
for (int i = 0; i < ImGuiOverlayDx::QUERY_BUFFER_COUNT; i++)
|
||||
for (int i = 0; i < HooksDx::QUERY_BUFFER_COUNT; i++)
|
||||
{
|
||||
InDevice->CreateQuery(&disjointQueryDesc, &ImGuiOverlayDx::disjointQueries[i]);
|
||||
InDevice->CreateQuery(×tampQueryDesc, &ImGuiOverlayDx::startQueries[i]);
|
||||
InDevice->CreateQuery(×tampQueryDesc, &ImGuiOverlayDx::endQueries[i]);
|
||||
InDevice->CreateQuery(&disjointQueryDesc, &HooksDx::disjointQueries[i]);
|
||||
InDevice->CreateQuery(×tampQueryDesc, &HooksDx::startQueries[i]);
|
||||
InDevice->CreateQuery(×tampQueryDesc, &HooksDx::endQueries[i]);
|
||||
}
|
||||
|
||||
return NVSDK_NGX_Result_Success;
|
||||
@@ -213,7 +213,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Shutdown()
|
||||
|
||||
// Unhooking and cleaning stuff causing issues during shutdown.
|
||||
// Disabled for now to check if it cause any issues
|
||||
//ImGuiOverlayDx::UnHookDx();
|
||||
//HooksDx::UnHookDx();
|
||||
|
||||
shutdown = false;
|
||||
|
||||
@@ -836,12 +836,12 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_EvaluateFeature(ID3D11DeviceConte
|
||||
}
|
||||
|
||||
// In the render loop:
|
||||
ImGuiOverlayDx::previousFrameIndex = (ImGuiOverlayDx::currentFrameIndex + ImGuiOverlayDx::QUERY_BUFFER_COUNT - 2) % ImGuiOverlayDx::QUERY_BUFFER_COUNT;
|
||||
int nextFrameIndex = ImGuiOverlayDx::currentFrameIndex;
|
||||
HooksDx::previousFrameIndex = (HooksDx::currentFrameIndex + HooksDx::QUERY_BUFFER_COUNT - 2) % HooksDx::QUERY_BUFFER_COUNT;
|
||||
int nextFrameIndex = HooksDx::currentFrameIndex;
|
||||
|
||||
// Record the queries in the current frame
|
||||
InDevCtx->Begin(ImGuiOverlayDx::disjointQueries[nextFrameIndex]);
|
||||
InDevCtx->End(ImGuiOverlayDx::startQueries[nextFrameIndex]);
|
||||
InDevCtx->Begin(HooksDx::disjointQueries[nextFrameIndex]);
|
||||
InDevCtx->End(HooksDx::startQueries[nextFrameIndex]);
|
||||
|
||||
if (!deviceContext->Evaluate(InDevCtx, InParameters) && !deviceContext->IsInited() && (deviceContext->Name() == "XeSS" || deviceContext->Name() == "DLSS" || deviceContext->Name() == "FSR3 w/Dx12"))
|
||||
{
|
||||
@@ -849,10 +849,10 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_EvaluateFeature(ID3D11DeviceConte
|
||||
Config::Instance()->changeBackend = true;
|
||||
}
|
||||
|
||||
InDevCtx->End(ImGuiOverlayDx::endQueries[nextFrameIndex]);
|
||||
InDevCtx->End(ImGuiOverlayDx::disjointQueries[nextFrameIndex]);
|
||||
InDevCtx->End(HooksDx::endQueries[nextFrameIndex]);
|
||||
InDevCtx->End(HooksDx::disjointQueries[nextFrameIndex]);
|
||||
|
||||
ImGuiOverlayDx::dx11UpscaleTrig[nextFrameIndex] = true;
|
||||
HooksDx::dx11UpscaleTrig[nextFrameIndex] = true;
|
||||
|
||||
return NVSDK_NGX_Result_Success;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "backends/fsr31/FSR31Feature_Dx12.h"
|
||||
#include "backends/xess/XeSSFeature_Dx12.h"
|
||||
|
||||
#include "imgui/imgui_overlay_dx.h"
|
||||
#include "hooks/HooksDx.h"
|
||||
|
||||
#include "detours/detours.h"
|
||||
#include <ankerl/unordered_dense.h>
|
||||
@@ -390,13 +390,13 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_Ext(unsigned long long InApp
|
||||
queryHeapDesc.Count = 2; // Start and End timestamps
|
||||
queryHeapDesc.NodeMask = 0;
|
||||
queryHeapDesc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP;
|
||||
auto result = InDevice->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&ImGuiOverlayDx::queryHeap));
|
||||
auto result = InDevice->CreateQueryHeap(&queryHeapDesc, IID_PPV_ARGS(&HooksDx::queryHeap));
|
||||
|
||||
// Create a readback buffer to retrieve timestamp data
|
||||
D3D12_RESOURCE_DESC bufferDesc = CD3DX12_RESOURCE_DESC::Buffer(2 * sizeof(UINT64));
|
||||
D3D12_HEAP_PROPERTIES heapProps = {};
|
||||
heapProps.Type = D3D12_HEAP_TYPE_READBACK;
|
||||
result = InDevice->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &bufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&ImGuiOverlayDx::readbackBuffer));
|
||||
result = InDevice->CreateCommittedResource(&heapProps, D3D12_HEAP_FLAG_NONE, &bufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, nullptr, IID_PPV_ARGS(&HooksDx::readbackBuffer));
|
||||
|
||||
if (_createContext == nullptr)
|
||||
LoadFSR31Funcs();
|
||||
@@ -523,9 +523,9 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown(void)
|
||||
|
||||
// Unhooking and cleaning stuff causing issues during shutdown.
|
||||
// Disabled for now to check if it cause any issues
|
||||
//ImGuiOverlayDx::UnHookDx();
|
||||
//HooksDx::UnHookDx();
|
||||
|
||||
ImGuiOverlayDx::StopAndDestroyFGContext(true, true);
|
||||
HooksDx::StopAndDestroyFGContext(true, true);
|
||||
|
||||
shutdown = false;
|
||||
|
||||
@@ -856,7 +856,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsComma
|
||||
HookToCommandList(InCmdList);
|
||||
evalCounter = 0;
|
||||
|
||||
ImGuiOverlayDx::fgTarget = 10;
|
||||
HooksDx::fgTarget = 10;
|
||||
|
||||
return NVSDK_NGX_Result_Success;
|
||||
}
|
||||
@@ -878,7 +878,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_ReleaseFeature(NVSDK_NGX_Handle*
|
||||
auto handleId = InHandle->Id;
|
||||
|
||||
Config::Instance()->FGChanged = true;
|
||||
ImGuiOverlayDx::StopAndDestroyFGContext(true, false);
|
||||
HooksDx::StopAndDestroyFGContext(true, false);
|
||||
|
||||
if (!shutdown)
|
||||
LOG_INFO("releasing feature with id {0}", handleId);
|
||||
@@ -1082,9 +1082,9 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
// first release everything
|
||||
if (changeBackendCounter == 1)
|
||||
{
|
||||
if (ImGuiOverlayDx::fgContext != nullptr)
|
||||
if (HooksDx::fgContext != nullptr)
|
||||
{
|
||||
ImGuiOverlayDx::StopAndDestroyFGContext(false, false);
|
||||
HooksDx::StopAndDestroyFGContext(false, false);
|
||||
}
|
||||
|
||||
if (Dx12Contexts.contains(handleId))
|
||||
@@ -1254,7 +1254,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
|
||||
// if initial feature can't be inited
|
||||
Config::Instance()->CurrentFeature = Dx12Contexts[handleId].get();
|
||||
ImGuiOverlayDx::fgTarget = 10;
|
||||
HooksDx::fgTarget = 10;
|
||||
|
||||
return NVSDK_NGX_Result_Success;
|
||||
}
|
||||
@@ -1297,22 +1297,22 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
// FG Init || Disable
|
||||
if (Config::Instance()->FGUseFGSwapChain.value_or(true) && Config::Instance()->OverlayMenu.value_or(true))
|
||||
{
|
||||
if (!Config::Instance()->FGChanged && ImGuiOverlayDx::fgTarget < deviceContext->FrameCount() && Config::Instance()->FGEnabled.value_or(false) &&
|
||||
_createContext != nullptr && !ImGuiOverlayDx::fgIsActive && ImGuiOverlayDx::currentSwapchain != nullptr &&
|
||||
ImGuiOverlayDx::swapchainFormat != DXGI_FORMAT_UNKNOWN)
|
||||
if (!Config::Instance()->FGChanged && HooksDx::fgTarget < deviceContext->FrameCount() && Config::Instance()->FGEnabled.value_or(false) &&
|
||||
_createContext != nullptr && !HooksDx::fgIsActive && HooksDx::currentSwapchain != nullptr &&
|
||||
HooksDx::swapchainFormat != DXGI_FORMAT_UNKNOWN)
|
||||
{
|
||||
ImGuiOverlayDx::CreateFGObjects(D3D12Device);
|
||||
ImGuiOverlayDx::CreateFGContext(D3D12Device, deviceContext);
|
||||
HooksDx::CreateFGObjects(D3D12Device);
|
||||
HooksDx::CreateFGContext(D3D12Device, deviceContext);
|
||||
}
|
||||
else if ((!Config::Instance()->FGEnabled.value_or(false) || Config::Instance()->FGChanged) && ImGuiOverlayDx::fgIsActive)
|
||||
else if ((!Config::Instance()->FGEnabled.value_or(false) || Config::Instance()->FGChanged) && HooksDx::fgIsActive)
|
||||
{
|
||||
ImGuiOverlayDx::StopAndDestroyFGContext(Config::Instance()->SCChanged, false);
|
||||
HooksDx::StopAndDestroyFGContext(Config::Instance()->SCChanged, false);
|
||||
}
|
||||
|
||||
if (Config::Instance()->FGChanged)
|
||||
{
|
||||
LOG_DEBUG(" FG disabled for 10 frames");
|
||||
ImGuiOverlayDx::fgTarget = deviceContext->FrameCount() + 20;
|
||||
HooksDx::fgTarget = deviceContext->FrameCount() + 20;
|
||||
Config::Instance()->FGChanged = false;
|
||||
}
|
||||
}
|
||||
@@ -1320,17 +1320,17 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
Config::Instance()->SCChanged = false;
|
||||
|
||||
// Record the first timestamp (before FSR2 upscaling)
|
||||
InCmdList->EndQuery(ImGuiOverlayDx::queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0);
|
||||
InCmdList->EndQuery(HooksDx::queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0);
|
||||
|
||||
bool evalResult = deviceContext->Evaluate(InCmdList, InParameters);
|
||||
|
||||
// Record the second timestamp (after FSR2 upscaling)
|
||||
InCmdList->EndQuery(ImGuiOverlayDx::queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 1);
|
||||
InCmdList->EndQuery(HooksDx::queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 1);
|
||||
|
||||
// Resolve the queries to the readback buffer
|
||||
InCmdList->ResolveQueryData(ImGuiOverlayDx::queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0, 2, ImGuiOverlayDx::readbackBuffer, 0);
|
||||
InCmdList->ResolveQueryData(HooksDx::queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, 0, 2, HooksDx::readbackBuffer, 0);
|
||||
|
||||
ImGuiOverlayDx::dx12UpscaleTrig = true;
|
||||
HooksDx::dx12UpscaleTrig = true;
|
||||
|
||||
if (deviceContext->Name() != "DLSSD" && (Config::Instance()->RestoreComputeSignature.value_or(false) || Config::Instance()->RestoreGraphicSignature.value_or(false)))
|
||||
{
|
||||
@@ -1380,9 +1380,9 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
if (evalResult)
|
||||
{
|
||||
// FG Dispatch || Prepare
|
||||
if (ImGuiOverlayDx::fgIsActive && Config::Instance()->FGUseFGSwapChain.value_or(true) && Config::Instance()->OverlayMenu.value_or(true) &&
|
||||
Config::Instance()->FGEnabled.value_or(false) && ImGuiOverlayDx::fgTarget < deviceContext->FrameCount() &&
|
||||
ImGuiOverlayDx::fgContext != nullptr && ImGuiOverlayDx::currentSwapchain != nullptr)
|
||||
if (HooksDx::fgIsActive && Config::Instance()->FGUseFGSwapChain.value_or(true) && Config::Instance()->OverlayMenu.value_or(true) &&
|
||||
Config::Instance()->FGEnabled.value_or(false) && HooksDx::fgTarget < deviceContext->FrameCount() &&
|
||||
HooksDx::fgContext != nullptr && HooksDx::currentSwapchain != nullptr)
|
||||
{
|
||||
float msDelta = 0.0;
|
||||
auto now = Util::MillisecondsNow();
|
||||
@@ -1398,15 +1398,15 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
ID3D12Resource* output;
|
||||
InParameters->Get(NVSDK_NGX_Parameter_Output, &output);
|
||||
|
||||
auto frameIndex = ImGuiOverlayDx::ClearFrameResources();
|
||||
ImGuiOverlayDx::NewFrame();
|
||||
ImGuiOverlayDx::fgUpscaledImage[frameIndex] = output;
|
||||
auto frameIndex = HooksDx::ClearFrameResources();
|
||||
HooksDx::NewFrame();
|
||||
HooksDx::fgUpscaledImage[frameIndex] = output;
|
||||
|
||||
auto allocator = ImGuiOverlayDx::fgCopyCommandAllocators[frameIndex];
|
||||
auto allocator = HooksDx::fgCopyCommandAllocators[frameIndex];
|
||||
auto result = allocator->Reset();
|
||||
result = ImGuiOverlayDx::fgCopyCommandList->Reset(allocator, nullptr);
|
||||
result = HooksDx::fgCopyCommandList->Reset(allocator, nullptr);
|
||||
|
||||
if (!Config::Instance()->FGHUDFix.value_or(false) || ImGuiOverlayDx::fgTarget > deviceContext->FrameCount())
|
||||
if (!Config::Instance()->FGHUDFix.value_or(false) || HooksDx::fgTarget > deviceContext->FrameCount())
|
||||
{
|
||||
LOG_DEBUG("FG running, frame: {0}", deviceContext->FrameCount());
|
||||
|
||||
@@ -1415,9 +1415,9 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
|
||||
ffxConfigureDescFrameGeneration m_FrameGenerationConfig = {};
|
||||
|
||||
if (desc.Format == ImGuiOverlayDx::swapchainFormat)
|
||||
if (desc.Format == HooksDx::swapchainFormat)
|
||||
{
|
||||
LOG_DEBUG("FG desc.Format == ImGuiOverlayDx::swapchainFormat, using hudless!");
|
||||
LOG_DEBUG("FG desc.Format == HooksDx::swapchainFormat, using hudless!");
|
||||
m_FrameGenerationConfig.HUDLessColor = ffxApiGetResourceDX12(output, FFX_API_RESOURCE_STATE_UNORDERED_ACCESS, 0);
|
||||
}
|
||||
else
|
||||
@@ -1443,26 +1443,30 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
m_FrameGenerationConfig.frameGenerationCallback = [](ffxDispatchDescFrameGeneration* params, void* pUserCtx) -> ffxReturnCode_t
|
||||
{
|
||||
#ifdef USE_COPY_QUEUE_FOR_FG
|
||||
auto fIndex = ImGuiOverlayDx::GetFrame();
|
||||
auto fIndex = HooksDx::GetFrame();
|
||||
|
||||
// check for status
|
||||
if (!Config::Instance()->FGEnabled.value_or(false) || Config::Instance()->FGChanged ||
|
||||
ImGuiOverlayDx::fgContext == nullptr || ImGuiOverlayDx::fgCopyCommandList == nullptr ||
|
||||
ImGuiOverlayDx::fgCopyCommandQueue == nullptr || !ImGuiOverlayDx::fgIsActive)
|
||||
HooksDx::fgContext == nullptr || HooksDx::fgCopyCommandList == nullptr ||
|
||||
HooksDx::fgCopyCommandQueue == nullptr)
|
||||
{
|
||||
LOG_WARN("Cancel async dispatch");
|
||||
ImGuiOverlayDx::fgSkipHudlessChecks = false;
|
||||
HooksDx::fgSkipHudlessChecks = false;
|
||||
return FFX_API_RETURN_OK;
|
||||
}
|
||||
|
||||
// If fg is active but upscaling paused
|
||||
if (Config::Instance()->CurrentFeature == nullptr || fgLastFGFrame == Config::Instance()->CurrentFeature->FrameCount())
|
||||
if (Config::Instance()->CurrentFeature == nullptr || !HooksDx::fgIsActive ||
|
||||
fgLastFGFrame == Config::Instance()->CurrentFeature->FrameCount())
|
||||
{
|
||||
LOG_WARN("Callback without hudless!");
|
||||
|
||||
auto allocator = ImGuiOverlayDx::fgCopyCommandAllocators[fIndex];
|
||||
auto allocator = HooksDx::fgCopyCommandAllocators[fIndex];
|
||||
auto result = allocator->Reset();
|
||||
result = ImGuiOverlayDx::fgCopyCommandList->Reset(allocator, nullptr);
|
||||
result = HooksDx::fgCopyCommandList->Reset(allocator, nullptr);
|
||||
|
||||
params->frameID = fgLastFGFrame;
|
||||
params->numGeneratedFrames = 0;
|
||||
}
|
||||
|
||||
if (Config::Instance()->CurrentFeature != nullptr)
|
||||
@@ -1471,13 +1475,13 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
auto result = _dispatch(reinterpret_cast<ffxContext*>(pUserCtx), ¶ms->header);
|
||||
|
||||
ID3D12CommandList* cl[1] = { nullptr };
|
||||
result = ImGuiOverlayDx::fgCopyCommandList->Close();
|
||||
cl[0] = ImGuiOverlayDx::fgCopyCommandList;
|
||||
ImGuiOverlayDx::gameCommandQueue->ExecuteCommandLists(1, cl);
|
||||
result = HooksDx::fgCopyCommandList->Close();
|
||||
cl[0] = HooksDx::fgCopyCommandList;
|
||||
HooksDx::gameCommandQueue->ExecuteCommandLists(1, cl);
|
||||
|
||||
return result;
|
||||
#else
|
||||
if (!Config::Instance()->FGEnabled.value_or(false) || Config::Instance()->FGChanged || Config::Instance()->CurrentFeature == nullptr || ImGuiOverlayDx::fgContext == nullptr)
|
||||
if (!Config::Instance()->FGEnabled.value_or(false) || Config::Instance()->FGChanged || Config::Instance()->CurrentFeature == nullptr || HooksDx::fgContext == nullptr)
|
||||
return FFX_API_RETURN_OK;
|
||||
|
||||
auto result = _dispatch(reinterpret_cast<ffxContext*>(pUserCtx), ¶ms->header);
|
||||
@@ -1485,10 +1489,10 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
#endif
|
||||
};
|
||||
|
||||
m_FrameGenerationConfig.frameGenerationCallbackUserContext = &ImGuiOverlayDx::fgContext;
|
||||
m_FrameGenerationConfig.frameGenerationCallbackUserContext = &HooksDx::fgContext;
|
||||
m_FrameGenerationConfig.onlyPresentGenerated = Config::Instance()->FGOnlyGenerated; // check here
|
||||
m_FrameGenerationConfig.frameID = deviceContext->FrameCount();
|
||||
m_FrameGenerationConfig.swapChain = ImGuiOverlayDx::currentSwapchain;
|
||||
m_FrameGenerationConfig.swapChain = HooksDx::currentSwapchain;
|
||||
|
||||
ffxConfigureDescGlobalDebug1 debugDesc;
|
||||
debugDesc.header.type = FFX_API_CONFIGURE_DESC_TYPE_GLOBALDEBUG1;
|
||||
@@ -1497,7 +1501,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
m_FrameGenerationConfig.header.pNext = &debugDesc.header;
|
||||
|
||||
Config::Instance()->dxgiSkipSpoofing = true;
|
||||
ffxReturnCode_t retCode = _configure(&ImGuiOverlayDx::fgContext, &m_FrameGenerationConfig.header);
|
||||
ffxReturnCode_t retCode = _configure(&HooksDx::fgContext, &m_FrameGenerationConfig.header);
|
||||
Config::Instance()->dxgiSkipSpoofing = false;
|
||||
LOG_DEBUG(" FG _configure result: {0:X}", retCode);
|
||||
|
||||
@@ -1512,7 +1516,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
dfgPrepare.header.pNext = &backendDesc.header;
|
||||
|
||||
#ifdef USE_COPY_QUEUE_FOR_FG
|
||||
dfgPrepare.commandList = ImGuiOverlayDx::fgCopyCommandList;
|
||||
dfgPrepare.commandList = HooksDx::fgCopyCommandList;
|
||||
#else
|
||||
dfgPrepare.commandList = InCmdList;
|
||||
#endif
|
||||
@@ -1528,15 +1532,15 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
if (InParameters->Get(NVSDK_NGX_Parameter_MotionVectors, ¶mVelocity) != NVSDK_NGX_Result_Success)
|
||||
InParameters->Get(NVSDK_NGX_Parameter_MotionVectors, (void**)¶mVelocity);
|
||||
|
||||
if (CreateBufferResource(L"fgVelocity", D3D12Device, paramVelocity, D3D12_RESOURCE_STATE_COPY_DEST, &ImGuiOverlayDx::paramVelocity[frameIndex]))
|
||||
InCmdList->CopyResource(ImGuiOverlayDx::paramVelocity[frameIndex], paramVelocity);
|
||||
if (CreateBufferResource(L"fgVelocity", D3D12Device, paramVelocity, D3D12_RESOURCE_STATE_COPY_DEST, &HooksDx::paramVelocity[frameIndex]))
|
||||
InCmdList->CopyResource(HooksDx::paramVelocity[frameIndex], paramVelocity);
|
||||
|
||||
ID3D12Resource* paramDepth;
|
||||
if (InParameters->Get(NVSDK_NGX_Parameter_Depth, ¶mDepth) != NVSDK_NGX_Result_Success)
|
||||
InParameters->Get(NVSDK_NGX_Parameter_Depth, (void**)¶mDepth);
|
||||
|
||||
if (CreateBufferResource(L"fgDepth", D3D12Device, paramDepth, D3D12_RESOURCE_STATE_COPY_DEST, &ImGuiOverlayDx::paramDepth[frameIndex]))
|
||||
InCmdList->CopyResource(ImGuiOverlayDx::paramDepth[frameIndex], paramDepth);
|
||||
if (CreateBufferResource(L"fgDepth", D3D12Device, paramDepth, D3D12_RESOURCE_STATE_COPY_DEST, &HooksDx::paramDepth[frameIndex]))
|
||||
InCmdList->CopyResource(HooksDx::paramDepth[frameIndex], paramDepth);
|
||||
#else
|
||||
ID3D12Resource* paramVelocity;
|
||||
if (InParameters->Get(NVSDK_NGX_Parameter_MotionVectors, ¶mVelocity) != NVSDK_NGX_Result_Success)
|
||||
@@ -1551,8 +1555,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
dfgPrepare.depth = ffxApiGetResourceDX12(paramDepth, FFX_API_RESOURCE_STATE_COMPUTE_READ);
|
||||
#endif
|
||||
|
||||
dfgPrepare.motionVectors = ffxApiGetResourceDX12(ImGuiOverlayDx::paramVelocity[frameIndex], FFX_API_RESOURCE_STATE_COMPUTE_READ);
|
||||
dfgPrepare.depth = ffxApiGetResourceDX12(ImGuiOverlayDx::paramDepth[frameIndex], FFX_API_RESOURCE_STATE_COMPUTE_READ);
|
||||
dfgPrepare.motionVectors = ffxApiGetResourceDX12(HooksDx::paramVelocity[frameIndex], FFX_API_RESOURCE_STATE_COMPUTE_READ);
|
||||
dfgPrepare.depth = ffxApiGetResourceDX12(HooksDx::paramDepth[frameIndex], FFX_API_RESOURCE_STATE_COMPUTE_READ);
|
||||
|
||||
float MVScaleX = 1.0f;
|
||||
float MVScaleY = 1.0f;
|
||||
@@ -1587,39 +1591,39 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom
|
||||
dfgPrepare.frameTimeDelta = msDelta;
|
||||
|
||||
Config::Instance()->dxgiSkipSpoofing = true;
|
||||
retCode = _dispatch(&ImGuiOverlayDx::fgContext, &dfgPrepare.header);
|
||||
retCode = _dispatch(&HooksDx::fgContext, &dfgPrepare.header);
|
||||
Config::Instance()->dxgiSkipSpoofing = false;
|
||||
LOG_DEBUG(" FG _dispatch result: {0}", retCode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ImGuiOverlayDx::upscaleRan = true;
|
||||
HooksDx::upscaleRan = true;
|
||||
|
||||
LOG_DEBUG("Set fgUpscaledImage[{}]", frameIndex);
|
||||
|
||||
LOG_DEBUG("HUDFix copy buffers running, frame: {0}", deviceContext->FrameCount());
|
||||
InParameters->Get(NVSDK_NGX_Parameter_Jitter_Offset_X, &ImGuiOverlayDx::jitterX);
|
||||
InParameters->Get(NVSDK_NGX_Parameter_Jitter_Offset_Y, &ImGuiOverlayDx::jitterY);
|
||||
InParameters->Get(NVSDK_NGX_Parameter_Jitter_Offset_X, &HooksDx::jitterX);
|
||||
InParameters->Get(NVSDK_NGX_Parameter_Jitter_Offset_Y, &HooksDx::jitterY);
|
||||
|
||||
ID3D12Resource* paramVelocity;
|
||||
if (InParameters->Get(NVSDK_NGX_Parameter_MotionVectors, ¶mVelocity) != NVSDK_NGX_Result_Success)
|
||||
InParameters->Get(NVSDK_NGX_Parameter_MotionVectors, (void**)¶mVelocity);
|
||||
|
||||
if (CreateBufferResource(L"fgVelocity", D3D12Device, paramVelocity, D3D12_RESOURCE_STATE_COPY_DEST, &ImGuiOverlayDx::paramVelocity[frameIndex]))
|
||||
InCmdList->CopyResource(ImGuiOverlayDx::paramVelocity[frameIndex], paramVelocity);
|
||||
if (CreateBufferResource(L"fgVelocity", D3D12Device, paramVelocity, D3D12_RESOURCE_STATE_COPY_DEST, &HooksDx::paramVelocity[frameIndex]))
|
||||
InCmdList->CopyResource(HooksDx::paramVelocity[frameIndex], paramVelocity);
|
||||
|
||||
ID3D12Resource* paramDepth;
|
||||
if (InParameters->Get(NVSDK_NGX_Parameter_Depth, ¶mDepth) != NVSDK_NGX_Result_Success)
|
||||
InParameters->Get(NVSDK_NGX_Parameter_Depth, (void**)¶mDepth);
|
||||
|
||||
if (CreateBufferResource(L"fgDepth", D3D12Device, paramDepth, D3D12_RESOURCE_STATE_COPY_DEST, &ImGuiOverlayDx::paramDepth[frameIndex]))
|
||||
InCmdList->CopyResource(ImGuiOverlayDx::paramDepth[frameIndex], paramDepth);
|
||||
if (CreateBufferResource(L"fgDepth", D3D12Device, paramDepth, D3D12_RESOURCE_STATE_COPY_DEST, &HooksDx::paramDepth[frameIndex]))
|
||||
InCmdList->CopyResource(HooksDx::paramDepth[frameIndex], paramDepth);
|
||||
|
||||
InParameters->Get(NVSDK_NGX_Parameter_MV_Scale_X, &ImGuiOverlayDx::mvScaleX);
|
||||
InParameters->Get(NVSDK_NGX_Parameter_MV_Scale_Y, &ImGuiOverlayDx::mvScaleY);
|
||||
InParameters->Get(NVSDK_NGX_Parameter_MV_Scale_X, &HooksDx::mvScaleX);
|
||||
InParameters->Get(NVSDK_NGX_Parameter_MV_Scale_Y, &HooksDx::mvScaleY);
|
||||
|
||||
ImGuiOverlayDx::fgFrameTime = msDelta;
|
||||
HooksDx::fgFrameTime = msDelta;
|
||||
|
||||
LOG_DEBUG("HUDFix copy buffers done, frame: {0}", deviceContext->FrameCount());
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "backends/fsr2_212/FSR2Feature_Vk_212.h"
|
||||
#include "backends/fsr31/FSR31Feature_Vk.h"
|
||||
|
||||
#include "imgui/imgui_overlay_vk.h"
|
||||
#include "hooks/HooksVk.h"
|
||||
|
||||
#include "NVNGX_Parameter.h"
|
||||
#include "NVNGX_Proxy.h"
|
||||
@@ -164,11 +164,11 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_Ext2(unsigned long long InA
|
||||
queryPoolInfo.queryType = VK_QUERY_TYPE_TIMESTAMP;
|
||||
queryPoolInfo.queryCount = 2; // Start and End timestamps
|
||||
|
||||
vkCreateQueryPool(InDevice, &queryPoolInfo, nullptr, &ImGuiOverlayVk::queryPool);
|
||||
vkCreateQueryPool(InDevice, &queryPoolInfo, nullptr, &HooksVk::queryPool);
|
||||
|
||||
VkPhysicalDeviceProperties deviceProperties;
|
||||
vkGetPhysicalDeviceProperties(InPD, &deviceProperties);
|
||||
ImGuiOverlayVk::timeStampPeriod = deviceProperties.limits.timestampPeriod;
|
||||
HooksVk::timeStampPeriod = deviceProperties.limits.timestampPeriod;
|
||||
|
||||
return NVSDK_NGX_Result_Success;
|
||||
}
|
||||
@@ -961,13 +961,13 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer
|
||||
Config::Instance()->RenderMenu = true;
|
||||
|
||||
// Record the first timestamp (before FSR2)
|
||||
vkCmdWriteTimestamp(InCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, ImGuiOverlayVk::queryPool, 0);
|
||||
vkCmdWriteTimestamp(InCmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, HooksVk::queryPool, 0);
|
||||
|
||||
auto upscaleResult = deviceContext->Evaluate(InCmdBuffer, InParameters);
|
||||
|
||||
// Record the second timestamp (after FSR2)
|
||||
vkCmdWriteTimestamp(InCmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, ImGuiOverlayVk::queryPool, 1);
|
||||
ImGuiOverlayVk::vkUpscaleTrig = true;
|
||||
vkCmdWriteTimestamp(InCmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, HooksVk::queryPool, 1);
|
||||
HooksVk::vkUpscaleTrig = true;
|
||||
|
||||
return upscaleResult ? NVSDK_NGX_Result_Success : NVSDK_NGX_Result_Fail;
|
||||
}
|
||||
|
||||
@@ -81,8 +81,8 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>$(SolutionDir)external\vulkan\include;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\FidelityFX-SDK\ffx-api\include\ffx_api;$(SolutionDir)external\simpleini;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\spdlog\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)fsr2\lib;$(ProjectDir)fsr2_212\lib;$(ProjectDir)fsr31\lib;$(ProjectDir)vulkan;$(ProjectDir)d3dx;$(ProjectDir)detours;$(SolutionDir)external\xess\lib;$(LibraryPath)</LibraryPath>
|
||||
<TargetName>dxgi</TargetName>
|
||||
<OutDir>D:\Folders\Games\Kena - Bridge of Spirits\Kena\Binaries\Win64\</OutDir>
|
||||
<TargetName>version</TargetName>
|
||||
<OutDir>D:\Folders\Games\No Man%27s Sky\Binaries\</OutDir>
|
||||
<IntDir>.\x64\Debug</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
@@ -208,6 +208,8 @@ copy $(SolutionDir)nvngx.ini $(SolutionDir)x64\Release\a\</Command>
|
||||
<ClInclude Include="bias\precompile\Bias_Shader.h" />
|
||||
<ClInclude Include="format_transfer\FT_Common.h" />
|
||||
<ClInclude Include="format_transfer\FT_Dx12.h" />
|
||||
<ClInclude Include="hooks\HooksDx.h" />
|
||||
<ClInclude Include="hooks\HooksVk.h" />
|
||||
<ClInclude Include="output_scaling\OS_Common.h" />
|
||||
<ClInclude Include="output_scaling\OS_Dx12.h" />
|
||||
<ClInclude Include="output_scaling\precompile\BCDS_Shader.h" />
|
||||
@@ -248,7 +250,7 @@ copy $(SolutionDir)nvngx.ini $(SolutionDir)x64\Release\a\</Command>
|
||||
<ClInclude Include="imgui\imgui_overlay_base.h" />
|
||||
<ClInclude Include="imgui\imgui_overlay_dx.h" />
|
||||
<ClInclude Include="imgui\imgui_overlay_vk.h" />
|
||||
<ClInclude Include="imgui\wrapped_swapchain.h" />
|
||||
<ClInclude Include="hooks\wrapped_swapchain.h" />
|
||||
<ClInclude Include="Logger.h" />
|
||||
<ClInclude Include="NVNGX_Parameter.h" />
|
||||
<ClInclude Include="NVNGX_Proxy.h" />
|
||||
@@ -295,6 +297,8 @@ copy $(SolutionDir)nvngx.ini $(SolutionDir)x64\Release\a\</Command>
|
||||
<ClCompile Include="backends\IFeature.cpp" />
|
||||
<ClCompile Include="backends\IFeature_Dx12.cpp" />
|
||||
<ClCompile Include="format_transfer\FT_Dx12.cpp" />
|
||||
<ClCompile Include="hooks\HooksDx.cpp" />
|
||||
<ClCompile Include="hooks\HooksVk.cpp" />
|
||||
<ClCompile Include="imgui\imgui\imgui.cpp" />
|
||||
<ClCompile Include="imgui\imgui\imgui_demo.cpp" />
|
||||
<ClCompile Include="imgui\imgui\imgui_draw.cpp" />
|
||||
@@ -311,7 +315,7 @@ copy $(SolutionDir)nvngx.ini $(SolutionDir)x64\Release\a\</Command>
|
||||
<ClCompile Include="imgui\imgui_overlay_base.cpp" />
|
||||
<ClCompile Include="imgui\imgui_overlay_dx.cpp" />
|
||||
<ClCompile Include="imgui\imgui_overlay_vk.cpp" />
|
||||
<ClCompile Include="imgui\wrapped_swapchain.cpp" />
|
||||
<ClCompile Include="hooks\wrapped_swapchain.cpp" />
|
||||
<ClCompile Include="Logger.cpp" />
|
||||
<ClCompile Include="NVNGX.cpp" />
|
||||
<ClCompile Include="NVNGX_DLSS_Dx11.cpp" />
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include "NVNGX_Proxy.h"
|
||||
#include "XeSS_Proxy.h"
|
||||
|
||||
#include "imgui/imgui_overlay_dx.h"
|
||||
#include "imgui/imgui_overlay_vk.h"
|
||||
#include "hooks/HooksDx.h"
|
||||
#include "hooks/HooksVk.h"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
@@ -959,8 +959,8 @@ static void DetachHooks()
|
||||
{
|
||||
if (!isNvngxMode)
|
||||
{
|
||||
ImGuiOverlayDx::UnHookDx();
|
||||
ImGuiOverlayVk::UnHookVk();
|
||||
HooksDx::UnHookDx();
|
||||
HooksVk::UnHookVk();
|
||||
}
|
||||
|
||||
if (o_LoadLibraryA != nullptr || o_LoadLibraryW != nullptr || o_LoadLibraryExA != nullptr || o_LoadLibraryExW != nullptr)
|
||||
@@ -1578,8 +1578,8 @@ static void CheckWorkingMode()
|
||||
Config::Instance()->OverlayMenu = (!isNvngxMode || isWorkingWithEnabler) && Config::Instance()->OverlayMenu.value_or(true);
|
||||
if (Config::Instance()->OverlayMenu.value())
|
||||
{
|
||||
ImGuiOverlayDx::HookDx();
|
||||
ImGuiOverlayVk::HookVk();
|
||||
HooksDx::HookDx();
|
||||
HooksVk::HookVk();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "../pch.h"
|
||||
#include "../format_transfer/FT_Dx12.h"
|
||||
#include "../backends/IFeature.h"
|
||||
|
||||
|
||||
#include <d3d11_4.h>
|
||||
#include <d3d12.h>
|
||||
#include <dxgi1_6.h>
|
||||
|
||||
#include <ffx_api.h>
|
||||
#include <dx12/ffx_api_dx12.h>
|
||||
#include <ffx_framegeneration.h>
|
||||
|
||||
namespace HooksDx
|
||||
{
|
||||
inline ID3D12QueryHeap* queryHeap = nullptr;
|
||||
inline ID3D12Resource* readbackBuffer = nullptr;
|
||||
inline bool dx12UpscaleTrig = false;
|
||||
|
||||
inline const int QUERY_BUFFER_COUNT = 3;
|
||||
inline ID3D11Query* disjointQueries[QUERY_BUFFER_COUNT] = { nullptr, nullptr, nullptr };
|
||||
inline ID3D11Query* startQueries[QUERY_BUFFER_COUNT] = { nullptr, nullptr, nullptr };
|
||||
inline ID3D11Query* endQueries[QUERY_BUFFER_COUNT] = { nullptr, nullptr, nullptr };
|
||||
inline bool dx11UpscaleTrig[QUERY_BUFFER_COUNT] = { false, false, false };
|
||||
|
||||
inline ID3D12CommandQueue* GameCommandQueue = nullptr;
|
||||
|
||||
inline int currentFrameIndex = 0;
|
||||
inline int previousFrameIndex = 0;
|
||||
|
||||
inline IDXGISwapChain* currentSwapchain = nullptr;
|
||||
inline DXGI_FORMAT swapchainFormat = DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
inline ffxContext fgSwapChainContext = nullptr;
|
||||
inline ffxContext fgContext = nullptr;
|
||||
inline float jitterX = 0.0;
|
||||
inline float jitterY = 0.0;
|
||||
inline float mvScaleX = 0.0;
|
||||
inline float mvScaleY = 0.0;
|
||||
inline const int FG_BUFFER_SIZE = 4;
|
||||
inline ID3D12Resource* paramVelocity[FG_BUFFER_SIZE] = { nullptr, nullptr, nullptr, nullptr };
|
||||
inline ID3D12Resource* paramDepth[FG_BUFFER_SIZE] = { nullptr, nullptr,nullptr, nullptr };
|
||||
inline UINT64 fgHUDlessCaptureCounter[FG_BUFFER_SIZE] = { 0,0,0,0 };
|
||||
inline bool upscaleRan = false;
|
||||
inline bool fgSkipHudlessChecks = false;
|
||||
inline double fgFrameTime = 0.0;
|
||||
inline ID3D12CommandQueue* fgCommandQueue = nullptr;
|
||||
inline ID3D12CommandQueue* gameCommandQueue = nullptr;
|
||||
inline ID3D12CommandQueue* fgCopyCommandQueue = nullptr;
|
||||
inline ID3D12GraphicsCommandList* fgCopyCommandList = nullptr;
|
||||
inline ID3D12CommandAllocator* fgCopyCommandAllocators[FG_BUFFER_SIZE] = { };
|
||||
inline UINT64 fgTarget = 10;
|
||||
inline ID3D12Resource* fgUpscaledImage[FG_BUFFER_SIZE] = { nullptr, nullptr, nullptr, nullptr };
|
||||
inline FT_Dx12* fgFormatTransfer = nullptr;
|
||||
inline bool fgIsActive = false;
|
||||
|
||||
void UnHookDx();
|
||||
void HookDx();
|
||||
UINT ClearFrameResources();
|
||||
UINT GetFrame();
|
||||
void NewFrame();
|
||||
void ReleaseFGObjects();
|
||||
void CreateFGObjects(ID3D12Device* InDevice);
|
||||
void CreateFGContext(ID3D12Device* InDevice, IFeature* deviceContext);
|
||||
void StopAndDestroyFGContext(bool destroy, bool shutDown);
|
||||
}
|
||||
@@ -0,0 +1,245 @@
|
||||
#include "HooksVk.h"
|
||||
|
||||
#include "../Util.h"
|
||||
#include "../Config.h"
|
||||
|
||||
#include "../imgui/imgui_overlay_vk.h"
|
||||
|
||||
#include "../detours/detours.h"
|
||||
|
||||
typedef struct VkWin32SurfaceCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkFlags flags;
|
||||
HINSTANCE hinstance;
|
||||
HWND hwnd;
|
||||
} VkWin32SurfaceCreateInfoKHR;
|
||||
|
||||
static bool _isInited = false;
|
||||
|
||||
// for menu rendering
|
||||
static VkDevice _device = VK_NULL_HANDLE;
|
||||
static VkInstance _instance = VK_NULL_HANDLE;
|
||||
static VkPhysicalDevice _PD = VK_NULL_HANDLE;
|
||||
static HWND _hwnd = nullptr;
|
||||
|
||||
static std::mutex _vkPresentMutex;
|
||||
|
||||
// hooking
|
||||
typedef VkResult(*PFN_QueuePresentKHR)(VkQueue, const VkPresentInfoKHR*);
|
||||
typedef VkResult(*PFN_CreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR*, const VkAllocationCallbacks*, VkSwapchainKHR*);
|
||||
typedef VkResult(*PFN_vkCreateWin32SurfaceKHR)(VkInstance, const VkWin32SurfaceCreateInfoKHR*, const VkAllocationCallbacks*, VkSurfaceKHR*);
|
||||
|
||||
PFN_vkCreateDevice o_vkCreateDevice = nullptr;
|
||||
PFN_vkCreateInstance o_vkCreateInstance = nullptr;
|
||||
PFN_vkCreateWin32SurfaceKHR o_vkCreateWin32SurfaceKHR = nullptr;
|
||||
PFN_QueuePresentKHR o_QueuePresentKHR = nullptr;
|
||||
PFN_CreateSwapchainKHR o_CreateSwapchainKHR = nullptr;
|
||||
|
||||
static VkResult hkvkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice);
|
||||
static VkResult hkvkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pPresentInfo);
|
||||
static VkResult hkvkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain);
|
||||
|
||||
static void HookDevice(VkDevice InDevice)
|
||||
{
|
||||
if (o_CreateSwapchainKHR != nullptr || Config::Instance()->VulkanSkipHooks)
|
||||
return;
|
||||
|
||||
LOG_FUNC();
|
||||
|
||||
o_QueuePresentKHR = (PFN_QueuePresentKHR)(vkGetDeviceProcAddr(InDevice, "vkQueuePresentKHR"));
|
||||
o_CreateSwapchainKHR = (PFN_CreateSwapchainKHR)(vkGetDeviceProcAddr(InDevice, "vkCreateSwapchainKHR"));
|
||||
|
||||
if (o_CreateSwapchainKHR)
|
||||
{
|
||||
LOG_DEBUG("Hooking VkDevice");
|
||||
|
||||
// Hook
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
DetourAttach(&(PVOID&)o_QueuePresentKHR, hkvkQueuePresentKHR);
|
||||
DetourAttach(&(PVOID&)o_CreateSwapchainKHR, hkvkCreateSwapchainKHR);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
}
|
||||
|
||||
static VkResult hkvkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
auto result = o_vkCreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
|
||||
|
||||
auto procHwnd = Util::GetProcessWindow();
|
||||
LOG_DEBUG("procHwnd: {0:X}, swapchain hwnd: {1:X}", (UINT64)procHwnd, (UINT64)pCreateInfo->hwnd);
|
||||
|
||||
if (result == VK_SUCCESS && !Config::Instance()->VulkanSkipHooks && procHwnd == pCreateInfo->hwnd)
|
||||
{
|
||||
ImGuiOverlayVk::DestroyVulkanObjects(false);
|
||||
|
||||
_instance = instance;
|
||||
LOG_DEBUG("_instance captured: {0:X}", (UINT64)_instance);
|
||||
_hwnd = pCreateInfo->hwnd;
|
||||
LOG_DEBUG("_hwnd captured: {0:X}", (UINT64)_hwnd);
|
||||
}
|
||||
|
||||
LOG_FUNC_RESULT(result);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
static VkResult hkvkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
auto result = o_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
|
||||
|
||||
if (result == VK_SUCCESS && !Config::Instance()->VulkanSkipHooks)
|
||||
{
|
||||
ImGuiOverlayVk::DestroyVulkanObjects(false);
|
||||
|
||||
_instance = *pInstance;
|
||||
LOG_DEBUG("_instance captured: {0:X}", (UINT64)_instance);
|
||||
}
|
||||
|
||||
LOG_FUNC_RESULT(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkResult hkvkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
auto result = o_vkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
|
||||
|
||||
if (result == VK_SUCCESS && !Config::Instance()->VulkanSkipHooks)
|
||||
{
|
||||
ImGuiOverlayVk::DestroyVulkanObjects(false);
|
||||
|
||||
_PD = physicalDevice;
|
||||
LOG_DEBUG("_PD captured: {0:X}", (UINT64)_PD);
|
||||
_device = *pDevice;
|
||||
LOG_DEBUG("_device captured: {0:X}", (UINT64)_device);
|
||||
HookDevice(_device);
|
||||
}
|
||||
|
||||
LOG_FUNC_RESULT(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkResult hkvkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pPresentInfo)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
// get upscaler time
|
||||
if (HooksVk::vkUpscaleTrig && HooksVk::queryPool != VK_NULL_HANDLE)
|
||||
{
|
||||
// Retrieve timestamps
|
||||
uint64_t timestamps[2];
|
||||
vkGetQueryPoolResults(_device, HooksVk::queryPool, 0, 2, sizeof(timestamps), timestamps, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT);
|
||||
|
||||
// Calculate elapsed time in milliseconds
|
||||
double elapsedTimeMs = (timestamps[1] - timestamps[0]) * HooksVk::timeStampPeriod / 1e6;
|
||||
|
||||
if (elapsedTimeMs > 0.0 && elapsedTimeMs < 5000.0)
|
||||
{
|
||||
Config::Instance()->upscaleTimes.push_back(elapsedTimeMs);
|
||||
Config::Instance()->upscaleTimes.pop_front();
|
||||
}
|
||||
|
||||
HooksVk::vkUpscaleTrig = false;
|
||||
}
|
||||
|
||||
// render menu if needed
|
||||
if(!ImGuiOverlayVk::QueuePresent(queue, pPresentInfo))
|
||||
return VK_ERROR_OUT_OF_DATE_KHR;
|
||||
|
||||
// original call
|
||||
Config::Instance()->VulkanCreatingSC = true;
|
||||
auto result = o_QueuePresentKHR(queue, pPresentInfo);
|
||||
Config::Instance()->VulkanCreatingSC = false;
|
||||
|
||||
LOG_FUNC_RESULT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkResult hkvkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
Config::Instance()->VulkanCreatingSC = true;
|
||||
auto result = o_CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
|
||||
Config::Instance()->VulkanCreatingSC = false;
|
||||
|
||||
if (result == VK_SUCCESS && device != VK_NULL_HANDLE && pCreateInfo != nullptr && *pSwapchain != VK_NULL_HANDLE && !Config::Instance()->VulkanSkipHooks)
|
||||
{
|
||||
Config::Instance()->ScreenWidth = pCreateInfo->imageExtent.width;
|
||||
Config::Instance()->ScreenHeight = pCreateInfo->imageExtent.height;
|
||||
|
||||
LOG_DEBUG("if (result == VK_SUCCESS && device != VK_NULL_HANDLE && pCreateInfo != nullptr && pSwapchain != VK_NULL_HANDLE)");
|
||||
|
||||
_device = device;
|
||||
LOG_DEBUG("_device captured: {0:X}", (UINT64)_device);
|
||||
|
||||
ImGuiOverlayVk::CreateSwapchain(device, _PD, _instance, _hwnd, pCreateInfo, pAllocator, pSwapchain);
|
||||
}
|
||||
|
||||
LOG_FUNC_RESULT(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void HooksVk::HookVk()
|
||||
{
|
||||
if (o_vkCreateDevice != nullptr)
|
||||
return;
|
||||
|
||||
o_vkCreateDevice = (PFN_vkCreateDevice)DetourFindFunction("vulkan-1.dll", "vkCreateDevice");
|
||||
o_vkCreateInstance = (PFN_vkCreateInstance)DetourFindFunction("vulkan-1.dll", "vkCreateInstance");
|
||||
o_vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)DetourFindFunction("vulkan-1.dll", "vkCreateWin32SurfaceKHR");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
if (o_vkCreateDevice != nullptr)
|
||||
DetourAttach(&(PVOID&)o_vkCreateDevice, hkvkCreateDevice);
|
||||
|
||||
if (o_vkCreateInstance != nullptr)
|
||||
DetourAttach(&(PVOID&)o_vkCreateInstance, hkvkCreateInstance);
|
||||
|
||||
if (o_vkCreateWin32SurfaceKHR != nullptr)
|
||||
DetourAttach(&(PVOID&)o_vkCreateWin32SurfaceKHR, hkvkCreateWin32SurfaceKHR);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
|
||||
void HooksVk::UnHookVk()
|
||||
{
|
||||
if (_isInited)
|
||||
{
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
if (o_QueuePresentKHR != nullptr)
|
||||
DetourDetach(&(PVOID&)o_QueuePresentKHR, hkvkQueuePresentKHR);
|
||||
|
||||
if (o_CreateSwapchainKHR != nullptr)
|
||||
DetourDetach(&(PVOID&)o_CreateSwapchainKHR, hkvkCreateSwapchainKHR);
|
||||
|
||||
if (o_vkCreateDevice != nullptr)
|
||||
DetourDetach(&(PVOID&)o_vkCreateDevice, hkvkCreateDevice);
|
||||
|
||||
if (o_vkCreateInstance != nullptr)
|
||||
DetourDetach(&(PVOID&)o_vkCreateInstance, hkvkCreateInstance);
|
||||
|
||||
if (o_vkCreateWin32SurfaceKHR != nullptr)
|
||||
DetourDetach(&(PVOID&)o_vkCreateWin32SurfaceKHR, hkvkCreateWin32SurfaceKHR);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
|
||||
_isInited = false;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "../pch.h"
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace HooksVk
|
||||
{
|
||||
inline VkQueryPool queryPool = VK_NULL_HANDLE;
|
||||
inline double timeStampPeriod = 1.0;
|
||||
inline bool vkUpscaleTrig = false;
|
||||
|
||||
void HookVk();
|
||||
void UnHookVk();
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "wrapped_swapchain.h"
|
||||
#include <d3d11_4.h>
|
||||
|
||||
#include "../Config.h"
|
||||
#include "../Util.h"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
//#pragma once
|
||||
#include "../pch.h"
|
||||
#include "dxgi1_6.h"
|
||||
#include "imgui_overlay_base.h"
|
||||
|
||||
typedef HRESULT(*PFN_SC_Present)(IDXGISwapChain*, UINT, UINT, const DXGI_PRESENT_PARAMETERS*, IUnknown*, HWND);
|
||||
typedef void(*PFN_SC_Clean)(bool, HWND);
|
||||
@@ -8,14 +8,14 @@
|
||||
|
||||
// LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
typedef HRESULT(__fastcall* PFN_Present)(IDXGISwapChain*, UINT, UINT);
|
||||
typedef HRESULT(__fastcall* PFN_Present1)(IDXGISwapChain1*, UINT, UINT, const DXGI_PRESENT_PARAMETERS*);
|
||||
typedef HRESULT(__fastcall* PFN_ResizeBuffers)(IDXGISwapChain*, UINT, UINT, UINT, DXGI_FORMAT, UINT);
|
||||
typedef HRESULT(__fastcall* PFN_ResizeBuffers1)(IDXGISwapChain*, UINT, UINT, UINT, DXGI_FORMAT, UINT, const UINT*, IUnknown* const*);
|
||||
typedef HRESULT(__fastcall* PFN_CreateSwapChain)(IDXGIFactory*, IUnknown*, DXGI_SWAP_CHAIN_DESC*, IDXGISwapChain**);
|
||||
typedef HRESULT(__fastcall* PFN_CreateSwapChainForHwnd)(IDXGIFactory*, IUnknown*, HWND, const DXGI_SWAP_CHAIN_DESC1*, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC*, IDXGIOutput*, IDXGISwapChain1**);
|
||||
typedef HRESULT(__fastcall* PFN_CreateSwapChainForCoreWindow)(IDXGIFactory*, IUnknown*, IUnknown*, const DXGI_SWAP_CHAIN_DESC1*, IDXGIOutput*, IDXGISwapChain1**);
|
||||
typedef HRESULT(__fastcall* PFN_CreateSwapChainForComposition)(IDXGIFactory*, IUnknown*, const DXGI_SWAP_CHAIN_DESC1*, IDXGIOutput*, IDXGISwapChain1**);
|
||||
//typedef HRESULT(__fastcall* PFN_Present)(IDXGISwapChain*, UINT, UINT);
|
||||
//typedef HRESULT(__fastcall* PFN_Present1)(IDXGISwapChain1*, UINT, UINT, const DXGI_PRESENT_PARAMETERS*);
|
||||
//typedef HRESULT(__fastcall* PFN_ResizeBuffers)(IDXGISwapChain*, UINT, UINT, UINT, DXGI_FORMAT, UINT);
|
||||
//typedef HRESULT(__fastcall* PFN_ResizeBuffers1)(IDXGISwapChain*, UINT, UINT, UINT, DXGI_FORMAT, UINT, const UINT*, IUnknown* const*);
|
||||
//typedef HRESULT(__fastcall* PFN_CreateSwapChain)(IDXGIFactory*, IUnknown*, DXGI_SWAP_CHAIN_DESC*, IDXGISwapChain**);
|
||||
//typedef HRESULT(__fastcall* PFN_CreateSwapChainForHwnd)(IDXGIFactory*, IUnknown*, HWND, const DXGI_SWAP_CHAIN_DESC1*, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC*, IDXGIOutput*, IDXGISwapChain1**);
|
||||
//typedef HRESULT(__fastcall* PFN_CreateSwapChainForCoreWindow)(IDXGIFactory*, IUnknown*, IUnknown*, const DXGI_SWAP_CHAIN_DESC1*, IDXGIOutput*, IDXGISwapChain1**);
|
||||
//typedef HRESULT(__fastcall* PFN_CreateSwapChainForComposition)(IDXGIFactory*, IUnknown*, const DXGI_SWAP_CHAIN_DESC1*, IDXGIOutput*, IDXGISwapChain1**);
|
||||
|
||||
class ImGuiOverlayBase
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -5,62 +5,8 @@
|
||||
#include <d3d12.h>
|
||||
#include <dxgi1_6.h>
|
||||
|
||||
#include <ffx_api.h>
|
||||
#include <dx12/ffx_api_dx12.h>
|
||||
#include <ffx_framegeneration.h>
|
||||
#include "../format_transfer/FT_Dx12.h"
|
||||
#include "../backends/IFeature.h"
|
||||
|
||||
namespace ImGuiOverlayDx
|
||||
{
|
||||
inline ID3D12QueryHeap* queryHeap = nullptr;
|
||||
inline ID3D12Resource* readbackBuffer = nullptr;
|
||||
inline bool dx12UpscaleTrig = false;
|
||||
|
||||
inline const int QUERY_BUFFER_COUNT = 3;
|
||||
inline ID3D11Query* disjointQueries[QUERY_BUFFER_COUNT] = { nullptr, nullptr, nullptr };
|
||||
inline ID3D11Query* startQueries[QUERY_BUFFER_COUNT] = { nullptr, nullptr, nullptr };
|
||||
inline ID3D11Query* endQueries[QUERY_BUFFER_COUNT] = { nullptr, nullptr, nullptr };
|
||||
inline bool dx11UpscaleTrig[QUERY_BUFFER_COUNT] = { false, false, false };
|
||||
|
||||
inline ID3D12CommandQueue* GameCommandQueue = nullptr;
|
||||
|
||||
inline int currentFrameIndex = 0;
|
||||
inline int previousFrameIndex = 0;
|
||||
|
||||
inline IDXGISwapChain* currentSwapchain = nullptr;
|
||||
inline DXGI_FORMAT swapchainFormat = DXGI_FORMAT_UNKNOWN;
|
||||
|
||||
inline ffxContext fgSwapChainContext = nullptr;
|
||||
inline ffxContext fgContext = nullptr;
|
||||
inline float jitterX = 0.0;
|
||||
inline float jitterY = 0.0;
|
||||
inline float mvScaleX = 0.0;
|
||||
inline float mvScaleY = 0.0;
|
||||
inline const int FG_BUFFER_SIZE = 4;
|
||||
inline ID3D12Resource* paramVelocity[FG_BUFFER_SIZE] = { nullptr, nullptr, nullptr, nullptr };
|
||||
inline ID3D12Resource* paramDepth[FG_BUFFER_SIZE] = { nullptr, nullptr,nullptr, nullptr };
|
||||
inline UINT64 fgHUDlessCaptureCounter[FG_BUFFER_SIZE] = { 0,0,0,0 };
|
||||
inline bool upscaleRan = false;
|
||||
inline bool fgSkipHudlessChecks = false;
|
||||
inline double fgFrameTime = 0.0;
|
||||
inline ID3D12CommandQueue* fgCommandQueue = nullptr;
|
||||
inline ID3D12CommandQueue* gameCommandQueue = nullptr;
|
||||
inline ID3D12CommandQueue* fgCopyCommandQueue = nullptr;
|
||||
inline ID3D12GraphicsCommandList* fgCopyCommandList = nullptr;
|
||||
inline ID3D12CommandAllocator* fgCopyCommandAllocators[FG_BUFFER_SIZE] = { };
|
||||
inline UINT64 fgTarget = 10;
|
||||
inline ID3D12Resource* fgUpscaledImage[FG_BUFFER_SIZE] = { nullptr, nullptr, nullptr, nullptr };
|
||||
inline FT_Dx12* fgFormatTransfer = nullptr;
|
||||
inline bool fgIsActive = false;
|
||||
|
||||
void UnHookDx();
|
||||
void HookDx();
|
||||
UINT ClearFrameResources();
|
||||
UINT GetFrame();
|
||||
void NewFrame();
|
||||
void ReleaseFGObjects();
|
||||
void CreateFGObjects(ID3D12Device* InDevice);
|
||||
void CreateFGContext(ID3D12Device* InDevice, IFeature* deviceContext);
|
||||
void StopAndDestroyFGContext(bool destroy, bool shutDown);
|
||||
void CleanupRenderTarget(bool clearQueue, HWND hWnd);
|
||||
void Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags, const DXGI_PRESENT_PARAMETERS* pPresentParameters, IUnknown* pDevice, HWND hWnd);
|
||||
}
|
||||
|
||||
@@ -2,33 +2,17 @@
|
||||
#include "imgui_overlay_vk.h"
|
||||
|
||||
#include "../Util.h"
|
||||
#include "../Config.h"
|
||||
|
||||
#include "imgui/imgui_impl_vulkan.h"
|
||||
#include "imgui/imgui_impl_win32.h"
|
||||
|
||||
#include "../detours/detours.h"
|
||||
#include "../Config.h"
|
||||
|
||||
// Vulkan overlay code adopted from here:
|
||||
// https://gist.github.com/mem99/0ec31ca302927457f86b1d6756aaa8c4
|
||||
// Need to check resize & recreate fixes
|
||||
|
||||
typedef struct VkWin32SurfaceCreateInfoKHR {
|
||||
VkStructureType sType;
|
||||
const void* pNext;
|
||||
VkFlags flags;
|
||||
HINSTANCE hinstance;
|
||||
HWND hwnd;
|
||||
} VkWin32SurfaceCreateInfoKHR;
|
||||
|
||||
static bool _isInited = false;
|
||||
|
||||
// for menu rendering
|
||||
static VkDevice _device = VK_NULL_HANDLE;
|
||||
static VkInstance _instance = VK_NULL_HANDLE;
|
||||
static VkPhysicalDevice _PD = VK_NULL_HANDLE;
|
||||
static HWND _hwnd = nullptr;
|
||||
|
||||
static bool _vulkanObjectsCreated = false;
|
||||
static std::mutex _vkCleanMutex;
|
||||
static std::mutex _vkPresentMutex;
|
||||
@@ -39,91 +23,7 @@ struct ImGui_ImplVulkanH_Frame* _ImVulkan_Frames = VK_NULL_HANDLE;
|
||||
static VkSemaphore* _ImVulkan_Semaphores = VK_NULL_HANDLE;
|
||||
static VkRenderPass _vkRenderPass = VK_NULL_HANDLE;
|
||||
|
||||
// hooking
|
||||
typedef VkResult(*PFN_QueuePresentKHR)(VkQueue, const VkPresentInfoKHR*);
|
||||
typedef VkResult(*PFN_CreateSwapchainKHR)(VkDevice, const VkSwapchainCreateInfoKHR*, const VkAllocationCallbacks*, VkSwapchainKHR*);
|
||||
typedef VkResult(*PFN_vkCreateWin32SurfaceKHR)(VkInstance, const VkWin32SurfaceCreateInfoKHR*, const VkAllocationCallbacks*, VkSurfaceKHR*);
|
||||
|
||||
PFN_vkCreateDevice o_vkCreateDevice = nullptr;
|
||||
PFN_vkCreateInstance o_vkCreateInstance = nullptr;
|
||||
PFN_vkCreateWin32SurfaceKHR o_vkCreateWin32SurfaceKHR = nullptr;
|
||||
PFN_QueuePresentKHR o_QueuePresentKHR = nullptr;
|
||||
PFN_CreateSwapchainKHR o_CreateSwapchainKHR = nullptr;
|
||||
|
||||
static VkResult hkvkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice);
|
||||
static VkResult hkvkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pPresentInfo);
|
||||
static VkResult hkvkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain);
|
||||
|
||||
static void DestroyVulkanObjects(bool shutdown)
|
||||
{
|
||||
if (_ImVulkan_Info.Device == VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
if (!shutdown)
|
||||
LOG_FUNC();
|
||||
|
||||
_vkCleanMutex.lock();
|
||||
|
||||
auto result = vkDeviceWaitIdle(_ImVulkan_Info.Device);
|
||||
if (result != VK_SUCCESS && !shutdown)
|
||||
LOG_WARN("vkDeviceWaitIdle error: {0:X}", (UINT)result);
|
||||
|
||||
if (shutdown)
|
||||
{
|
||||
if (_vkRenderPass)
|
||||
vkDestroyRenderPass(_ImVulkan_Info.Device, _vkRenderPass, VK_NULL_HANDLE);
|
||||
|
||||
if (_ImVulkan_Info.DescriptorPool)
|
||||
vkDestroyDescriptorPool(_ImVulkan_Info.Device, _ImVulkan_Info.DescriptorPool, VK_NULL_HANDLE);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < _ImVulkan_Info.ImageCount; i++)
|
||||
{
|
||||
ImGui_ImplVulkanH_Frame* fd = &_ImVulkan_Frames[i];
|
||||
|
||||
if (fd->Fence != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyFence(_ImVulkan_Info.Device, fd->Fence, VK_NULL_HANDLE);
|
||||
fd->Fence = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (fd->CommandBuffer != VK_NULL_HANDLE)
|
||||
{
|
||||
vkFreeCommandBuffers(_ImVulkan_Info.Device, fd->CommandPool, 1, &fd->CommandBuffer);
|
||||
fd->CommandBuffer = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (fd->CommandPool != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyCommandPool(_ImVulkan_Info.Device, fd->CommandPool, VK_NULL_HANDLE);
|
||||
fd->CommandPool = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (fd->BackbufferView != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyImageView(_ImVulkan_Info.Device, fd->BackbufferView, VK_NULL_HANDLE);
|
||||
fd->BackbufferView = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (fd->BackbufferView != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyFramebuffer(_ImVulkan_Info.Device, fd->Framebuffer, VK_NULL_HANDLE);
|
||||
fd->Framebuffer = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (_ImVulkan_Semaphores[i] != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroySemaphore(_ImVulkan_Info.Device, _ImVulkan_Semaphores[i], VK_NULL_HANDLE);
|
||||
_ImVulkan_Semaphores[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
_ImVulkan_Info = {};
|
||||
}
|
||||
|
||||
_vkCleanMutex.unlock();
|
||||
}
|
||||
|
||||
static void CreateVulkanObjects(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkSwapchainKHR* pSwapchain)
|
||||
static void CreateVulkanObjects(VkDevice device, VkPhysicalDevice pd, VkInstance instance, HWND hwnd, const VkSwapchainCreateInfoKHR* pCreateInfo, VkSwapchainKHR* pSwapchain)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
@@ -140,19 +40,19 @@ static void CreateVulkanObjects(VkDevice device, const VkSwapchainCreateInfoKHR*
|
||||
if (ImGui::GetIO().BackendRendererUserData != nullptr)
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
|
||||
DestroyVulkanObjects(false);
|
||||
ImGuiOverlayVk::DestroyVulkanObjects(false);
|
||||
|
||||
_vulkanObjectsCreated = false;
|
||||
}
|
||||
|
||||
// Initialize ImGui
|
||||
if (!ImGuiOverlayBase::IsInited() || ImGuiOverlayBase::Handle() != _hwnd)
|
||||
if (!ImGuiOverlayBase::IsInited() || ImGuiOverlayBase::Handle() != hwnd)
|
||||
{
|
||||
if (ImGuiOverlayBase::IsInited())
|
||||
ImGuiOverlayBase::Shutdown();
|
||||
|
||||
LOG_DEBUG("ImGuiOverlayBase::Init");
|
||||
ImGuiOverlayBase::Init(_hwnd);
|
||||
ImGuiOverlayBase::Init(hwnd);
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
@@ -191,13 +91,13 @@ static void CreateVulkanObjects(VkDevice device, const VkSwapchainCreateInfoKHR*
|
||||
{
|
||||
// get count
|
||||
uint32_t count = 0;
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(_PD, &count, NULL);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(pd, &count, NULL);
|
||||
|
||||
// get queues
|
||||
if (count > 0)
|
||||
{
|
||||
VkQueueFamilyProperties queues[8];
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(_PD, &count, queues);
|
||||
vkGetPhysicalDeviceQueueFamilyProperties(pd, &count, queues);
|
||||
|
||||
|
||||
// find graphic queue
|
||||
@@ -402,8 +302,8 @@ static void CreateVulkanObjects(VkDevice device, const VkSwapchainCreateInfoKHR*
|
||||
|
||||
// Initialize ImGui and upload fonts
|
||||
{
|
||||
_ImVulkan_Info.Instance = _instance;
|
||||
_ImVulkan_Info.PhysicalDevice = _PD;
|
||||
_ImVulkan_Info.Instance = instance;
|
||||
_ImVulkan_Info.PhysicalDevice = pd;
|
||||
_ImVulkan_Info.Device = device;
|
||||
_ImVulkan_Info.QueueFamily = queueFamily;
|
||||
_ImVulkan_Info.Queue = queue;
|
||||
@@ -470,147 +370,92 @@ static void CreateVulkanObjects(VkDevice device, const VkSwapchainCreateInfoKHR*
|
||||
LOG_FUNC_RESULT(_vulkanObjectsCreated);
|
||||
}
|
||||
|
||||
static void HookDevice(VkDevice InDevice)
|
||||
void ImGuiOverlayVk::DestroyVulkanObjects(bool shutdown)
|
||||
{
|
||||
if (o_CreateSwapchainKHR != nullptr || Config::Instance()->VulkanSkipHooks)
|
||||
if (_ImVulkan_Info.Device == VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
LOG_FUNC();
|
||||
if (!shutdown)
|
||||
LOG_FUNC();
|
||||
|
||||
o_QueuePresentKHR = (PFN_QueuePresentKHR)(vkGetDeviceProcAddr(InDevice, "vkQueuePresentKHR"));
|
||||
o_CreateSwapchainKHR = (PFN_CreateSwapchainKHR)(vkGetDeviceProcAddr(InDevice, "vkCreateSwapchainKHR"));
|
||||
_vkCleanMutex.lock();
|
||||
|
||||
if (o_CreateSwapchainKHR)
|
||||
auto result = vkDeviceWaitIdle(_ImVulkan_Info.Device);
|
||||
if (result != VK_SUCCESS && !shutdown)
|
||||
LOG_WARN("vkDeviceWaitIdle error: {0:X}", (UINT)result);
|
||||
|
||||
if (shutdown)
|
||||
{
|
||||
LOG_DEBUG("Hooking VkDevice");
|
||||
if (_vkRenderPass)
|
||||
vkDestroyRenderPass(_ImVulkan_Info.Device, _vkRenderPass, VK_NULL_HANDLE);
|
||||
|
||||
// Hook
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
DetourAttach(&(PVOID&)o_QueuePresentKHR, hkvkQueuePresentKHR);
|
||||
DetourAttach(&(PVOID&)o_CreateSwapchainKHR, hkvkCreateSwapchainKHR);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
}
|
||||
|
||||
static VkResult hkvkCreateWin32SurfaceKHR(VkInstance instance, const VkWin32SurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
auto result = o_vkCreateWin32SurfaceKHR(instance, pCreateInfo, pAllocator, pSurface);
|
||||
|
||||
auto procHwnd = Util::GetProcessWindow();
|
||||
LOG_DEBUG("procHwnd: {0:X}, swapchain hwnd: {1:X}", (UINT64)procHwnd, (UINT64)pCreateInfo->hwnd);
|
||||
|
||||
if (result == VK_SUCCESS && !Config::Instance()->VulkanSkipHooks && procHwnd == pCreateInfo->hwnd)
|
||||
{
|
||||
DestroyVulkanObjects(false);
|
||||
|
||||
_instance = instance;
|
||||
LOG_DEBUG("_instance captured: {0:X}", (UINT64)_instance);
|
||||
_hwnd = pCreateInfo->hwnd;
|
||||
LOG_DEBUG("_hwnd captured: {0:X}", (UINT64)_hwnd);
|
||||
if (_ImVulkan_Info.DescriptorPool)
|
||||
vkDestroyDescriptorPool(_ImVulkan_Info.Device, _ImVulkan_Info.DescriptorPool, VK_NULL_HANDLE);
|
||||
}
|
||||
|
||||
LOG_FUNC_RESULT(result);
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
static VkResult hkvkCreateInstance(const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
auto result = o_vkCreateInstance(pCreateInfo, pAllocator, pInstance);
|
||||
|
||||
if (result == VK_SUCCESS && !Config::Instance()->VulkanSkipHooks)
|
||||
for (uint32_t i = 0; i < _ImVulkan_Info.ImageCount; i++)
|
||||
{
|
||||
DestroyVulkanObjects(false);
|
||||
ImGui_ImplVulkanH_Frame* fd = &_ImVulkan_Frames[i];
|
||||
|
||||
_instance = *pInstance;
|
||||
LOG_DEBUG("_instance captured: {0:X}", (UINT64)_instance);
|
||||
if (fd->Fence != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyFence(_ImVulkan_Info.Device, fd->Fence, VK_NULL_HANDLE);
|
||||
fd->Fence = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (fd->CommandBuffer != VK_NULL_HANDLE)
|
||||
{
|
||||
vkFreeCommandBuffers(_ImVulkan_Info.Device, fd->CommandPool, 1, &fd->CommandBuffer);
|
||||
fd->CommandBuffer = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (fd->CommandPool != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyCommandPool(_ImVulkan_Info.Device, fd->CommandPool, VK_NULL_HANDLE);
|
||||
fd->CommandPool = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (fd->BackbufferView != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyImageView(_ImVulkan_Info.Device, fd->BackbufferView, VK_NULL_HANDLE);
|
||||
fd->BackbufferView = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (fd->BackbufferView != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyFramebuffer(_ImVulkan_Info.Device, fd->Framebuffer, VK_NULL_HANDLE);
|
||||
fd->Framebuffer = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
if (_ImVulkan_Semaphores[i] != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroySemaphore(_ImVulkan_Info.Device, _ImVulkan_Semaphores[i], VK_NULL_HANDLE);
|
||||
_ImVulkan_Semaphores[i] = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
_ImVulkan_Info = {};
|
||||
}
|
||||
|
||||
LOG_FUNC_RESULT(result);
|
||||
|
||||
return result;
|
||||
_vkCleanMutex.unlock();
|
||||
}
|
||||
|
||||
static VkResult hkvkCreateDevice(VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
auto result = o_vkCreateDevice(physicalDevice, pCreateInfo, pAllocator, pDevice);
|
||||
|
||||
if (result == VK_SUCCESS && !Config::Instance()->VulkanSkipHooks)
|
||||
{
|
||||
DestroyVulkanObjects(false);
|
||||
|
||||
_PD = physicalDevice;
|
||||
LOG_DEBUG("_PD captured: {0:X}", (UINT64)_PD);
|
||||
_device = *pDevice;
|
||||
LOG_DEBUG("_device captured: {0:X}", (UINT64)_device);
|
||||
HookDevice(_device);
|
||||
}
|
||||
|
||||
LOG_FUNC_RESULT(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static VkResult hkvkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pPresentInfo)
|
||||
bool ImGuiOverlayVk::QueuePresent(VkQueue queue, VkPresentInfoKHR* pPresentInfo)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
if (!_vulkanObjectsCreated)
|
||||
{
|
||||
LOG_TRACE("!_vulkanObjectsCreated return o_QueuePresentKHR");
|
||||
|
||||
Config::Instance()->VulkanCreatingSC = true;
|
||||
auto r0 = o_QueuePresentKHR(queue, pPresentInfo);
|
||||
Config::Instance()->VulkanCreatingSC = false;
|
||||
|
||||
if (r0 != VK_SUCCESS)
|
||||
LOG_ERROR("r0 = o_QueuePresentKHR(queue, pPresentInfo): {0:X}", (UINT)r0);
|
||||
|
||||
return r0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!ImGuiOverlayBase::IsInited() || !ImGuiOverlayBase::IsVisible() || _ImVulkan_Info.Device == VK_NULL_HANDLE)
|
||||
{
|
||||
Config::Instance()->VulkanCreatingSC = true;
|
||||
auto r1 = o_QueuePresentKHR(queue, pPresentInfo);
|
||||
Config::Instance()->VulkanCreatingSC = false;
|
||||
|
||||
if (r1 != VK_SUCCESS)
|
||||
LOG_ERROR("r1 = o_QueuePresentKHR(queue, pPresentInfo): {0:X}", (UINT)r1);
|
||||
|
||||
return r1;
|
||||
return true;
|
||||
}
|
||||
|
||||
_vkPresentMutex.lock();
|
||||
|
||||
if (ImGuiOverlayVk::vkUpscaleTrig && ImGuiOverlayVk::queryPool != VK_NULL_HANDLE)
|
||||
{
|
||||
// Retrieve timestamps
|
||||
uint64_t timestamps[2];
|
||||
vkGetQueryPoolResults(_device, ImGuiOverlayVk::queryPool, 0, 2, sizeof(timestamps), timestamps, sizeof(uint64_t), VK_QUERY_RESULT_64_BIT);
|
||||
|
||||
// Calculate elapsed time in milliseconds
|
||||
double elapsedTimeMs = (timestamps[1] - timestamps[0]) * ImGuiOverlayVk::timeStampPeriod / 1e6;
|
||||
|
||||
if (elapsedTimeMs > 0.0 && elapsedTimeMs < 5000.0)
|
||||
{
|
||||
Config::Instance()->upscaleTimes.push_back(elapsedTimeMs);
|
||||
Config::Instance()->upscaleTimes.pop_front();
|
||||
}
|
||||
|
||||
ImGuiOverlayVk::vkUpscaleTrig = false;
|
||||
}
|
||||
|
||||
LOG_DEBUG("rendering menu, swapchain count: {0}", pPresentInfo->swapchainCount);
|
||||
|
||||
bool errorWhenRenderingMenu = true;
|
||||
@@ -702,120 +547,37 @@ static VkResult hkvkQueuePresentKHR(VkQueue queue, VkPresentInfoKHR* pPresentInf
|
||||
// if there are errors when rendering try to recreate swapchain
|
||||
_vkPresentMutex.unlock();
|
||||
LOG_FUNC_RESULT(VK_ERROR_OUT_OF_DATE_KHR);
|
||||
return VK_ERROR_OUT_OF_DATE_KHR;
|
||||
return false;
|
||||
}
|
||||
|
||||
// original call
|
||||
Config::Instance()->VulkanCreatingSC = true;
|
||||
auto result = o_QueuePresentKHR(queue, pPresentInfo);
|
||||
Config::Instance()->VulkanCreatingSC = false;
|
||||
LOG_FUNC_RESULT(result);
|
||||
_vkPresentMutex.unlock();
|
||||
return result;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static VkResult hkvkCreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* pCreateInfo, VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain)
|
||||
void ImGuiOverlayVk::CreateSwapchain(VkDevice device, VkPhysicalDevice pd, VkInstance instance, HWND hwnd, const VkSwapchainCreateInfoKHR* pCreateInfo, VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain)
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
Config::Instance()->VulkanCreatingSC = true;
|
||||
auto result = o_CreateSwapchainKHR(device, pCreateInfo, pAllocator, pSwapchain);
|
||||
Config::Instance()->VulkanCreatingSC = false;
|
||||
|
||||
if (result == VK_SUCCESS && device != VK_NULL_HANDLE && pCreateInfo != nullptr && *pSwapchain != VK_NULL_HANDLE && !Config::Instance()->VulkanSkipHooks)
|
||||
if (ImGuiOverlayBase::Handle() != hwnd)
|
||||
{
|
||||
Config::Instance()->ScreenWidth = pCreateInfo->imageExtent.width;
|
||||
Config::Instance()->ScreenHeight = pCreateInfo->imageExtent.height;
|
||||
LOG_DEBUG("ImGuiOverlayBase::Handle() != _hwnd");
|
||||
|
||||
LOG_DEBUG("if (result == VK_SUCCESS && device != VK_NULL_HANDLE && pCreateInfo != nullptr && pSwapchain != VK_NULL_HANDLE)");
|
||||
|
||||
_device = device;
|
||||
LOG_DEBUG("_device captured: {0:X}", (UINT64)_device);
|
||||
|
||||
if (ImGuiOverlayBase::Handle() != _hwnd)
|
||||
if (ImGuiOverlayBase::IsInited())
|
||||
{
|
||||
LOG_DEBUG("ImGuiOverlayBase::Handle() != _hwnd");
|
||||
|
||||
if (ImGuiOverlayBase::IsInited())
|
||||
{
|
||||
LOG_DEBUG("ImGuiOverlayBase::Shutdown();");
|
||||
ImGuiOverlayBase::Shutdown();
|
||||
}
|
||||
|
||||
LOG_DEBUG("ImGuiOverlayBase::Init({0:X})", (UINT64)_hwnd);
|
||||
ImGuiOverlayBase::Init(_hwnd);
|
||||
LOG_DEBUG("ImGuiOverlayBase::Shutdown();");
|
||||
ImGuiOverlayBase::Shutdown();
|
||||
}
|
||||
|
||||
CreateVulkanObjects(_device, pCreateInfo, pSwapchain);
|
||||
|
||||
if (_ImVulkan_Info.Device != VK_NULL_HANDLE)
|
||||
{
|
||||
_isInited = true;
|
||||
ImGuiOverlayBase::VulkanReady();
|
||||
}
|
||||
LOG_DEBUG("ImGuiOverlayBase::Init({0:X})", (UINT64)hwnd);
|
||||
ImGuiOverlayBase::Init(hwnd);
|
||||
}
|
||||
|
||||
LOG_FUNC_RESULT(result);
|
||||
return result;
|
||||
}
|
||||
CreateVulkanObjects(device, pd, instance, hwnd, pCreateInfo, pSwapchain);
|
||||
|
||||
void ImGuiOverlayVk::HookVk()
|
||||
{
|
||||
if (o_vkCreateDevice != nullptr)
|
||||
return;
|
||||
|
||||
o_vkCreateDevice = (PFN_vkCreateDevice)DetourFindFunction("vulkan-1.dll", "vkCreateDevice");
|
||||
o_vkCreateInstance = (PFN_vkCreateInstance)DetourFindFunction("vulkan-1.dll", "vkCreateInstance");
|
||||
o_vkCreateWin32SurfaceKHR = (PFN_vkCreateWin32SurfaceKHR)DetourFindFunction("vulkan-1.dll", "vkCreateWin32SurfaceKHR");
|
||||
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
if (o_vkCreateDevice != nullptr)
|
||||
DetourAttach(&(PVOID&)o_vkCreateDevice, hkvkCreateDevice);
|
||||
|
||||
if (o_vkCreateInstance != nullptr)
|
||||
DetourAttach(&(PVOID&)o_vkCreateInstance, hkvkCreateInstance);
|
||||
|
||||
if (o_vkCreateWin32SurfaceKHR != nullptr)
|
||||
DetourAttach(&(PVOID&)o_vkCreateWin32SurfaceKHR, hkvkCreateWin32SurfaceKHR);
|
||||
|
||||
DetourTransactionCommit();
|
||||
}
|
||||
|
||||
void ImGuiOverlayVk::UnHookVk()
|
||||
{
|
||||
if (_isInited)
|
||||
ImGui_ImplVulkan_Shutdown();
|
||||
|
||||
ImGuiOverlayBase::Shutdown();
|
||||
|
||||
if (_vulkanObjectsCreated)
|
||||
DestroyVulkanObjects(true);
|
||||
|
||||
if (_isInited)
|
||||
if (_ImVulkan_Info.Device != VK_NULL_HANDLE)
|
||||
{
|
||||
DetourTransactionBegin();
|
||||
DetourUpdateThread(GetCurrentThread());
|
||||
|
||||
if (o_QueuePresentKHR != nullptr)
|
||||
DetourDetach(&(PVOID&)o_QueuePresentKHR, hkvkQueuePresentKHR);
|
||||
|
||||
if (o_CreateSwapchainKHR != nullptr)
|
||||
DetourDetach(&(PVOID&)o_CreateSwapchainKHR, hkvkCreateSwapchainKHR);
|
||||
|
||||
if (o_vkCreateDevice != nullptr)
|
||||
DetourDetach(&(PVOID&)o_vkCreateDevice, hkvkCreateDevice);
|
||||
|
||||
if (o_vkCreateInstance != nullptr)
|
||||
DetourDetach(&(PVOID&)o_vkCreateInstance, hkvkCreateInstance);
|
||||
|
||||
if (o_vkCreateWin32SurfaceKHR != nullptr)
|
||||
DetourDetach(&(PVOID&)o_vkCreateWin32SurfaceKHR, hkvkCreateWin32SurfaceKHR);
|
||||
|
||||
DetourTransactionCommit();
|
||||
_isInited = true;
|
||||
ImGuiOverlayBase::VulkanReady();
|
||||
}
|
||||
|
||||
_isInited = false;
|
||||
_vulkanObjectsCreated = false;
|
||||
}
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
|
||||
namespace ImGuiOverlayVk
|
||||
{
|
||||
inline VkQueryPool queryPool = VK_NULL_HANDLE;
|
||||
inline double timeStampPeriod = 1.0;
|
||||
inline bool vkUpscaleTrig = false;
|
||||
|
||||
void HookVk();
|
||||
void UnHookVk();
|
||||
void CreateSwapchain(VkDevice device, VkPhysicalDevice pd, VkInstance instance, HWND hwnd, const VkSwapchainCreateInfoKHR* pCreateInfo, VkAllocationCallbacks* pAllocator, VkSwapchainKHR* pSwapchain);
|
||||
bool QueuePresent(VkQueue queue, VkPresentInfoKHR* pPresentInfo);
|
||||
void DestroyVulkanObjects(bool shutdown);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user