sys_rsx: Fix gcm events spam

In realhw the events are only sent if they are masked in driver_info->handlers as well.
This commit is contained in:
Eladash 2020-04-07 18:31:19 +03:00 committed by kd-11
parent 3f48450408
commit f7536bbce0
3 changed files with 45 additions and 17 deletions

View File

@ -38,9 +38,19 @@ u64 rsxTimeStamp()
return get_timebased_time();
}
void lv2_rsx_config::send_event(u64 data1, u64 data2, u64 data3) const
void lv2_rsx_config::send_event(u64 data1, u64 event_flags, u64 data3) const
{
auto error = sys_event_port_send(rsx_event_port, data1, data2, data3);
// Filter event bits, send them only if they are masked by gcm
// Except the upper 32-bits, they are reserved for unmapped io events and execute unconditionally
event_flags &= vm::_ref<RsxDriverInfo>(driver_info).handlers | 0xffff'ffffull << 32;
if (!event_flags)
{
// Nothing to do
return;
}
auto error = sys_event_port_send(rsx_event_port, data1, event_flags, data3);
while (error + 0u == CELL_EBUSY)
{
@ -70,7 +80,7 @@ void lv2_rsx_config::send_event(u64 data1, u64 data2, u64 data3) const
break;
}
error = sys_event_port_send(rsx_event_port, data1, data2, data3);
error = sys_event_port_send(rsx_event_port, data1, event_flags, data3);
}
if (error)
@ -420,6 +430,9 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
// otherwise it contains a display buffer offset
if ((a4 & 0x80000000) != 0)
{
// NOTE: There currently seem to only be 2 active heads on PS3
verify(HERE), a3 < 2;
// last half byte gives buffer, 0xf seems to trigger just last queued
u8 idx_check = a4 & 0xf;
if (idx_check > 7)
@ -457,14 +470,13 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
case 0x103: // Display Queue
{
driverInfo.head[a3].lastQueuedBufferId = static_cast<u32>(a4);
driverInfo.head[a3].flipFlags |= 0x40000000 | (1 << a4);
// NOTE: There currently seem to only be 2 active heads on PS3
verify(HERE), a3 < 2;
const u64 shift_offset = (a3 + 5);
rsx_cfg->send_event(0, (1ull << shift_offset), 0);
driverInfo.head[a3].lastQueuedBufferId = static_cast<u32>(a4);
driverInfo.head[a3].flipFlags |= 0x40000000 | (1 << a4);
rsx_cfg->send_event(0, SYS_RSX_EVENT_QUEUE_BASE << a3, 0);
render->on_frame_end(static_cast<u32>(a4));
}
@ -513,6 +525,9 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
return SYS_RSX_CONTEXT_ATTRIBUTE_ERROR;
}
// NOTE: There currently seem to only be 2 active heads on PS3
verify(HERE), a3 < 2;
driverInfo.head[a3].flipFlags.atomic_op([&](be_t<u32>& flipStatus)
{
flipStatus = (flipStatus & static_cast<u32>(a4)) | static_cast<u32>(a5);
@ -589,6 +604,7 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
break;
case 0xFEC: // hack: flip event notification
// we only ever use head 1 for now
driverInfo.head[1].flipFlags |= 0x80000000;
driverInfo.head[1].lastFlipTime = rsxTimeStamp(); // should rsxthread set this?
@ -597,23 +613,23 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
// seems gcmSysWaitLabel uses this offset, so lets set it to 0 every flip
vm::_ref<u32>(render->label_addr + 0x10) = 0;
//if (a3 == 0)
// rsx_cfg->send_event(0, (1 << 3), 0);
//if (a3 == 1)
rsx_cfg->send_event(0, (1 << 4), 0);
rsx_cfg->send_event(0, SYS_RSX_EVENT_FLIP_BASE << 1, 0);
break;
case 0xFED: // hack: vblank command
{
// NOTE: There currently seem to only be 2 active heads on PS3
verify(HERE), a3 < 2;
// todo: this is wrong and should be 'second' vblank handler and freq, but since currently everything is reported as being 59.94, this should be fine
vm::_ref<u32>(render->device_addr + 0x30) = 1;
driverInfo.head[a3].vBlankCount++;
driverInfo.head[a3].lastSecondVTime = rsxTimeStamp();
u64 event_flags = (1 << 1);
u64 event_flags = SYS_RSX_EVENT_VBLANK;
if (render->enable_second_vhandler)
event_flags |= (1 << 11); // second vhandler
event_flags |= SYS_RSX_EVENT_SECOND_VBLANK_BASE << a3; // second vhandler
rsx_cfg->send_event(0, event_flags, 0);
break;
@ -624,7 +640,7 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
// as i think we need custom lv1 interrupts to handle this accurately
// this also should probly be set by rsxthread
driverInfo.userCmdParam = static_cast<u32>(a4);
rsx_cfg->send_event(0, (1 << 7), 0);
rsx_cfg->send_event(0, SYS_RSX_EVENT_USER_CMD, 0);
break;
default:

View File

@ -37,7 +37,7 @@ struct RsxDriverInfo
be_t<u32> unk7; // 0x12B8
be_t<u32> unk8; // 0x12BC
be_t<u32> handlers; // 0x12C0 -- flags showing which handlers are set
atomic_be_t<u32> handlers; // 0x12C0 -- flags showing which handlers are set
be_t<u32> unk9; // 0x12C4
be_t<u32> unk10; // 0x12C8
be_t<u32> userCmdParam; // 0x12CC
@ -62,6 +62,18 @@ enum : u64
SYS_RSX_IO_MAP_IS_STRICT = 1ull << 60
};
// Unofficial event names
enum : u64
{
//SYS_RSX_EVENT_GRAPHICS_ERROR = 1 << 0,
SYS_RSX_EVENT_VBLANK = 1 << 1,
SYS_RSX_EVENT_FLIP_BASE = 1 << 3,
SYS_RSX_EVENT_QUEUE_BASE = 1 << 5,
SYS_RSX_EVENT_USER_CMD = 1 << 7,
SYS_RSX_EVENT_SECOND_VBLANK_BASE = 1 << 10,
SYS_RSX_EVENT_UNMAPPED_BASE = 1ull << 32,
};
struct RsxDmaControl
{
u8 resv[0x40];

View File

@ -2424,7 +2424,7 @@ namespace rsx
if (u64 to_unmap = unmap_status[i])
{
// Each 64 entries are grouped by a bit
const u64 io_event = 0x100000000ull << i;
const u64 io_event = SYS_RSX_EVENT_UNMAPPED_BASE << i;
g_fxo->get<lv2_rsx_config>()->send_event(0, io_event, to_unmap);
}
}