rsx: Trivial non-blocking display synchronization

This commit is contained in:
kd-11 2022-05-21 13:05:35 +03:00 committed by kd-11
parent 1be36fe6a9
commit d52bb78d2c
4 changed files with 37 additions and 6 deletions

View File

@ -498,9 +498,8 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
driverInfo.head[a3].lastQueuedBufferId = static_cast<u32>(a4);
driverInfo.head[a3].flipFlags |= 0x40000000 | (1 << a4);
render->send_event(0, SYS_RSX_EVENT_QUEUE_BASE << a3, 0);
render->on_frame_end(static_cast<u32>(a4));
render->send_event(0, SYS_RSX_EVENT_QUEUE_BASE << a3, 0);
}
break;

View File

@ -3099,6 +3099,18 @@ namespace rsx
Emu.Pause();
}
if (false && wait_for_flip_sema) // Breaks framepacing
{
const auto& value = vm::_ref<RsxSemaphore>(device_addr + 0x30).val;
while (value != flip_sema_wait_val && !test_stopped())
{
_mm_pause();
}
wait_for_flip_sema = false;
m_eng_interrupt_mask |= rsx::display_interrupt;
}
if (zcull_ctrl->has_pending())
{
// NOTE: This is a workaround for buggy games.
@ -3195,7 +3207,7 @@ namespace rsx
case frame_limit_type::_50: limit = 50.; break;
case frame_limit_type::_60: limit = 60.; break;
case frame_limit_type::_30: limit = 30.; break;
case frame_limit_type::_auto: limit = 0.; break; // Handled in RSX semaphore_acquire
case frame_limit_type::_auto: limit = 0.; break;
default:
break;
}
@ -3231,6 +3243,18 @@ namespace rsx
}
}
}
else if (wait_for_flip_sema)
{
const auto& value = vm::_ref<RsxSemaphore>(device_addr + 0x30).val;
if (value != flip_sema_wait_val)
{
// Not yet signaled, handle it later
async_flip_requested |= flip_request::emu_requested;
return;
}
wait_for_flip_sema = false;
}
int_flip_index++;

View File

@ -650,6 +650,9 @@ namespace rsx
atomic_t<u64> vblank_count{0};
bool capture_current_frame = false;
bool wait_for_flip_sema = false;
u32 flip_sema_wait_val = 0;
public:
atomic_t<bool> sync_point_request = false;
bool in_begin_end = false;

View File

@ -104,8 +104,13 @@ namespace rsx
rsx->flush_fifo();
}
if (addr == rsx->device_addr + 0x30 && g_cfg.video.frame_limit == frame_limit_type::none)
if (addr == rsx->device_addr + 0x30)
{
if (g_cfg.video.frame_limit == frame_limit_type::_auto)
{
rsx->flip_sema_wait_val = arg;
rsx->wait_for_flip_sema = (sema != arg);
}
return;
}
@ -1733,7 +1738,7 @@ namespace rsx
template<u32 index>
struct driver_flip
{
static void impl(thread* /*rsx*/, u32 /*reg*/, u32 arg)
static void impl(thread* rsx, u32 /*reg*/, u32 arg)
{
sys_rsx_context_attribute(0x55555555, 0x102, index, arg, 0, 0);
}
@ -1742,7 +1747,7 @@ namespace rsx
template<u32 index>
struct queue_flip
{
static void impl(thread* /*rsx*/, u32 /*reg*/, u32 arg)
static void impl(thread* rsx, u32 /*reg*/, u32 arg)
{
sys_rsx_context_attribute(0x55555555, 0x103, index, arg, 0, 0);
}