diff --git a/src/xenia/gpu/command_processor.cc b/src/xenia/gpu/command_processor.cc index 6ab30e22e..e44193e45 100644 --- a/src/xenia/gpu/command_processor.cc +++ b/src/xenia/gpu/command_processor.cc @@ -468,13 +468,14 @@ bool CommandProcessor::ExecutePacketType0(RingBuffer* reader, uint32_t packet) { // (base_index << 2). uint32_t count = ((packet >> 16) & 0x3FFF) + 1; - trace_writer_.WritePacketStart(uint32_t(reader->read_ptr() - 4), 1 + count); if (reader->read_count() < count * sizeof(uint32_t)) { XELOGE("ExecutePacketType0 overflow (read count %.8X, packet count %.8X)", reader->read_count(), count * sizeof(uint32_t)); return false; } + trace_writer_.WritePacketStart(uint32_t(reader->read_ptr() - 4), 1 + count); + uint32_t base_index = (packet & 0x7FFF); uint32_t write_one_reg = (packet >> 15) & 0x1; for (uint32_t m = 0; m < count; m++) { @@ -662,6 +663,25 @@ bool CommandProcessor::ExecutePacketType3(RingBuffer* reader, uint32_t packet) { } trace_writer_.WritePacketEnd(); + if (opcode == PM4_XE_SWAP) { + // End the trace writer frame. + if (trace_writer_.is_open()) { + trace_writer_.WriteEvent(EventCommand::Type::kSwap); + trace_writer_.Flush(); + if (trace_state_ == TraceState::kSingleFrame) { + trace_state_ = TraceState::kDisabled; + trace_writer_.Close(); + } + } else if (trace_state_ == TraceState::kSingleFrame) { + // New trace request - we only start tracing at the beginning of a frame. + uint32_t title_id = kernel_state_->GetExecutableModule()->title_id(); + auto file_name = xe::format_string(L"title_%8X_frame_%u.xenia_gpu_trace", + title_id, counter_ - 1); + auto path = trace_frame_path_ + file_name; + trace_writer_.Open(path, title_id); + } + } + assert_true(reader->read_offset() == (data_start_offset + (count * sizeof(uint32_t))) % reader->capacity()); @@ -725,21 +745,6 @@ bool CommandProcessor::ExecutePacketType3_XE_SWAP(RingBuffer* reader, IssueSwap(frontbuffer_ptr, frontbuffer_width, frontbuffer_height); } - if (trace_writer_.is_open()) { - trace_writer_.WriteEvent(EventCommand::Type::kSwap); - trace_writer_.Flush(); - if (trace_state_ == TraceState::kSingleFrame) { - trace_state_ = TraceState::kDisabled; - trace_writer_.Close(); - } - } else if (trace_state_ == TraceState::kSingleFrame) { - // New trace request - we only start tracing at the beginning of a frame. - uint32_t title_id = kernel_state_->GetExecutableModule()->title_id(); - auto file_name = xe::format_string(L"title_%8X_frame_%u.xenia_gpu_trace", - title_id, counter_); - auto path = trace_frame_path_ + file_name; - trace_writer_.Open(path, title_id); - } ++counter_; return true; } diff --git a/src/xenia/gpu/trace_dump.cc b/src/xenia/gpu/trace_dump.cc index c45d170cf..17471732d 100644 --- a/src/xenia/gpu/trace_dump.cc +++ b/src/xenia/gpu/trace_dump.cc @@ -51,10 +51,8 @@ int TraceDump::Main(const std::vector& args) { } else if (args.size() >= 2) { // Passed as an unnamed argument. path = args[1]; - } - - // If no path passed, ask the user. - if (path.empty()) { + } else { + // Open a file chooser and ask the user. auto file_picker = xe::ui::FilePicker::Create(); file_picker->set_mode(ui::FilePicker::Mode::kOpen); file_picker->set_type(ui::FilePicker::Type::kFile); diff --git a/src/xenia/gpu/trace_reader.cc b/src/xenia/gpu/trace_reader.cc index 6bedfb9b4..caa4d1e26 100644 --- a/src/xenia/gpu/trace_reader.cc +++ b/src/xenia/gpu/trace_reader.cc @@ -151,7 +151,17 @@ void TraceReader::ParseTrace() { uint32_t(current_frame.commands.size() - 1))); break; } - case PacketCategory::kSwap: + case PacketCategory::kSwap: { + Frame::Command command; + command.type = Frame::Command::Type::kSwap; + command.head_ptr = packet_start_ptr; + command.start_ptr = last_ptr; + command.end_ptr = trace_ptr; + current_frame.commands.push_back(std::move(command)); + last_ptr = trace_ptr; + current_command_buffer->commands.push_back(CommandBuffer::Command( + uint32_t(current_frame.commands.size() - 1))); + } break; case PacketCategory::kGeneric: { // Ignored. break;