mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-31 20:41:45 +01:00
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:
parent
3f48450408
commit
f7536bbce0
@ -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:
|
||||
|
@ -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];
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user