mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-10-07 20:42:35 +00:00
Add per shader GPU times to Vulkan
Slopped.
This commit is contained in:
1 parent
f72e47b9ba
commit
e199fac4e0
23 files changed
+302
-106
No files matched your search
@@ -307,6 +307,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClInclude Include="fsr4\FSR4Upgrade.h" />
|
||||
<ClInclude Include="gpu_time\GpuTime_Dx11.h" />
|
||||
<ClInclude Include="gpu_time\GpuTime_Dx12.h" />
|
||||
<ClInclude Include="gpu_time\GpuTime_Vk.h" />
|
||||
<ClInclude Include="hooks\Amdxc64_Hooks.h" />
|
||||
<ClInclude Include="DllNames.h" />
|
||||
<ClInclude Include="BuildInfo.h" />
|
||||
@@ -452,7 +453,6 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClInclude Include="upscalers\ffx\FFXFeature_VkOn12.h" />
|
||||
<ClInclude Include="upscalers\fsr31\FSR31Feature.h" />
|
||||
<ClInclude Include="upscalers\IFeature_VkwDx12.h" />
|
||||
<ClInclude Include="upscaler_time\UpscalerTime_Vk.h" />
|
||||
<ClInclude Include="SysUtils.h" />
|
||||
<ClInclude Include="with_dx12\dx11_with_dx12.h" />
|
||||
<ClInclude Include="with_dx12\with_dx12.h" />
|
||||
@@ -624,6 +624,7 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClCompile Include="fsr4\FSR4Upgrade.cpp" />
|
||||
<ClCompile Include="gpu_time\GpuTime_Dx11.cpp" />
|
||||
<ClCompile Include="gpu_time\GpuTime_Dx12.cpp" />
|
||||
<ClCompile Include="gpu_time\GpuTime_Vk.cpp" />
|
||||
<ClCompile Include="hooks\Amdxc64_Hooks.cpp" />
|
||||
<ClCompile Include="framegen\dlssg\DLSSG_Dx12.cpp" />
|
||||
<ClCompile Include="framegen\ffx\FSRFG_Dx12.cpp" />
|
||||
@@ -721,7 +722,6 @@ copy NUL "$(SolutionDir)x64\Release\a\!! EXTRACT ALL FILES TO GAME FOLDER !!" /Y
|
||||
<ClCompile Include="upscalers\fsr31\FSR31Feature.cpp" />
|
||||
<ClCompile Include="upscalers\IFeature_Vk.cpp" />
|
||||
<ClCompile Include="upscalers\IFeature_VkwDx12.cpp" />
|
||||
<ClCompile Include="upscaler_time\UpscalerTime_Vk.cpp" />
|
||||
<ClCompile Include="with_dx12\dx11_with_dx12.cpp" />
|
||||
<ClCompile Include="with_dx12\with_dx12.cpp" />
|
||||
<ClCompile Include="with_dx12\dx11_with_dx12_sc.cpp" />
|
||||
|
||||
@@ -566,9 +566,6 @@
|
||||
<ClInclude Include="hooks\D3D11_Hooks.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="upscaler_time\UpscalerTime_Vk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="hooks\DxgiFactory_WrappedCalls.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -977,6 +974,9 @@
|
||||
<ClInclude Include="gpu_time\GpuTime_Dx11.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="gpu_time\GpuTime_Vk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="shaders\magnifier\Magnifier_Vk.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -1340,9 +1340,6 @@
|
||||
<ClCompile Include="hooks\D3D11_Hooks.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="upscaler_time\UpscalerTime_Vk.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="hooks\DxgiFactory_WrappedCalls.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -1610,6 +1607,9 @@
|
||||
<ClCompile Include="gpu_time\GpuTime_Dx11.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="gpu_time\GpuTime_Vk.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="upscalers\IFeature_Vk.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#include "pch.h"
|
||||
#include "GpuTime_Vk.h"
|
||||
|
||||
#include <State.h>
|
||||
|
||||
GpuTime_Vk::GpuTime_Vk(VkDevice device, VkPhysicalDevice physicalDevice) : _device(device)
|
||||
{
|
||||
if (device == VK_NULL_HANDLE || physicalDevice == VK_NULL_HANDLE)
|
||||
{
|
||||
LOG_ERROR("GpuTime_Vk created with null device");
|
||||
return;
|
||||
}
|
||||
|
||||
// Start and End timestamps per buffer
|
||||
VkQueryPoolCreateInfo queryPoolInfo {};
|
||||
queryPoolInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
|
||||
queryPoolInfo.queryType = VK_QUERY_TYPE_TIMESTAMP;
|
||||
queryPoolInfo.queryCount = QUERY_BUFFER_COUNT * 2;
|
||||
|
||||
auto result = vkCreateQueryPool(device, &queryPoolInfo, nullptr, &_queryPool);
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR("vkCreateQueryPool error: {}", (int) result);
|
||||
_queryPool = VK_NULL_HANDLE;
|
||||
return;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceProperties deviceProperties {};
|
||||
vkGetPhysicalDeviceProperties(physicalDevice, &deviceProperties);
|
||||
_timestampPeriod = deviceProperties.limits.timestampPeriod;
|
||||
|
||||
_init = true;
|
||||
}
|
||||
|
||||
GpuTime_Vk::~GpuTime_Vk()
|
||||
{
|
||||
if (State::Instance().isShuttingDown)
|
||||
return;
|
||||
|
||||
if (_queryPool != VK_NULL_HANDLE)
|
||||
{
|
||||
vkDestroyQueryPool(_device, _queryPool, nullptr);
|
||||
_queryPool = VK_NULL_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
void GpuTime_Vk::Start(VkCommandBuffer cmdBuffer)
|
||||
{
|
||||
if (_init && _queryPool != VK_NULL_HANDLE)
|
||||
{
|
||||
_currentFrameIndex = (_currentFrameIndex + 1) % QUERY_BUFFER_COUNT;
|
||||
|
||||
vkCmdResetQueryPool(cmdBuffer, _queryPool, _currentFrameIndex * 2, 2);
|
||||
vkCmdWriteTimestamp(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, _queryPool, _currentFrameIndex * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void GpuTime_Vk::End(VkCommandBuffer cmdBuffer)
|
||||
{
|
||||
if (_init && _queryPool != VK_NULL_HANDLE)
|
||||
{
|
||||
vkCmdWriteTimestamp(cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, _queryPool, _currentFrameIndex * 2 + 1);
|
||||
|
||||
_trigger[_currentFrameIndex] = true;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<double> GpuTime_Vk::ReadGpuTime()
|
||||
{
|
||||
std::optional<double> elapsedTimeMs = std::nullopt;
|
||||
|
||||
if (!_init || _queryPool == VK_NULL_HANDLE)
|
||||
return elapsedTimeMs;
|
||||
|
||||
// Try to read the oldest frame's timestamps
|
||||
uint32_t previousFrameIndex = (_currentFrameIndex + 1) % QUERY_BUFFER_COUNT;
|
||||
|
||||
if (!_trigger[previousFrameIndex])
|
||||
return elapsedTimeMs;
|
||||
|
||||
uint64_t timestamps[2] {};
|
||||
auto result = vkGetQueryPoolResults(_device, _queryPool, previousFrameIndex * 2, 2, sizeof(timestamps), timestamps,
|
||||
sizeof(uint64_t), VK_QUERY_RESULT_64_BIT);
|
||||
|
||||
// Results not available yet, the slot will get overwritten by the next Start anyway
|
||||
if (result != VK_SUCCESS)
|
||||
return elapsedTimeMs;
|
||||
|
||||
_trigger[previousFrameIndex] = false;
|
||||
|
||||
if (timestamps[1] < timestamps[0])
|
||||
return elapsedTimeMs;
|
||||
|
||||
elapsedTimeMs = (timestamps[1] - timestamps[0]) * _timestampPeriod / 1e6;
|
||||
|
||||
return elapsedTimeMs;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "SysUtils.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <optional>
|
||||
#include <array>
|
||||
|
||||
class GpuTime_Vk
|
||||
{
|
||||
static constexpr int QUERY_BUFFER_COUNT = 3;
|
||||
|
||||
VkDevice _device = VK_NULL_HANDLE;
|
||||
VkQueryPool _queryPool = VK_NULL_HANDLE;
|
||||
double _timestampPeriod = 1.0;
|
||||
std::array<bool, QUERY_BUFFER_COUNT> _trigger {};
|
||||
|
||||
int _currentFrameIndex = 0;
|
||||
bool _init = false;
|
||||
|
||||
public:
|
||||
GpuTime_Vk(VkDevice device, VkPhysicalDevice physicalDevice);
|
||||
~GpuTime_Vk();
|
||||
|
||||
void Start(VkCommandBuffer cmdBuffer);
|
||||
void End(VkCommandBuffer cmdBuffer);
|
||||
|
||||
std::optional<double> ReadGpuTime();
|
||||
};
|
||||
|
||||
class ScopedGpuTime_Vk
|
||||
{
|
||||
GpuTime_Vk* _gpuTime;
|
||||
VkCommandBuffer _cmdBuffer;
|
||||
|
||||
public:
|
||||
ScopedGpuTime_Vk(GpuTime_Vk* gpuTime, VkCommandBuffer cmdBuffer) : _gpuTime(gpuTime), _cmdBuffer(cmdBuffer)
|
||||
{
|
||||
if (_gpuTime && _cmdBuffer)
|
||||
_gpuTime->Start(_cmdBuffer);
|
||||
}
|
||||
|
||||
~ScopedGpuTime_Vk()
|
||||
{
|
||||
if (_gpuTime && _cmdBuffer)
|
||||
_gpuTime->End(_cmdBuffer);
|
||||
}
|
||||
};
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <menu/menu_overlay_vk.h>
|
||||
#include <proxies/KernelBase_Proxy.h>
|
||||
#include <upscaler_time/UpscalerTime_Vk.h>
|
||||
#include <upscalers/IFeature_Vk.h>
|
||||
|
||||
#include <misc/FrameLimit.h>
|
||||
#include "Reflex_Hooks.h"
|
||||
@@ -243,8 +243,24 @@ static VkResult hkvkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPres
|
||||
{
|
||||
LOG_FUNC();
|
||||
|
||||
// get upscaler time
|
||||
UpscalerTimeVk::ReadUpscalingTime(_device);
|
||||
// Upscaler GPU time computation
|
||||
if (auto vkFeature = dynamic_cast<IFeature_Vk*>(State::Instance().currentFeature); vkFeature != nullptr)
|
||||
{
|
||||
if (auto upscalerTimeOpt = vkFeature->ReadUpscalerTime(nullptr); upscalerTimeOpt.has_value())
|
||||
{
|
||||
vkFeature->ReadDetailedGpuTimes(nullptr, State::Instance().detailedGpuTimes);
|
||||
|
||||
auto upscalerTime = upscalerTimeOpt.value();
|
||||
// filter out possibly wrong measured high values
|
||||
if (upscalerTime < 100.0)
|
||||
{
|
||||
State::Instance().frameTimeMutex.lock();
|
||||
State::Instance().upscaleTimes.push_back(upscalerTime);
|
||||
State::Instance().upscaleTimes.pop_front();
|
||||
State::Instance().frameTimeMutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ??? TODO: if we are hooking dxvk's vulkan calls then this present call could be either coming from dxvk or from a
|
||||
// native vk game
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
#include "upscalers/FeatureProvider_Vk.h"
|
||||
|
||||
#include <upscaler_time/UpscalerTime_Vk.h>
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include <ankerl/unordered_dense.h>
|
||||
#include <imgui/ImGuiNotify.hpp>
|
||||
@@ -246,8 +244,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_Ext2(
|
||||
|
||||
State::Instance().currentVkDevice = InDevice;
|
||||
|
||||
UpscalerTimeVk::Init(InDevice, InPD);
|
||||
|
||||
State::Instance().nvngxVkInited = true;
|
||||
|
||||
return NVSDK_NGX_Result_Success;
|
||||
@@ -1063,8 +1059,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer
|
||||
deviceContext = VkContexts[handleId].feature.get();
|
||||
state.currentFeature = deviceContext;
|
||||
|
||||
UpscalerTimeVk::UpscaleStart(InCmdList);
|
||||
|
||||
auto upscaleResult = deviceContext->Evaluate(InCmdList, InParameters);
|
||||
|
||||
if (!upscaleResult)
|
||||
@@ -1078,8 +1072,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer
|
||||
return NVSDK_NGX_Result_Success;
|
||||
}
|
||||
|
||||
UpscalerTimeVk::UpscaleEnd(InCmdList);
|
||||
|
||||
return upscaleResult ? NVSDK_NGX_Result_Success : NVSDK_NGX_Result_Fail;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#include <BuildInfo.h>
|
||||
#include <version_check.h>
|
||||
|
||||
#include <upscaler_time/UpscalerTime_Vk.h>
|
||||
|
||||
#include <imgui/imgui_internal.h>
|
||||
#include <imgui/ImGuiNotify.hpp>
|
||||
#include <imgui/imgui_impl_win32.h>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
Shader_Vk::Shader_Vk(std::string InName, VkDevice InDevice, VkPhysicalDevice InPhysicalDevice)
|
||||
: _name(InName), _device(InDevice), _physicalDevice(InPhysicalDevice)
|
||||
{
|
||||
GpuTime = std::make_unique<GpuTime_Vk>(InDevice, InPhysicalDevice);
|
||||
}
|
||||
|
||||
Shader_Vk::~Shader_Vk()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "SysUtils.h"
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <gpu_time/GpuTime_Vk.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -25,6 +26,8 @@ class Shader_Vk
|
||||
VkDevice _device = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice _physicalDevice = VK_NULL_HANDLE;
|
||||
|
||||
std::unique_ptr<GpuTime_Vk> GpuTime = nullptr;
|
||||
|
||||
// Pipeline Layouts
|
||||
VkPipeline _pipeline = VK_NULL_HANDLE;
|
||||
VkPipelineLayout _pipelineLayout = VK_NULL_HANDLE;
|
||||
@@ -84,6 +87,8 @@ class Shader_Vk
|
||||
public:
|
||||
bool IsInit() const { return _init; }
|
||||
bool CanRender() const { return _init && _pipeline != VK_NULL_HANDLE; }
|
||||
std::string Name() const { return _name; }
|
||||
std::optional<double> ReadGpuTime() { return GpuTime->ReadGpuTime(); }
|
||||
|
||||
VkImageView GetImageView() const { return _intermediateImageView; }
|
||||
VkImage GetImage() const { return _intermediateImage; }
|
||||
|
||||
@@ -66,6 +66,8 @@ bool Magnifier_Vk::Dispatch(VkCommandBuffer InCmdList, const VkImageInfo& InReso
|
||||
|
||||
LOG_DEBUG("[{0}] Start!", _name);
|
||||
|
||||
ScopedGpuTime_Vk scopedGpuTime(GpuTime.get(), InCmdList);
|
||||
|
||||
if (!InitializeViews(InResourceInfo.ImageView, OutResourceInfo.ImageView))
|
||||
return false;
|
||||
|
||||
|
||||
@@ -113,6 +113,8 @@ bool OS_Vk::Dispatch(VkCommandBuffer InCmdList, const VkImageInfo& InResourceVie
|
||||
if (!_init || InCmdList == VK_NULL_HANDLE)
|
||||
return false;
|
||||
|
||||
ScopedGpuTime_Vk scopedGpuTime(GpuTime.get(), InCmdList);
|
||||
|
||||
// Update Constants
|
||||
FsrEasuCon(fsr1Constants.const0, fsr1Constants.const1, fsr1Constants.const2, fsr1Constants.const3,
|
||||
State::Instance().currentFeature->TargetWidth(), State::Instance().currentFeature->TargetHeight(),
|
||||
|
||||
@@ -241,6 +241,8 @@ bool RCAS_Vk::Dispatch(VkDevice InDevice, VkCommandBuffer InCmdList, RcasConstan
|
||||
State::Instance().currentFeature == nullptr)
|
||||
return false;
|
||||
|
||||
ScopedGpuTime_Vk scopedGpuTime(GpuTime.get(), InCmdList);
|
||||
|
||||
auto sharpnessShader = Config::Instance()->SharpnessShader.value_or_default();
|
||||
if (sharpnessShader == SharpenShader::LocalContrastDepthAware)
|
||||
{
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
#include "pch.h"
|
||||
#include "UpscalerTime_Vk.h"
|
||||
|
||||
#include <State.h>
|
||||
|
||||
void UpscalerTimeVk::Init(VkDevice device, VkPhysicalDevice pd)
|
||||
{
|
||||
VkQueryPoolCreateInfo queryPoolInfo = {};
|
||||
queryPoolInfo.sType = VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
|
||||
queryPoolInfo.queryType = VK_QUERY_TYPE_TIMESTAMP;
|
||||
queryPoolInfo.queryCount = 2; // Start and End timestamps
|
||||
|
||||
vkCreateQueryPool(device, &queryPoolInfo, nullptr, &_queryPool);
|
||||
|
||||
VkPhysicalDeviceProperties deviceProperties;
|
||||
vkGetPhysicalDeviceProperties(pd, &deviceProperties);
|
||||
_timeStampPeriod = deviceProperties.limits.timestampPeriod;
|
||||
}
|
||||
|
||||
void UpscalerTimeVk::UpscaleStart(VkCommandBuffer cmdBuffer)
|
||||
{
|
||||
if (_queryPool == VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
vkCmdResetQueryPool(cmdBuffer, _queryPool, 0, 2);
|
||||
vkCmdWriteTimestamp(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, _queryPool, 0);
|
||||
}
|
||||
|
||||
void UpscalerTimeVk::UpscaleEnd(VkCommandBuffer cmdBuffer)
|
||||
{
|
||||
if (_queryPool == VK_NULL_HANDLE)
|
||||
return;
|
||||
|
||||
vkCmdWriteTimestamp(cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, _queryPool, 1);
|
||||
_vkUpscaleTrig = true;
|
||||
}
|
||||
|
||||
void UpscalerTimeVk::ReadUpscalingTime(VkDevice device)
|
||||
{
|
||||
if (_vkUpscaleTrig && _queryPool != VK_NULL_HANDLE)
|
||||
{
|
||||
// Retrieve timestamps
|
||||
uint64_t timestamps[2];
|
||||
vkGetQueryPoolResults(device, _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]) * _timeStampPeriod / 1e6;
|
||||
|
||||
if (elapsedTimeMs > 0.0 && elapsedTimeMs < 5000.0)
|
||||
{
|
||||
State::Instance().frameTimeMutex.lock();
|
||||
State::Instance().upscaleTimes.push_back(elapsedTimeMs);
|
||||
State::Instance().upscaleTimes.pop_front();
|
||||
State::Instance().frameTimeMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
_vkUpscaleTrig = false;
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "SysUtils.h"
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
class UpscalerTimeVk
|
||||
{
|
||||
public:
|
||||
static void Init(VkDevice device, VkPhysicalDevice pd);
|
||||
static void UpscaleStart(VkCommandBuffer cmdBuffer);
|
||||
static void UpscaleEnd(VkCommandBuffer cmdBuffer);
|
||||
static void ReadUpscalingTime(VkDevice device);
|
||||
|
||||
private:
|
||||
static inline VkQueryPool _queryPool = VK_NULL_HANDLE;
|
||||
static inline double _timeStampPeriod = 1.0;
|
||||
static inline bool _vkUpscaleTrig = false;
|
||||
};
|
||||
@@ -18,12 +18,10 @@ bool IFeature_Vk::Init(VkInstance InInstance, VkPhysicalDevice InPD, VkDevice In
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
||||
OutputScaler = std::make_unique<OS_Vk>("Output Scaling", InDevice, InPD, (TargetWidth() < DisplayWidth()));
|
||||
RCAS = std::make_unique<RCAS_Vk>("RCAS", InDevice, InPD);
|
||||
Magnifier = std::make_unique<Magnifier_Vk>("Magnifier", InDevice, InPD);
|
||||
|
||||
// UpscalerTime = std::make_unique<GpuTime_Vk>(InDevice);
|
||||
UpscalerTime = std::make_unique<GpuTime_Vk>(InDevice, InPD);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -271,11 +269,11 @@ bool IFeature_Vk::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter* InP
|
||||
paramOutput->Resource.ImageViewInfo.Height = currentTarget.Height;
|
||||
}
|
||||
|
||||
// UpscalerTime->Start(InCmdBuffer);
|
||||
UpscalerTime->Start(InCmdBuffer);
|
||||
|
||||
auto evalResult = EvaluateInternal(InCmdBuffer, InParameters);
|
||||
|
||||
// UpscalerTime->End(InCmdBuffer);
|
||||
UpscalerTime->End(InCmdBuffer);
|
||||
|
||||
if (!evalResult)
|
||||
return false;
|
||||
@@ -306,4 +304,39 @@ bool IFeature_Vk::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter* InP
|
||||
_frameCount++;
|
||||
|
||||
return evalResult;
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<double> IFeature_Vk::ReadUpscalerTime(void* unused)
|
||||
{
|
||||
if (!UpscalerTime || !RCAS || !OutputScaler)
|
||||
return std::nullopt;
|
||||
|
||||
lastUpscalerTime = UpscalerTime->ReadGpuTime();
|
||||
lastRcasTime = RCAS->ReadGpuTime();
|
||||
lastOutputScalingTime = OutputScaler->ReadGpuTime();
|
||||
|
||||
return sumOpts(lastUpscalerTime, lastRcasTime, lastOutputScalingTime);
|
||||
}
|
||||
|
||||
void IFeature_Vk::ReadDetailedGpuTimes(void* unused, std::vector<DetailedGpuTime>& detailedGpuTimes)
|
||||
{
|
||||
detailedGpuTimes.clear();
|
||||
|
||||
// Do not call ReadGpuTime twice for shaders
|
||||
if (lastUpscalerTime)
|
||||
detailedGpuTimes.emplace_back(DetailedGpuTime { ShortName(), lastUpscalerTime.value(), true });
|
||||
|
||||
if (lastRcasTime)
|
||||
detailedGpuTimes.emplace_back(DetailedGpuTime { RCAS->Name(), lastRcasTime.value(), true });
|
||||
|
||||
if (lastOutputScalingTime)
|
||||
detailedGpuTimes.emplace_back(DetailedGpuTime { OutputScaler->Name(), lastOutputScalingTime.value(), true });
|
||||
|
||||
if (!Magnifier)
|
||||
return;
|
||||
|
||||
auto magnifierTime = Magnifier->ReadGpuTime();
|
||||
|
||||
if (magnifierTime)
|
||||
detailedGpuTimes.emplace_back(DetailedGpuTime { Magnifier->Name(), magnifierTime.value(), false });
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <shaders/rcas/RCAS_Vk.h>
|
||||
#include <shaders/output_scaling/OS_Vk.h>
|
||||
#include <shaders/magnifier/Magnifier_Vk.h>
|
||||
#include <gpu_time/GpuTime_Vk.h>
|
||||
|
||||
class IFeature_Vk : public virtual IFeature
|
||||
{
|
||||
@@ -33,6 +34,8 @@ class IFeature_Vk : public virtual IFeature
|
||||
std::unique_ptr<RCAS_Vk> RCAS = nullptr;
|
||||
std::unique_ptr<Magnifier_Vk> Magnifier = nullptr;
|
||||
|
||||
std::unique_ptr<GpuTime_Vk> UpscalerTime = nullptr;
|
||||
|
||||
virtual bool InitInternal(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter* InParameters) = 0;
|
||||
virtual bool EvaluateInternal(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter* InParameters) = 0;
|
||||
|
||||
@@ -42,6 +45,9 @@ class IFeature_Vk : public virtual IFeature
|
||||
NVSDK_NGX_Parameter* InParameters);
|
||||
virtual bool Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter* InParameters);
|
||||
|
||||
std::optional<double> ReadUpscalerTime(void* unused) override;
|
||||
void ReadDetailedGpuTimes(void* unused, std::vector<DetailedGpuTime>& detailedGpuTimes) override;
|
||||
|
||||
IFeature_Vk(unsigned int InHandleId, NVSDK_NGX_Parameter* InParameters) : IFeature(InHandleId, InParameters) {}
|
||||
|
||||
bool IsWithDx12() override { return false; }
|
||||
|
||||
@@ -1622,6 +1622,8 @@ bool IFeature_VkwDx12::CopyBackOutput(VkCommandBuffer InCmdBuffer)
|
||||
vkOut.VkSourceImageAccess = copyBarriers[1].dstAccessMask;
|
||||
}
|
||||
|
||||
UpscalerTime->End(b.VulkanCopyCommandBuffer[frame]);
|
||||
|
||||
vkResult = vkEndCommandBuffer(b.VulkanCopyCommandBuffer[frame]);
|
||||
if (vkResult != VK_SUCCESS)
|
||||
{
|
||||
@@ -2041,6 +2043,8 @@ bool IFeature_VkwDx12::Init(VkInstance InInstance, VkPhysicalDevice InPD, VkDevi
|
||||
return false;
|
||||
}
|
||||
|
||||
UpscalerTime = std::make_unique<GpuTime_Vk>(InDevice, InPD);
|
||||
|
||||
SetInitParameters(InParameters);
|
||||
|
||||
// Non-DLSS upscalers don't use the cmdList during Init
|
||||
@@ -2061,6 +2065,9 @@ bool IFeature_VkwDx12::Evaluate(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Parameter
|
||||
auto frame = _frameCount % VKDX12_BUFFER_COUNT;
|
||||
auto cmdList = Dx12CommandList[frame];
|
||||
|
||||
// Ends in the copy back command buffer, covers the whole interop with D3D12 upscaling in between
|
||||
UpscalerTime->Start(InCmdBuffer);
|
||||
|
||||
void* originalColor = nullptr;
|
||||
void* originalMotionVectors = nullptr;
|
||||
void* originalOutput = nullptr;
|
||||
|
||||
@@ -87,6 +87,8 @@ class IFeature_VkwDx12 : public virtual IFeature_Vk
|
||||
uint64_t pendingResourceCopyValue = 0;
|
||||
std::mutex EvaluateMutex;
|
||||
|
||||
std::vector<DetailedGpuTime> detailedGpuTimes;
|
||||
|
||||
// Copy shaders
|
||||
std::unique_ptr<ResourceCopy_Vk> ColorCopy = nullptr;
|
||||
std::unique_ptr<ResourceCopy_Vk> VelocityCopy = nullptr;
|
||||
@@ -148,6 +150,45 @@ class IFeature_VkwDx12 : public virtual IFeature_Vk
|
||||
API Api() const override { return API::DX12; }
|
||||
bool IsWithDx12() override { return true; }
|
||||
|
||||
std::optional<double> ReadUpscalerTime(void* unused) override
|
||||
{
|
||||
if (auto feature = dx12Feature.get(); feature && Dx12CommandQueue && UpscalerTime)
|
||||
{
|
||||
auto dx12UpscalerTime = feature->ReadUpscalerTime(Dx12CommandQueue);
|
||||
|
||||
feature->ReadDetailedGpuTimes(Dx12CommandQueue, detailedGpuTimes);
|
||||
|
||||
// Count up shader times that are included in upscalerWithInterop but not in dx12UpscalerTime
|
||||
double deductedUpscalerTime = 0.0;
|
||||
for (const auto& time : detailedGpuTimes)
|
||||
{
|
||||
if (!time.includedInUpscalerTime)
|
||||
deductedUpscalerTime += time.time;
|
||||
}
|
||||
|
||||
auto upscalerWithInterop = UpscalerTime->ReadGpuTime();
|
||||
|
||||
if (dx12UpscalerTime && upscalerWithInterop)
|
||||
{
|
||||
auto interopTime = upscalerWithInterop.value() - dx12UpscalerTime.value() - deductedUpscalerTime;
|
||||
|
||||
if (interopTime > 0.0)
|
||||
{
|
||||
detailedGpuTimes.push_back({ "Interop", interopTime, true });
|
||||
return interopTime + dx12UpscalerTime.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
};
|
||||
|
||||
void ReadDetailedGpuTimes(void* unused, std::vector<DetailedGpuTime>& detailedGpuTimes) override
|
||||
{
|
||||
// We already queried and prepared detailedGpuTimes in ReadUpscalerTime
|
||||
detailedGpuTimes = this->detailedGpuTimes;
|
||||
};
|
||||
|
||||
feature_version Version() final
|
||||
{
|
||||
return CallFeature([](auto f) { return f->Version(); }, feature_version {});
|
||||
|
||||
@@ -16,6 +16,11 @@ class DLSSFeatureVk : public DLSSFeature, public IFeature_Vk
|
||||
feature_version Version() override { return DLSSFeature::Version(); }
|
||||
Upscaler GetUpscalerType() const final { return DLSSFeature::GetUpscalerType(); }
|
||||
API Api() const override { return IFeature_Vk::Api(); }
|
||||
std::optional<double> ReadUpscalerTime(void* unused) override { return IFeature_Vk::ReadUpscalerTime(unused); };
|
||||
void ReadDetailedGpuTimes(void* unused, std::vector<DetailedGpuTime>& detailedGpuTimes) override
|
||||
{
|
||||
return IFeature_Vk::ReadDetailedGpuTimes(unused, detailedGpuTimes);
|
||||
};
|
||||
|
||||
bool IsWithDx12() override { return false; }
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@ class DLSSDFeatureVk : public DLSSDFeature, public IFeature_Vk
|
||||
feature_version Version() override { return DLSSDFeature::Version(); }
|
||||
Upscaler GetUpscalerType() const final { return DLSSDFeature::GetUpscalerType(); }
|
||||
API Api() const override { return IFeature_Vk::Api(); }
|
||||
std::optional<double> ReadUpscalerTime(void* unused) override { return IFeature_Vk::ReadUpscalerTime(unused); };
|
||||
void ReadDetailedGpuTimes(void* unused, std::vector<DetailedGpuTime>& detailedGpuTimes) override
|
||||
{
|
||||
return IFeature_Vk::ReadDetailedGpuTimes(unused, detailedGpuTimes);
|
||||
};
|
||||
|
||||
bool IsWithDx12() override { return false; }
|
||||
|
||||
|
||||
@@ -21,6 +21,11 @@ class FFXFeatureVk : public FFXFeature, public IFeature_Vk
|
||||
feature_version Version() override { return FFXFeature::Version(); }
|
||||
Upscaler GetUpscalerType() const final { return Upscaler::FFX; }
|
||||
API Api() const override { return IFeature_Vk::Api(); }
|
||||
std::optional<double> ReadUpscalerTime(void* unused) override { return IFeature_Vk::ReadUpscalerTime(unused); };
|
||||
void ReadDetailedGpuTimes(void* unused, std::vector<DetailedGpuTime>& detailedGpuTimes) override
|
||||
{
|
||||
return IFeature_Vk::ReadDetailedGpuTimes(unused, detailedGpuTimes);
|
||||
};
|
||||
|
||||
bool IsWithDx12() final { return false; }
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@ class FSR2FeatureVk : public FSR2Feature, public IFeature_Vk
|
||||
feature_version Version() override { return FSR2Feature::Version(); }
|
||||
Upscaler GetUpscalerType() const final { return Upscaler::FSR22; }
|
||||
API Api() const override { return IFeature_Vk::Api(); }
|
||||
std::optional<double> ReadUpscalerTime(void* unused) override { return IFeature_Vk::ReadUpscalerTime(unused); };
|
||||
void ReadDetailedGpuTimes(void* unused, std::vector<DetailedGpuTime>& detailedGpuTimes) override
|
||||
{
|
||||
return IFeature_Vk::ReadDetailedGpuTimes(unused, detailedGpuTimes);
|
||||
};
|
||||
|
||||
bool IsWithDx12() override { return false; }
|
||||
};
|
||||
@@ -26,6 +26,11 @@ class FSR2FeatureVk212 : public FSR2Feature212, public IFeature_Vk
|
||||
feature_version Version() override { return FSR2Feature212::Version(); }
|
||||
Upscaler GetUpscalerType() const final { return Upscaler::FSR21; }
|
||||
API Api() const override { return IFeature_Vk::Api(); }
|
||||
std::optional<double> ReadUpscalerTime(void* unused) override { return IFeature_Vk::ReadUpscalerTime(unused); };
|
||||
void ReadDetailedGpuTimes(void* unused, std::vector<DetailedGpuTime>& detailedGpuTimes) override
|
||||
{
|
||||
return IFeature_Vk::ReadDetailedGpuTimes(unused, detailedGpuTimes);
|
||||
};
|
||||
|
||||
bool IsWithDx12() override { return false; }
|
||||
};
|
||||
Reference in new issue
Block a user