/** ****************************************************************************** * 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 #include #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(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(buf); } Command(uint32_t id) { type = Type::kCommand; command_id = id; } ~Command() = default; Type type; uint32_t command_id = -1; std::unique_ptr command_subtree = nullptr; }; CommandBuffer() {} ~CommandBuffer() {} // Parent command buffer, if one exists. CommandBuffer* parent = nullptr; std::vector 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 commands; // Tree of all command buffers std::unique_ptr command_tree; }; TraceReader() = default; virtual ~TraceReader() = default; const TraceHeader* header() const { return reinterpret_cast(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 mmap_; const uint8_t* trace_data_ = nullptr; size_t trace_size_ = 0; std::vector frames_; }; } // namespace gpu } // namespace xe #endif // XENIA_GPU_TRACE_READER_H_