diff options
| author | 2015-04-04 12:57:31 +0200 | |
|---|---|---|
| committer | 2015-07-13 22:27:20 +0200 | |
| commit | 902fa4da52737d43e04c2a028658ad9840811a89 (patch) | |
| tree | 0a2346b4e08b5865c3369247f5720453b170e0c6 /src/core/hw/gpu.cpp | |
| parent | GPU: Be robust against nullptr addresses; properly reset busy bits in the tri... (diff) | |
| download | yuzu-902fa4da52737d43e04c2a028658ad9840811a89.tar.gz yuzu-902fa4da52737d43e04c2a028658ad9840811a89.tar.xz yuzu-902fa4da52737d43e04c2a028658ad9840811a89.zip | |
Add CiTrace recording support.
This is exposed in the GUI as a new "CiTrace Recording" widget.
Playback is implemented by a standalone 3DS homebrew application (which only runs reliably within Citra currently; on an actual 3DS it will often crash still).
Diffstat (limited to 'src/core/hw/gpu.cpp')
| -rw-r--r-- | src/core/hw/gpu.cpp | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp index 796493378..a3a7d128f 100644 --- a/src/core/hw/gpu.cpp +++ b/src/core/hw/gpu.cpp | |||
| @@ -21,12 +21,17 @@ | |||
| 21 | #include "core/hw/hw.h" | 21 | #include "core/hw/hw.h" |
| 22 | #include "core/hw/gpu.h" | 22 | #include "core/hw/gpu.h" |
| 23 | 23 | ||
| 24 | #include "core/tracer/recorder.h" | ||
| 25 | |||
| 24 | #include "video_core/command_processor.h" | 26 | #include "video_core/command_processor.h" |
| 25 | #include "video_core/hwrasterizer_base.h" | 27 | #include "video_core/hwrasterizer_base.h" |
| 26 | #include "video_core/renderer_base.h" | 28 | #include "video_core/renderer_base.h" |
| 27 | #include "video_core/utils.h" | 29 | #include "video_core/utils.h" |
| 28 | #include "video_core/video_core.h" | 30 | #include "video_core/video_core.h" |
| 29 | 31 | ||
| 32 | #include "video_core/debug_utils/debug_utils.h" | ||
| 33 | |||
| 34 | |||
| 30 | namespace GPU { | 35 | namespace GPU { |
| 31 | 36 | ||
| 32 | Regs g_regs; | 37 | Regs g_regs; |
| @@ -289,6 +294,11 @@ inline void Write(u32 addr, const T data) { | |||
| 289 | if (config.trigger & 1) | 294 | if (config.trigger & 1) |
| 290 | { | 295 | { |
| 291 | u32* buffer = (u32*)Memory::GetPhysicalPointer(config.GetPhysicalAddress()); | 296 | u32* buffer = (u32*)Memory::GetPhysicalPointer(config.GetPhysicalAddress()); |
| 297 | |||
| 298 | if (Pica::g_debug_context && Pica::g_debug_context->recorder) { | ||
| 299 | Pica::g_debug_context->recorder->MemoryAccessed((u8*)buffer, config.size * sizeof(u32), config.GetPhysicalAddress()); | ||
| 300 | } | ||
| 301 | |||
| 292 | Pica::CommandProcessor::ProcessCommandList(buffer, config.size); | 302 | Pica::CommandProcessor::ProcessCommandList(buffer, config.size); |
| 293 | 303 | ||
| 294 | g_regs.command_processor_config.trigger = 0; | 304 | g_regs.command_processor_config.trigger = 0; |
| @@ -299,6 +309,13 @@ inline void Write(u32 addr, const T data) { | |||
| 299 | default: | 309 | default: |
| 300 | break; | 310 | break; |
| 301 | } | 311 | } |
| 312 | |||
| 313 | // Notify tracer about the register write | ||
| 314 | // This is happening *after* handling the write to make sure we properly catch all memory reads. | ||
| 315 | if (Pica::g_debug_context && Pica::g_debug_context->recorder) { | ||
| 316 | // addr + GPU VBase - IO VBase + IO PBase | ||
| 317 | Pica::g_debug_context->recorder->RegisterWritten<T>(addr + 0x1EF00000 - 0x1EC00000 + 0x10100000, data); | ||
| 318 | } | ||
| 302 | } | 319 | } |
| 303 | 320 | ||
| 304 | // Explicitly instantiate template functions because we aren't defining this in the header: | 321 | // Explicitly instantiate template functions because we aren't defining this in the header: |