Files
Xenia-Canary/src/xenia/gpu/trace_reader.h

151 lines
3.8 KiB
C++

/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2020 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/
#ifndef XENIA_GPU_TRACE_READER_H_
#define XENIA_GPU_TRACE_READER_H_
#include <string>
#include <vector>
#include "xenia/base/mapped_memory.h"
#include "xenia/gpu/trace_protocol.h"
#include "xenia/memory.h"
namespace xe {
namespace gpu {
// void Foo() {
// auto trace_ptr = trace_data;
// while (trace_ptr < trace_data + trace_size) {
// auto cmd_type = *reinterpret_cast<const TraceCommandType*>(trace_ptr);
// switch (cmd_type) {
// case TraceCommandType::kPrimaryBufferStart:
// break;
// case TraceCommandType::kPrimaryBufferEnd:
// break;
// case TraceCommandType::kIndirectBufferStart:
// break;
// case TraceCommandType::kIndirectBufferEnd:
// break;
// case TraceCommandType::kPacketStart:
// break;
// case TraceCommandType::kPacketEnd:
// break;
// case TraceCommandType::kMemoryRead:
// break;
// case TraceCommandType::kMemoryWrite:
// break;
// case TraceCommandType::kEvent:
// break;
// }
// /*trace_ptr = graphics_system->PlayTrace(
// trace_ptr, trace_size - (trace_ptr - trace_data),
// GraphicsSystem::TracePlaybackMode::kBreakOnSwap);*/
// }
//}
class TraceReader {
public:
struct CommandBuffer {
struct Command {
enum class Type {
kCommand,
kBuffer,
};
Command() {}
Command(Command&& other) {
type = other.type;
command_id = other.command_id;
command_subtree = std::move(other.command_subtree);
}
Command(CommandBuffer* buf) {
type = Type::kBuffer;
command_subtree = std::unique_ptr<CommandBuffer>(buf);
}
Command(uint32_t id) {
type = Type::kCommand;
command_id = id;
}
~Command() = default;
Type type;
uint32_t command_id = -1;
std::unique_ptr<CommandBuffer> command_subtree = nullptr;
};
CommandBuffer() {}
~CommandBuffer() {}
// Parent command buffer, if one exists.
CommandBuffer* parent = nullptr;
std::vector<Command> commands;
};
struct Frame {
struct Command {
enum class Type {
kDraw,
kSwap,
};
const uint8_t* head_ptr;
const uint8_t* start_ptr;
const uint8_t* end_ptr;
Type type;
union {
struct {
//
} draw;
struct {
//
} swap;
};
};
const uint8_t* start_ptr = nullptr;
const uint8_t* end_ptr = nullptr;
int command_count = 0;
// Flat list of all commands in this frame.
std::vector<Command> commands;
// Tree of all command buffers
std::unique_ptr<CommandBuffer> command_tree;
};
TraceReader() = default;
virtual ~TraceReader() = default;
const TraceHeader* header() const {
return reinterpret_cast<const TraceHeader*>(trace_data_);
}
const Frame* frame(int n) const { return &frames_[n]; }
int frame_count() const { return int(frames_.size()); }
bool Open(const std::filesystem::path& path);
void Close();
protected:
void ParseTrace();
bool DecompressMemory(MemoryEncodingFormat encoding_format, const void* src,
size_t src_size, void* dest, size_t dest_size);
std::unique_ptr<MappedMemory> mmap_;
const uint8_t* trace_data_ = nullptr;
size_t trace_size_ = 0;
std::vector<Frame> frames_;
};
} // namespace gpu
} // namespace xe
#endif // XENIA_GPU_TRACE_READER_H_