summaryrefslogtreecommitdiff
path: root/src/core/tracer/recorder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/tracer/recorder.cpp')
-rw-r--r--src/core/tracer/recorder.cpp145
1 files changed, 83 insertions, 62 deletions
diff --git a/src/core/tracer/recorder.cpp b/src/core/tracer/recorder.cpp
index 7abaacf70..276a5b288 100644
--- a/src/core/tracer/recorder.cpp
+++ b/src/core/tracer/recorder.cpp
@@ -3,18 +3,14 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cstring> 5#include <cstring>
6
7#include "common/assert.h" 6#include "common/assert.h"
8#include "common/file_util.h" 7#include "common/file_util.h"
9#include "common/logging/log.h" 8#include "common/logging/log.h"
10
11#include "recorder.h" 9#include "recorder.h"
12 10
13namespace CiTrace { 11namespace CiTrace {
14 12
15Recorder::Recorder(const InitialState& initial_state) : initial_state(initial_state) { 13Recorder::Recorder(const InitialState& initial_state) : initial_state(initial_state) {}
16
17}
18 14
19void Recorder::Finish(const std::string& filename) { 15void Recorder::Finish(const std::string& filename) {
20 // Setup CiTrace header 16 // Setup CiTrace header
@@ -26,35 +22,41 @@ void Recorder::Finish(const std::string& filename) {
26 // Calculate file offsets 22 // Calculate file offsets
27 auto& initial = header.initial_state_offsets; 23 auto& initial = header.initial_state_offsets;
28 24
29 initial.gpu_registers_size = static_cast<u32>(initial_state.gpu_registers.size()); 25 initial.gpu_registers_size = static_cast<u32>(initial_state.gpu_registers.size());
30 initial.lcd_registers_size = static_cast<u32>(initial_state.lcd_registers.size()); 26 initial.lcd_registers_size = static_cast<u32>(initial_state.lcd_registers.size());
31 initial.pica_registers_size = static_cast<u32>(initial_state.pica_registers.size()); 27 initial.pica_registers_size = static_cast<u32>(initial_state.pica_registers.size());
32 initial.default_attributes_size = static_cast<u32>(initial_state.default_attributes.size()); 28 initial.default_attributes_size = static_cast<u32>(initial_state.default_attributes.size());
33 initial.vs_program_binary_size = static_cast<u32>(initial_state.vs_program_binary.size()); 29 initial.vs_program_binary_size = static_cast<u32>(initial_state.vs_program_binary.size());
34 initial.vs_swizzle_data_size = static_cast<u32>(initial_state.vs_swizzle_data.size()); 30 initial.vs_swizzle_data_size = static_cast<u32>(initial_state.vs_swizzle_data.size());
35 initial.vs_float_uniforms_size = static_cast<u32>(initial_state.vs_float_uniforms.size()); 31 initial.vs_float_uniforms_size = static_cast<u32>(initial_state.vs_float_uniforms.size());
36 initial.gs_program_binary_size = static_cast<u32>(initial_state.gs_program_binary.size()); 32 initial.gs_program_binary_size = static_cast<u32>(initial_state.gs_program_binary.size());
37 initial.gs_swizzle_data_size = static_cast<u32>(initial_state.gs_swizzle_data.size()); 33 initial.gs_swizzle_data_size = static_cast<u32>(initial_state.gs_swizzle_data.size());
38 initial.gs_float_uniforms_size = static_cast<u32>(initial_state.gs_float_uniforms.size()); 34 initial.gs_float_uniforms_size = static_cast<u32>(initial_state.gs_float_uniforms.size());
39 header.stream_size = static_cast<u32>(stream.size()); 35 header.stream_size = static_cast<u32>(stream.size());
40 36
41 initial.gpu_registers = sizeof(header); 37 initial.gpu_registers = sizeof(header);
42 initial.lcd_registers = initial.gpu_registers + initial.gpu_registers_size * sizeof(u32); 38 initial.lcd_registers = initial.gpu_registers + initial.gpu_registers_size * sizeof(u32);
43 initial.pica_registers = initial.lcd_registers + initial.lcd_registers_size * sizeof(u32);; 39 initial.pica_registers = initial.lcd_registers + initial.lcd_registers_size * sizeof(u32);
44 initial.default_attributes = initial.pica_registers + initial.pica_registers_size * sizeof(u32); 40 ;
45 initial.vs_program_binary = initial.default_attributes + initial.default_attributes_size * sizeof(u32); 41 initial.default_attributes = initial.pica_registers + initial.pica_registers_size * sizeof(u32);
46 initial.vs_swizzle_data = initial.vs_program_binary + initial.vs_program_binary_size * sizeof(u32); 42 initial.vs_program_binary =
47 initial.vs_float_uniforms = initial.vs_swizzle_data + initial.vs_swizzle_data_size * sizeof(u32); 43 initial.default_attributes + initial.default_attributes_size * sizeof(u32);
48 initial.gs_program_binary = initial.vs_float_uniforms + initial.vs_float_uniforms_size * sizeof(u32); 44 initial.vs_swizzle_data =
49 initial.gs_swizzle_data = initial.gs_program_binary + initial.gs_program_binary_size * sizeof(u32); 45 initial.vs_program_binary + initial.vs_program_binary_size * sizeof(u32);
50 initial.gs_float_uniforms = initial.gs_swizzle_data + initial.gs_swizzle_data_size * sizeof(u32); 46 initial.vs_float_uniforms =
51 header.stream_offset = initial.gs_float_uniforms + initial.gs_float_uniforms_size * sizeof(u32); 47 initial.vs_swizzle_data + initial.vs_swizzle_data_size * sizeof(u32);
48 initial.gs_program_binary =
49 initial.vs_float_uniforms + initial.vs_float_uniforms_size * sizeof(u32);
50 initial.gs_swizzle_data =
51 initial.gs_program_binary + initial.gs_program_binary_size * sizeof(u32);
52 initial.gs_float_uniforms =
53 initial.gs_swizzle_data + initial.gs_swizzle_data_size * sizeof(u32);
54 header.stream_offset = initial.gs_float_uniforms + initial.gs_float_uniforms_size * sizeof(u32);
52 55
53 // Iterate through stream elements, update relevant stream element data 56 // Iterate through stream elements, update relevant stream element data
54 for (auto& stream_element : stream) { 57 for (auto& stream_element : stream) {
55 switch (stream_element.data.type) { 58 switch (stream_element.data.type) {
56 case MemoryLoad: 59 case MemoryLoad: {
57 {
58 auto& file_offset = memory_regions[stream_element.hash]; 60 auto& file_offset = memory_regions[stream_element.hash];
59 if (!stream_element.uses_existing_data) { 61 if (!stream_element.uses_existing_data) {
60 file_offset = header.stream_offset; 62 file_offset = header.stream_offset;
@@ -79,44 +81,62 @@ void Recorder::Finish(const std::string& filename) {
79 throw "Failed to write header"; 81 throw "Failed to write header";
80 82
81 // Write initial state 83 // Write initial state
82 written = file.WriteArray(initial_state.gpu_registers.data(), initial_state.gpu_registers.size()); 84 written =
85 file.WriteArray(initial_state.gpu_registers.data(), initial_state.gpu_registers.size());
83 if (written != initial_state.gpu_registers.size() || file.Tell() != initial.lcd_registers) 86 if (written != initial_state.gpu_registers.size() || file.Tell() != initial.lcd_registers)
84 throw "Failed to write GPU registers"; 87 throw "Failed to write GPU registers";
85 88
86 written = file.WriteArray(initial_state.lcd_registers.data(), initial_state.lcd_registers.size()); 89 written =
90 file.WriteArray(initial_state.lcd_registers.data(), initial_state.lcd_registers.size());
87 if (written != initial_state.lcd_registers.size() || file.Tell() != initial.pica_registers) 91 if (written != initial_state.lcd_registers.size() || file.Tell() != initial.pica_registers)
88 throw "Failed to write LCD registers"; 92 throw "Failed to write LCD registers";
89 93
90 written = file.WriteArray(initial_state.pica_registers.data(), initial_state.pica_registers.size()); 94 written = file.WriteArray(initial_state.pica_registers.data(),
91 if (written != initial_state.pica_registers.size() || file.Tell() != initial.default_attributes) 95 initial_state.pica_registers.size());
96 if (written != initial_state.pica_registers.size() ||
97 file.Tell() != initial.default_attributes)
92 throw "Failed to write Pica registers"; 98 throw "Failed to write Pica registers";
93 99
94 written = file.WriteArray(initial_state.default_attributes.data(), initial_state.default_attributes.size()); 100 written = file.WriteArray(initial_state.default_attributes.data(),
95 if (written != initial_state.default_attributes.size() || file.Tell() != initial.vs_program_binary) 101 initial_state.default_attributes.size());
102 if (written != initial_state.default_attributes.size() ||
103 file.Tell() != initial.vs_program_binary)
96 throw "Failed to write default vertex attributes"; 104 throw "Failed to write default vertex attributes";
97 105
98 written = file.WriteArray(initial_state.vs_program_binary.data(), initial_state.vs_program_binary.size()); 106 written = file.WriteArray(initial_state.vs_program_binary.data(),
99 if (written != initial_state.vs_program_binary.size() || file.Tell() != initial.vs_swizzle_data) 107 initial_state.vs_program_binary.size());
108 if (written != initial_state.vs_program_binary.size() ||
109 file.Tell() != initial.vs_swizzle_data)
100 throw "Failed to write vertex shader program binary"; 110 throw "Failed to write vertex shader program binary";
101 111
102 written = file.WriteArray(initial_state.vs_swizzle_data.data(), initial_state.vs_swizzle_data.size()); 112 written = file.WriteArray(initial_state.vs_swizzle_data.data(),
103 if (written != initial_state.vs_swizzle_data.size() || file.Tell() != initial.vs_float_uniforms) 113 initial_state.vs_swizzle_data.size());
114 if (written != initial_state.vs_swizzle_data.size() ||
115 file.Tell() != initial.vs_float_uniforms)
104 throw "Failed to write vertex shader swizzle data"; 116 throw "Failed to write vertex shader swizzle data";
105 117
106 written = file.WriteArray(initial_state.vs_float_uniforms.data(), initial_state.vs_float_uniforms.size()); 118 written = file.WriteArray(initial_state.vs_float_uniforms.data(),
107 if (written != initial_state.vs_float_uniforms.size() || file.Tell() != initial.gs_program_binary) 119 initial_state.vs_float_uniforms.size());
120 if (written != initial_state.vs_float_uniforms.size() ||
121 file.Tell() != initial.gs_program_binary)
108 throw "Failed to write vertex shader float uniforms"; 122 throw "Failed to write vertex shader float uniforms";
109 123
110 written = file.WriteArray(initial_state.gs_program_binary.data(), initial_state.gs_program_binary.size()); 124 written = file.WriteArray(initial_state.gs_program_binary.data(),
111 if (written != initial_state.gs_program_binary.size() || file.Tell() != initial.gs_swizzle_data) 125 initial_state.gs_program_binary.size());
126 if (written != initial_state.gs_program_binary.size() ||
127 file.Tell() != initial.gs_swizzle_data)
112 throw "Failed to write geomtry shader program binary"; 128 throw "Failed to write geomtry shader program binary";
113 129
114 written = file.WriteArray(initial_state.gs_swizzle_data.data(), initial_state.gs_swizzle_data.size()); 130 written = file.WriteArray(initial_state.gs_swizzle_data.data(),
115 if (written != initial_state.gs_swizzle_data.size() || file.Tell() != initial.gs_float_uniforms) 131 initial_state.gs_swizzle_data.size());
132 if (written != initial_state.gs_swizzle_data.size() ||
133 file.Tell() != initial.gs_float_uniforms)
116 throw "Failed to write geometry shader swizzle data"; 134 throw "Failed to write geometry shader swizzle data";
117 135
118 written = file.WriteArray(initial_state.gs_float_uniforms.data(), initial_state.gs_float_uniforms.size()); 136 written = file.WriteArray(initial_state.gs_float_uniforms.data(),
119 if (written != initial_state.gs_float_uniforms.size() || file.Tell() != initial.gs_float_uniforms + sizeof(u32) * initial.gs_float_uniforms_size) 137 initial_state.gs_float_uniforms.size());
138 if (written != initial_state.gs_float_uniforms.size() ||
139 file.Tell() != initial.gs_float_uniforms + sizeof(u32) * initial.gs_float_uniforms_size)
120 throw "Failed to write geometry shader float uniforms"; 140 throw "Failed to write geometry shader float uniforms";
121 141
122 // Iterate through stream elements, write "extra data" 142 // Iterate through stream elements, write "extra data"
@@ -124,7 +144,8 @@ void Recorder::Finish(const std::string& filename) {
124 if (stream_element.extra_data.size() == 0) 144 if (stream_element.extra_data.size() == 0)
125 continue; 145 continue;
126 146
127 written = file.WriteBytes(stream_element.extra_data.data(), stream_element.extra_data.size()); 147 written =
148 file.WriteBytes(stream_element.extra_data.data(), stream_element.extra_data.size());
128 if (written != stream_element.extra_data.size()) 149 if (written != stream_element.extra_data.size())
129 throw "Failed to write extra data"; 150 throw "Failed to write extra data";
130 } 151 }
@@ -137,17 +158,17 @@ void Recorder::Finish(const std::string& filename) {
137 if (1 != file.WriteObject(stream_element.data)) 158 if (1 != file.WriteObject(stream_element.data))
138 throw "Failed to write stream element"; 159 throw "Failed to write stream element";
139 } 160 }
140 } catch(const char* str) { 161 } catch (const char* str) {
141 LOG_ERROR(HW_GPU, "Writing CiTrace file failed: %s", str); 162 LOG_ERROR(HW_GPU, "Writing CiTrace file failed: %s", str);
142 } 163 }
143} 164}
144 165
145void Recorder::FrameFinished() { 166void Recorder::FrameFinished() {
146 stream.push_back( { { FrameMarker } } ); 167 stream.push_back({{FrameMarker}});
147} 168}
148 169
149void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) { 170void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) {
150 StreamElement element = { { MemoryLoad } }; 171 StreamElement element = {{MemoryLoad}};
151 element.data.memory_load.size = size; 172 element.data.memory_load.size = size;
152 element.data.memory_load.physical_address = physical_address; 173 element.data.memory_load.physical_address = physical_address;
153 174
@@ -166,22 +187,22 @@ void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) {
166 stream.push_back(element); 187 stream.push_back(element);
167} 188}
168 189
169template<typename T> 190template <typename T>
170void Recorder::RegisterWritten(u32 physical_address, T value) { 191void Recorder::RegisterWritten(u32 physical_address, T value) {
171 StreamElement element = { { RegisterWrite } }; 192 StreamElement element = {{RegisterWrite}};
172 element.data.register_write.size = (sizeof(T) == 1) ? CTRegisterWrite::SIZE_8 193 element.data.register_write.size =
173 : (sizeof(T) == 2) ? CTRegisterWrite::SIZE_16 194 (sizeof(T) == 1) ? CTRegisterWrite::SIZE_8
174 : (sizeof(T) == 4) ? CTRegisterWrite::SIZE_32 195 : (sizeof(T) == 2) ? CTRegisterWrite::SIZE_16
175 : CTRegisterWrite::SIZE_64; 196 : (sizeof(T) == 4) ? CTRegisterWrite::SIZE_32
197 : CTRegisterWrite::SIZE_64;
176 element.data.register_write.physical_address = physical_address; 198 element.data.register_write.physical_address = physical_address;
177 element.data.register_write.value = value; 199 element.data.register_write.value = value;
178 200
179 stream.push_back(element); 201 stream.push_back(element);
180} 202}
181 203
182template void Recorder::RegisterWritten(u32,u8); 204template void Recorder::RegisterWritten(u32, u8);
183template void Recorder::RegisterWritten(u32,u16); 205template void Recorder::RegisterWritten(u32, u16);
184template void Recorder::RegisterWritten(u32,u32); 206template void Recorder::RegisterWritten(u32, u32);
185template void Recorder::RegisterWritten(u32,u64); 207template void Recorder::RegisterWritten(u32, u64);
186
187} 208}