mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-06 20:58:37 +01:00
[hud] Add render latency
This commit is contained in:
parent
a8bd6f069e
commit
2c26eb2118
7 changed files with 133 additions and 5 deletions
|
@ -295,6 +295,9 @@ namespace dxvk {
|
|||
if (m_latencyHud)
|
||||
m_latencyHud->accumulateStats(latencyStats);
|
||||
|
||||
if (m_renderLatencyHud)
|
||||
m_renderLatencyHud->updateLatencyTracker(m_latency);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -604,8 +607,14 @@ namespace dxvk {
|
|||
if (hud) {
|
||||
hud->addItem<hud::HudClientApiItem>("api", 1, GetApiName());
|
||||
|
||||
if (m_latency)
|
||||
if (m_latency) {
|
||||
m_latencyHud = hud->addItem<hud::HudLatencyItem>("latency", 4);
|
||||
FramePacer* framePacer = dynamic_cast<FramePacer*>(m_latency.ptr());
|
||||
if (framePacer) {
|
||||
int32_t fpsItemPos = hud->getItemPos<hud::HudFpsItem>();
|
||||
m_renderLatencyHud = hud->addItem<hud::HudRenderLatencyItem>("renderlatency", fpsItemPos+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_blitter = new DxvkSwapchainBlitter(m_device, std::move(hud));
|
||||
|
|
|
@ -126,6 +126,7 @@ namespace dxvk {
|
|||
DXGI_VK_FRAME_STATISTICS m_frameStatistics = { };
|
||||
|
||||
Rc<hud::HudLatencyItem> m_latencyHud;
|
||||
Rc<hud::HudRenderLatencyItem> m_renderLatencyHud;
|
||||
|
||||
Rc<DxvkImageView> GetBackBufferView();
|
||||
|
||||
|
|
|
@ -925,6 +925,9 @@ namespace dxvk {
|
|||
if (m_latencyHud)
|
||||
m_latencyHud->accumulateStats(latencyStats);
|
||||
|
||||
if (m_renderLatencyHud)
|
||||
m_renderLatencyHud->updateLatencyTracker(m_latencyTracker);
|
||||
|
||||
// Rotate swap chain buffers so that the back
|
||||
// buffer at index 0 becomes the front buffer.
|
||||
for (uint32_t i = 1; i < m_backBuffers.size(); i++)
|
||||
|
@ -1062,8 +1065,14 @@ namespace dxvk {
|
|||
if (hud) {
|
||||
m_apiHud = hud->addItem<hud::HudClientApiItem>("api", 1, GetApiName());
|
||||
|
||||
if (m_latencyTracking)
|
||||
if (m_latencyTracking) {
|
||||
m_latencyHud = hud->addItem<hud::HudLatencyItem>("latency", 4);
|
||||
FramePacer* framePacer = dynamic_cast<FramePacer*>(m_latencyTracker.ptr());
|
||||
if (framePacer) {
|
||||
int32_t fpsItemPos = hud->getItemPos<hud::HudFpsItem>();
|
||||
m_renderLatencyHud = hud->addItem<hud::HudRenderLatencyItem>("renderlatency", fpsItemPos+1);
|
||||
}
|
||||
}
|
||||
|
||||
hud->addItem<hud::HudSamplerCount>("samplers", -1, m_parent);
|
||||
hud->addItem<hud::HudFixedFunctionShaders>("ffshaders", -1, m_parent);
|
||||
|
|
|
@ -185,6 +185,7 @@ namespace dxvk {
|
|||
|
||||
Rc<hud::HudClientApiItem> m_apiHud;
|
||||
Rc<hud::HudLatencyItem> m_latencyHud;
|
||||
Rc<hud::HudRenderLatencyItem> m_renderLatencyHud;
|
||||
|
||||
std::optional<VkHdrMetadataEXT> m_hdrMetadata;
|
||||
bool m_unlockAdditionalFormats = false;
|
||||
|
|
|
@ -60,6 +60,11 @@ namespace dxvk::hud {
|
|||
return m_hudItems.add<T>(name, at, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int32_t getItemPos() {
|
||||
return m_hudItems.getItemPos<T>();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Creates the HUD
|
||||
*
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "dxvk_hud_item.h"
|
||||
#include "../framepacer/dxvk_framepacer.h"
|
||||
|
||||
#include <hud_chunk_frag_background.h>
|
||||
#include <hud_chunk_frag_visualize.h>
|
||||
|
@ -213,6 +214,63 @@ namespace dxvk::hud {
|
|||
}
|
||||
|
||||
|
||||
HudRenderLatencyItem::HudRenderLatencyItem() { }
|
||||
HudRenderLatencyItem::~HudRenderLatencyItem() { }
|
||||
|
||||
void HudRenderLatencyItem::update(dxvk::high_resolution_clock::time_point time) {
|
||||
// we cannot measure latency when fps-limiting is performed in Presenter::runFrameThread()
|
||||
// because it's interfering with getting the right timestamp from vkWaitForPresent()
|
||||
// if we truely wanted to measure it, we would need one additional thread
|
||||
if (FpsLimiter::m_isActive) {
|
||||
m_latency = "N/A";
|
||||
return;
|
||||
}
|
||||
|
||||
const Rc<DxvkLatencyTracker> tracker = m_tracker;
|
||||
const FramePacer* framePacer = dynamic_cast<FramePacer*>( tracker.ptr() );
|
||||
if (!framePacer)
|
||||
return;
|
||||
|
||||
auto elapsed = std::chrono::duration_cast<std::chrono::microseconds>(time - m_lastUpdate);
|
||||
|
||||
if (elapsed.count() >= UpdateInterval) {
|
||||
m_lastUpdate = time;
|
||||
|
||||
LatencyMarkersReader reader = framePacer->m_latencyMarkersStorage.getReader(100);
|
||||
const LatencyMarkers* markers;
|
||||
uint32_t count = 0;
|
||||
uint64_t totalLatency = 0;
|
||||
while (reader.getNext(markers)) {
|
||||
totalLatency += markers->presentFinished;
|
||||
++count;
|
||||
}
|
||||
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
uint64_t latency = totalLatency / count;
|
||||
m_latency = str::format(latency / 1000, ".", (latency/100) % 10, " ms");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HudPos HudRenderLatencyItem::render(
|
||||
const DxvkContextObjects& ctx,
|
||||
const HudPipelineKey& key,
|
||||
const HudOptions& options,
|
||||
HudRenderer& renderer,
|
||||
HudPos position) {
|
||||
|
||||
position.y += 12;
|
||||
renderer.drawText(16, position, 0xff4040ffu, "Render latency:");
|
||||
renderer.drawText(16, { position.x + 195, position.y },
|
||||
0xffffffffu, m_latency);
|
||||
|
||||
position.y += 8;
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
HudFrameTimeItem::HudFrameTimeItem(const Rc<DxvkDevice>& device, HudRenderer* renderer)
|
||||
: m_device (device),
|
||||
m_gfxSetLayout (createDescriptorSetLayout()),
|
||||
|
|
|
@ -131,6 +131,15 @@ namespace dxvk::hud {
|
|||
return value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
int32_t getItemPos() {
|
||||
for (int i=0; i<(int)m_items.size(); ++i) {
|
||||
if (dynamic_cast<T*>(m_items[i].ptr()))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool m_enableFull = false;
|
||||
|
@ -244,6 +253,42 @@ namespace dxvk::hud {
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief HUD item to display render latency
|
||||
*/
|
||||
class HudRenderLatencyItem : public HudItem {
|
||||
constexpr static int64_t UpdateInterval = 500'000;
|
||||
public:
|
||||
|
||||
HudRenderLatencyItem();
|
||||
|
||||
~HudRenderLatencyItem();
|
||||
|
||||
void updateLatencyTracker( const Rc<DxvkLatencyTracker>& tracker ) {
|
||||
m_tracker = tracker;
|
||||
}
|
||||
|
||||
void update(dxvk::high_resolution_clock::time_point time);
|
||||
|
||||
HudPos render(
|
||||
const DxvkContextObjects& ctx,
|
||||
const HudPipelineKey& key,
|
||||
const HudOptions& options,
|
||||
HudRenderer& renderer,
|
||||
HudPos position);
|
||||
|
||||
private:
|
||||
|
||||
Rc<DxvkLatencyTracker> m_tracker;
|
||||
|
||||
dxvk::high_resolution_clock::time_point m_lastUpdate
|
||||
= dxvk::high_resolution_clock::now();
|
||||
|
||||
std::string m_latency;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \brief HUD item to display the frame rate
|
||||
*/
|
||||
|
|
Loading…
Add table
Reference in a new issue