GPU: Move stats from renderer class to base classes

This commit is contained in:
Connor McLaughlin 2019-11-05 19:44:17 +10:00
parent afbec85f89
commit 2c631aba5e
11 changed files with 144 additions and 158 deletions

View File

@ -757,12 +757,66 @@ bool GPU::DumpVRAMToFile(const char* filename, u32 width, u32 height, u32 stride
void GPU::DrawDebugStateWindow()
{
ImGui::SetNextWindowSize(ImVec2(450, 550), ImGuiCond_FirstUseEver);
if (!ImGui::Begin("GPU State", &m_system->GetSettings().debugging.show_gpu_state))
if (!ImGui::Begin("GPU", &m_system->GetSettings().debugging.show_gpu_state))
{
ImGui::End();
return;
}
const bool is_idle_frame = m_stats.num_polygons == 0;
if (!is_idle_frame)
{
m_last_stats = m_stats;
m_stats = {};
}
if (ImGui::CollapsingHeader("Statistics", ImGuiTreeNodeFlags_DefaultOpen))
{
const Stats& stats = m_last_stats;
ImGui::Columns(2);
ImGui::SetColumnWidth(0, 200.0f);
ImGui::TextUnformatted("Idle Frame: ");
ImGui::NextColumn();
ImGui::Text("%s", is_idle_frame ? "Yes" : "No");
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Reads: ");
ImGui::NextColumn();
ImGui::Text("%u", stats.num_vram_reads);
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Fills: ");
ImGui::NextColumn();
ImGui::Text("%u", stats.num_vram_fills);
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Writes: ");
ImGui::NextColumn();
ImGui::Text("%u", stats.num_vram_writes);
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Copies: ");
ImGui::NextColumn();
ImGui::Text("%u", stats.num_vram_copies);
ImGui::NextColumn();
ImGui::TextUnformatted("Vertices Processed: ");
ImGui::NextColumn();
ImGui::Text("%u", stats.num_vertices);
ImGui::NextColumn();
ImGui::TextUnformatted("Polygons Drawn: ");
ImGui::NextColumn();
ImGui::Text("%u", stats.num_polygons);
ImGui::NextColumn();
ImGui::Columns(1);
}
DrawRendererStats(is_idle_frame);
if (ImGui::CollapsingHeader("CRTC", ImGuiTreeNodeFlags_DefaultOpen))
{
const auto& cs = m_crtc_state;
@ -803,4 +857,4 @@ void GPU::DrawDebugStateWindow()
ImGui::End();
}
void GPU::DrawRendererStatsWindow() {}
void GPU::DrawRendererStats(bool is_idle_frame) {}

View File

@ -104,7 +104,6 @@ public:
// Render statistics debug window.
void DrawDebugStateWindow();
virtual void DrawRendererStatsWindow();
// MMIO access
u32 ReadRegister(u32 offset);
@ -289,13 +288,14 @@ protected:
void HandleGetGPUInfoCommand(u32 value);
// Rendering in the backend
virtual void UpdateDisplay();
virtual void ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer);
virtual void FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color);
virtual void UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* data);
virtual void CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height);
virtual void DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* command_ptr);
virtual void FlushRender();
virtual void UpdateDisplay();
virtual void DrawRendererStats(bool is_idle_frame);
HostDisplay* m_host_display = nullptr;
System* m_system = nullptr;
@ -461,6 +461,18 @@ protected:
std::vector<u32> m_GP0_buffer;
std::deque<u32> m_GPUREAD_buffer;
struct Stats
{
u32 num_vram_reads;
u32 num_vram_fills;
u32 num_vram_writes;
u32 num_vram_copies;
u32 num_vertices;
u32 num_polygons;
};
Stats m_stats = {};
Stats m_last_stats = {};
private:
using GP0CommandHandler = bool (GPU::*)(const u32*&, u32);
using GP0CommandHandlerTable = std::array<GP0CommandHandler, 256>;

View File

@ -236,6 +236,8 @@ bool GPU::HandleRenderCommand(const u32*& command_ptr, u32 command_size)
DispatchRenderCommand(rc, num_vertices, command_ptr);
command_ptr += total_words;
m_stats.num_vertices += num_vertices;
m_stats.num_polygons++;
return true;
}
@ -256,6 +258,7 @@ bool GPU::HandleFillRectangleCommand(const u32*& command_ptr, u32 command_size)
Log_DebugPrintf("Fill VRAM rectangle offset=(%u,%u), size=(%u,%u)", dst_x, dst_y, width, height);
FillVRAM(dst_x, dst_y, width, height, color);
m_stats.num_vram_fills++;
return true;
}
@ -293,6 +296,7 @@ bool GPU::HandleCopyRectangleCPUToVRAMCommand(const u32*& command_ptr, u32 comma
FlushRender();
UpdateVRAM(dst_x, dst_y, copy_width, copy_height, &command_ptr[3]);
command_ptr += num_words;
m_stats.num_vram_writes++;
return true;
}
@ -332,7 +336,7 @@ bool GPU::HandleCopyRectangleVRAMToCPUCommand(const u32*& command_ptr, u32 comma
sizeof(u16) * width, temp.data(), true);
}
// Is this correct?
m_stats.num_vram_reads++;
return true;
}
@ -361,5 +365,6 @@ bool GPU::HandleCopyRectangleVRAMToVRAMCommand(const u32*& command_ptr, u32 comm
FlushRender();
CopyVRAM(src_x, src_y, dst_x, dst_y, width, height);
m_stats.num_vram_copies++;
return true;
}

View File

@ -3,6 +3,7 @@
#include "YBaseLib/Log.h"
#include "settings.h"
#include "system.h"
#include <imgui.h>
#include <sstream>
Log_SetChannel(GPU_HW);
@ -291,3 +292,37 @@ void GPU_HW::DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32
LoadVertices(rc, num_vertices, command_ptr);
}
void GPU_HW::DrawRendererStats(bool is_idle_frame)
{
if (!is_idle_frame)
{
m_last_renderer_stats = m_renderer_stats;
m_renderer_stats = {};
}
if (ImGui::CollapsingHeader("Renderer Statistics", ImGuiTreeNodeFlags_DefaultOpen))
{
const auto& stats = m_last_renderer_stats;
ImGui::Columns(2);
ImGui::SetColumnWidth(0, 200.0f);
ImGui::TextUnformatted("Batches Drawn:");
ImGui::NextColumn();
ImGui::Text("%u", stats.num_batches);
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Read Texture Updates:");
ImGui::NextColumn();
ImGui::Text("%u", stats.num_vram_read_texture_updates);
ImGui::NextColumn();
ImGui::TextUnformatted("Uniform Buffer Updates: ");
ImGui::NextColumn();
ImGui::Text("%u", stats.num_uniform_buffer_updates);
ImGui::NextColumn();
ImGui::Columns(1);
}
}

View File

@ -33,6 +33,13 @@ public:
virtual void UpdateSettings() override;
protected:
enum : u32
{
VRAM_UPDATE_TEXTURE_BUFFER_SIZE = VRAM_WIDTH * VRAM_HEIGHT * sizeof(u32),
VERTEX_BUFFER_SIZE = 1 * 1024 * 1024,
UNIFORM_BUFFER_SIZE = 512 * 1024
};
struct BatchVertex
{
s32 x;
@ -88,11 +95,12 @@ protected:
float u_dst_alpha_factor;
};
static constexpr u32 VRAM_UPDATE_TEXTURE_BUFFER_SIZE = VRAM_WIDTH * VRAM_HEIGHT * sizeof(u32);
static constexpr u32 VERTEX_BUFFER_SIZE = 1 * 1024 * 1024;
static constexpr u32 MIN_BATCH_VERTEX_COUNT = 6;
static constexpr u32 MAX_BATCH_VERTEX_COUNT = VERTEX_BUFFER_SIZE / sizeof(BatchVertex);
static constexpr u32 UNIFORM_BUFFER_SIZE = 512 * 1024;
struct RendererStats
{
u32 num_batches;
u32 num_vram_read_texture_updates;
u32 num_uniform_buffer_updates;
};
static constexpr std::tuple<float, float, float, float> RGBA8ToFloat(u32 rgba)
{
@ -112,6 +120,7 @@ protected:
bool IsFlushed() const { return m_batch_current_vertex_ptr == m_batch_start_vertex_ptr; }
void DispatchRenderCommand(RenderCommand rc, u32 num_vertices, const u32* command_ptr) override;
void DrawRendererStats(bool is_idle_frame) override;
void CalcScissorRect(int* left, int* top, int* right, int* bottom);
@ -131,13 +140,25 @@ protected:
BatchConfig m_batch = {};
BatchUBOData m_batch_ubo_data = {};
bool m_batch_ubo_dirty = true;
// Bounding box of VRAM area that the GPU has drawn into.
Common::Rectangle<u32> m_vram_dirty_rect;
// Statistics
RendererStats m_renderer_stats = {};
RendererStats m_last_renderer_stats = {};
// Changed state
bool m_batch_ubo_dirty = true;
bool m_vram_read_texture_dirty = false;
private:
enum : u32
{
MIN_BATCH_VERTEX_COUNT = 6,
MAX_BATCH_VERTEX_COUNT = VERTEX_BUFFER_SIZE / sizeof(BatchVertex)
};
static BatchPrimitive GetPrimitiveForCommand(RenderCommand rc);
void LoadVertices(RenderCommand rc, u32 num_vertices, const u32* command_ptr);

View File

@ -6,7 +6,6 @@
#include "gpu_hw_shadergen.h"
#include "host_display.h"
#include "host_interface.h"
#include "imgui.h"
#include "system.h"
Log_SetChannel(GPU_HW_D3D11);
@ -120,58 +119,6 @@ void GPU_HW_D3D11::UpdateSettings()
UpdateDisplay();
}
void GPU_HW_D3D11::DrawRendererStatsWindow()
{
GPU_HW::DrawRendererStatsWindow();
ImGui::SetNextWindowSize(ImVec2(300.0f, 150.0f), ImGuiCond_FirstUseEver);
const bool is_null_frame = m_stats.num_batches == 0;
if (!is_null_frame)
{
m_last_stats = m_stats;
m_stats = {};
}
if (ImGui::Begin("GPU Renderer Statistics", &m_show_renderer_statistics))
{
ImGui::Columns(2);
ImGui::SetColumnWidth(0, 200.0f);
ImGui::TextUnformatted("GPU Active In This Frame: ");
ImGui::NextColumn();
ImGui::Text("%s", is_null_frame ? "Yes" : "No");
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Reads: ");
ImGui::NextColumn();
ImGui::Text("%u", m_last_stats.num_vram_reads);
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Writes: ");
ImGui::NextColumn();
ImGui::Text("%u", m_last_stats.num_vram_writes);
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Read Texture Updates:");
ImGui::NextColumn();
ImGui::Text("%u", m_last_stats.num_vram_read_texture_updates);
ImGui::NextColumn();
ImGui::TextUnformatted("Batches Drawn:");
ImGui::NextColumn();
ImGui::Text("%u", m_last_stats.num_batches);
ImGui::NextColumn();
ImGui::TextUnformatted("Vertices Drawn: ");
ImGui::NextColumn();
ImGui::Text("%u", m_last_stats.num_vertices);
ImGui::NextColumn();
}
ImGui::End();
}
void GPU_HW_D3D11::MapBatchVertexPointer(u32 required_vertices)
{
Assert(!m_batch_start_vertex_ptr);
@ -449,7 +396,7 @@ void GPU_HW_D3D11::UploadUniformBlock(const void* data, u32 data_size)
m_context->VSSetConstantBuffers(0, 1, m_uniform_stream_buffer.GetD3DBufferArray());
m_context->PSSetConstantBuffers(0, 1, m_uniform_stream_buffer.GetD3DBufferArray());
m_stats.num_uniform_buffer_updates++;
m_renderer_stats.num_uniform_buffer_updates++;
}
void GPU_HW_D3D11::SetViewport(u32 x, u32 y, u32 width, u32 height)
@ -640,7 +587,6 @@ void GPU_HW_D3D11::UpdateDisplay()
void GPU_HW_D3D11::ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer)
{
Log_WarningPrintf("VRAM readback not implemented");
m_stats.num_vram_reads++;
}
void GPU_HW_D3D11::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
@ -677,7 +623,6 @@ void GPU_HW_D3D11::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void* d
RestoreGraphicsAPIState();
InvalidateVRAMReadTexture();
m_stats.num_vram_writes++;
}
void GPU_HW_D3D11::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
@ -696,7 +641,7 @@ void GPU_HW_D3D11::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 widt
void GPU_HW_D3D11::UpdateVRAMReadTexture()
{
m_stats.num_vram_read_texture_updates++;
m_renderer_stats.num_vram_read_texture_updates++;
m_vram_read_texture_dirty = false;
m_vram_dirty_rect.SetInvalid();
@ -710,8 +655,7 @@ void GPU_HW_D3D11::FlushRender()
if (vertex_count == 0)
return;
m_stats.num_batches++;
m_stats.num_vertices += vertex_count;
m_renderer_stats.num_batches++;
m_vertex_stream_buffer.Unmap(m_context.Get(), vertex_count * sizeof(BatchVertex));
m_batch_start_vertex_ptr = nullptr;

View File

@ -26,8 +26,6 @@ public:
void RestoreGraphicsAPIState() override;
void UpdateSettings() override;
void DrawRendererStatsWindow() override;
protected:
void UpdateDisplay() override;
void ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) override;
@ -38,16 +36,6 @@ protected:
void MapBatchVertexPointer(u32 required_vertices) override;
private:
struct GLStats
{
u32 num_batches;
u32 num_vertices;
u32 num_vram_reads;
u32 num_vram_writes;
u32 num_vram_read_texture_updates;
u32 num_uniform_buffer_updates;
};
void SetCapabilities();
bool CreateFramebuffer();
void ClearFramebuffer();
@ -112,9 +100,4 @@ private:
ComPtr<ID3D11PixelShader> m_fill_pixel_shader;
ComPtr<ID3D11PixelShader> m_vram_write_pixel_shader;
std::array<std::array<ComPtr<ID3D11PixelShader>, 2>, 2> m_display_pixel_shaders; // [depth_24][interlaced]
GLStats m_stats = {};
GLStats m_last_stats = {};
bool m_show_renderer_statistics = false;
};

View File

@ -4,7 +4,6 @@
#include "YBaseLib/String.h"
#include "gpu_hw_shadergen.h"
#include "host_display.h"
#include "imgui.h"
#include "system.h"
Log_SetChannel(GPU_HW_OpenGL);
@ -88,58 +87,6 @@ void GPU_HW_OpenGL::UpdateSettings()
UpdateDisplay();
}
void GPU_HW_OpenGL::DrawRendererStatsWindow()
{
GPU_HW::DrawRendererStatsWindow();
ImGui::SetNextWindowSize(ImVec2(300.0f, 150.0f), ImGuiCond_FirstUseEver);
const bool is_null_frame = m_stats.num_batches == 0;
if (!is_null_frame)
{
m_last_stats = m_stats;
m_stats = {};
}
if (ImGui::Begin("GPU Renderer Statistics", &m_show_renderer_statistics))
{
ImGui::Columns(2);
ImGui::SetColumnWidth(0, 200.0f);
ImGui::TextUnformatted("GPU Active In This Frame: ");
ImGui::NextColumn();
ImGui::Text("%s", is_null_frame ? "Yes" : "No");
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Reads: ");
ImGui::NextColumn();
ImGui::Text("%u", m_last_stats.num_vram_reads);
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Writes: ");
ImGui::NextColumn();
ImGui::Text("%u", m_last_stats.num_vram_writes);
ImGui::NextColumn();
ImGui::TextUnformatted("VRAM Read Texture Updates:");
ImGui::NextColumn();
ImGui::Text("%u", m_last_stats.num_vram_read_texture_updates);
ImGui::NextColumn();
ImGui::TextUnformatted("Batches Drawn:");
ImGui::NextColumn();
ImGui::Text("%u", m_last_stats.num_batches);
ImGui::NextColumn();
ImGui::TextUnformatted("Vertices Drawn: ");
ImGui::NextColumn();
ImGui::Text("%u", m_last_stats.num_vertices);
ImGui::NextColumn();
}
ImGui::End();
}
void GPU_HW_OpenGL::MapBatchVertexPointer(u32 required_vertices)
{
Assert(!m_batch_start_vertex_ptr);
@ -429,7 +376,7 @@ void GPU_HW_OpenGL::UploadUniformBlock(const void* data, u32 data_size)
glBindBufferRange(GL_UNIFORM_BUFFER, 1, m_uniform_stream_buffer->GetGLBufferId(), res.buffer_offset, data_size);
m_stats.num_uniform_buffer_updates++;
m_renderer_stats.num_uniform_buffer_updates++;
}
void GPU_HW_OpenGL::UpdateDisplay()
@ -593,8 +540,6 @@ void GPU_HW_OpenGL::ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer)
source_ptr -= source_stride;
dst_ptr += dst_stride;
}
m_stats.num_vram_reads++;
}
void GPU_HW_OpenGL::FillVRAM(u32 x, u32 y, u32 width, u32 height, u32 color)
@ -703,7 +648,6 @@ void GPU_HW_OpenGL::UpdateVRAM(u32 x, u32 y, u32 width, u32 height, const void*
#endif
InvalidateVRAMReadTexture();
m_stats.num_vram_writes++;
}
void GPU_HW_OpenGL::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 width, u32 height)
@ -730,7 +674,7 @@ void GPU_HW_OpenGL::CopyVRAM(u32 src_x, u32 src_y, u32 dst_x, u32 dst_y, u32 wid
void GPU_HW_OpenGL::UpdateVRAMReadTexture()
{
m_stats.num_vram_read_texture_updates++;
m_renderer_stats.num_vram_read_texture_updates++;
m_vram_read_texture_dirty = false;
m_vram_dirty_rect.SetInvalid();
@ -745,8 +689,7 @@ void GPU_HW_OpenGL::FlushRender()
if (vertex_count == 0)
return;
m_stats.num_batches++;
m_stats.num_vertices += vertex_count;
m_renderer_stats.num_batches++;
m_vertex_stream_buffer->Unmap(vertex_count * sizeof(BatchVertex));
m_vertex_stream_buffer->Bind();

View File

@ -22,8 +22,6 @@ public:
void RestoreGraphicsAPIState() override;
void UpdateSettings() override;
void DrawRendererStatsWindow() override;
protected:
void UpdateDisplay() override;
void ReadVRAM(u32 x, u32 y, u32 width, u32 height, void* buffer) override;
@ -81,9 +79,4 @@ private:
std::array<std::array<std::array<GL::Program, 2>, 9>, 4> m_render_programs; // [render_mode][texture_mode][dithering]
std::array<std::array<GL::Program, 2>, 2> m_display_programs; // [depth_24][interlaced]
GL::Program m_vram_write_program;
GLStats m_stats = {};
GLStats m_last_stats = {};
bool m_show_renderer_statistics = false;
};

View File

@ -24,7 +24,6 @@ struct Settings
struct DebugSettings
{
bool show_gpu_state = false;
bool show_gpu_renderer_stats = false;
bool show_vram = false;
bool dump_cpu_to_vram_copies = false;
bool dump_vram_to_cpu_copies = false;

View File

@ -866,7 +866,6 @@ void SDLHostInterface::DrawDebugMenu()
ImGui::Separator();
ImGui::MenuItem("Show GPU State", nullptr, &debug_settings.show_gpu_state);
ImGui::MenuItem("Show GPU Renderer Stats", nullptr, &debug_settings.show_gpu_renderer_stats);
ImGui::MenuItem("Show VRAM", nullptr, &debug_settings.show_vram);
ImGui::MenuItem("Dump CPU to VRAM Copies", nullptr, &debug_settings.dump_cpu_to_vram_copies);
ImGui::MenuItem("Dump VRAM to CPU Copies", nullptr, &debug_settings.dump_vram_to_cpu_copies);
@ -893,8 +892,6 @@ void SDLHostInterface::DrawDebugWindows()
if (debug_settings.show_gpu_state)
m_system->GetGPU()->DrawDebugStateWindow();
if (debug_settings.show_gpu_renderer_stats)
m_system->GetGPU()->DrawRendererStatsWindow();
if (debug_settings.show_cdrom_state)
m_system->GetCDROM()->DrawDebugWindow();
if (debug_settings.show_timers_state)