From f4786c0761a2d1758ffc33643e25a632c62a3c9b Mon Sep 17 00:00:00 2001 From: Eladash Date: Thu, 25 Jul 2019 16:12:51 +0300 Subject: [PATCH 1/3] rsx: Fix gcm unmap events --- rpcs3/Emu/Cell/lv2/sys_rsx.cpp | 2 ++ rpcs3/Emu/RSX/RSXThread.cpp | 42 +++++++++++++++++++++++++--------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp index a5fb3990212b..8f6e18930ebf 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.cpp @@ -222,6 +222,8 @@ error_code sys_rsx_context_iounmap(u32 context_id, u32 io, u32 size) return CELL_EINVAL; } + vm::reader_lock rlock; + std::scoped_lock lock(s_rsxmem_mtx); const u32 end = (io >>= 20) + (size >>= 20); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index eee3b52ccd2b..17e033af731b 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2398,25 +2398,45 @@ namespace rsx { if (!m_rsx_thread_exiting && address < rsx::constants::local_mem_base) { - u32 ea = address >> 20, io = RSXIOMem.io[ea]; - - if (io < 512) + if (!isHLE) { - if (!isHLE) + // Each bit represents io entry to be unmapped + u64 unmap_status[512 / 64]{}; + + for (u32 ea = address >> 20, end = ea + size >> 20; ea < end; ea++) { - const u64 unmap_key = u64((1ull << (size >> 20)) - 1) << (io & 0x3f); - const u64 gcm_flag = 0x100000000ull << (io >> 6); - sys_event_port_send(fxm::get()->rsx_event_port, 0, gcm_flag, unmap_key); + u32 io = RSXIOMem.io[ea]; + + if (io < 512) + { + unmap_status[io / 64] |= 1ull << (io & 63); + RSXIOMem.ea[io].raw() = 0xFFFF; + RSXIOMem.io[ea].raw() = 0xFFFF; + } } - else + + for (u32 i = 0; i < std::size(unmap_status); i++) { - for (const u32 end = ea + (size >> 20); ea < end;) + // TODO: Check order when sending multiple events + if (u64 to_unmap = unmap_status[i]) { - offsetTable.ioAddress[ea++] = 0xFFFF; - offsetTable.eaAddress[io++] = 0xFFFF; + // Each 64 entries are grouped by a bit + const u64 io_event = 0x100000000ull << i; + sys_event_port_send(fxm::get()->rsx_event_port, 0, io_event, to_unmap); } } } + else + { + // TODO: Fix this + u32 ea = address >> 20, io = RSXIOMem.io[ea]; + + for (const u32 end = ea + (size >> 20); ea < end;) + { + offsetTable.ioAddress[ea++] = 0xFFFF; + offsetTable.eaAddress[io++] = 0xFFFF; + } + } // Queue up memory invalidation std::lock_guard lock(m_mtx_task); From aa406afe6a6c44a70d73baccf86dd2b628abd1be Mon Sep 17 00:00:00 2001 From: Eladash Date: Thu, 25 Jul 2019 17:24:04 +0300 Subject: [PATCH 2/3] Fix cellCamera events support with clocks scaling --- rpcs3/Emu/Cell/Modules/cellCamera.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rpcs3/Emu/Cell/Modules/cellCamera.cpp b/rpcs3/Emu/Cell/Modules/cellCamera.cpp index bf1f94d6bfd8..ee33b9150fdc 100644 --- a/rpcs3/Emu/Cell/Modules/cellCamera.cpp +++ b/rpcs3/Emu/Cell/Modules/cellCamera.cpp @@ -1308,7 +1308,7 @@ void camera_context::operator()() if (time_passed >= frame_target_time) break; - thread_ctrl::wait_for(frame_target_time - time_passed); + lv2_obj::wait_timeout(frame_target_time - time_passed); } } } From b2f6823dabf358548b2aa0fa39b8ff1816cfd67d Mon Sep 17 00:00:00 2001 From: Eladash Date: Fri, 26 Jul 2019 08:05:50 +0300 Subject: [PATCH 3/3] rsx: Write atomically semaphore updates and fix zcull timestamp --- rpcs3/Emu/Cell/lv2/sys_rsx.h | 6 +++--- rpcs3/Emu/RSX/GCM.h | 2 +- rpcs3/Emu/RSX/RSXThread.cpp | 16 +++++---------- rpcs3/Emu/RSX/RSXThread.h | 2 +- rpcs3/Emu/RSX/rsx_methods.cpp | 38 +++++++++++++++++++++-------------- 5 files changed, 33 insertions(+), 31 deletions(-) diff --git a/rpcs3/Emu/Cell/lv2/sys_rsx.h b/rpcs3/Emu/Cell/lv2/sys_rsx.h index df8cee938f3f..ba437936c204 100644 --- a/rpcs3/Emu/Cell/lv2/sys_rsx.h +++ b/rpcs3/Emu/Cell/lv2/sys_rsx.h @@ -68,20 +68,20 @@ struct RsxDmaControl be_t unk1; }; -struct RsxSemaphore +struct alignas(16) RsxSemaphore { be_t val; be_t pad; be_t timestamp; }; -struct RsxNotify +struct alignas(16) RsxNotify { be_t timestamp; be_t zero; }; -struct RsxReport +struct alignas(16) RsxReport { be_t timestamp; be_t val; diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 68e85791d784..3e0c4340df12 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -65,7 +65,7 @@ struct CellGcmSurface be_t y; }; -struct CellGcmReportData +struct alignas(16) CellGcmReportData { be_t timer; be_t value; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 17e033af731b..90b5c6f76b9c 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2340,10 +2340,7 @@ namespace rsx } } - vm::ptr result = sink; - result->value = value; - result->padding = 0; - result->timer = timestamp(); + vm::_ref>(sink).store({ timestamp(), value, 0}); } void thread::sync() @@ -2819,7 +2816,7 @@ namespace rsx m_cycles_delay = max_zcull_delay_us; } - void ZCULL_control::write(vm::addr_t sink, u32 timestamp, u32 type, u32 value) + void ZCULL_control::write(vm::addr_t sink, u64 timestamp, u32 type, u32 value) { verify(HERE), sink; @@ -2840,10 +2837,7 @@ namespace rsx break; } - vm::ptr out = sink; - out->value = value; - out->timer = timestamp; - out->padding = 0; + vm::_ref>(sink).store({ timestamp, value, 0}); } void ZCULL_control::sync(::rsx::thread* ptimer) @@ -2888,7 +2882,7 @@ namespace rsx if (!writer.forwarder) //No other queries in the chain, write result - write(writer.sink, (u32)ptimer->timestamp(), writer.type, result); + write(writer.sink, ptimer->timestamp(), writer.type, result); processed++; } @@ -3049,7 +3043,7 @@ namespace rsx //only zpass supported right now if (!writer.forwarder) //No other queries in the chain, write result - write(writer.sink, (u32)ptimer->timestamp(), writer.type, result); + write(writer.sink, ptimer->timestamp(), writer.type, result); processed++; } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 565aad16dc63..aaa27e233cd6 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -371,7 +371,7 @@ namespace rsx void set_enabled(class ::rsx::thread* ptimer, bool state); void set_active(class ::rsx::thread* ptimer, bool state); - void write(vm::addr_t sink, u32 timestamp, u32 type, u32 value); + void write(vm::addr_t sink, u64 timestamp, u32 type, u32 value); // Read current zcull statistics into the address provided void read_report(class ::rsx::thread* ptimer, vm::addr_t sink, u32 type); diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 97fb6fd1eff5..39aa5d359af7 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -180,9 +180,11 @@ namespace rsx return; } - auto& notify = vm::_ref(verify(HERE, RSXIOMem.RealAddr(0xf100000 + (index * 0x40)))); - notify.zero = 0; - notify.timestamp = rsx->timestamp(); + vm::_ref>(verify(HERE, RSXIOMem.RealAddr(0xf100000 + (index * 0x40)))).store( + { + rsx->timestamp(), + 0 + }); } void texture_read_semaphore_release(thread* rsx, u32 _reg, u32 arg) @@ -196,10 +198,12 @@ namespace rsx // } - auto& sema = vm::_ref(get_address(offset, method_registers.semaphore_context_dma_4097())); - sema.val = arg; - sema.pad = 0; - sema.timestamp = rsx->timestamp(); + vm::_ref>(get_address(offset, method_registers.semaphore_context_dma_4097())).store( + { + arg, + 0, + rsx->timestamp() + }); } void back_end_write_semaphore_release(thread* rsx, u32 _reg, u32 arg) @@ -213,10 +217,12 @@ namespace rsx rsx->sync(); u32 val = (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff); - auto& sema = vm::_ref(get_address(offset, method_registers.semaphore_context_dma_4097())); - sema.val = val; - sema.pad = 0; - sema.timestamp = rsx->timestamp(); + vm::_ref>(get_address(offset, method_registers.semaphore_context_dma_4097())).store( + { + val, + 0, + rsx->timestamp() + }); } /** @@ -509,8 +515,6 @@ namespace rsx return; } - vm::ptr result = address_ptr; - switch (type) { case CELL_GCM_ZPASS_PIXEL_CNT: @@ -522,8 +526,12 @@ namespace rsx break; default: LOG_ERROR(RSX, "NV4097_GET_REPORT: Bad type %d", type); - result->timer = rsx->timestamp(); - result->padding = 0; + + vm::_ref>(address_ptr).atomic_op([&](CellGcmReportData& data) + { + data.timer = rsx->timestamp(); + data.padding = 0; + }); break; } }