mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
133 lines
3.8 KiB
C++
133 lines
3.8 KiB
C++
#include "dxvk_hud_fps.h"
|
|
|
|
#include <cmath>
|
|
#include <iomanip>
|
|
|
|
namespace dxvk::hud {
|
|
|
|
HudFps::HudFps(HudElements elements)
|
|
: m_elements (elements),
|
|
m_fpsString ("FPS: "),
|
|
m_prevFpsUpdate(Clock::now()),
|
|
m_prevFtgUpdate(Clock::now()) {
|
|
|
|
}
|
|
|
|
|
|
HudFps::~HudFps() {
|
|
|
|
}
|
|
|
|
|
|
void HudFps::update() {
|
|
m_frameCount += 1;
|
|
|
|
TimePoint now = Clock::now();
|
|
TimeDiff elapsedFps = std::chrono::duration_cast<TimeDiff>(now - m_prevFpsUpdate);
|
|
TimeDiff elapsedFtg = std::chrono::duration_cast<TimeDiff>(now - m_prevFtgUpdate);
|
|
m_prevFtgUpdate = now;
|
|
|
|
// Update FPS string
|
|
if (elapsedFps.count() >= UpdateInterval) {
|
|
const int64_t fps = (10'000'000ll * m_frameCount) / elapsedFps.count();
|
|
m_fpsString = str::format("FPS: ", fps / 10, ".", fps % 10);
|
|
|
|
m_prevFpsUpdate = now;
|
|
m_frameCount = 0;
|
|
}
|
|
|
|
// Update frametime stuff
|
|
m_dataPoints[m_dataPointId] = float(elapsedFtg.count());
|
|
m_dataPointId = (m_dataPointId + 1) % NumDataPoints;
|
|
}
|
|
|
|
|
|
HudPos HudFps::render(
|
|
const Rc<DxvkContext>& context,
|
|
HudRenderer& renderer,
|
|
HudPos position) {
|
|
if (m_elements.test(HudElement::Framerate)) {
|
|
position = this->renderFpsText(
|
|
context, renderer, position);
|
|
}
|
|
|
|
if (m_elements.test(HudElement::Frametimes)) {
|
|
position = this->renderFrametimeGraph(
|
|
context, renderer, position);
|
|
}
|
|
|
|
return position;
|
|
}
|
|
|
|
|
|
HudPos HudFps::renderFpsText(
|
|
const Rc<DxvkContext>& context,
|
|
HudRenderer& renderer,
|
|
HudPos position) {
|
|
renderer.drawText(context, 16.0f,
|
|
{ position.x, position.y },
|
|
{ 1.0f, 1.0f, 1.0f, 1.0f },
|
|
m_fpsString);
|
|
|
|
return HudPos { position.x, position.y + 24 };
|
|
}
|
|
|
|
|
|
HudPos HudFps::renderFrametimeGraph(
|
|
const Rc<DxvkContext>& context,
|
|
HudRenderer& renderer,
|
|
HudPos position) {
|
|
std::array<HudVertex, NumDataPoints * 2> vData;
|
|
|
|
// 60 FPS = optimal, 10 FPS = worst
|
|
const float targetUs = 16'666.6f;
|
|
const float minUs = 5'000.0f;
|
|
const float maxUs = 100'000.0f;
|
|
|
|
// Ten times the maximum/minimum number
|
|
// of milliseconds for a single frame
|
|
uint32_t minMs = 0xFFFFFFFFu;
|
|
uint32_t maxMs = 0x00000000u;
|
|
|
|
// Paint the time points
|
|
for (uint32_t i = 0; i < NumDataPoints; i++) {
|
|
float us = m_dataPoints[(m_dataPointId + i) % NumDataPoints];
|
|
|
|
minMs = std::min(minMs, uint32_t(us / 100.0f));
|
|
maxMs = std::max(maxMs, uint32_t(us / 100.0f));
|
|
|
|
float r = std::min(std::max(-1.0f + us / targetUs, 0.0f), 1.0f);
|
|
float g = std::min(std::max( 3.0f - us / targetUs, 0.0f), 1.0f);
|
|
float l = std::sqrt(r * r + g * g);
|
|
|
|
HudTexCoord tc = { 0u, 0u };
|
|
HudColor color = { r / l, g / l, 0.0f, 1.0f };
|
|
|
|
float x = position.x + float(i);
|
|
float y = position.y + 24.0f;
|
|
|
|
float hVal = std::log2(std::max((us - minUs) / targetUs + 1.0f, 1.0f))
|
|
/ std::log2((maxUs - minUs) / targetUs);
|
|
float h = std::min(std::max(40.0f * hVal, 2.0f), 40.0f);
|
|
|
|
vData[2 * i + 0] = HudVertex { { x, y }, tc, color };
|
|
vData[2 * i + 1] = HudVertex { { x, y - h }, tc, color };
|
|
}
|
|
|
|
renderer.drawLines(context, vData.size(), vData.data());
|
|
|
|
// Paint min/max frame times in the entire window
|
|
renderer.drawText(context, 14.0f,
|
|
{ position.x, position.y + 44.0f },
|
|
{ 1.0f, 1.0f, 1.0f, 1.0f },
|
|
str::format("min: ", minMs / 10, ".", minMs % 10));
|
|
|
|
renderer.drawText(context, 14.0f,
|
|
{ position.x + 150.0f, position.y + 44.0f },
|
|
{ 1.0f, 1.0f, 1.0f, 1.0f },
|
|
str::format("max: ", maxMs / 10, ".", maxMs % 10));
|
|
|
|
return HudPos { position.x, position.y + 66.0f };
|
|
}
|
|
|
|
} |