summaryrefslogtreecommitdiff
path: root/src/core/hw
diff options
context:
space:
mode:
authorGravatar Tony Wasserka2015-07-13 21:39:58 +0200
committerGravatar Tony Wasserka2015-07-13 21:39:58 +0200
commit884b681ccaf3cb4057ca0ed0102e446736bb535f (patch)
tree9359e9b88f0147879c672638d8c02960d2179d3a /src/core/hw
parentMerge pull request #859 from Apology11/master (diff)
parentCiTrace: Clean up initialization method. (diff)
downloadyuzu-884b681ccaf3cb4057ca0ed0102e446736bb535f.tar.gz
yuzu-884b681ccaf3cb4057ca0ed0102e446736bb535f.tar.xz
yuzu-884b681ccaf3cb4057ca0ed0102e446736bb535f.zip
Merge pull request #702 from neobrain/citrace
Add CiTrace recording support.
Diffstat (limited to 'src/core/hw')
-rw-r--r--src/core/hw/gpu.cpp78
-rw-r--r--src/core/hw/hw.cpp30
-rw-r--r--src/core/hw/lcd.cpp10
3 files changed, 91 insertions, 27 deletions
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index a1789f9c7..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
30namespace GPU { 35namespace GPU {
31 36
32Regs g_regs; 37Regs g_regs;
@@ -101,39 +106,43 @@ inline void Write(u32 addr, const T data) {
101 const bool is_second_filler = (index != GPU_REG_INDEX(memory_fill_config[0].trigger)); 106 const bool is_second_filler = (index != GPU_REG_INDEX(memory_fill_config[0].trigger));
102 auto& config = g_regs.memory_fill_config[is_second_filler]; 107 auto& config = g_regs.memory_fill_config[is_second_filler];
103 108
104 if (config.address_start && config.trigger) { 109 if (config.trigger) {
105 u8* start = Memory::GetPhysicalPointer(config.GetStartAddress()); 110 if (config.address_start) { // Some games pass invalid values here
106 u8* end = Memory::GetPhysicalPointer(config.GetEndAddress()); 111 u8* start = Memory::GetPhysicalPointer(config.GetStartAddress());
107 112 u8* end = Memory::GetPhysicalPointer(config.GetEndAddress());
108 if (config.fill_24bit) { 113
109 // fill with 24-bit values 114 if (config.fill_24bit) {
110 for (u8* ptr = start; ptr < end; ptr += 3) { 115 // fill with 24-bit values
111 ptr[0] = config.value_24bit_r; 116 for (u8* ptr = start; ptr < end; ptr += 3) {
112 ptr[1] = config.value_24bit_g; 117 ptr[0] = config.value_24bit_r;
113 ptr[2] = config.value_24bit_b; 118 ptr[1] = config.value_24bit_g;
119 ptr[2] = config.value_24bit_b;
120 }
121 } else if (config.fill_32bit) {
122 // fill with 32-bit values
123 for (u32* ptr = (u32*)start; ptr < (u32*)end; ++ptr)
124 *ptr = config.value_32bit;
125 } else {
126 // fill with 16-bit values
127 for (u16* ptr = (u16*)start; ptr < (u16*)end; ++ptr)
128 *ptr = config.value_16bit;
114 } 129 }
115 } else if (config.fill_32bit) {
116 // fill with 32-bit values
117 for (u32* ptr = (u32*)start; ptr < (u32*)end; ++ptr)
118 *ptr = config.value_32bit;
119 } else {
120 // fill with 16-bit values
121 for (u16* ptr = (u16*)start; ptr < (u16*)end; ++ptr)
122 *ptr = config.value_16bit;
123 }
124 130
125 LOG_TRACE(HW_GPU, "MemoryFill from 0x%08x to 0x%08x", config.GetStartAddress(), config.GetEndAddress()); 131 LOG_TRACE(HW_GPU, "MemoryFill from 0x%08x to 0x%08x", config.GetStartAddress(), config.GetEndAddress());
126 132
127 config.trigger = 0; 133 if (!is_second_filler) {
128 config.finished = 1; 134 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC0);
135 } else {
136 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1);
137 }
129 138
130 if (!is_second_filler) { 139 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetStartAddress(), config.GetEndAddress() - config.GetStartAddress());
131 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC0);
132 } else {
133 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PSC1);
134 } 140 }
135 141
136 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetStartAddress(), config.GetEndAddress() - config.GetStartAddress()); 142 // Reset "trigger" flag and set the "finish" flag
143 // NOTE: This was confirmed to happen on hardware even if "address_start" is zero.
144 config.trigger = 0;
145 config.finished = 1;
137 } 146 }
138 break; 147 break;
139 } 148 }
@@ -270,6 +279,7 @@ inline void Write(u32 addr, const T data) {
270 config.GetPhysicalOutputAddress(), output_width, output_height, 279 config.GetPhysicalOutputAddress(), output_width, output_height,
271 config.output_format.Value(), config.flags); 280 config.output_format.Value(), config.flags);
272 281
282 g_regs.display_transfer_config.trigger = 0;
273 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF); 283 GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PPF);
274 284
275 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetPhysicalOutputAddress(), output_size); 285 VideoCore::g_renderer->hw_rasterizer->NotifyFlush(config.GetPhysicalOutputAddress(), output_size);
@@ -284,7 +294,14 @@ inline void Write(u32 addr, const T data) {
284 if (config.trigger & 1) 294 if (config.trigger & 1)
285 { 295 {
286 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
287 Pica::CommandProcessor::ProcessCommandList(buffer, config.size); 302 Pica::CommandProcessor::ProcessCommandList(buffer, config.size);
303
304 g_regs.command_processor_config.trigger = 0;
288 } 305 }
289 break; 306 break;
290 } 307 }
@@ -292,6 +309,13 @@ inline void Write(u32 addr, const T data) {
292 default: 309 default:
293 break; 310 break;
294 } 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 }
295} 319}
296 320
297// 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:
diff --git a/src/core/hw/hw.cpp b/src/core/hw/hw.cpp
index c7006a498..b5fdbf9c1 100644
--- a/src/core/hw/hw.cpp
+++ b/src/core/hw/hw.cpp
@@ -15,6 +15,21 @@ template <typename T>
15inline void Read(T &var, const u32 addr) { 15inline void Read(T &var, const u32 addr) {
16 switch (addr & 0xFFFFF000) { 16 switch (addr & 0xFFFFF000) {
17 case VADDR_GPU: 17 case VADDR_GPU:
18 case VADDR_GPU + 0x1000:
19 case VADDR_GPU + 0x2000:
20 case VADDR_GPU + 0x3000:
21 case VADDR_GPU + 0x4000:
22 case VADDR_GPU + 0x5000:
23 case VADDR_GPU + 0x6000:
24 case VADDR_GPU + 0x7000:
25 case VADDR_GPU + 0x8000:
26 case VADDR_GPU + 0x9000:
27 case VADDR_GPU + 0xA000:
28 case VADDR_GPU + 0xB000:
29 case VADDR_GPU + 0xC000:
30 case VADDR_GPU + 0xD000:
31 case VADDR_GPU + 0xE000:
32 case VADDR_GPU + 0xF000:
18 GPU::Read(var, addr); 33 GPU::Read(var, addr);
19 break; 34 break;
20 case VADDR_LCD: 35 case VADDR_LCD:
@@ -29,6 +44,21 @@ template <typename T>
29inline void Write(u32 addr, const T data) { 44inline void Write(u32 addr, const T data) {
30 switch (addr & 0xFFFFF000) { 45 switch (addr & 0xFFFFF000) {
31 case VADDR_GPU: 46 case VADDR_GPU:
47 case VADDR_GPU + 0x1000:
48 case VADDR_GPU + 0x2000:
49 case VADDR_GPU + 0x3000:
50 case VADDR_GPU + 0x4000:
51 case VADDR_GPU + 0x5000:
52 case VADDR_GPU + 0x6000:
53 case VADDR_GPU + 0x7000:
54 case VADDR_GPU + 0x8000:
55 case VADDR_GPU + 0x9000:
56 case VADDR_GPU + 0xA000:
57 case VADDR_GPU + 0xB000:
58 case VADDR_GPU + 0xC000:
59 case VADDR_GPU + 0xD000:
60 case VADDR_GPU + 0xE000:
61 case VADDR_GPU + 0xF000:
32 GPU::Write(addr, data); 62 GPU::Write(addr, data);
33 break; 63 break;
34 case VADDR_LCD: 64 case VADDR_LCD:
diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp
index cdb757a18..6f93709e3 100644
--- a/src/core/hw/lcd.cpp
+++ b/src/core/hw/lcd.cpp
@@ -10,6 +10,9 @@
10#include "core/hw/hw.h" 10#include "core/hw/hw.h"
11#include "core/hw/lcd.h" 11#include "core/hw/lcd.h"
12 12
13#include "core/tracer/recorder.h"
14#include "video_core/debug_utils/debug_utils.h"
15
13namespace LCD { 16namespace LCD {
14 17
15Regs g_regs; 18Regs g_regs;
@@ -40,6 +43,13 @@ inline void Write(u32 addr, const T data) {
40 } 43 }
41 44
42 g_regs[index] = static_cast<u32>(data); 45 g_regs[index] = static_cast<u32>(data);
46
47 // Notify tracer about the register write
48 // This is happening *after* handling the write to make sure we properly catch all memory reads.
49 if (Pica::g_debug_context && Pica::g_debug_context->recorder) {
50 // addr + GPU VBase - IO VBase + IO PBase
51 Pica::g_debug_context->recorder->RegisterWritten<T>(addr + HW::VADDR_LCD - 0x1EC00000 + 0x10100000, data);
52 }
43} 53}
44 54
45// Explicitly instantiate template functions because we aren't defining this in the header: 55// Explicitly instantiate template functions because we aren't defining this in the header: