mirror of
https://github.com/ARMSX2/ARMSX3.git
synced 2026-08-24 16:58:52 -07:00
Record the GPU draw region that was declared and never written
The GPU timer measures the whole frame, readbacks, blits and uploads, and the one region it names but never records is draw. So the split it exists to provide has been missing exactly where it matters: with the RSX thread no longer waiting on a fence, the Adreno sits at 99% busy at its top clock and nothing says how much of that is drawing the game. Bracket the render pass at the only place one actually starts, not at the wrapper, which early-outs when the same pass and framebuffer are already bound. Roughly thirty passes a frame, comfortably inside the per-frame event cap. Both timestamps sit outside the pass rather than inside it. On a tiler the load at the start and the store at the end are the expensive part, and timing from within would exclude the cost worth knowing about. Take the command buffer by const reference, which is what the render pass helpers hold and what the conversion operator already permits.
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "Utilities/mutex.h"
|
||||
#include "VKRenderPass.h"
|
||||
#include "vkutils/image.h"
|
||||
#include "vkutils/gpu_timer.h"
|
||||
|
||||
#include "Emu/RSX/Common/unordered_map.hpp"
|
||||
|
||||
@@ -430,6 +431,15 @@ namespace vk
|
||||
rsx::prof::g_render_passes++;
|
||||
}
|
||||
|
||||
// The draw region was declared and never recorded anywhere, so the one figure that
|
||||
// says how much of the GPU is actually drawing the game has been missing while
|
||||
// everything else about the GPU was measured.
|
||||
//
|
||||
// Timed from outside the pass on both ends deliberately. On a tiler the load at the
|
||||
// start and the store at the end are the expensive part, and a timestamp placed
|
||||
// inside the pass would exclude exactly the cost worth knowing about.
|
||||
vk::get_gpu_timer().begin(cmd, vk::gpu_timer::region::draw);
|
||||
|
||||
vkCmdBeginRenderPass(cmd, &rp_begin, VK_SUBPASS_CONTENTS_INLINE);
|
||||
renderpass_info = { pass, target };
|
||||
}
|
||||
@@ -448,6 +458,10 @@ namespace vk
|
||||
void end_renderpass(const vk::command_buffer& cmd)
|
||||
{
|
||||
vkCmdEndRenderPass(cmd);
|
||||
|
||||
// After the pass ends, so the tile store it triggers is charged to the region.
|
||||
vk::get_gpu_timer().end(cmd, vk::gpu_timer::region::draw);
|
||||
|
||||
g_current_renderpass[cmd] = {};
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ namespace vk
|
||||
reset();
|
||||
}
|
||||
|
||||
void gpu_timer::begin(command_buffer& cmd, region r)
|
||||
void gpu_timer::begin(const command_buffer& cmd, region r)
|
||||
{
|
||||
// Nothing recorded unless the profiler is armed.
|
||||
//
|
||||
@@ -139,7 +139,7 @@ namespace vk
|
||||
vkCmdWriteTimestamp(cmd, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, *m_pool, q);
|
||||
}
|
||||
|
||||
void gpu_timer::end(command_buffer& cmd, region r)
|
||||
void gpu_timer::end(const command_buffer& cmd, region r)
|
||||
{
|
||||
if (!m_pool)
|
||||
{
|
||||
|
||||
@@ -55,8 +55,11 @@ namespace vk
|
||||
bool usable() const { return m_pool != nullptr; }
|
||||
|
||||
// Bracket a region. Safe to call when uninitialised, in which case they do nothing.
|
||||
void begin(command_buffer& cmd, region r);
|
||||
void end(command_buffer& cmd, region r);
|
||||
//
|
||||
// By const reference because the render pass helpers hold one and only ever record
|
||||
// commands into it, which the conversion operator already allows on a const buffer.
|
||||
void begin(const command_buffer& cmd, region r);
|
||||
void end(const command_buffer& cmd, region r);
|
||||
|
||||
// Call once per presented frame. Retires the current ring slot; see the definition
|
||||
// for why this is not driven off the frame region closing.
|
||||
@@ -153,11 +156,11 @@ namespace vk
|
||||
*/
|
||||
class gpu_scope
|
||||
{
|
||||
command_buffer& m_cmd;
|
||||
const command_buffer& m_cmd;
|
||||
gpu_timer::region m_region;
|
||||
|
||||
public:
|
||||
gpu_scope(command_buffer& cmd, gpu_timer::region r)
|
||||
gpu_scope(const command_buffer& cmd, gpu_timer::region r)
|
||||
: m_cmd(cmd), m_region(r)
|
||||
{
|
||||
get_gpu_timer().begin(m_cmd, m_region);
|
||||
|
||||
Reference in New Issue
Block a user