Skip to content

Commit

Permalink
Refactor: Lift the frame time history data up one level into thin3d
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Aug 16, 2023
1 parent 08cf6e3 commit 572595c
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 46 deletions.
29 changes: 26 additions & 3 deletions Common/Data/Collections/FastVec.h
Expand Up @@ -157,14 +157,37 @@ class FastVec {
};

// Simple cyclical vector.
// Initially, doesn't do any sanity checking.
template <class T, size_t size>
class HistoryBuffer {
public:
T &Add(size_t index) {
_dbg_assert_((int64_t)index >= 0);
if (index > maxIndex_)
maxIndex_ = index;
T &entry = data_[index % size];
entry = T{};
return entry;
}

const T &Back(size_t index) const {
_dbg_assert_(index < maxIndex_ && index < size);
return data_[(maxIndex_ - index) % size];
}

// Out of bounds (past size() - 1) is undefined behavior.
T &operator[] (const size_t index) { return data_[index % size]; }
const T &operator[] (const size_t index) const { return data_[index % size]; }
T &operator[] (const size_t index) {
_dbg_assert_(index <= maxIndex_);
return data_[index % size];
}
const T &operator[] (const size_t index) const {
_dbg_assert_(index <= maxIndex_);
return data_[index % size];
}
size_t MaxIndex() const {
return maxIndex_;
}

private:
T data_[size]{};
size_t maxIndex_ = 0;
};
1 change: 1 addition & 0 deletions Common/GPU/MiscTypes.h
Expand Up @@ -34,3 +34,4 @@ struct FrameTimeData {
double earliestPresentTime;
double presentMargin;
};
constexpr size_t FRAME_TIME_HISTORY_LENGTH = 32;
35 changes: 18 additions & 17 deletions Common/GPU/Vulkan/VulkanRenderManager.cpp
Expand Up @@ -250,12 +250,13 @@ bool VKRComputePipeline::CreateAsync(VulkanContext *vulkan) {
return true;
}

VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan, bool useThread)
VulkanRenderManager::VulkanRenderManager(VulkanContext *vulkan, bool useThread, HistoryBuffer<FrameTimeData, FRAME_TIME_HISTORY_LENGTH> &frameTimeHistory)
: vulkan_(vulkan), queueRunner_(vulkan),
initTimeMs_("initTimeMs"),
totalGPUTimeMs_("totalGPUTimeMs"),
renderCPUTimeMs_("renderCPUTimeMs"),
useRenderThread_(useThread)
useRenderThread_(useThread),
frameTimeHistory_(frameTimeHistory)
{
inflightFramesAtStart_ = vulkan_->GetInflightFrames();

Expand Down Expand Up @@ -552,13 +553,13 @@ void VulkanRenderManager::PresentWaitThreadFunc() {
while (run_) {
const uint64_t timeout = 1000000000ULL; // 1 sec
if (VK_SUCCESS == vkWaitForPresentKHR(vulkan_->GetDevice(), vulkan_->GetSwapchain(), waitedId, timeout)) {
frameTimeData_[waitedId].actualPresent = time_now_d();
frameTimeData_[waitedId].waitCount++;
frameTimeHistory_[waitedId].actualPresent = time_now_d();
frameTimeHistory_[waitedId].waitCount++;
waitedId++;
} else {
// We caught up somehow, which is a bad sign (we should have blocked, right?). Maybe we should break out of the loop?
sleep_ms(1);
frameTimeData_[waitedId].waitCount++;
frameTimeHistory_[waitedId].waitCount++;
}
_dbg_assert_(waitedId <= frameIdGen_);
}
Expand All @@ -580,11 +581,11 @@ void VulkanRenderManager::PollPresentTiming() {
vkGetPastPresentationTimingGOOGLE(vulkan_->GetDevice(), vulkan_->GetSwapchain(), &count, timings);
for (uint32_t i = 0; i < count; i++) {
uint64_t presentId = timings[i].presentID;
frameTimeData_[presentId].actualPresent = from_time_raw(timings[i].actualPresentTime);
frameTimeData_[presentId].desiredPresentTime = from_time_raw(timings[i].desiredPresentTime);
frameTimeData_[presentId].earliestPresentTime = from_time_raw(timings[i].earliestPresentTime);
frameTimeHistory_[presentId].actualPresent = from_time_raw(timings[i].actualPresentTime);
frameTimeHistory_[presentId].desiredPresentTime = from_time_raw(timings[i].desiredPresentTime);
frameTimeHistory_[presentId].earliestPresentTime = from_time_raw(timings[i].earliestPresentTime);
double presentMargin = from_time_raw_relative(timings[i].presentMargin);
frameTimeData_[presentId].presentMargin = presentMargin;
frameTimeHistory_[presentId].presentMargin = presentMargin;
}
delete[] timings;
}
Expand Down Expand Up @@ -623,16 +624,16 @@ void VulkanRenderManager::BeginFrame(bool enableProfiling, bool enableLogProfile

int validBits = vulkan_->GetQueueFamilyProperties(vulkan_->GetGraphicsQueueFamilyIndex()).timestampValidBits;

FrameTimeData &frameTimeData = frameTimeHistory_.Add(frameId);
frameTimeData.frameId = frameId;
frameTimeData.frameBegin = frameBeginTime;
frameTimeData.afterFenceWait = time_now_d();

// Can't set this until after the fence.
frameData.profile.enabled = enableProfiling;
frameData.profile.timestampsEnabled = enableProfiling && validBits > 0;
frameData.frameId = frameId;

frameTimeData_[frameId] = {};
frameTimeData_[frameId].frameId = frameId;
frameTimeData_[frameId].frameBegin = frameBeginTime;
frameTimeData_[frameId].afterFenceWait = time_now_d();

uint64_t queryResults[MAX_TIMESTAMP_QUERIES];

if (enableProfiling) {
Expand Down Expand Up @@ -1391,7 +1392,7 @@ void VulkanRenderManager::Run(VKRRenderThreadTask &task) {
if (task.runType == VKRRunType::PRESENT) {
if (!frameData.skipSwap) {
VkResult res = frameData.QueuePresent(vulkan_, frameDataShared_);
frameTimeData_[frameData.frameId].queuePresent = time_now_d();
frameTimeHistory_[frameData.frameId].queuePresent = time_now_d();
if (res == VK_ERROR_OUT_OF_DATE_KHR) {
// We clearly didn't get this in vkAcquireNextImageKHR because of the skipSwap check above.
// Do the increment.
Expand All @@ -1414,8 +1415,8 @@ void VulkanRenderManager::Run(VKRRenderThreadTask &task) {

_dbg_assert_(!frameData.hasPresentCommands);

if (!frameTimeData_[frameData.frameId].firstSubmit) {
frameTimeData_[frameData.frameId].firstSubmit = time_now_d();
if (!frameTimeHistory_[frameData.frameId].firstSubmit) {
frameTimeHistory_[frameData.frameId].firstSubmit = time_now_d();
}
frameData.SubmitPending(vulkan_, FrameSubmitType::Pending, frameDataShared_);

Expand Down
15 changes: 2 additions & 13 deletions Common/GPU/Vulkan/VulkanRenderManager.h
Expand Up @@ -182,7 +182,7 @@ struct CompileQueueEntry {

class VulkanRenderManager {
public:
VulkanRenderManager(VulkanContext *vulkan, bool useThread);
VulkanRenderManager(VulkanContext *vulkan, bool useThread, HistoryBuffer<FrameTimeData, FRAME_TIME_HISTORY_LENGTH> &frameTimeHistory);
~VulkanRenderManager();

// Makes sure that the GPU has caught up enough that we can start writing buffers of this frame again.
Expand Down Expand Up @@ -458,17 +458,6 @@ class VulkanRenderManager {
void ResetStats();
void DrainCompileQueue();

// framesBack is the number of frames into the past to look.
FrameTimeData GetFrameTimeData(int framesBack) const {
FrameTimeData data;
if (framesBack >= frameIdGen_) {
data = {};
return data;
}
data = frameTimeData_[frameIdGen_ - framesBack];
return data;
}

private:
void EndCurRenderStep();

Expand Down Expand Up @@ -553,5 +542,5 @@ class VulkanRenderManager {
std::function<void(InvalidationCallbackFlags)> invalidationCallback_;

uint64_t frameIdGen_ = 31;
HistoryBuffer<FrameTimeData, 32> frameTimeData_;
HistoryBuffer<FrameTimeData, 32> &frameTimeHistory_;
};
8 changes: 2 additions & 6 deletions Common/GPU/Vulkan/thin3d_vulkan.cpp
Expand Up @@ -488,10 +488,6 @@ class VKContext : public DrawContext {
return frameCount_;
}

FrameTimeData GetFrameTimeData(int framesBack) const override {
return renderManager_.GetFrameTimeData(framesBack);
}

void FlushState() override {}

void ResetStats() override {
Expand Down Expand Up @@ -564,7 +560,7 @@ class VKContext : public DrawContext {
AutoRef<VKTexture> boundTextures_[MAX_BOUND_TEXTURES];
AutoRef<VKSamplerState> boundSamplers_[MAX_BOUND_TEXTURES];
VkImageView boundImageView_[MAX_BOUND_TEXTURES]{};
TextureBindFlags boundTextureFlags_[MAX_BOUND_TEXTURES];
TextureBindFlags boundTextureFlags_[MAX_BOUND_TEXTURES]{};

VulkanPushPool *push_ = nullptr;

Expand Down Expand Up @@ -866,7 +862,7 @@ static DataFormat DataFormatFromVulkanDepth(VkFormat fmt) {
}

VKContext::VKContext(VulkanContext *vulkan, bool useRenderThread)
: vulkan_(vulkan), renderManager_(vulkan, useRenderThread) {
: vulkan_(vulkan), renderManager_(vulkan, useRenderThread, frameTimeHistory_) {
shaderLanguageDesc_.Init(GLSL_VULKAN);

VkFormat depthStencilFormat = vulkan->GetDeviceInfo().preferredDepthStencilFormat;
Expand Down
11 changes: 7 additions & 4 deletions Common/GPU/thin3d.h
Expand Up @@ -18,6 +18,7 @@
#include "Common/GPU/Shader.h"
#include "Common/GPU/MiscTypes.h"
#include "Common/Data/Collections/Slice.h"
#include "Common/Data/Collections/FastVec.h"

namespace Lin {
class Matrix4x4;
Expand Down Expand Up @@ -853,15 +854,17 @@ class DrawContext {
// Total amount of frames rendered. Unaffected by game pause, so more robust than gpuStats.numFlips
virtual int GetFrameCount() = 0;

virtual FrameTimeData GetFrameTimeData(int framesBack) const {
return FrameTimeData{};
}

virtual std::string GetGpuProfileString() const {
return "";
}

const HistoryBuffer<FrameTimeData, FRAME_TIME_HISTORY_LENGTH> &FrameTimeHistory() const {
return frameTimeHistory_;
}

protected:
HistoryBuffer<FrameTimeData, FRAME_TIME_HISTORY_LENGTH> frameTimeHistory_;

ShaderModule *vsPresets_[VS_MAX_PRESET];
ShaderModule *fsPresets_[FS_MAX_PRESET];

Expand Down
9 changes: 6 additions & 3 deletions UI/DebugOverlay.cpp
Expand Up @@ -115,15 +115,18 @@ static void DrawFrameTiming(UIContext *ctx, const Bounds &bounds) {
ctx->Draw()->SetFontScale(0.5f, 0.5f);

snprintf(statBuf, sizeof(statBuf),
"Present mode (interval): %s (%d)",
"Mode (interval): %s (%d)",
Draw::PresentModeToString(g_frameTiming.presentMode),
g_frameTiming.presentInterval);

ctx->Draw()->DrawTextRect(ubuntu24, statBuf, bounds.x + 10, bounds.y + 50, bounds.w - 20, bounds.h - 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII);

for (int i = 0; i < 5; i++) {
FrameTimeData data = ctx->GetDrawContext()->GetFrameTimeData(6 + i);
FrameTimeData prevData = ctx->GetDrawContext()->GetFrameTimeData(7 + i);
size_t curIndex = i + 6;
size_t prevIndex = i + 7;

FrameTimeData data = ctx->GetDrawContext()->FrameTimeHistory().Back(curIndex);
FrameTimeData prevData = ctx->GetDrawContext()->FrameTimeHistory().Back(prevIndex);
if (data.frameBegin == 0.0) {
snprintf(statBuf, sizeof(statBuf), "(No frame time data)");
} else {
Expand Down

0 comments on commit 572595c

Please sign in to comment.