From 685d5d3ea3d11c50dd4ca74ff1a3f89333e949e6 Mon Sep 17 00:00:00 2001 From: DHrpcs3 Date: Wed, 20 Jan 2016 15:46:58 +0300 Subject: [PATCH] Access violation handled by rsx::thread gfxHandler -> rsx::g_access_violation_handler --- Utilities/Thread.cpp | 19 +++++++++---------- rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 25 ++++++++++++++++--------- rpcs3/Emu/RSX/D3D12/D3D12GSRender.h | 2 ++ rpcs3/Emu/RSX/RSXThread.cpp | 17 ++++++++++++++++- rpcs3/Emu/RSX/RSXThread.h | 7 +++++-- 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 86a6701b3a..aac60cad67 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -794,16 +794,18 @@ size_t get_x64_access_size(x64_context* context, x64_op_t op, x64_reg_t reg, siz return d_size; } -/** - * Callback that can be customised by GSRender backends to track memory access. - * Backends can protect memory pages and get this callback called when an access - * violation is met. - * Should return true if the backend handles the access violation. - */ -std::function gfxHandler = [](u32) { return false; }; +namespace rsx +{ + extern std::function g_access_violation_handler; +} bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) { + if (rsx::g_access_violation_handler && rsx::g_access_violation_handler(addr, is_writing)) + { + return true; + } + auto code = (const u8*)RIP(context); x64_op_t op; @@ -811,9 +813,6 @@ bool handle_access_violation(u32 addr, bool is_writing, x64_context* context) size_t d_size; size_t i_size; - if (gfxHandler(addr)) - return true; - // decode single x64 instruction that causes memory access decode_x64_reg_op(code, op, reg, d_size, i_size); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 9d89cdf53f..9400dfc919 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -67,8 +67,6 @@ void D3D12GSRender::Shader::Release() m_samplerDescriptorHeap->Release(); } -extern std::function gfxHandler; - bool D3D12GSRender::invalidate_address(u32 addr) { bool result = false; @@ -89,12 +87,6 @@ D3D12DLLManagement::~D3D12DLLManagement() D3D12GSRender::D3D12GSRender() : GSRender(frame_type::DX12), m_d3d12_lib(), m_current_pso({}) { - gfxHandler = [this](u32 addr) { - bool result = invalidate_address(addr); - if (result) - LOG_WARNING(RSX, "Reporting Cell writing to 0x%x", addr); - return result; - }; if (rpcs3::config.rsx.d3d12.debug_output.value()) { Microsoft::WRL::ComPtr debugInterface; @@ -204,7 +196,6 @@ D3D12GSRender::~D3D12GSRender() m_texture_cache.unprotect_all(); - gfxHandler = [this](u32) { return false; }; m_dummy_texture->Release(); m_convertPSO->Release(); m_convertRootSignature->Release(); @@ -552,6 +543,22 @@ void D3D12GSRender::flip(int buffer) m_timers.m_flip_duration += std::chrono::duration_cast(flip_end - flip_start).count(); } +bool D3D12GSRender::on_access_violation(u32 address, bool is_writing) +{ + if (!is_writing) + { + return false; + } + + if (invalidate_address(address)) + { + LOG_WARNING(RSX, "Reporting Cell writing to 0x%x", address); + return true; + } + + return false; +} + void D3D12GSRender::reset_timer() { m_timers.m_draw_calls_count = 0; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index a7e34fcffe..0e8a2dc1b7 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -193,6 +193,8 @@ protected: virtual void end() override; virtual void flip(int buffer) override; + virtual bool on_access_violation(u32 address, bool is_writing) override; + virtual std::array, 4> copy_render_targets_to_memory() override; virtual std::array, 2> copy_depth_stencil_buffer_to_memory() override; virtual std::pair get_programs() const override; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 37d7ee6b44..44d572c55c 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -19,6 +19,8 @@ frame_capture_data frame_debug; namespace rsx { + std::function g_access_violation_handler; + std::string shaders_cache::path_to_root() { return fs::get_executable_dir() + "data/"; @@ -167,7 +169,7 @@ namespace rsx return 0; } } - + void tiled_region::write(const void *src, u32 width, u32 height, u32 pitch) { if (!tile) @@ -270,6 +272,19 @@ namespace rsx } } + thread::thread() + { + g_access_violation_handler = [this](u32 address, bool is_writing) + { + return on_access_violation(address, is_writing); + }; + } + + thread::~thread() + { + g_access_violation_handler = nullptr; + } + void thread::capture_frame(const std::string &name) { frame_capture_data::draw_state draw_state = {}; diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index aee737cb7c..2635f92964 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -257,6 +257,7 @@ namespace rsx bool capture_current_frame = false; void capture_frame(const std::string &name); + public: u32 ioAddress, ioSize; int flip_status; @@ -283,7 +284,6 @@ namespace rsx u32 local_mem_addr, main_mem_addr; bool strict_ordering[0x1000]; - bool draw_inline_vertex_array; std::vector inline_vertex_array; @@ -309,7 +309,8 @@ namespace rsx std::set m_used_gcm_commands; protected: - virtual ~thread() {} + thread(); + virtual ~thread(); virtual void on_task() override; @@ -324,6 +325,7 @@ namespace rsx virtual bool do_method(u32 cmd, u32 value) { return false; } virtual void flip(int buffer) = 0; virtual u64 timestamp() const; + virtual bool on_access_violation(u32 address, bool is_writing) { return false; } /** * Fill buffer with 4x4 scale offset matrix. @@ -362,6 +364,7 @@ namespace rsx }; virtual std::pair get_programs() const { return std::make_pair("", ""); }; + public: void reset(); void init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress);