core: Remove unused CiTrace source files
These source files have been unused for the entire lifecycle of the project. They're a hold-over from Citra and only add to the build time of the project, so they can be removed. There's also likely no way this would ever work in yuzu in its current form without revamping quite a bit of it, given how different the GPU on the Switch is compared to the 3DS.
This commit is contained in:
parent
834e07d639
commit
61d2498f00
|
@ -463,9 +463,6 @@ add_library(core STATIC
|
||||||
settings.h
|
settings.h
|
||||||
telemetry_session.cpp
|
telemetry_session.cpp
|
||||||
telemetry_session.h
|
telemetry_session.h
|
||||||
tracer/citrace.h
|
|
||||||
tracer/recorder.cpp
|
|
||||||
tracer/recorder.h
|
|
||||||
)
|
)
|
||||||
|
|
||||||
create_target_directory_groups(core)
|
create_target_directory_groups(core)
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
// Copyright 2015 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/common_types.h"
|
|
||||||
|
|
||||||
namespace CiTrace {
|
|
||||||
|
|
||||||
// NOTE: Things are stored in little-endian
|
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
struct CTHeader {
|
|
||||||
static const char* ExpectedMagicWord() {
|
|
||||||
return "CiTr";
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 ExpectedVersion() {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char magic[4];
|
|
||||||
u32 version;
|
|
||||||
u32 header_size;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
// NOTE: Register range sizes are technically hardware-constants, but the actual limits
|
|
||||||
// aren't known. Hence we store the presumed limits along the offsets.
|
|
||||||
// Sizes are given in u32 units.
|
|
||||||
u32 gpu_registers;
|
|
||||||
u32 gpu_registers_size;
|
|
||||||
u32 lcd_registers;
|
|
||||||
u32 lcd_registers_size;
|
|
||||||
u32 pica_registers;
|
|
||||||
u32 pica_registers_size;
|
|
||||||
u32 default_attributes;
|
|
||||||
u32 default_attributes_size;
|
|
||||||
u32 vs_program_binary;
|
|
||||||
u32 vs_program_binary_size;
|
|
||||||
u32 vs_swizzle_data;
|
|
||||||
u32 vs_swizzle_data_size;
|
|
||||||
u32 vs_float_uniforms;
|
|
||||||
u32 vs_float_uniforms_size;
|
|
||||||
u32 gs_program_binary;
|
|
||||||
u32 gs_program_binary_size;
|
|
||||||
u32 gs_swizzle_data;
|
|
||||||
u32 gs_swizzle_data_size;
|
|
||||||
u32 gs_float_uniforms;
|
|
||||||
u32 gs_float_uniforms_size;
|
|
||||||
|
|
||||||
// Other things we might want to store here:
|
|
||||||
// - Initial framebuffer data, maybe even a full copy of FCRAM/VRAM
|
|
||||||
// - Lookup tables for fragment lighting
|
|
||||||
// - Lookup tables for procedural textures
|
|
||||||
} initial_state_offsets;
|
|
||||||
|
|
||||||
u32 stream_offset;
|
|
||||||
u32 stream_size;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CTStreamElementType : u32 {
|
|
||||||
FrameMarker = 0xE1,
|
|
||||||
MemoryLoad = 0xE2,
|
|
||||||
RegisterWrite = 0xE3,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CTMemoryLoad {
|
|
||||||
u32 file_offset;
|
|
||||||
u32 size;
|
|
||||||
u32 physical_address;
|
|
||||||
u32 pad;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CTRegisterWrite {
|
|
||||||
u32 physical_address;
|
|
||||||
|
|
||||||
enum : u32 {
|
|
||||||
SIZE_8 = 0xD1,
|
|
||||||
SIZE_16 = 0xD2,
|
|
||||||
SIZE_32 = 0xD3,
|
|
||||||
SIZE_64 = 0xD4,
|
|
||||||
} size;
|
|
||||||
|
|
||||||
// TODO: Make it clearer which bits of this member are used for sizes other than 32 bits
|
|
||||||
u64 value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CTStreamElement {
|
|
||||||
CTStreamElementType type;
|
|
||||||
|
|
||||||
union {
|
|
||||||
CTMemoryLoad memory_load;
|
|
||||||
CTRegisterWrite register_write;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma pack()
|
|
||||||
} // namespace CiTrace
|
|
|
@ -1,208 +0,0 @@
|
||||||
// Copyright 2015 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "common/file_util.h"
|
|
||||||
#include "common/logging/log.h"
|
|
||||||
#include "core/tracer/recorder.h"
|
|
||||||
|
|
||||||
namespace CiTrace {
|
|
||||||
|
|
||||||
Recorder::Recorder(const InitialState& initial_state) : initial_state(initial_state) {}
|
|
||||||
|
|
||||||
void Recorder::Finish(const std::string& filename) {
|
|
||||||
// Setup CiTrace header
|
|
||||||
CTHeader header;
|
|
||||||
std::memcpy(header.magic, CTHeader::ExpectedMagicWord(), 4);
|
|
||||||
header.version = CTHeader::ExpectedVersion();
|
|
||||||
header.header_size = sizeof(CTHeader);
|
|
||||||
|
|
||||||
// Calculate file offsets
|
|
||||||
auto& initial = header.initial_state_offsets;
|
|
||||||
|
|
||||||
initial.gpu_registers_size = static_cast<u32>(initial_state.gpu_registers.size());
|
|
||||||
initial.lcd_registers_size = static_cast<u32>(initial_state.lcd_registers.size());
|
|
||||||
initial.pica_registers_size = static_cast<u32>(initial_state.pica_registers.size());
|
|
||||||
initial.default_attributes_size = static_cast<u32>(initial_state.default_attributes.size());
|
|
||||||
initial.vs_program_binary_size = static_cast<u32>(initial_state.vs_program_binary.size());
|
|
||||||
initial.vs_swizzle_data_size = static_cast<u32>(initial_state.vs_swizzle_data.size());
|
|
||||||
initial.vs_float_uniforms_size = static_cast<u32>(initial_state.vs_float_uniforms.size());
|
|
||||||
initial.gs_program_binary_size = static_cast<u32>(initial_state.gs_program_binary.size());
|
|
||||||
initial.gs_swizzle_data_size = static_cast<u32>(initial_state.gs_swizzle_data.size());
|
|
||||||
initial.gs_float_uniforms_size = static_cast<u32>(initial_state.gs_float_uniforms.size());
|
|
||||||
header.stream_size = static_cast<u32>(stream.size());
|
|
||||||
|
|
||||||
initial.gpu_registers = sizeof(header);
|
|
||||||
initial.lcd_registers = initial.gpu_registers + initial.gpu_registers_size * sizeof(u32);
|
|
||||||
initial.pica_registers = initial.lcd_registers + initial.lcd_registers_size * sizeof(u32);
|
|
||||||
;
|
|
||||||
initial.default_attributes = initial.pica_registers + initial.pica_registers_size * sizeof(u32);
|
|
||||||
initial.vs_program_binary =
|
|
||||||
initial.default_attributes + initial.default_attributes_size * sizeof(u32);
|
|
||||||
initial.vs_swizzle_data =
|
|
||||||
initial.vs_program_binary + initial.vs_program_binary_size * sizeof(u32);
|
|
||||||
initial.vs_float_uniforms =
|
|
||||||
initial.vs_swizzle_data + initial.vs_swizzle_data_size * sizeof(u32);
|
|
||||||
initial.gs_program_binary =
|
|
||||||
initial.vs_float_uniforms + initial.vs_float_uniforms_size * sizeof(u32);
|
|
||||||
initial.gs_swizzle_data =
|
|
||||||
initial.gs_program_binary + initial.gs_program_binary_size * sizeof(u32);
|
|
||||||
initial.gs_float_uniforms =
|
|
||||||
initial.gs_swizzle_data + initial.gs_swizzle_data_size * sizeof(u32);
|
|
||||||
header.stream_offset = initial.gs_float_uniforms + initial.gs_float_uniforms_size * sizeof(u32);
|
|
||||||
|
|
||||||
// Iterate through stream elements, update relevant stream element data
|
|
||||||
for (auto& stream_element : stream) {
|
|
||||||
switch (stream_element.data.type) {
|
|
||||||
case MemoryLoad: {
|
|
||||||
auto& file_offset = memory_regions[stream_element.hash];
|
|
||||||
if (!stream_element.uses_existing_data) {
|
|
||||||
file_offset = header.stream_offset;
|
|
||||||
}
|
|
||||||
stream_element.data.memory_load.file_offset = file_offset;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
// Other commands don't use any extra data
|
|
||||||
DEBUG_ASSERT(stream_element.extra_data.size() == 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
header.stream_offset += static_cast<u32>(stream_element.extra_data.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Open file and write header
|
|
||||||
FileUtil::IOFile file(filename, "wb");
|
|
||||||
std::size_t written = file.WriteObject(header);
|
|
||||||
if (written != 1 || file.Tell() != initial.gpu_registers)
|
|
||||||
throw "Failed to write header";
|
|
||||||
|
|
||||||
// Write initial state
|
|
||||||
written =
|
|
||||||
file.WriteArray(initial_state.gpu_registers.data(), initial_state.gpu_registers.size());
|
|
||||||
if (written != initial_state.gpu_registers.size() || file.Tell() != initial.lcd_registers)
|
|
||||||
throw "Failed to write GPU registers";
|
|
||||||
|
|
||||||
written =
|
|
||||||
file.WriteArray(initial_state.lcd_registers.data(), initial_state.lcd_registers.size());
|
|
||||||
if (written != initial_state.lcd_registers.size() || file.Tell() != initial.pica_registers)
|
|
||||||
throw "Failed to write LCD registers";
|
|
||||||
|
|
||||||
written = file.WriteArray(initial_state.pica_registers.data(),
|
|
||||||
initial_state.pica_registers.size());
|
|
||||||
if (written != initial_state.pica_registers.size() ||
|
|
||||||
file.Tell() != initial.default_attributes)
|
|
||||||
throw "Failed to write Pica registers";
|
|
||||||
|
|
||||||
written = file.WriteArray(initial_state.default_attributes.data(),
|
|
||||||
initial_state.default_attributes.size());
|
|
||||||
if (written != initial_state.default_attributes.size() ||
|
|
||||||
file.Tell() != initial.vs_program_binary)
|
|
||||||
throw "Failed to write default vertex attributes";
|
|
||||||
|
|
||||||
written = file.WriteArray(initial_state.vs_program_binary.data(),
|
|
||||||
initial_state.vs_program_binary.size());
|
|
||||||
if (written != initial_state.vs_program_binary.size() ||
|
|
||||||
file.Tell() != initial.vs_swizzle_data)
|
|
||||||
throw "Failed to write vertex shader program binary";
|
|
||||||
|
|
||||||
written = file.WriteArray(initial_state.vs_swizzle_data.data(),
|
|
||||||
initial_state.vs_swizzle_data.size());
|
|
||||||
if (written != initial_state.vs_swizzle_data.size() ||
|
|
||||||
file.Tell() != initial.vs_float_uniforms)
|
|
||||||
throw "Failed to write vertex shader swizzle data";
|
|
||||||
|
|
||||||
written = file.WriteArray(initial_state.vs_float_uniforms.data(),
|
|
||||||
initial_state.vs_float_uniforms.size());
|
|
||||||
if (written != initial_state.vs_float_uniforms.size() ||
|
|
||||||
file.Tell() != initial.gs_program_binary)
|
|
||||||
throw "Failed to write vertex shader float uniforms";
|
|
||||||
|
|
||||||
written = file.WriteArray(initial_state.gs_program_binary.data(),
|
|
||||||
initial_state.gs_program_binary.size());
|
|
||||||
if (written != initial_state.gs_program_binary.size() ||
|
|
||||||
file.Tell() != initial.gs_swizzle_data)
|
|
||||||
throw "Failed to write geomtry shader program binary";
|
|
||||||
|
|
||||||
written = file.WriteArray(initial_state.gs_swizzle_data.data(),
|
|
||||||
initial_state.gs_swizzle_data.size());
|
|
||||||
if (written != initial_state.gs_swizzle_data.size() ||
|
|
||||||
file.Tell() != initial.gs_float_uniforms)
|
|
||||||
throw "Failed to write geometry shader swizzle data";
|
|
||||||
|
|
||||||
written = file.WriteArray(initial_state.gs_float_uniforms.data(),
|
|
||||||
initial_state.gs_float_uniforms.size());
|
|
||||||
if (written != initial_state.gs_float_uniforms.size() ||
|
|
||||||
file.Tell() != initial.gs_float_uniforms + sizeof(u32) * initial.gs_float_uniforms_size)
|
|
||||||
throw "Failed to write geometry shader float uniforms";
|
|
||||||
|
|
||||||
// Iterate through stream elements, write "extra data"
|
|
||||||
for (const auto& stream_element : stream) {
|
|
||||||
if (stream_element.extra_data.size() == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
written =
|
|
||||||
file.WriteBytes(stream_element.extra_data.data(), stream_element.extra_data.size());
|
|
||||||
if (written != stream_element.extra_data.size())
|
|
||||||
throw "Failed to write extra data";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.Tell() != header.stream_offset)
|
|
||||||
throw "Unexpected end of extra data";
|
|
||||||
|
|
||||||
// Write actual stream elements
|
|
||||||
for (const auto& stream_element : stream) {
|
|
||||||
if (1 != file.WriteObject(stream_element.data))
|
|
||||||
throw "Failed to write stream element";
|
|
||||||
}
|
|
||||||
} catch (const char* str) {
|
|
||||||
LOG_ERROR(HW_GPU, "Writing CiTrace file failed: {}", str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Recorder::FrameFinished() {
|
|
||||||
stream.push_back({{FrameMarker}});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Recorder::MemoryAccessed(const u8* data, u32 size, u32 physical_address) {
|
|
||||||
StreamElement element = {{MemoryLoad}};
|
|
||||||
element.data.memory_load.size = size;
|
|
||||||
element.data.memory_load.physical_address = physical_address;
|
|
||||||
|
|
||||||
// Compute hash over given memory region to check if the contents are already stored internally
|
|
||||||
boost::crc_32_type result;
|
|
||||||
result.process_bytes(data, size);
|
|
||||||
element.hash = result.checksum();
|
|
||||||
|
|
||||||
element.uses_existing_data = (memory_regions.find(element.hash) != memory_regions.end());
|
|
||||||
if (!element.uses_existing_data) {
|
|
||||||
element.extra_data.resize(size);
|
|
||||||
memcpy(element.extra_data.data(), data, size);
|
|
||||||
memory_regions.insert({element.hash, 0}); // file offset will be initialized in Finish()
|
|
||||||
}
|
|
||||||
|
|
||||||
stream.push_back(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void Recorder::RegisterWritten(u32 physical_address, T value) {
|
|
||||||
StreamElement element = {{RegisterWrite}};
|
|
||||||
element.data.register_write.size =
|
|
||||||
(sizeof(T) == 1) ? CTRegisterWrite::SIZE_8
|
|
||||||
: (sizeof(T) == 2) ? CTRegisterWrite::SIZE_16
|
|
||||||
: (sizeof(T) == 4) ? CTRegisterWrite::SIZE_32
|
|
||||||
: CTRegisterWrite::SIZE_64;
|
|
||||||
element.data.register_write.physical_address = physical_address;
|
|
||||||
element.data.register_write.value = value;
|
|
||||||
|
|
||||||
stream.push_back(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
template void Recorder::RegisterWritten(u32, u8);
|
|
||||||
template void Recorder::RegisterWritten(u32, u16);
|
|
||||||
template void Recorder::RegisterWritten(u32, u32);
|
|
||||||
template void Recorder::RegisterWritten(u32, u64);
|
|
||||||
} // namespace CiTrace
|
|
|
@ -1,87 +0,0 @@
|
||||||
// Copyright 2015 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
#include <boost/crc.hpp>
|
|
||||||
#include "common/common_types.h"
|
|
||||||
#include "core/tracer/citrace.h"
|
|
||||||
|
|
||||||
namespace CiTrace {
|
|
||||||
|
|
||||||
class Recorder {
|
|
||||||
public:
|
|
||||||
struct InitialState {
|
|
||||||
std::vector<u32> gpu_registers;
|
|
||||||
std::vector<u32> lcd_registers;
|
|
||||||
std::vector<u32> pica_registers;
|
|
||||||
std::vector<u32> default_attributes;
|
|
||||||
std::vector<u32> vs_program_binary;
|
|
||||||
std::vector<u32> vs_swizzle_data;
|
|
||||||
std::vector<u32> vs_float_uniforms;
|
|
||||||
std::vector<u32> gs_program_binary;
|
|
||||||
std::vector<u32> gs_swizzle_data;
|
|
||||||
std::vector<u32> gs_float_uniforms;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recorder constructor
|
|
||||||
* @param initial_state Initial recorder state
|
|
||||||
*/
|
|
||||||
explicit Recorder(const InitialState& initial_state);
|
|
||||||
|
|
||||||
/// Finish recording of this Citrace and save it using the given filename.
|
|
||||||
void Finish(const std::string& filename);
|
|
||||||
|
|
||||||
/// Mark end of a frame
|
|
||||||
void FrameFinished();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a copy of the given memory range in the recording.
|
|
||||||
* @note Use this whenever the GPU is about to access a particular memory region.
|
|
||||||
* @note The implementation will make sure to minimize redundant memory updates.
|
|
||||||
*/
|
|
||||||
void MemoryAccessed(const u8* data, u32 size, u32 physical_address);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Record a register write.
|
|
||||||
* @note Use this whenever a GPU-related MMIO register has been written to.
|
|
||||||
*/
|
|
||||||
template <typename T>
|
|
||||||
void RegisterWritten(u32 physical_address, T value);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Initial state of recording start
|
|
||||||
InitialState initial_state;
|
|
||||||
|
|
||||||
// Command stream
|
|
||||||
struct StreamElement {
|
|
||||||
CTStreamElement data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extra data to store along "core" data.
|
|
||||||
* This is e.g. used for data used in MemoryUpdates.
|
|
||||||
*/
|
|
||||||
std::vector<u8> extra_data;
|
|
||||||
|
|
||||||
/// Optional CRC hash (e.g. for hashing memory regions)
|
|
||||||
boost::crc_32_type::value_type hash;
|
|
||||||
|
|
||||||
/// If true, refer to data already written to the output file instead of extra_data
|
|
||||||
bool uses_existing_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<StreamElement> stream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal cache which maps hashes of memory contents to file offsets at which those memory
|
|
||||||
* contents are stored.
|
|
||||||
*/
|
|
||||||
std::unordered_map<boost::crc_32_type::value_type /*hash*/, u32 /*file_offset*/> memory_regions;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace CiTrace
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
#include "core/telemetry_session.h"
|
#include "core/telemetry_session.h"
|
||||||
#include "core/tracer/recorder.h"
|
|
||||||
#include "video_core/morton.h"
|
#include "video_core/morton.h"
|
||||||
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
||||||
#include "video_core/renderer_opengl/renderer_opengl.h"
|
#include "video_core/renderer_opengl/renderer_opengl.h"
|
||||||
|
|
Reference in New Issue