mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 12:05:23 +00:00
rsx/gl/vk: Enable frame skipping
This commit is contained in:
parent
b95ffaf4dd
commit
e9b8f94fb1
10 changed files with 102 additions and 26 deletions
|
@ -186,6 +186,9 @@ void GLGSRender::begin()
|
|||
{
|
||||
rsx::thread::begin();
|
||||
|
||||
if (skip_frame)
|
||||
return;
|
||||
|
||||
init_buffers();
|
||||
|
||||
if (!draw_fbo.check())
|
||||
|
@ -319,7 +322,7 @@ namespace
|
|||
|
||||
void GLGSRender::end()
|
||||
{
|
||||
if (!draw_fbo || !draw_fbo.check())
|
||||
if (skip_frame || !draw_fbo || !draw_fbo.check())
|
||||
{
|
||||
rsx::thread::end();
|
||||
return;
|
||||
|
@ -688,13 +691,9 @@ void GLGSRender::on_exit()
|
|||
|
||||
void GLGSRender::clear_surface(u32 arg)
|
||||
{
|
||||
if (skip_frame) return;
|
||||
if (rsx::method_registers.surface_color_target() == rsx::surface_target::none) return;
|
||||
|
||||
if ((arg & 0xf3) == 0)
|
||||
{
|
||||
//do nothing
|
||||
return;
|
||||
}
|
||||
if ((arg & 0xf3) == 0) return;
|
||||
|
||||
GLbitfield mask = 0;
|
||||
|
||||
|
@ -864,6 +863,23 @@ bool GLGSRender::load_program()
|
|||
|
||||
void GLGSRender::flip(int buffer)
|
||||
{
|
||||
if (skip_frame)
|
||||
{
|
||||
m_frame->flip(m_context, true);
|
||||
rsx::thread::flip(buffer);
|
||||
|
||||
if (!skip_frame)
|
||||
{
|
||||
m_draw_calls = 0;
|
||||
m_begin_time = 0;
|
||||
m_draw_time = 0;
|
||||
m_vertex_upload_time = 0;
|
||||
m_textures_upload_time = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
u32 buffer_width = gcm_buffers[buffer].width;
|
||||
u32 buffer_height = gcm_buffers[buffer].height;
|
||||
u32 buffer_pitch = gcm_buffers[buffer].pitch;
|
||||
|
@ -963,24 +979,26 @@ void GLGSRender::flip(int buffer)
|
|||
}
|
||||
|
||||
m_frame->flip(m_context);
|
||||
rsx::thread::flip(buffer);
|
||||
|
||||
m_gl_texture_cache.clear_temporary_surfaces();
|
||||
|
||||
for (auto &tex : m_rtts.invalidated_resources)
|
||||
tex->remove();
|
||||
|
||||
m_rtts.invalidated_resources.clear();
|
||||
|
||||
if (g_cfg.video.invalidate_surface_cache_every_frame)
|
||||
m_rtts.invalidate_surface_cache_data(nullptr);
|
||||
|
||||
//If we are skipping the next frame, fo not reset perf counters
|
||||
if (skip_frame) return;
|
||||
|
||||
m_draw_calls = 0;
|
||||
m_begin_time = 0;
|
||||
m_draw_time = 0;
|
||||
m_vertex_upload_time = 0;
|
||||
m_textures_upload_time = 0;
|
||||
|
||||
m_gl_texture_cache.clear_temporary_surfaces();
|
||||
|
||||
for (auto &tex : m_rtts.invalidated_resources)
|
||||
{
|
||||
tex->remove();
|
||||
}
|
||||
|
||||
m_rtts.invalidated_resources.clear();
|
||||
|
||||
if (g_cfg.video.invalidate_surface_cache_every_frame)
|
||||
m_rtts.invalidate_surface_cache_data(nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ public:
|
|||
draw_context_t new_context();
|
||||
|
||||
virtual void set_current(draw_context_t ctx) = 0;
|
||||
virtual void flip(draw_context_t ctx) = 0;
|
||||
virtual void flip(draw_context_t ctx, bool skip_frame=false) = 0;
|
||||
virtual int client_width() = 0;
|
||||
virtual int client_height() = 0;
|
||||
|
||||
|
|
|
@ -1228,4 +1228,17 @@ namespace rsx
|
|||
|
||||
return (m_vertex_streaming_task.remaining_packets == 0 && m_vertex_streaming_task.ready_threads == 0);
|
||||
}
|
||||
|
||||
void thread::flip(int buffer)
|
||||
{
|
||||
if (g_cfg.video.frame_skip_enabled)
|
||||
{
|
||||
m_skip_frame_ctr++;
|
||||
|
||||
if (m_skip_frame_ctr == g_cfg.video.consequtive_frames_to_draw)
|
||||
m_skip_frame_ctr = -g_cfg.video.consequtive_frames_to_skip;
|
||||
|
||||
skip_frame = (m_skip_frame_ctr < 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,6 +151,10 @@ namespace rsx
|
|||
bool m_textures_dirty[16];
|
||||
bool m_vertex_attribs_changed;
|
||||
bool m_index_buffer_changed;
|
||||
|
||||
protected:
|
||||
s32 m_skip_frame_ctr = 0;
|
||||
bool skip_frame = false;
|
||||
protected:
|
||||
std::array<u32, 4> get_color_surface_addresses() const;
|
||||
u32 get_zeta_surface_address() const;
|
||||
|
|
|
@ -795,6 +795,9 @@ void VKGSRender::begin()
|
|||
{
|
||||
rsx::thread::begin();
|
||||
|
||||
if (skip_frame)
|
||||
return;
|
||||
|
||||
//Ease resource pressure if the number of draw calls becomes too high or we are running low on memory resources
|
||||
if (m_used_descriptors >= DESCRIPTOR_MAX_DRAW_CALLS ||
|
||||
m_attrib_ring_info.is_critical() ||
|
||||
|
@ -895,6 +898,12 @@ void VKGSRender::close_render_pass()
|
|||
|
||||
void VKGSRender::end()
|
||||
{
|
||||
if (skip_frame)
|
||||
{
|
||||
rsx::thread::end();
|
||||
return;
|
||||
}
|
||||
|
||||
std::chrono::time_point<steady_clock> program_start = steady_clock::now();
|
||||
|
||||
const bool is_instanced = is_probable_instanced_draw() && m_last_descriptor_set != VK_NULL_HANDLE && m_program != nullptr;
|
||||
|
@ -1159,6 +1168,8 @@ void VKGSRender::on_exit()
|
|||
|
||||
void VKGSRender::clear_surface(u32 mask)
|
||||
{
|
||||
if (skip_frame) return;
|
||||
|
||||
// Ignore clear if surface target is set to CELL_GCM_SURFACE_TARGET_NONE
|
||||
if (rsx::method_registers.surface_color_target() == rsx::surface_target::none) return;
|
||||
|
||||
|
@ -1870,6 +1881,24 @@ void VKGSRender::prepare_rtts()
|
|||
|
||||
void VKGSRender::flip(int buffer)
|
||||
{
|
||||
if (skip_frame)
|
||||
{
|
||||
m_frame->flip(m_context);
|
||||
rsx::thread::flip(buffer);
|
||||
|
||||
if (!skip_frame)
|
||||
{
|
||||
m_draw_calls = 0;
|
||||
m_instanced_draws = 0;
|
||||
m_draw_time = 0;
|
||||
m_setup_time = 0;
|
||||
m_vertex_upload_time = 0;
|
||||
m_textures_upload_time = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bool resize_screen = false;
|
||||
|
||||
if (m_client_height != m_frame->client_height() ||
|
||||
|
@ -2062,7 +2091,13 @@ void VKGSRender::flip(int buffer)
|
|||
m_attrib_ring_info.reset_allocation_stats();
|
||||
m_texture_upload_buffer_ring_info.reset_allocation_stats();
|
||||
|
||||
//Resource destruction is handled within the real swap handler
|
||||
//NOTE:Resource destruction is handled within the real swap handler
|
||||
|
||||
m_frame->flip(m_context);
|
||||
rsx::thread::flip(buffer);
|
||||
|
||||
//Do not reset perf counters if we are skipping the next frame
|
||||
if (skip_frame) return;
|
||||
|
||||
m_draw_calls = 0;
|
||||
m_instanced_draws = 0;
|
||||
|
@ -2070,5 +2105,4 @@ void VKGSRender::flip(int buffer)
|
|||
m_setup_time = 0;
|
||||
m_vertex_upload_time = 0;
|
||||
m_textures_upload_time = 0;
|
||||
m_frame->flip(m_context);
|
||||
}
|
||||
|
|
|
@ -317,6 +317,10 @@ struct cfg_root : cfg::node
|
|||
cfg::_bool batch_instanced_geometry{this, "Batch Instanced Geometry", false};
|
||||
cfg::_int<1, 16> vertex_upload_threads{ this, "Vertex Upload Threads", 1 };
|
||||
|
||||
cfg::_bool frame_skip_enabled{this, "Enable Frame Skip"};
|
||||
cfg::_int<1, 8> consequtive_frames_to_draw{this, "Consequtive Frames Drawn", 1};
|
||||
cfg::_int<1, 8> consequtive_frames_to_skip{this, "Consequtive Frames Skept", 1};
|
||||
|
||||
struct node_d3d12 : cfg::node
|
||||
{
|
||||
node_d3d12(cfg::node* _this) : cfg::node(_this, "D3D12") {}
|
||||
|
|
|
@ -45,10 +45,13 @@ void gl_gs_frame::delete_context(void* ctx)
|
|||
delete (QOpenGLContext*)ctx;
|
||||
}
|
||||
|
||||
void gl_gs_frame::flip(draw_context_t context)
|
||||
void gl_gs_frame::flip(draw_context_t context, bool skip_frame)
|
||||
{
|
||||
gs_frame::flip(context);
|
||||
|
||||
//Do not swap buffers if frame skip is active
|
||||
if (skip_frame) return;
|
||||
|
||||
((QOpenGLContext*)context.get())->makeCurrent(this);
|
||||
((QOpenGLContext*)context.get())->swapBuffers(this);
|
||||
}
|
||||
|
|
|
@ -14,5 +14,5 @@ public:
|
|||
void* make_context() override;
|
||||
void set_current(draw_context_t context) override;
|
||||
void delete_context(void* context) override;
|
||||
void flip(draw_context_t context) override;
|
||||
void flip(draw_context_t context, bool skip_frame=false) override;
|
||||
};
|
||||
|
|
|
@ -151,7 +151,7 @@ int gs_frame::client_height()
|
|||
#endif
|
||||
}
|
||||
|
||||
void gs_frame::flip(draw_context_t)
|
||||
void gs_frame::flip(draw_context_t, bool /*skip_frame*/)
|
||||
{
|
||||
QString title;
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ protected:
|
|||
void* make_context() override;
|
||||
void set_current(draw_context_t context) override;
|
||||
void delete_context(void* context) override;
|
||||
void flip(draw_context_t context) override;
|
||||
void flip(draw_context_t context, bool skip_frame=false) override;
|
||||
int client_width() override;
|
||||
int client_height() override;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue