From 5b0ed1e2eb32a2ca3df45da258365131664bc940 Mon Sep 17 00:00:00 2001 From: eladash Date: Wed, 26 Sep 2018 11:41:39 +0300 Subject: [PATCH] rsx-capture: Map dynamically rsx data injection addresses --- rpcs3/Emu/RSX/Capture/rsx_capture.cpp | 68 +++++++++++++-------------- rpcs3/Emu/RSX/Capture/rsx_replay.cpp | 20 +++++--- rpcs3/Emu/RSX/Capture/rsx_replay.h | 12 +++-- 3 files changed, 54 insertions(+), 46 deletions(-) diff --git a/rpcs3/Emu/RSX/Capture/rsx_capture.cpp b/rpcs3/Emu/RSX/Capture/rsx_capture.cpp index 2e2a6188f3..332d965c1b 100644 --- a/rpcs3/Emu/RSX/Capture/rsx_capture.cpp +++ b/rpcs3/Emu/RSX/Capture/rsx_capture.cpp @@ -91,8 +91,8 @@ namespace rsx const u32 ucode_size = program_info.program_ucode_length; frame_capture_data::memory_block block; - block.addr = addr; - block.ioOffset = get_io_offset(program_offset, program_location); + block.ioOffset = program_offset, + block.location = program_location; frame_capture_data::memory_block_data block_data; block_data.data.resize(ucode_size + program_start); std::memcpy(block_data.data.data(), vm::base(addr), ucode_size + program_start); @@ -118,8 +118,8 @@ namespace rsx continue; frame_capture_data::memory_block block; - block.addr = texaddr; - block.ioOffset = get_io_offset(tex.offset(), tex.location()); + block.ioOffset = tex.offset(); + block.location = tex.location(); frame_capture_data::memory_block_data block_data; block_data.data.resize(texSize); @@ -145,8 +145,8 @@ namespace rsx continue; frame_capture_data::memory_block block; - block.addr = texaddr; - block.ioOffset = get_io_offset(tex.offset(), tex.location()); + block.ioOffset = tex.offset(); + block.location = tex.location(); frame_capture_data::memory_block_data block_data; block_data.data.resize(texSize); std::memcpy(block_data.data.data(), vm::base(texaddr), texSize); @@ -181,10 +181,9 @@ namespace rsx const size_t bufferSize = vertCount * vertStride + vertSize; frame_capture_data::memory_block block; - block.addr = addr; - block.ioOffset = get_io_offset(base_address, memory_location); + block.ioOffset = base_address; + block.location = memory_location; block.offset = (count.first * vertStride); - frame_capture_data::memory_block_data block_data; block_data.data.resize(bufferSize); std::memcpy(block_data.data.data(), vm::base(addr + block.offset), bufferSize); @@ -221,8 +220,8 @@ namespace rsx const size_t bufferSize = idxCount * type_size; frame_capture_data::memory_block block; - block.addr = base_addr; - block.ioOffset = get_io_offset(base_address, memory_location); + block.ioOffset = base_address; + block.location = memory_location; block.offset = (idxFirst * type_size); frame_capture_data::memory_block_data block_data; @@ -289,8 +288,8 @@ namespace rsx const u32 bufferSize = vertStride * (max_index - min_index + 1) + vertSize; frame_capture_data::memory_block block; - block.addr = addr; - block.ioOffset = get_io_offset(base_address, memory_location); + block.ioOffset = base_address; + block.location = memory_location; block.offset = (min_index * vertStride); frame_capture_data::memory_block_data block_data; @@ -339,8 +338,8 @@ namespace rsx const tiled_region src_region = rsx->get_tiled_address(src_offset + in_offset, src_dma & 0xf); frame_capture_data::memory_block block; - block.addr = src_region.address; - block.ioOffset = get_io_offset(src_region.tile ? src_region.base : src_offset + in_offset, src_dma & 0xf); + block.ioOffset = src_region.tile ? src_region.base : src_offset + in_offset; + block.location = src_dma & 0xf; u8* pixels_src = src_region.tile ? src_region.ptr + src_region.base : src_region.ptr; @@ -387,9 +386,9 @@ namespace rsx const tiled_region dst_region = rsx->get_tiled_address(dst_offset + out_offset, dst_dma & 0xf); frame_capture_data::memory_block blockDst; - blockDst.addr = dst_region.address; - blockDst.ioOffset = get_io_offset(dst_region.tile ? dst_region.base : dst_offset + out_offset, dst_dma & 0xf); - if (blockDst.ioOffset != -1) + blockDst.ioOffset = dst_region.tile ? dst_region.base : dst_offset + out_offset; + blockDst.location = dst_dma & 0xf; + if (get_io_offset(blockDst.ioOffset, blockDst.location) != -1) { u32 blockSize = method_registers.blit_engine_context_surface() != blit_engine::context_surface::swizzle2d ? out_pitch * out_h : out_bpp * next_pow2(out_w) * next_pow2(out_h); @@ -422,8 +421,8 @@ namespace rsx const u8* src = (u8*)vm::base(src_addr); frame_capture_data::memory_block block; - block.addr = src_addr; - block.ioOffset = get_io_offset(src_offset, src_dma); + block.ioOffset = src_offset; + block.location = src_dma; frame_capture_data::memory_block_data block_data; block_data.data.resize(in_pitch * line_count); @@ -448,11 +447,11 @@ namespace rsx } frame_capture_data::memory_block blockDst; - blockDst.addr = dst_addr; - blockDst.ioOffset = get_io_offset(dst_offset, dst_dma); + blockDst.ioOffset = dst_offset; + blockDst.location = dst_dma; - // only check for iooffset'd data - if (blockDst.ioOffset != -1) + // check if allocated + if (get_io_offset(blockDst.ioOffset, blockDst.location) != -1) { frame_capture_data::memory_block_data block_data; blockDst.size = out_pitch * line_count; @@ -543,11 +542,12 @@ namespace rsx u32 addr = get_address(offset, location); frame_capture_data::memory_block block; - block.addr = addr; - block.ioOffset = get_io_offset(offset, location); + block.ioOffset = offset; + block.location = location; block.size = 16; frame_capture_data::memory_block_data block_data; + insert_mem_block_in_map(replay_command.memory_state, std::move(block), std::move(block_data)); } @@ -579,11 +579,9 @@ namespace rsx if (ioOffset == -1) return; - u32 addr = get_address(offset, dma); - frame_capture_data::memory_block block; - block.addr = addr; - block.ioOffset = ioOffset; + block.ioOffset = offset; + block.location = dma; block.size = 64; frame_capture_data::memory_block_data block_data; @@ -608,15 +606,15 @@ namespace rsx // just need to capture dst for allocation later if in iomem - u32 ioOffset = get_io_offset(addr_offset, method_registers.blit_engine_output_location_nv3062()); + const u32 memory_location = method_registers.blit_engine_output_location_nv3062(); + + const u32 ioOffset = get_io_offset(addr_offset, memory_location); if (ioOffset == -1) return; - u32 addr = get_address(addr_offset, method_registers.blit_engine_output_location_nv3062()); - frame_capture_data::memory_block block; - block.addr = addr; - block.ioOffset = ioOffset; + block.ioOffset = addr_offset; + block.location = memory_location; block.size = 4; frame_capture_data::memory_block_data block_data; diff --git a/rpcs3/Emu/RSX/Capture/rsx_replay.cpp b/rpcs3/Emu/RSX/Capture/rsx_replay.cpp index b247f4bcb0..c4a5f5be6a 100644 --- a/rpcs3/Emu/RSX/Capture/rsx_replay.cpp +++ b/rpcs3/Emu/RSX/Capture/rsx_replay.cpp @@ -14,8 +14,8 @@ namespace rsx { // 'fake' initialize usermemory // todo: seriously, need to probly watch the replay memory map and just make sure its mapped before we copy rather than do this - const auto user_mem = vm::get(vm::user64k); - vm::falloc(user_mem->addr, 0x10000000); + user_mem_addr = vm::falloc(vm::get(vm::user1m)->addr, 0x10000000); + verify(HERE), user_mem_addr != 0; const u32 contextAddr = vm::alloc(sizeof(rsx_context), vm::main); if (contextAddr == 0) @@ -120,7 +120,7 @@ namespace rsx fmt::throw_exception("requested memory data state for command not found in memory_data_map"); const auto& data_block = it_data->second; - std::memcpy(vm::base(memblock.addr + memblock.offset), data_block.data.data(), data_block.data.size()); + std::memcpy(vm::base(get_address(memblock.ioOffset + memblock.offset, memblock.location)), data_block.data.data(), data_block.data.size()); } } @@ -213,10 +213,18 @@ namespace rsx for (const auto it : frame->memory_map) { const auto& memblock = it.second; - if (memblock.ioOffset == 0xFFFFFFFF) + if (memblock.location == CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN) + { + // Special area for reports + if (sys_rsx_context_iomap(context_id, (memblock.ioOffset & ~0xFFFFF) + 0x0e000000, (memblock.ioOffset & ~0xFFFFF) + user_mem_addr + 0x0e000000, 0x100000, 0) != CELL_OK) + fmt::throw_exception("rsx io map failed for block"); + continue; + } + + if (const u32 location = memblock.location; location != CELL_GCM_LOCATION_MAIN && location != CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER) continue; - if (sys_rsx_context_iomap(context_id, memblock.ioOffset & ~0xFFFFF, memblock.addr & ~0xFFFFF, ::align(memblock.size + memblock.offset, 0x100000), 0) != CELL_OK) + if (sys_rsx_context_iomap(context_id, memblock.ioOffset & ~0xFFFFF, user_mem_addr + (memblock.ioOffset & ~0xFFFFF), ::align(memblock.size + memblock.offset, 0x100000), 0) != CELL_OK) fmt::throw_exception("rsx io map failed for block"); } @@ -225,7 +233,7 @@ namespace rsx // start up fifo buffer by dumping the put ptr to first stop sys_rsx_context_attribute(context_id, 0x001, 0x20000000, fifo_stops[0], 0, 0); - auto renderer = fxm::get(); + auto renderer = rsx::get_current_renderer(); size_t stopIdx = 0; for (const auto& replay_cmd : frame->replay_commands) { diff --git a/rpcs3/Emu/RSX/Capture/rsx_replay.h b/rpcs3/Emu/RSX/Capture/rsx_replay.h index fd0b490e5c..f9525fe0ce 100644 --- a/rpcs3/Emu/RSX/Capture/rsx_replay.h +++ b/rpcs3/Emu/RSX/Capture/rsx_replay.h @@ -5,6 +5,7 @@ #include "Emu/Cell/PPUModule.h" #include "Emu/Cell/lv2/sys_sync.h" #include "Emu/Cell/lv2/sys_ppu_thread.h" +#include "Emu/RSX/gcm_enums.h" #include #include @@ -15,7 +16,7 @@ namespace rsx { constexpr u32 FRAME_CAPTURE_MAGIC = 0x52524300; // ascii 'RRC/0' - constexpr u32 FRAME_CAPTURE_VERSION = 0x1; + constexpr u32 FRAME_CAPTURE_VERSION = 0x2; struct frame_capture_data { @@ -32,18 +33,18 @@ namespace rsx // simple block to hold ps3 address and data struct memory_block { - u32 addr{0}; u32 ioOffset{0xFFFFFFFF}; // rsx ioOffset, -1 signifies unused - u32 offset{0}; // offset into addr/ioOffset to copy state into - u32 size{0}; // size of block needed + u32 offset{0}; // offset into addr/ioOffset to copy state into + u32 size{0}; // size of block needed + u32 location{0xFFFFFFFF}; // Location of the block in RSX memory space u64 data_state{0}; // this can be 0, in which case its just needed as an alloc template void serialize(Archive & ar) { - ar(addr); ar(ioOffset); ar(offset); ar(size); + ar(location); ar(data_state); } }; @@ -224,6 +225,7 @@ namespace rsx frame_capture_data::tile_state tile_state; }; + u32 user_mem_addr; current_state cs; std::unique_ptr frame;