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(); 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) while (error + 0u == CELL_EBUSY)
{ {
@ -70,7 +80,7 @@ void lv2_rsx_config::send_event(u64 data1, u64 data2, u64 data3) const
break; 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) 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 // otherwise it contains a display buffer offset
if ((a4 & 0x80000000) != 0) 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 // last half byte gives buffer, 0xf seems to trigger just last queued
u8 idx_check = a4 & 0xf; u8 idx_check = a4 & 0xf;
if (idx_check > 7) 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 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 // NOTE: There currently seem to only be 2 active heads on PS3
verify(HERE), a3 < 2; verify(HERE), a3 < 2;
const u64 shift_offset = (a3 + 5); driverInfo.head[a3].lastQueuedBufferId = static_cast<u32>(a4);
rsx_cfg->send_event(0, (1ull << shift_offset), 0); 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)); 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; 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) driverInfo.head[a3].flipFlags.atomic_op([&](be_t<u32>& flipStatus)
{ {
flipStatus = (flipStatus & static_cast<u32>(a4)) | static_cast<u32>(a5); 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; break;
case 0xFEC: // hack: flip event notification case 0xFEC: // hack: flip event notification
// we only ever use head 1 for now // we only ever use head 1 for now
driverInfo.head[1].flipFlags |= 0x80000000; driverInfo.head[1].flipFlags |= 0x80000000;
driverInfo.head[1].lastFlipTime = rsxTimeStamp(); // should rsxthread set this? 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 // seems gcmSysWaitLabel uses this offset, so lets set it to 0 every flip
vm::_ref<u32>(render->label_addr + 0x10) = 0; vm::_ref<u32>(render->label_addr + 0x10) = 0;
//if (a3 == 0) rsx_cfg->send_event(0, SYS_RSX_EVENT_FLIP_BASE << 1, 0);
// rsx_cfg->send_event(0, (1 << 3), 0);
//if (a3 == 1)
rsx_cfg->send_event(0, (1 << 4), 0);
break; break;
case 0xFED: // hack: vblank command 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 // 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; vm::_ref<u32>(render->device_addr + 0x30) = 1;
driverInfo.head[a3].vBlankCount++; driverInfo.head[a3].vBlankCount++;
driverInfo.head[a3].lastSecondVTime = rsxTimeStamp(); driverInfo.head[a3].lastSecondVTime = rsxTimeStamp();
u64 event_flags = (1 << 1); u64 event_flags = SYS_RSX_EVENT_VBLANK;
if (render->enable_second_vhandler) 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); rsx_cfg->send_event(0, event_flags, 0);
break; 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 // as i think we need custom lv1 interrupts to handle this accurately
// this also should probly be set by rsxthread // this also should probly be set by rsxthread
driverInfo.userCmdParam = static_cast<u32>(a4); 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; break;
default: default:

View file

@ -37,7 +37,7 @@ struct RsxDriverInfo
be_t<u32> unk7; // 0x12B8 be_t<u32> unk7; // 0x12B8
be_t<u32> unk8; // 0x12BC 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> unk9; // 0x12C4
be_t<u32> unk10; // 0x12C8 be_t<u32> unk10; // 0x12C8
be_t<u32> userCmdParam; // 0x12CC be_t<u32> userCmdParam; // 0x12CC
@ -62,6 +62,18 @@ enum : u64
SYS_RSX_IO_MAP_IS_STRICT = 1ull << 60 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 struct RsxDmaControl
{ {
u8 resv[0x40]; u8 resv[0x40];

View file

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