mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-16 03:38:38 +12:00
sys_rsx: Minor atomicity fixes
This commit is contained in:
parent
a38d2461c9
commit
3f48450408
6 changed files with 75 additions and 19 deletions
|
@ -38,6 +38,47 @@ u64 rsxTimeStamp()
|
||||||
return get_timebased_time();
|
return get_timebased_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lv2_rsx_config::send_event(u64 data1, u64 data2, u64 data3) const
|
||||||
|
{
|
||||||
|
auto error = sys_event_port_send(rsx_event_port, data1, data2, data3);
|
||||||
|
|
||||||
|
while (error + 0u == CELL_EBUSY)
|
||||||
|
{
|
||||||
|
auto cpu = get_current_cpu_thread();
|
||||||
|
|
||||||
|
if (cpu && cpu->id_type() != 1)
|
||||||
|
{
|
||||||
|
cpu = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpu)
|
||||||
|
{
|
||||||
|
// Deschedule
|
||||||
|
lv2_obj::sleep(*cpu, 100);
|
||||||
|
}
|
||||||
|
else if (const auto rsx = rsx::get_current_renderer(); rsx->is_current_thread())
|
||||||
|
{
|
||||||
|
rsx->on_semaphore_acquire_wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait a bit before resending event
|
||||||
|
thread_ctrl::wait_for(100);
|
||||||
|
|
||||||
|
if (cpu && cpu->check_state())
|
||||||
|
{
|
||||||
|
error = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = sys_event_port_send(rsx_event_port, data1, data2, data3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
fmt::throw_exception("rsx_event_port_send() Failed to send event! (error=%x)" HERE, +error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
error_code sys_rsx_device_open()
|
error_code sys_rsx_device_open()
|
||||||
{
|
{
|
||||||
sys_rsx.todo("sys_rsx_device_open()");
|
sys_rsx.todo("sys_rsx_device_open()");
|
||||||
|
@ -202,6 +243,8 @@ error_code sys_rsx_context_allocate(vm::ptr<u32> context_id, vm::ptr<u64> lpar_d
|
||||||
sys_event_queue_create(vm::get_addr(&driverInfo.handler_queue), attr, 0, 0x20);
|
sys_event_queue_create(vm::get_addr(&driverInfo.handler_queue), attr, 0, 0x20);
|
||||||
sys_event_port_connect_local(rsx_cfg->rsx_event_port, driverInfo.handler_queue);
|
sys_event_port_connect_local(rsx_cfg->rsx_event_port, driverInfo.handler_queue);
|
||||||
|
|
||||||
|
rsx_cfg->dma_address = vm::cast(*lpar_dma_control, HERE);
|
||||||
|
|
||||||
const auto render = rsx::get_current_renderer();
|
const auto render = rsx::get_current_renderer();
|
||||||
render->display_buffers_count = 0;
|
render->display_buffers_count = 0;
|
||||||
render->current_display_buffer = 0;
|
render->current_display_buffer = 0;
|
||||||
|
@ -350,12 +393,17 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
|
||||||
switch (package_id)
|
switch (package_id)
|
||||||
{
|
{
|
||||||
case 0x001: // FIFO
|
case 0x001: // FIFO
|
||||||
|
{
|
||||||
render->pause();
|
render->pause();
|
||||||
|
const u64 get = static_cast<u32>(a3);
|
||||||
|
const u64 put = static_cast<u32>(a4);
|
||||||
|
vm::_ref<atomic_be_t<u64>>(rsx_cfg->dma_address + ::offset32(&RsxDmaControl::put)).release(put << 32 | get);
|
||||||
render->ctrl->get = static_cast<u32>(a3);
|
render->ctrl->get = static_cast<u32>(a3);
|
||||||
render->ctrl->put = static_cast<u32>(a4);
|
render->ctrl->put = static_cast<u32>(a4);
|
||||||
render->restore_point = static_cast<u32>(a3);
|
render->sync_point_request.release(true);
|
||||||
render->unpause();
|
render->unpause();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0x100: // Display mode set
|
case 0x100: // Display mode set
|
||||||
break;
|
break;
|
||||||
|
@ -416,7 +464,7 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
|
||||||
verify(HERE), a3 < 2;
|
verify(HERE), a3 < 2;
|
||||||
|
|
||||||
const u64 shift_offset = (a3 + 5);
|
const u64 shift_offset = (a3 + 5);
|
||||||
sys_event_port_send(rsx_cfg->rsx_event_port, 0, (1ull << shift_offset), 0);
|
rsx_cfg->send_event(0, (1ull << shift_offset), 0);
|
||||||
|
|
||||||
render->on_frame_end(static_cast<u32>(a4));
|
render->on_frame_end(static_cast<u32>(a4));
|
||||||
}
|
}
|
||||||
|
@ -465,9 +513,10 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 flipStatus = driverInfo.head[a3].flipFlags;
|
driverInfo.head[a3].flipFlags.atomic_op([&](be_t<u32>& flipStatus)
|
||||||
flipStatus = (flipStatus & static_cast<u32>(a4)) | static_cast<u32>(a5);
|
{
|
||||||
driverInfo.head[a3].flipFlags = flipStatus;
|
flipStatus = (flipStatus & static_cast<u32>(a4)) | static_cast<u32>(a5);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -549,29 +598,33 @@ error_code sys_rsx_context_attribute(u32 context_id, u32 package_id, u64 a3, u64
|
||||||
vm::_ref<u32>(render->label_addr + 0x10) = 0;
|
vm::_ref<u32>(render->label_addr + 0x10) = 0;
|
||||||
|
|
||||||
//if (a3 == 0)
|
//if (a3 == 0)
|
||||||
// sys_event_port_send(rsx_cfg->rsx_event_port, 0, (1 << 3), 0);
|
// rsx_cfg->send_event(0, (1 << 3), 0);
|
||||||
//if (a3 == 1)
|
//if (a3 == 1)
|
||||||
sys_event_port_send(rsx_cfg->rsx_event_port, 0, (1 << 4), 0);
|
rsx_cfg->send_event(0, (1 << 4), 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xFED: // hack: vblank command
|
case 0xFED: // hack: vblank command
|
||||||
|
{
|
||||||
// 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();
|
||||||
sys_event_port_send(rsx_cfg->rsx_event_port, 0, (1 << 1), 0);
|
|
||||||
|
u64 event_flags = (1 << 1);
|
||||||
|
|
||||||
if (render->enable_second_vhandler)
|
if (render->enable_second_vhandler)
|
||||||
sys_event_port_send(rsx_cfg->rsx_event_port, 0, (1 << 11), 0); // second vhandler
|
event_flags |= (1 << 11); // second vhandler
|
||||||
|
|
||||||
|
rsx_cfg->send_event(0, event_flags, 0);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case 0xFEF: // hack: user command
|
case 0xFEF: // hack: user command
|
||||||
// 'custom' invalid package id for now
|
// 'custom' invalid package id for now
|
||||||
// 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);
|
||||||
sys_event_port_send(rsx_cfg->rsx_event_port, 0, (1 << 7), 0);
|
rsx_cfg->send_event(0, (1 << 7), 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -22,7 +22,7 @@ struct RsxDriverInfo
|
||||||
struct Head
|
struct Head
|
||||||
{
|
{
|
||||||
be_t<u64> lastFlipTime; // 0x0 last flip time
|
be_t<u64> lastFlipTime; // 0x0 last flip time
|
||||||
be_t<u32> flipFlags; // 0x8 flags to handle flip/queue
|
atomic_be_t<u32> flipFlags; // 0x8 flags to handle flip/queue
|
||||||
be_t<u32> offset; // 0xC
|
be_t<u32> offset; // 0xC
|
||||||
be_t<u32> flipBufferId; // 0x10
|
be_t<u32> flipBufferId; // 0x10
|
||||||
be_t<u32> lastQueuedBufferId; // 0x14 todo: this is definately not this variable but its 'unused' so im using it for queueId to pass to flip handler
|
be_t<u32> lastQueuedBufferId; // 0x14 todo: this is definately not this variable but its 'unused' so im using it for queueId to pass to flip handler
|
||||||
|
@ -30,7 +30,7 @@ struct RsxDriverInfo
|
||||||
be_t<u32> unk6; // 0x18 possible low bits of time stamp? used in getlastVBlankTime
|
be_t<u32> unk6; // 0x18 possible low bits of time stamp? used in getlastVBlankTime
|
||||||
be_t<u64> lastSecondVTime; // 0x20 last time for second vhandler freq
|
be_t<u64> lastSecondVTime; // 0x20 last time for second vhandler freq
|
||||||
be_t<u64> unk4; // 0x28
|
be_t<u64> unk4; // 0x28
|
||||||
be_t<u64> vBlankCount; // 0x30
|
atomic_be_t<u64> vBlankCount; // 0x30
|
||||||
be_t<u32> unk; // 0x38 possible u32, 'flip field', top/bottom for interlaced
|
be_t<u32> unk; // 0x38 possible u32, 'flip field', top/bottom for interlaced
|
||||||
be_t<u32> unk5; // 0x3C possible high bits of time stamp? used in getlastVBlankTime
|
be_t<u32> unk5; // 0x3C possible high bits of time stamp? used in getlastVBlankTime
|
||||||
} head[8]; // size = 0x40, 0x200
|
} head[8]; // size = 0x40, 0x200
|
||||||
|
@ -114,6 +114,9 @@ struct lv2_rsx_config
|
||||||
u32 context_base{};
|
u32 context_base{};
|
||||||
u32 device_addr{};
|
u32 device_addr{};
|
||||||
u32 driver_info{};
|
u32 driver_info{};
|
||||||
|
u32 dma_address{};
|
||||||
|
|
||||||
|
void send_event(u64, u64, u64) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
// SysCalls
|
// SysCalls
|
||||||
|
|
|
@ -431,7 +431,7 @@ namespace rsx
|
||||||
if (performance_counters.state == FIFO_state::running)
|
if (performance_counters.state == FIFO_state::running)
|
||||||
{
|
{
|
||||||
performance_counters.FIFO_idle_timestamp = get_system_time();
|
performance_counters.FIFO_idle_timestamp = get_system_time();
|
||||||
sync_point_request = true;
|
sync_point_request.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
performance_counters.state = FIFO_state::spinning;
|
performance_counters.state = FIFO_state::spinning;
|
||||||
|
@ -450,7 +450,7 @@ namespace rsx
|
||||||
if (performance_counters.state == FIFO_state::running)
|
if (performance_counters.state == FIFO_state::running)
|
||||||
{
|
{
|
||||||
performance_counters.FIFO_idle_timestamp = get_system_time();
|
performance_counters.FIFO_idle_timestamp = get_system_time();
|
||||||
sync_point_request = true;
|
sync_point_request.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
performance_counters.state = FIFO_state::spinning;
|
performance_counters.state = FIFO_state::spinning;
|
||||||
|
|
|
@ -615,7 +615,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
restore_point = ctrl->get;
|
restore_point = ctrl->get;
|
||||||
saved_fifo_ret = fifo_ret_addr;
|
saved_fifo_ret = fifo_ret_addr;
|
||||||
sync_point_request = false;
|
sync_point_request.release(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute backend-local tasks first
|
// Execute backend-local tasks first
|
||||||
|
@ -2425,7 +2425,7 @@ namespace rsx
|
||||||
{
|
{
|
||||||
// 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 = 0x100000000ull << i;
|
||||||
sys_event_port_send(g_fxo->get<lv2_rsx_config>()->rsx_event_port, 0, io_event, to_unmap);
|
g_fxo->get<lv2_rsx_config>()->send_event(0, io_event, to_unmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -725,7 +725,7 @@ namespace rsx
|
||||||
bool capture_current_frame = false;
|
bool capture_current_frame = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool sync_point_request = false;
|
atomic_t<bool> sync_point_request = false;
|
||||||
bool in_begin_end = false;
|
bool in_begin_end = false;
|
||||||
|
|
||||||
struct desync_fifo_cmd_info
|
struct desync_fifo_cmd_info
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace rsx
|
||||||
|
|
||||||
void semaphore_acquire(thread* rsx, u32 /*_reg*/, u32 arg)
|
void semaphore_acquire(thread* rsx, u32 /*_reg*/, u32 arg)
|
||||||
{
|
{
|
||||||
rsx->sync_point_request = true;
|
rsx->sync_point_request.release(true);
|
||||||
const u32 addr = get_address(method_registers.semaphore_offset_406e(), method_registers.semaphore_context_dma_406e(), HERE);
|
const u32 addr = get_address(method_registers.semaphore_offset_406e(), method_registers.semaphore_context_dma_406e(), HERE);
|
||||||
|
|
||||||
const auto& sema = vm::_ref<atomic_be_t<u32>>(addr);
|
const auto& sema = vm::_ref<atomic_be_t<u32>>(addr);
|
||||||
|
@ -132,7 +132,7 @@ namespace rsx
|
||||||
if (const bool is_flip_sema = (offset == 0x10 && ctxt == CELL_GCM_CONTEXT_DMA_SEMAPHORE_R);
|
if (const bool is_flip_sema = (offset == 0x10 && ctxt == CELL_GCM_CONTEXT_DMA_SEMAPHORE_R);
|
||||||
!is_flip_sema)
|
!is_flip_sema)
|
||||||
{
|
{
|
||||||
rsx->sync_point_request = true;
|
rsx->sync_point_request.release(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u32 addr = get_address(offset, ctxt, HERE);
|
const u32 addr = get_address(offset, ctxt, HERE);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue