Access violation handled by rsx::thread

gfxHandler -> rsx::g_access_violation_handler
This commit is contained in:
DHrpcs3 2016-01-20 15:46:58 +03:00
parent 9f7caf90e3
commit 685d5d3ea3
5 changed files with 48 additions and 22 deletions

View File

@ -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<bool(u32 addr)> gfxHandler = [](u32) { return false; };
namespace rsx
{
extern std::function<bool(u32 addr, bool is_writing)> 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);

View File

@ -67,8 +67,6 @@ void D3D12GSRender::Shader::Release()
m_samplerDescriptorHeap->Release();
}
extern std::function<bool(u32 addr)> 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<ID3D12Debug> 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<std::chrono::microseconds>(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;

View File

@ -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<std::vector<gsl::byte>, 4> copy_render_targets_to_memory() override;
virtual std::array<std::vector<gsl::byte>, 2> copy_depth_stencil_buffer_to_memory() override;
virtual std::pair<std::string, std::string> get_programs() const override;

View File

@ -19,6 +19,8 @@ frame_capture_data frame_debug;
namespace rsx
{
std::function<bool(u32 addr, bool is_writing)> g_access_violation_handler;
std::string shaders_cache::path_to_root()
{
return fs::get_executable_dir() + "data/";
@ -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 = {};

View File

@ -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<u32> inline_vertex_array;
@ -309,7 +309,8 @@ namespace rsx
std::set<u32> 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<std::string, std::string> get_programs() const { return std::make_pair("", ""); };
public:
void reset();
void init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress);