Add per shader GPU times to Vulkan

Slopped.
This commit is contained in:
FakeMichau committed 2026-10-07 00:54:11 +02:00
1 parent f72e47b9ba
commit e199fac4e0
23 files changed
+302 -106

No files matched your search

+2 -2
View File
@@ -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" />
+6 -6
View File
@@ -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>
+98
View File
@@ -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;
}
+47
View File
@@ -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);
}
};
+19 -3
View File
@@ -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
-8
View File
@@ -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;
}
-2
View File
@@ -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>
+1
View File
@@ -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()
+5
View File
@@ -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(),
+2
View File
@@ -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;
};
+39 -6
View File
@@ -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 });
}
+6
View File
@@ -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;
+41
View File
@@ -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; }
+5
View File
@@ -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; }
};