rsx: Restructure deferred flip queue handling

- Allows frameskipping to occur naturally if RSX thread is bombarded with flip requests but just jumping to the last one if possible
- See request_emu_flip() for async frame submission and implicit skipping
- Also allows display queue to fill faster than the flip thread can drain the queue
This commit is contained in:
kd-11 2019-09-28 15:30:30 +03:00 committed by kd-11
parent b9b879c3d3
commit 1464069476
2 changed files with 36 additions and 9 deletions

View File

@ -2537,7 +2537,7 @@ namespace rsx
// Save current state // Save current state
m_queued_flip.stats = m_frame_stats; m_queued_flip.stats = m_frame_stats;
m_queued_flip.buffer = buffer; m_queued_flip.push(buffer);
m_queued_flip.skip_frame = skip_current_frame; m_queued_flip.skip_frame = skip_current_frame;
if (LIKELY(!forced)) if (LIKELY(!forced))
@ -2579,10 +2579,7 @@ namespace rsx
void thread::request_emu_flip(u32 buffer) void thread::request_emu_flip(u32 buffer)
{ {
const bool is_rsxthr = std::this_thread::get_id() == m_rsx_thread; if (is_current_thread()) // requested through command buffer
// requested through command buffer
if (is_rsxthr)
{ {
// NOTE: The flip will clear any queued flip requests // NOTE: The flip will clear any queued flip requests
handle_emu_flip(buffer); handle_emu_flip(buffer);
@ -2608,10 +2605,11 @@ namespace rsx
return; return;
} }
if (m_queued_flip.buffer == ~0u) if (!m_queued_flip.pop(buffer))
{ {
// Frame was not queued before flipping // Frame was not queued before flipping
on_frame_end(buffer, true); on_frame_end(buffer, true);
verify(HERE), m_queued_flip.pop(buffer);
} }
double limit = 0.; double limit = 0.;
@ -2656,16 +2654,14 @@ namespace rsx
int_flip_index++; int_flip_index++;
verify(HERE), m_queued_flip.buffer == buffer;
current_display_buffer = buffer; current_display_buffer = buffer;
m_queued_flip.emu_flip = true; m_queued_flip.emu_flip = true;
m_queued_flip.in_progress = true; m_queued_flip.in_progress = true;
flip(m_queued_flip); flip(m_queued_flip);
last_flip_time = get_system_time() - 1000000; last_flip_time = get_system_time() - 1000000;
flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_DONE; flip_status = CELL_GCM_DISPLAY_FLIP_STATUS_DONE;
m_queued_flip.buffer = ~0u;
m_queued_flip.in_progress = false; m_queued_flip.in_progress = false;
if (flip_handler) if (flip_handler)

View File

@ -426,11 +426,42 @@ namespace rsx
struct display_flip_info_t struct display_flip_info_t
{ {
std::deque<u32> buffer_queue;
u32 buffer; u32 buffer;
bool skip_frame; bool skip_frame;
bool emu_flip; bool emu_flip;
bool in_progress; bool in_progress;
frame_statistics_t stats; frame_statistics_t stats;
inline void push(u32 _buffer)
{
buffer_queue.push_back(_buffer);
}
inline bool pop(u32 _buffer)
{
if (buffer_queue.empty())
{
return false;
}
do
{
const auto index = buffer_queue.front();
buffer_queue.pop_front();
if (index == _buffer)
{
buffer = _buffer;
return true;
}
}
while (!buffer_queue.empty());
// Need to observe this happening in the wild
LOG_ERROR(RSX, "Display queue was discarded while not empty!");
return false;
}
}; };
struct sampled_image_descriptor_base; struct sampled_image_descriptor_base;