Skip to content

Commit

Permalink
Merge pull request #17475 from hrydgard/opengl-basic-profiler
Browse files Browse the repository at this point in the history
Add a trivial profiling tool to the OpenGL backend
  • Loading branch information
hrydgard committed May 17, 2023
2 parents e0e25ab + 05b6bbd commit 5d7a051
Show file tree
Hide file tree
Showing 11 changed files with 60 additions and 7 deletions.
9 changes: 9 additions & 0 deletions Common/GPU/OpenGL/GLFrameData.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ class GLDeleter {
std::vector<GLPushBuffer *> pushBuffers;
};

struct GLQueueProfileContext {
bool enabled;
double cpuStartTime;
double cpuEndTime;
};


// Per-frame data, round-robin so we can overlap submission with execution of the previous frame.
struct GLFrameData {
bool skipSwap = false;
Expand All @@ -49,4 +56,6 @@ struct GLFrameData {
GLDeleter deleter;
GLDeleter deleter_prev;
std::set<GLPushBuffer *> activePushBuffers;

GLQueueProfileContext profile;
};
20 changes: 19 additions & 1 deletion Common/GPU/OpenGL/GLRenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "Common/Log.h"
#include "Common/TimeUtil.h"
#include "Common/MemoryUtil.h"
#include "Common/StringUtils.h"
#include "Common/Math/math_util.h"

#if 0 // def _DEBUG
Expand Down Expand Up @@ -187,6 +188,14 @@ void GLRenderManager::StopThread() {
}
}

std::string GLRenderManager::GetGpuProfileString() const {
int curFrame = GetCurFrame();
const GLQueueProfileContext &profile = frameData_[curFrame].profile;

float cputime_ms = 1000.0f * (profile.cpuEndTime - profile.cpuStartTime);
return StringFromFormat("CPU time to run the list: %0.2f ms", cputime_ms);
}

void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRenderPassAction color, GLRRenderPassAction depth, GLRRenderPassAction stencil, uint32_t clearColor, float clearDepth, uint8_t clearStencil, const char *tag) {
_assert_(insideFrame_);
#ifdef _DEBUG
Expand Down Expand Up @@ -341,14 +350,15 @@ void GLRenderManager::CopyImageToMemorySync(GLRTexture *texture, int mipLevel, i
queueRunner_.CopyFromReadbackBuffer(nullptr, w, h, Draw::DataFormat::R8G8B8A8_UNORM, destFormat, pixelStride, pixels);
}

void GLRenderManager::BeginFrame() {
void GLRenderManager::BeginFrame(bool enableProfiling) {
#ifdef _DEBUG
curProgram_ = nullptr;
#endif

int curFrame = GetCurFrame();

GLFrameData &frameData = frameData_[curFrame];
frameData.profile.enabled = enableProfiling;
{
VLOG("PUSH: BeginFrame (curFrame = %d, readyForFence = %d, time=%0.3f)", curFrame, (int)frameData.readyForFence, time_now_d());
std::unique_lock<std::mutex> lock(frameData.fenceMutex);
Expand Down Expand Up @@ -417,6 +427,10 @@ bool GLRenderManager::Run(GLRRenderThreadTask &task) {
}
}

if (frameData.profile.enabled) {
frameData.profile.cpuStartTime = time_now_d();
}

if (IsVREnabled()) {
int passes = GetVRPassesCount();
for (int i = 0; i < passes; i++) {
Expand All @@ -428,6 +442,10 @@ bool GLRenderManager::Run(GLRRenderThreadTask &task) {
queueRunner_.RunSteps(task.steps, skipGLCalls_, false, false);
}

if (frameData.profile.enabled) {
frameData.profile.cpuEndTime = time_now_d();
}

if (!skipGLCalls_) {
for (auto iter : frameData.activePushBuffers) {
iter->MapDevice(bufferStrategy_);
Expand Down
4 changes: 3 additions & 1 deletion Common/GPU/OpenGL/GLRenderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,10 @@ class GLRenderManager {
caps_ = caps;
}

std::string GetGpuProfileString() const;

// Makes sure that the GPU has caught up enough that we can start writing buffers of this frame again.
void BeginFrame();
void BeginFrame(bool enableProfiling);
// Can run on a different thread!
void Finish();

Expand Down
7 changes: 6 additions & 1 deletion Common/GPU/OpenGL/thin3d_gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,9 @@ class OpenGLContext : public DrawContext {
DrawContext::SetTargetSize(w, h);
renderManager_.Resize(w, h);
}
void SetDebugFlags(DebugFlags flags) override {
debugFlags_ = flags;
}

const DeviceCaps &GetDeviceCaps() const override {
return caps_;
Expand Down Expand Up @@ -514,6 +517,8 @@ class OpenGLContext : public DrawContext {
GLPushBuffer *push;
};
FrameData frameData_[GLRenderManager::MAX_INFLIGHT_FRAMES]{};

DebugFlags debugFlags_ = DebugFlags::NONE;
};

static constexpr int MakeIntelSimpleVer(int v1, int v2, int v3) {
Expand Down Expand Up @@ -778,7 +783,7 @@ OpenGLContext::~OpenGLContext() {
}

void OpenGLContext::BeginFrame() {
renderManager_.BeginFrame();
renderManager_.BeginFrame(debugFlags_ & DebugFlags::PROFILE_TIMESTAMPS);
FrameData &frameData = frameData_[renderManager_.GetCurFrame()];
renderManager_.BeginPushBuffer(frameData.push);
}
Expand Down
3 changes: 3 additions & 0 deletions GPU/Common/GPUDebugInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,9 @@ class GPUDebugInterface {
// cached framebuffers / textures / vertices?
// get content of specific framebuffer / texture?
// vertex / texture decoding?

// Note: Wanted to name it GetProfileString but clashes with a Windows API.
virtual std::string GetGpuProfileString() { return ""; }
};

bool GPUDebugInitExpression(GPUDebugInterface *g, const char *str, PostfixExpression &exp);
Expand Down
5 changes: 5 additions & 0 deletions GPU/GLES/GPU_GLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,3 +305,8 @@ void GPU_GLES::GetStats(char *buffer, size_t bufsize) {
shaderManagerGL_->GetNumPrograms()
);
}

std::string GPU_GLES::GetGpuProfileString() {
GLRenderManager *rm = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
return rm->GetGpuProfileString();
}
2 changes: 2 additions & 0 deletions GPU/GLES/GPU_GLES.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class GPU_GLES : public GPUCommonHW {
void BeginHostFrame() override;
void EndHostFrame() override;

std::string GetGpuProfileString() override;

protected:
void FinishDeferred() override;

Expand Down
11 changes: 9 additions & 2 deletions GPU/Vulkan/DebugVisVulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#include "GPU/Vulkan/VulkanUtil.h"
#include "GPU/Vulkan/TextureCacheVulkan.h"

#include "Core/Config.h"

#undef DrawText

bool comparePushBufferNames(const VulkanMemoryManager *a, const VulkanMemoryManager *b) {
Expand Down Expand Up @@ -107,9 +109,14 @@ void DrawGPUProfilerVis(UIContext *ui, GPUInterface *gpu) {

ui->Begin();

GPU_Vulkan *gpuVulkan = static_cast<GPU_Vulkan *>(gpu);
float scale = 0.4f;
if (g_Config.iGPUBackend == (int)GPUBackend::OPENGL) {
// Don't have as much info, let's go bigger.
scale = 0.7f;
}

std::string text = gpuVulkan->GetGpuProfileString();
GPUCommon *gpuCommon = static_cast<GPUCommon *>(gpu);
std::string text = gpuCommon->GetGpuProfileString();

ui->SetFontScale(0.4f, 0.4f);
ui->DrawTextShadow(text.c_str(), x, y, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII);
Expand Down
2 changes: 1 addition & 1 deletion GPU/Vulkan/GPU_Vulkan.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class GPU_Vulkan : public GPUCommonHW {
return textureCacheVulkan_;
}

std::string GetGpuProfileString();
std::string GetGpuProfileString() override;

protected:
void FinishDeferred() override;
Expand Down
2 changes: 2 additions & 0 deletions UI/DevScreens.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ void DevMenuScreen::CreatePopupContents(UI::ViewGroup *parent) {
items->Add(new Choice(dev->T("Shader Viewer")))->OnClick.Handle(this, &DevMenuScreen::OnShaderView);
if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN) {
items->Add(new CheckBox(&g_Config.bShowAllocatorDebug, dev->T("Allocator Viewer")));
}
if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN || g_Config.iGPUBackend == (int)GPUBackend::OPENGL) {
items->Add(new CheckBox(&g_Config.bShowGpuProfile, dev->T("GPU Profile")));
}
items->Add(new Choice(dev->T("Toggle Freeze")))->OnClick.Handle(this, &DevMenuScreen::OnFreezeFrame);
Expand Down
2 changes: 1 addition & 1 deletion UI/EmuScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1616,7 +1616,7 @@ void EmuScreen::renderUI() {
DrawAllocatorVis(ctx, gpu);
}

if (g_Config.iGPUBackend == (int)GPUBackend::VULKAN && g_Config.bShowGpuProfile) {
if ((g_Config.iGPUBackend == (int)GPUBackend::VULKAN || g_Config.iGPUBackend == (int)GPUBackend::OPENGL) && g_Config.bShowGpuProfile) {
DrawGPUProfilerVis(ctx, gpu);
}

Expand Down

0 comments on commit 5d7a051

Please sign in to comment.