rsx/gl/vk: Enable frame skipping

This commit is contained in:
kd-11 2017-06-30 01:20:23 +03:00
parent b95ffaf4dd
commit e9b8f94fb1
10 changed files with 102 additions and 26 deletions

View file

@ -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);
}

View file

@ -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;

View file

@ -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);
}
}
}

View file

@ -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;

View file

@ -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);
}

View file

@ -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") {}

View file

@ -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);
}

View file

@ -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;
};

View file

@ -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;

View file

@ -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;