mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
rsx: Refactoring and improvement
- Separate displayed statistics from actual backend statistics. Allows asynchronous flipping to work correctly as it just uses display stats. The real stats are used by the frame scope marker to determine behavior like engaging the FIFO optimizer or skipping draw calls correctly.
This commit is contained in:
parent
2c76f47eec
commit
e0005ec347
11 changed files with 119 additions and 136 deletions
|
@ -518,7 +518,7 @@ bool is_flip_surface_in_global_memory(rsx::surface_target color_target)
|
|||
}
|
||||
}
|
||||
|
||||
void D3D12GSRender::flip(int buffer, bool emu_flip)
|
||||
void D3D12GSRender::flip(const rsx::display_flip_info_t&)
|
||||
{
|
||||
ID3D12Resource *resource_to_flip;
|
||||
float viewport_w, viewport_h;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#pragma once
|
||||
#pragma once
|
||||
|
||||
#include "D3D12Utils.h"
|
||||
#include "Emu/Memory/vm.h"
|
||||
|
@ -177,7 +177,7 @@ protected:
|
|||
virtual void do_local_task(rsx::FIFO_state state) override;
|
||||
virtual bool do_method(u32 cmd, u32 arg) override;
|
||||
virtual void end() override;
|
||||
virtual void flip(int buffer, bool emu_flip = false) override;
|
||||
virtual void flip(const rsx::display_flip_info_t&) override;
|
||||
|
||||
virtual bool on_access_violation(u32 address, bool is_writing) override;
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ void GLGSRender::begin()
|
|||
{
|
||||
rsx::thread::begin();
|
||||
|
||||
if (skip_frame ||
|
||||
if (skip_current_frame ||
|
||||
(conditional_render_enabled && conditional_render_test_failed))
|
||||
return;
|
||||
|
||||
|
@ -185,7 +185,7 @@ void GLGSRender::end()
|
|||
{
|
||||
m_profiler.start();
|
||||
|
||||
if (skip_frame || !framebuffer_status_valid ||
|
||||
if (skip_current_frame || !framebuffer_status_valid ||
|
||||
(conditional_render_enabled && conditional_render_test_failed))
|
||||
{
|
||||
execute_nop_draw();
|
||||
|
@ -193,7 +193,7 @@ void GLGSRender::end()
|
|||
return;
|
||||
}
|
||||
|
||||
m_begin_time += m_profiler.duration();
|
||||
m_frame_stats.setup_time += m_profiler.duration();
|
||||
|
||||
const auto do_heap_cleanup = [this]()
|
||||
{
|
||||
|
@ -294,7 +294,7 @@ void GLGSRender::end()
|
|||
|
||||
m_samplers_dirty.store(false);
|
||||
|
||||
m_textures_upload_time += m_profiler.duration();
|
||||
m_frame_stats.textures_upload_time += m_profiler.duration();
|
||||
}
|
||||
|
||||
// NOTE: Due to common OpenGL driver architecture, vertex data has to be uploaded as far away from the draw as possible
|
||||
|
@ -312,7 +312,7 @@ void GLGSRender::end()
|
|||
// Load program execution environment
|
||||
load_program_env();
|
||||
|
||||
m_begin_time += m_profiler.duration();
|
||||
m_frame_stats.setup_time += m_profiler.duration();
|
||||
|
||||
//Bind textures and resolve external copy operations
|
||||
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||
|
@ -386,7 +386,7 @@ void GLGSRender::end()
|
|||
}
|
||||
}
|
||||
|
||||
m_textures_upload_time += m_profiler.duration();
|
||||
m_frame_stats.textures_upload_time += m_profiler.duration();
|
||||
|
||||
// Optionally do memory synchronization if the texture stage has not yet triggered this
|
||||
if (true)//g_cfg.video.strict_rendering_mode)
|
||||
|
@ -636,7 +636,7 @@ void GLGSRender::end()
|
|||
m_fragment_constants_buffer->notify();
|
||||
m_transform_constants_buffer->notify();
|
||||
|
||||
m_draw_time += m_profiler.duration();
|
||||
m_frame_stats.textures_upload_time += m_profiler.duration();
|
||||
|
||||
rsx::thread::end();
|
||||
}
|
||||
|
@ -930,19 +930,19 @@ void GLGSRender::on_init_thread()
|
|||
{
|
||||
const char *text = index == 0 ? "Loading pipeline object %u of %u" : "Compiling pipeline object %u of %u";
|
||||
dlg->progress_bar_set_message(index, fmt::format(text, processed, entry_count));
|
||||
owner->flip(0);
|
||||
owner->flip({});
|
||||
}
|
||||
|
||||
void inc_value(u32 index, u32 value) override
|
||||
{
|
||||
dlg->progress_bar_increment(index, (f32)value);
|
||||
owner->flip(0);
|
||||
owner->flip({});
|
||||
}
|
||||
|
||||
void set_limit(u32 index, u32 limit) override
|
||||
{
|
||||
dlg->progress_bar_set_limit(index, limit);
|
||||
owner->flip(0);
|
||||
owner->flip({});
|
||||
}
|
||||
|
||||
void refresh() override
|
||||
|
@ -1081,7 +1081,7 @@ void GLGSRender::on_exit()
|
|||
|
||||
void GLGSRender::clear_surface(u32 arg)
|
||||
{
|
||||
if (skip_frame || !framebuffer_status_valid) return;
|
||||
if (skip_current_frame || !framebuffer_status_valid) return;
|
||||
|
||||
// If stencil write mask is disabled, remove clear_stencil bit
|
||||
if (!rsx::method_registers.stencil_mask()) arg &= ~0x2u;
|
||||
|
@ -1546,30 +1546,21 @@ void GLGSRender::update_draw_state()
|
|||
//NV4097_SET_ANTI_ALIASING_CONTROL
|
||||
//NV4097_SET_CLIP_ID_TEST_ENABLE
|
||||
|
||||
m_begin_time += m_profiler.duration();
|
||||
m_frame_stats.setup_time += m_profiler.duration();
|
||||
}
|
||||
|
||||
void GLGSRender::flip(int buffer, bool emu_flip)
|
||||
void GLGSRender::flip(const rsx::display_flip_info_t& info)
|
||||
{
|
||||
if (skip_frame)
|
||||
if (info.skip_frame)
|
||||
{
|
||||
m_frame->flip(m_context, true);
|
||||
rsx::thread::flip(buffer);
|
||||
|
||||
if (!skip_frame)
|
||||
{
|
||||
m_begin_time = 0;
|
||||
m_draw_time = 0;
|
||||
m_vertex_upload_time = 0;
|
||||
m_textures_upload_time = 0;
|
||||
}
|
||||
|
||||
rsx::thread::flip(info);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 buffer_width = display_buffers[buffer].width;
|
||||
u32 buffer_height = display_buffers[buffer].height;
|
||||
u32 buffer_pitch = display_buffers[buffer].pitch;
|
||||
u32 buffer_width = display_buffers[info.buffer].width;
|
||||
u32 buffer_height = display_buffers[info.buffer].height;
|
||||
u32 buffer_pitch = display_buffers[info.buffer].pitch;
|
||||
|
||||
u32 av_format;
|
||||
const auto avconfig = g_fxo->get<rsx::avconf>();
|
||||
|
@ -1598,7 +1589,7 @@ void GLGSRender::flip(int buffer, bool emu_flip)
|
|||
gl::screen.bind();
|
||||
gl::screen.clear(gl::buffers::color);
|
||||
|
||||
if ((u32)buffer < display_buffers_count && buffer_width && buffer_height)
|
||||
if ((u32)info.buffer < display_buffers_count && buffer_width && buffer_height)
|
||||
{
|
||||
// Calculate blit coordinates
|
||||
coordi aspect_ratio;
|
||||
|
@ -1626,7 +1617,7 @@ void GLGSRender::flip(int buffer, bool emu_flip)
|
|||
aspect_ratio.size = new_size;
|
||||
|
||||
// Find the source image
|
||||
const u32 absolute_address = rsx::get_address(display_buffers[buffer].offset, CELL_GCM_LOCATION_LOCAL);
|
||||
const u32 absolute_address = rsx::get_address(display_buffers[info.buffer].offset, CELL_GCM_LOCATION_LOCAL);
|
||||
GLuint image = GL_NONE;
|
||||
|
||||
if (auto render_target_texture = m_rtts.get_color_surface_at(absolute_address))
|
||||
|
@ -1658,7 +1649,7 @@ void GLGSRender::flip(int buffer, bool emu_flip)
|
|||
// TODO: Should emit only once to avoid flooding the log file
|
||||
// TODO: Take AA scaling into account
|
||||
LOG_WARNING(RSX, "Selected output image does not satisfy the video configuration. Display buffer resolution=%dx%d, avconf resolution=%dx%d, surface=%dx%d",
|
||||
display_buffers[buffer].width, display_buffers[buffer].height, avconfig->state * avconfig->resolution_x, avconfig->state * avconfig->resolution_y,
|
||||
display_buffers[info.buffer].width, display_buffers[info.buffer].height, avconfig->state * avconfig->resolution_x, avconfig->state * avconfig->resolution_y,
|
||||
render_target_texture->get_surface_width(rsx::surface_metrics::pixels), render_target_texture->get_surface_height(rsx::surface_metrics::pixels));
|
||||
|
||||
buffer_width = render_target_texture->width();
|
||||
|
@ -1776,11 +1767,11 @@ void GLGSRender::flip(int buffer, bool emu_flip)
|
|||
glViewport(0, 0, m_frame->client_width(), m_frame->client_height());
|
||||
|
||||
m_text_printer.print_text(0, 0, m_frame->client_width(), m_frame->client_height(), fmt::format("RSX Load: %3d%%", get_load()));
|
||||
m_text_printer.print_text(0, 18, m_frame->client_width(), m_frame->client_height(), fmt::format("draw calls: %16d", m_draw_calls));
|
||||
m_text_printer.print_text(0, 36, m_frame->client_width(), m_frame->client_height(), fmt::format("draw call setup: %11dus", m_begin_time));
|
||||
m_text_printer.print_text(0, 54, m_frame->client_width(), m_frame->client_height(), fmt::format("vertex upload time: %8dus", m_vertex_upload_time));
|
||||
m_text_printer.print_text(0, 72, m_frame->client_width(), m_frame->client_height(), fmt::format("textures upload time: %6dus", m_textures_upload_time));
|
||||
m_text_printer.print_text(0, 90, m_frame->client_width(), m_frame->client_height(), fmt::format("draw call execution: %7dus", m_draw_time));
|
||||
m_text_printer.print_text(0, 18, m_frame->client_width(), m_frame->client_height(), fmt::format("draw calls: %16d", info.stats.draw_calls));
|
||||
m_text_printer.print_text(0, 36, m_frame->client_width(), m_frame->client_height(), fmt::format("draw call setup: %11dus", info.stats.setup_time));
|
||||
m_text_printer.print_text(0, 54, m_frame->client_width(), m_frame->client_height(), fmt::format("vertex upload time: %8dus", info.stats.vertex_upload_time));
|
||||
m_text_printer.print_text(0, 72, m_frame->client_width(), m_frame->client_height(), fmt::format("textures upload time: %6dus", info.stats.textures_upload_time));
|
||||
m_text_printer.print_text(0, 90, m_frame->client_width(), m_frame->client_height(), fmt::format("draw call execution: %7dus", info.stats.draw_exec_time));
|
||||
|
||||
const auto num_dirty_textures = m_gl_texture_cache.get_unreleased_textures_count();
|
||||
const auto texture_memory_size = m_gl_texture_cache.get_texture_memory_in_use() / (1024 * 1024);
|
||||
|
@ -1796,7 +1787,7 @@ void GLGSRender::flip(int buffer, bool emu_flip)
|
|||
}
|
||||
|
||||
m_frame->flip(m_context);
|
||||
rsx::thread::flip(buffer, emu_flip);
|
||||
rsx::thread::flip(info);
|
||||
|
||||
// Cleanup
|
||||
m_gl_texture_cache.on_frame_end();
|
||||
|
@ -1818,14 +1809,6 @@ void GLGSRender::flip(int buffer, bool emu_flip)
|
|||
set_viewport();
|
||||
set_scissor(!!(m_graphics_state & rsx::pipeline_state::scissor_setup_clipped));
|
||||
}
|
||||
|
||||
// If we are skipping the next frame, do not reset perf counters
|
||||
if (skip_frame) return;
|
||||
|
||||
m_begin_time = 0;
|
||||
m_draw_time = 0;
|
||||
m_vertex_upload_time = 0;
|
||||
m_textures_upload_time = 0;
|
||||
}
|
||||
|
||||
bool GLGSRender::on_access_violation(u32 address, bool is_writing)
|
||||
|
@ -1922,7 +1905,9 @@ void GLGSRender::do_local_task(rsx::FIFO_state state)
|
|||
{
|
||||
if (!in_begin_end && async_flip_requested & flip_request::native_ui)
|
||||
{
|
||||
flip((s32)current_display_buffer, false);
|
||||
rsx::display_flip_info_t info{};
|
||||
info.buffer = current_display_buffer;
|
||||
flip(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,11 +86,6 @@ private:
|
|||
// Identity buffer used to fix broken gl_VertexID on ATI stack
|
||||
std::unique_ptr<gl::buffer> m_identity_index_buffer;
|
||||
|
||||
s64 m_begin_time = 0;
|
||||
s64 m_draw_time = 0;
|
||||
s64 m_vertex_upload_time = 0;
|
||||
s64 m_textures_upload_time = 0;
|
||||
|
||||
std::unique_ptr<gl::vertex_cache> m_vertex_cache;
|
||||
std::unique_ptr<gl::shader_cache> m_shaders_cache;
|
||||
|
||||
|
@ -171,7 +166,7 @@ protected:
|
|||
void on_init_thread() override;
|
||||
void on_exit() override;
|
||||
bool do_method(u32 cmd, u32 arg) override;
|
||||
void flip(int buffer, bool emu_flip = false) override;
|
||||
void flip(const rsx::display_flip_info_t& info) override;
|
||||
|
||||
void do_local_task(rsx::FIFO_state state) override;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "GLGSRender.h"
|
||||
#include "../Common/BufferUtils.h"
|
||||
#include "GLHelpers.h"
|
||||
|
@ -254,6 +254,6 @@ gl::vertex_upload_info GLGSRender::set_vertex_buffer()
|
|||
//Write all the data
|
||||
write_vertex_data_to_memory(m_vertex_layout, vertex_base, vertex_count, persistent_mapping.first, volatile_mapping.first);
|
||||
|
||||
m_vertex_upload_time += m_profiler.duration();
|
||||
m_frame_stats.vertex_upload_time += m_profiler.duration();
|
||||
return upload_info;
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ void GSRender::on_exit()
|
|||
rsx::thread::on_exit();
|
||||
}
|
||||
|
||||
void GSRender::flip(int buffer, bool emu_flip)
|
||||
void GSRender::flip(const rsx::display_flip_info_t& info)
|
||||
{
|
||||
if (m_frame)
|
||||
{
|
||||
|
|
|
@ -104,7 +104,7 @@ public:
|
|||
void on_init_thread() override;
|
||||
void on_exit() override;
|
||||
|
||||
void flip(int buffer, bool emu_flip = false) override;
|
||||
void flip(const rsx::display_flip_info_t& info) override;
|
||||
|
||||
GSFrameBase* get_frame() { return m_frame; }
|
||||
};
|
||||
|
|
|
@ -352,7 +352,7 @@ namespace rsx
|
|||
capture::capture_draw_memory(this);
|
||||
|
||||
in_begin_end = false;
|
||||
m_draw_calls++;
|
||||
m_frame_stats.draw_calls++;
|
||||
|
||||
method_registers.current_draw_clause.post_execute_cleanup();
|
||||
|
||||
|
@ -2233,12 +2233,12 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
void thread::flip(int buffer, bool emu_flip)
|
||||
void thread::flip(const display_flip_info_t& info)
|
||||
{
|
||||
if (async_flip_requested & flip_request::any)
|
||||
{
|
||||
// Deferred flip
|
||||
if (emu_flip)
|
||||
if (info.emu_flip)
|
||||
{
|
||||
async_flip_requested.clear(flip_request::emu_requested);
|
||||
}
|
||||
|
@ -2248,14 +2248,8 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
if (emu_flip)
|
||||
if (info.emu_flip)
|
||||
{
|
||||
if (g_cfg.video.frame_skip_enabled)
|
||||
{
|
||||
skip_frame = (m_skip_frame_ctr < 0);
|
||||
}
|
||||
|
||||
m_draw_calls = 0;
|
||||
performance_counters.sampled_frames++;
|
||||
}
|
||||
}
|
||||
|
@ -2543,13 +2537,18 @@ namespace rsx
|
|||
zcull_ctrl->sync(this);
|
||||
}
|
||||
|
||||
// Save current state
|
||||
m_queued_flip.stats = m_frame_stats;
|
||||
m_queued_flip.buffer = buffer;
|
||||
m_queued_flip.skip_frame = skip_current_frame;
|
||||
|
||||
if (LIKELY(!forced))
|
||||
{
|
||||
if (!g_cfg.video.disable_FIFO_reordering)
|
||||
{
|
||||
// Try to enable FIFO optimizations
|
||||
// Only rarely useful for some games like RE4
|
||||
m_flattener.evaluate_performance(m_draw_calls);
|
||||
m_flattener.evaluate_performance(m_frame_stats.draw_calls);
|
||||
}
|
||||
|
||||
if (g_cfg.video.frame_skip_enabled)
|
||||
|
@ -2558,6 +2557,8 @@ namespace rsx
|
|||
|
||||
if (m_skip_frame_ctr == g_cfg.video.consequtive_frames_to_draw)
|
||||
m_skip_frame_ctr = -g_cfg.video.consequtive_frames_to_skip;
|
||||
|
||||
skip_current_frame = (m_skip_frame_ctr < 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2574,7 +2575,8 @@ namespace rsx
|
|||
}
|
||||
}
|
||||
|
||||
queued_flip_index = int(buffer);
|
||||
// Reset current stats
|
||||
m_frame_stats = {};
|
||||
}
|
||||
|
||||
void thread::request_emu_flip(u32 buffer)
|
||||
|
@ -2602,7 +2604,7 @@ namespace rsx
|
|||
|
||||
void thread::handle_emu_flip(u32 buffer)
|
||||
{
|
||||
if (queued_flip_index < 0)
|
||||
if (m_queued_flip.buffer == ~0u)
|
||||
{
|
||||
// Frame was not queued before flipping
|
||||
on_frame_end(buffer, true);
|
||||
|
@ -2649,12 +2651,15 @@ namespace rsx
|
|||
}
|
||||
|
||||
int_flip_index++;
|
||||
|
||||
verify(HERE), m_queued_flip.buffer == buffer;
|
||||
current_display_buffer = buffer;
|
||||
flip(buffer, true);
|
||||
m_queued_flip.emu_flip = true;
|
||||
flip(m_queued_flip);
|
||||
|
||||
last_flip_time = get_system_time() - 1000000;
|
||||
flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_DONE;
|
||||
queued_flip_index = -1;
|
||||
m_queued_flip.buffer = ~0u;
|
||||
|
||||
if (flip_handler)
|
||||
{
|
||||
|
|
|
@ -413,6 +413,24 @@ namespace rsx
|
|||
};
|
||||
}
|
||||
|
||||
struct frame_statistics_t
|
||||
{
|
||||
u32 draw_calls;
|
||||
s64 setup_time;
|
||||
s64 vertex_upload_time;
|
||||
s64 textures_upload_time;
|
||||
s64 draw_exec_time;
|
||||
s64 flip_time;
|
||||
};
|
||||
|
||||
struct display_flip_info_t
|
||||
{
|
||||
u32 buffer;
|
||||
bool skip_frame;
|
||||
bool emu_flip;
|
||||
frame_statistics_t stats;
|
||||
};
|
||||
|
||||
struct sampled_image_descriptor_base;
|
||||
|
||||
class thread
|
||||
|
@ -420,6 +438,8 @@ namespace rsx
|
|||
u64 timestamp_ctrl = 0;
|
||||
u64 timestamp_subvalue = 0;
|
||||
|
||||
display_flip_info_t m_queued_flip;
|
||||
|
||||
protected:
|
||||
std::thread::id m_rsx_thread;
|
||||
atomic_t<bool> m_rsx_thread_exiting{ true };
|
||||
|
@ -428,7 +448,8 @@ namespace rsx
|
|||
std::vector<u32> element_push_buffer;
|
||||
|
||||
s32 m_skip_frame_ctr = 0;
|
||||
bool skip_frame = false;
|
||||
bool skip_current_frame = false;
|
||||
frame_statistics_t stats{};
|
||||
|
||||
bool supports_multidraw = false; // Draw call batching
|
||||
bool supports_hw_a2c = false; // Alpha to coverage
|
||||
|
@ -454,11 +475,9 @@ namespace rsx
|
|||
// Invalidated memory range
|
||||
address_range m_invalidated_memory_range;
|
||||
|
||||
// Draw call stats
|
||||
u32 m_draw_calls = 0;
|
||||
|
||||
// Profiler
|
||||
rsx::profiling_timer m_profiler;
|
||||
frame_statistics_t m_frame_stats;
|
||||
|
||||
public:
|
||||
RsxDmaControl* ctrl = nullptr;
|
||||
|
@ -558,7 +577,6 @@ namespace rsx
|
|||
u64 start_rsx_time = 0;
|
||||
u64 int_flip_index = 0;
|
||||
u64 last_flip_time;
|
||||
int queued_flip_index = -1;
|
||||
vm::ptr<void(u32)> flip_handler = vm::null;
|
||||
vm::ptr<void(u32)> user_handler = vm::null;
|
||||
vm::ptr<void(u32)> vblank_handler = vm::null;
|
||||
|
@ -609,7 +627,7 @@ namespace rsx
|
|||
virtual void on_init_thread() = 0;
|
||||
virtual bool do_method(u32 /*cmd*/, u32 /*value*/) { return false; }
|
||||
virtual void on_frame_end(u32 buffer, bool forced = false);
|
||||
virtual void flip(int buffer, bool emu_flip = false) = 0;
|
||||
virtual void flip(const display_flip_info_t& info) = 0;
|
||||
virtual u64 timestamp();
|
||||
virtual bool on_access_violation(u32 /*address*/, bool /*is_writing*/) { return false; }
|
||||
virtual void on_invalidate_memory_range(const address_range & /*range*/, rsx::invalidation_cause) {}
|
||||
|
|
|
@ -863,7 +863,7 @@ void VKGSRender::check_heap_status(u32 flags)
|
|||
frame_context_cleanup(target_frame, true);
|
||||
}
|
||||
|
||||
m_flip_time += m_profiler.duration();
|
||||
m_frame_stats.flip_time += m_profiler.duration();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -920,7 +920,7 @@ void VKGSRender::begin()
|
|||
{
|
||||
rsx::thread::begin();
|
||||
|
||||
if (skip_frame || swapchain_unavailable ||
|
||||
if (skip_current_frame || swapchain_unavailable ||
|
||||
(conditional_render_enabled && conditional_render_test_failed))
|
||||
return;
|
||||
|
||||
|
@ -1009,7 +1009,7 @@ void VKGSRender::update_draw_state()
|
|||
|
||||
//TODO: Set up other render-state parameters into the program pipeline
|
||||
|
||||
m_setup_time += m_profiler.duration();
|
||||
m_frame_stats.setup_time += m_profiler.duration();
|
||||
}
|
||||
|
||||
void VKGSRender::begin_render_pass()
|
||||
|
@ -1085,7 +1085,7 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
|||
return;
|
||||
}
|
||||
|
||||
m_vertex_upload_time += m_profiler.duration();
|
||||
m_frame_stats.vertex_upload_time += m_profiler.duration();
|
||||
|
||||
auto persistent_buffer = m_persistent_attribute_storage ? m_persistent_attribute_storage->value : null_buffer_view->value;
|
||||
auto volatile_buffer = m_volatile_attribute_storage ? m_volatile_attribute_storage->value : null_buffer_view->value;
|
||||
|
@ -1149,7 +1149,7 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
|||
// Bind the new set of descriptors for use with this draw call
|
||||
vkCmdBindDescriptorSets(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &m_current_frame->descriptor_set, 0, nullptr);
|
||||
|
||||
m_setup_time += m_profiler.duration();
|
||||
m_frame_stats.setup_time += m_profiler.duration();
|
||||
|
||||
if (!upload_info.index_info)
|
||||
{
|
||||
|
@ -1193,12 +1193,12 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
|||
}
|
||||
}
|
||||
|
||||
m_draw_time += m_profiler.duration();
|
||||
m_frame_stats.draw_exec_time += m_profiler.duration();
|
||||
}
|
||||
|
||||
void VKGSRender::end()
|
||||
{
|
||||
if (skip_frame || !framebuffer_status_valid || swapchain_unavailable ||
|
||||
if (skip_current_frame || !framebuffer_status_valid || swapchain_unavailable ||
|
||||
(conditional_render_enabled && conditional_render_test_failed))
|
||||
{
|
||||
execute_nop_draw();
|
||||
|
@ -1450,7 +1450,7 @@ void VKGSRender::end()
|
|||
}
|
||||
}
|
||||
|
||||
m_textures_upload_time += m_profiler.duration();
|
||||
m_frame_stats.textures_upload_time += m_profiler.duration();
|
||||
|
||||
if (!load_program())
|
||||
{
|
||||
|
@ -1469,7 +1469,7 @@ void VKGSRender::end()
|
|||
// Load program execution environment
|
||||
load_program_env();
|
||||
|
||||
m_setup_time += m_profiler.duration();
|
||||
m_frame_stats.setup_time += m_profiler.duration();
|
||||
|
||||
for (int i = 0; i < rsx::limits::fragment_textures_count; ++i)
|
||||
{
|
||||
|
@ -1672,7 +1672,7 @@ void VKGSRender::end()
|
|||
}
|
||||
}
|
||||
|
||||
m_textures_upload_time += m_profiler.duration();
|
||||
m_frame_stats.textures_upload_time += m_profiler.duration();
|
||||
|
||||
if (m_current_command_buffer->flags & vk::command_buffer::cb_load_occluson_task)
|
||||
{
|
||||
|
@ -1811,19 +1811,19 @@ void VKGSRender::on_init_thread()
|
|||
{
|
||||
const char *text = index == 0 ? "Loading pipeline object %u of %u" : "Compiling pipeline object %u of %u";
|
||||
dlg->progress_bar_set_message(index, fmt::format(text, processed, entry_count));
|
||||
owner->flip(0);
|
||||
owner->flip({});
|
||||
}
|
||||
|
||||
void inc_value(u32 index, u32 value) override
|
||||
{
|
||||
dlg->progress_bar_increment(index, (f32)value);
|
||||
owner->flip(0);
|
||||
owner->flip({});
|
||||
}
|
||||
|
||||
void set_limit(u32 index, u32 limit) override
|
||||
{
|
||||
dlg->progress_bar_set_limit(index, limit);
|
||||
owner->flip(0);
|
||||
owner->flip({});
|
||||
}
|
||||
|
||||
void refresh() override
|
||||
|
@ -1852,7 +1852,7 @@ void VKGSRender::on_exit()
|
|||
|
||||
void VKGSRender::clear_surface(u32 mask)
|
||||
{
|
||||
if (skip_frame || swapchain_unavailable) return;
|
||||
if (skip_current_frame || swapchain_unavailable) return;
|
||||
|
||||
// If stencil write mask is disabled, remove clear_stencil bit
|
||||
if (!rsx::method_registers.stencil_mask()) mask &= ~0x2u;
|
||||
|
@ -2393,7 +2393,9 @@ void VKGSRender::do_local_task(rsx::FIFO_state state)
|
|||
if (!in_begin_end && async_flip_requested & flip_request::native_ui)
|
||||
{
|
||||
flush_command_queue(true);
|
||||
flip((s32)current_display_buffer, false);
|
||||
rsx::display_flip_info_t info{};
|
||||
info.buffer = current_display_buffer;
|
||||
flip(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3093,7 +3095,7 @@ void VKGSRender::reinitialize_swapchain()
|
|||
should_reinitialize_swapchain = false;
|
||||
}
|
||||
|
||||
void VKGSRender::flip(int buffer, bool emu_flip)
|
||||
void VKGSRender::flip(const rsx::display_flip_info_t& info)
|
||||
{
|
||||
// Check swapchain condition/status
|
||||
if (!m_swapchain->supports_automatic_wm_reports())
|
||||
|
@ -3127,7 +3129,7 @@ void VKGSRender::flip(int buffer, bool emu_flip)
|
|||
}
|
||||
else if (m_current_frame->swap_command_buffer)
|
||||
{
|
||||
if (m_draw_calls > 0)
|
||||
if (info.stats.draw_calls > 0)
|
||||
{
|
||||
// This can be 'legal' if the window was being resized and no polling happened because of swapchain_unavailable flag
|
||||
LOG_ERROR(RSX, "Possible data corruption on frame context storage detected");
|
||||
|
@ -3137,9 +3139,9 @@ void VKGSRender::flip(int buffer, bool emu_flip)
|
|||
frame_context_cleanup(m_current_frame, true);
|
||||
}
|
||||
|
||||
if (skip_frame || swapchain_unavailable)
|
||||
if (info.skip_frame || swapchain_unavailable)
|
||||
{
|
||||
if (!skip_frame)
|
||||
if (!info.skip_frame)
|
||||
{
|
||||
verify(HERE), swapchain_unavailable;
|
||||
|
||||
|
@ -3148,21 +3150,16 @@ void VKGSRender::flip(int buffer, bool emu_flip)
|
|||
flush_command_queue(true);
|
||||
vk::advance_frame_counter();
|
||||
frame_context_cleanup(m_current_frame, true);
|
||||
|
||||
m_draw_time = 0;
|
||||
m_setup_time = 0;
|
||||
m_vertex_upload_time = 0;
|
||||
m_textures_upload_time = 0;
|
||||
}
|
||||
|
||||
m_frame->flip(m_context);
|
||||
rsx::thread::flip(buffer, emu_flip);
|
||||
rsx::thread::flip(info);
|
||||
return;
|
||||
}
|
||||
|
||||
u32 buffer_width = display_buffers[buffer].width;
|
||||
u32 buffer_height = display_buffers[buffer].height;
|
||||
u32 buffer_pitch = display_buffers[buffer].pitch;
|
||||
u32 buffer_width = display_buffers[info.buffer].width;
|
||||
u32 buffer_height = display_buffers[info.buffer].height;
|
||||
u32 buffer_pitch = display_buffers[info.buffer].pitch;
|
||||
|
||||
u32 av_format;
|
||||
const auto avconfig = g_fxo->get<rsx::avconf>();
|
||||
|
@ -3251,9 +3248,9 @@ void VKGSRender::flip(int buffer, bool emu_flip)
|
|||
//Blit contents to screen..
|
||||
vk::image* image_to_flip = nullptr;
|
||||
|
||||
if ((u32)buffer < display_buffers_count && buffer_width && buffer_height)
|
||||
if ((u32)info.buffer < display_buffers_count && buffer_width && buffer_height)
|
||||
{
|
||||
const u32 absolute_address = rsx::get_address(display_buffers[buffer].offset, CELL_GCM_LOCATION_LOCAL);
|
||||
const u32 absolute_address = rsx::get_address(display_buffers[info.buffer].offset, CELL_GCM_LOCATION_LOCAL);
|
||||
|
||||
if (auto render_target_texture = m_rtts.get_color_surface_at(absolute_address))
|
||||
{
|
||||
|
@ -3282,7 +3279,7 @@ void VKGSRender::flip(int buffer, bool emu_flip)
|
|||
// TODO: Should emit only once to avoid flooding the log file
|
||||
// TODO: Take AA scaling into account
|
||||
LOG_WARNING(RSX, "Selected output image does not satisfy the video configuration. Display buffer resolution=%dx%d, avconf resolution=%dx%d, surface=%dx%d",
|
||||
display_buffers[buffer].width, display_buffers[buffer].height, avconfig->state * avconfig->resolution_x, avconfig->state * avconfig->resolution_y,
|
||||
display_buffers[info.buffer].width, display_buffers[info.buffer].height, avconfig->state * avconfig->resolution_x, avconfig->state * avconfig->resolution_y,
|
||||
render_target_texture->get_surface_width(rsx::surface_metrics::pixels), render_target_texture->get_surface_height(rsx::surface_metrics::pixels));
|
||||
|
||||
buffer_width = render_target_texture->width();
|
||||
|
@ -3435,12 +3432,12 @@ void VKGSRender::flip(int buffer, bool emu_flip)
|
|||
if (g_cfg.video.overlay)
|
||||
{
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 0, direct_fbo->width(), direct_fbo->height(), fmt::format("RSX Load: %3d%%", get_load()));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 18, direct_fbo->width(), direct_fbo->height(), fmt::format("draw calls: %17d", m_draw_calls));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 36, direct_fbo->width(), direct_fbo->height(), fmt::format("draw call setup: %12dus", m_setup_time));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 54, direct_fbo->width(), direct_fbo->height(), fmt::format("vertex upload time: %9dus", m_vertex_upload_time));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 72, direct_fbo->width(), direct_fbo->height(), fmt::format("texture upload time: %8dus", m_textures_upload_time));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 90, direct_fbo->width(), direct_fbo->height(), fmt::format("draw call execution: %8dus", m_draw_time));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 108, direct_fbo->width(), direct_fbo->height(), fmt::format("submit and flip: %12dus", m_flip_time));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 18, direct_fbo->width(), direct_fbo->height(), fmt::format("draw calls: %17d", info.stats.draw_calls));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 36, direct_fbo->width(), direct_fbo->height(), fmt::format("draw call setup: %12dus", info.stats.setup_time));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 54, direct_fbo->width(), direct_fbo->height(), fmt::format("vertex upload time: %9dus", info.stats.vertex_upload_time));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 72, direct_fbo->width(), direct_fbo->height(), fmt::format("texture upload time: %8dus", info.stats.textures_upload_time));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 90, direct_fbo->width(), direct_fbo->height(), fmt::format("draw call execution: %8dus", info.stats.draw_exec_time));
|
||||
m_text_writer->print_text(*m_current_command_buffer, *direct_fbo, 0, 108, direct_fbo->width(), direct_fbo->height(), fmt::format("submit and flip: %12dus", info.stats.flip_time));
|
||||
|
||||
const auto num_dirty_textures = m_texture_cache.get_unreleased_textures_count();
|
||||
const auto texture_memory_size = m_texture_cache.get_texture_memory_in_use() / (1024 * 1024);
|
||||
|
@ -3464,20 +3461,10 @@ void VKGSRender::flip(int buffer, bool emu_flip)
|
|||
|
||||
queue_swap_request();
|
||||
|
||||
m_flip_time = m_profiler.duration();
|
||||
|
||||
//NOTE:Resource destruction is handled within the real swap handler
|
||||
m_frame_stats.flip_time = m_profiler.duration();
|
||||
|
||||
m_frame->flip(m_context);
|
||||
rsx::thread::flip(buffer, emu_flip);
|
||||
|
||||
//Do not reset perf counters if we are skipping the next frame
|
||||
if (skip_frame) return;
|
||||
|
||||
m_draw_time = 0;
|
||||
m_setup_time = 0;
|
||||
m_vertex_upload_time = 0;
|
||||
m_textures_upload_time = 0;
|
||||
rsx::thread::flip(info);
|
||||
}
|
||||
|
||||
bool VKGSRender::scaled_image_from_memory(rsx::blit_src_info& src, rsx::blit_dst_info& dst, bool interpolate)
|
||||
|
|
|
@ -398,13 +398,6 @@ private:
|
|||
VkViewport m_viewport{};
|
||||
VkRect2D m_scissor{};
|
||||
|
||||
// Timers
|
||||
s64 m_setup_time = 0;
|
||||
s64 m_vertex_upload_time = 0;
|
||||
s64 m_textures_upload_time = 0;
|
||||
s64 m_draw_time = 0;
|
||||
s64 m_flip_time = 0;
|
||||
|
||||
std::vector<u8> m_draw_buffers;
|
||||
|
||||
shared_mutex m_flush_queue_mutex;
|
||||
|
@ -492,7 +485,7 @@ protected:
|
|||
void on_init_thread() override;
|
||||
void on_exit() override;
|
||||
bool do_method(u32 cmd, u32 arg) override;
|
||||
void flip(int buffer, bool emu_flip = false) override;
|
||||
void flip(const rsx::display_flip_info_t& info) override;
|
||||
|
||||
void do_local_task(rsx::FIFO_state state) override;
|
||||
bool scaled_image_from_memory(rsx::blit_src_info& src, rsx::blit_dst_info& dst, bool interpolate) override;
|
||||
|
|
Loading…
Add table
Reference in a new issue