New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rsx: initial capture/replay functionality #4510
Conversation
Whoops, good catch, i added a 'cached state' during replay now, which will lower/remove most of the log spam |
rpcs3/Emu/RSX/rsx_replay.cpp
Outdated
(u64)dbstate.buffers[i].width << 32 | dbstate.buffers[i].height, (u64)dbstate.buffers[i].pitch << 32 | dbstate.buffers[i].offset, 0); | ||
} | ||
cs.display_buffer_hash = replay_cmd.display_buffer_state; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newline
rpcs3/Emu/RSX/rsx_replay.cpp
Outdated
|
||
const auto& ti = t.pack(); | ||
sys_rsx_context_attribute(context_id, 0x300, i, (u64)ti.tile << 32 | ti.limit, (u64)ti.pitch << 32 | ti.format, 0); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newline
rpcs3/Emu/RSX/rsx_replay.cpp
Outdated
default: | ||
return 0xFFFFFFFFu; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
newline
rpcs3/Emu/RSX/rsx_replay.cpp
Outdated
} | ||
else | ||
frame_capture.memory_data_map.insert(std::make_pair(data_hash, std::move(data))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vbcrlf
rpcs3/Emu/RSX/RSXThread.cpp
Outdated
|
||
int clip_w = rsx::method_registers.surface_clip_width(); | ||
/*int clip_w = rsx::method_registers.surface_clip_width(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove this if you wish, its based on some old reasoning on what can invalidate a draw command and is technically incorrect/incomplete anyway.
rpcs3/Emu/RSX/rsx_replay.cpp
Outdated
|
||
const auto& zci = zc.pack(); | ||
sys_rsx_context_attribute(context_id, 0x301, i, (u64)zci.region << 32 | zci.size, (u64)zci.start << 32 | zci.offset, (u64)zci.status0 << 32 | zci.status1); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might as well toss one in here if spacing the other blocks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Love the minimal disruption to rsx core. Maybe this should be moved to RSX/Util or RSX/Capture? RSX/ is cluttered with things unrelated to core and imo they do not belong there (I will be moving some stuff like overlays from RSX core folders)
Sure, added 'RSX/Capture', threw rsx_trace.h in there as well for now, also broke out the capture methods to rsx_capture.h/cpp, also lots of fixes for yakuza capture/replay |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
madness
case CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER: | ||
case CELL_GCM_LOCATION_MAIN: | ||
{ | ||
if (u32 result = RSXIOMem.RealAddr(offset)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
} | ||
case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN: | ||
{ | ||
if (u32 result = RSXIOMem.RealAddr(0x0e000000 + offset)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
void insert_mem_block_in_map(std::unordered_set<u64>& mem_changes, frame_capture_data::memory_block&& block, frame_capture_data::memory_block_data&& data) | ||
{ | ||
u64 data_hash = 0; | ||
if (data.data.size() > 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
block.data_state = data_hash; | ||
|
||
auto it = frame_capture.memory_data_map.find(data_hash); | ||
if (it != frame_capture.memory_data_map.end()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
|
||
// capture fragment shader mem | ||
const u32 shader_program = method_registers.shader_program_address(); | ||
if (shader_program != 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
tstate.size = tile.size; | ||
} | ||
|
||
for (u32 i = 0; i < limits::zculls_count; ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
{ | ||
const auto target = rsx::method_registers.surface_color_target(); | ||
|
||
u32 offset_color[] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
rsx::method_registers.surface_d_dma(), | ||
}; | ||
|
||
auto check_add = [&replay_command](u32 offset, u32 dma) -> void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
insert_mem_block_in_map(replay_command.memory_state, std::move(block), std::move(block_data)); | ||
}; | ||
|
||
for (const auto& index : utility::get_rtt_indexes(target)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
rsx::method_registers.surface_d_offset(), | ||
}; | ||
|
||
u32 context_dma_color[] = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{
This is an initial version of a 'renderdoc' type capturing/replay system. The base idea, similar to renderdoc, is that the emulator can now 'capture' all rsx data used during a frame, and can then 'replay' it later. The general idea would be this could be used to ease testing for regressions, and ease of development of fixes, as some graphics issues could instead now be captured and fixed from replay rather than needing the full title/app. This also has the added benefit of still being able to 'renderdoc' a replay.
Implementation notes:
if (replay){}
type checks anywhere in emucore/rsx, which should serve to give us the same code paths and most accurate replayUsage notes:
Notes/PSA: