TraceViewer: Build a tree of all command buffers and display that instead of a flat list.
This commit is contained in:
parent
6101b70641
commit
cbccc785cc
|
@ -51,7 +51,7 @@ void TracePlayer::SeekFrame(int target_frame) {
|
||||||
|
|
||||||
assert_true(frame->start_ptr <= frame->end_ptr);
|
assert_true(frame->start_ptr <= frame->end_ptr);
|
||||||
PlayTrace(frame->start_ptr, frame->end_ptr - frame->start_ptr,
|
PlayTrace(frame->start_ptr, frame->end_ptr - frame->start_ptr,
|
||||||
TracePlaybackMode::kBreakOnSwap);
|
TracePlaybackMode::kBreakOnSwap, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TracePlayer::SeekCommand(int target_command) {
|
void TracePlayer::SeekCommand(int target_command) {
|
||||||
|
@ -71,11 +71,11 @@ void TracePlayer::SeekCommand(int target_command) {
|
||||||
const auto& previous_command = frame->commands[previous_command_index];
|
const auto& previous_command = frame->commands[previous_command_index];
|
||||||
PlayTrace(previous_command.end_ptr,
|
PlayTrace(previous_command.end_ptr,
|
||||||
command.end_ptr - previous_command.end_ptr,
|
command.end_ptr - previous_command.end_ptr,
|
||||||
TracePlaybackMode::kBreakOnSwap);
|
TracePlaybackMode::kBreakOnSwap, false);
|
||||||
} else {
|
} else {
|
||||||
// Full playback from frame start.
|
// Full playback from frame start.
|
||||||
PlayTrace(frame->start_ptr, command.end_ptr - frame->start_ptr,
|
PlayTrace(frame->start_ptr, command.end_ptr - frame->start_ptr,
|
||||||
TracePlaybackMode::kBreakOnSwap);
|
TracePlaybackMode::kBreakOnSwap, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,19 +84,25 @@ void TracePlayer::WaitOnPlayback() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TracePlayer::PlayTrace(const uint8_t* trace_data, size_t trace_size,
|
void TracePlayer::PlayTrace(const uint8_t* trace_data, size_t trace_size,
|
||||||
TracePlaybackMode playback_mode) {
|
TracePlaybackMode playback_mode,
|
||||||
graphics_system_->command_processor()->CallInThread(
|
bool clear_caches) {
|
||||||
[this, trace_data, trace_size, playback_mode]() {
|
playing_trace_ = true;
|
||||||
PlayTraceOnThread(trace_data, trace_size, playback_mode);
|
graphics_system_->command_processor()->CallInThread([=]() {
|
||||||
|
PlayTraceOnThread(trace_data, trace_size, playback_mode, clear_caches);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void TracePlayer::PlayTraceOnThread(const uint8_t* trace_data,
|
void TracePlayer::PlayTraceOnThread(const uint8_t* trace_data,
|
||||||
size_t trace_size,
|
size_t trace_size,
|
||||||
TracePlaybackMode playback_mode) {
|
TracePlaybackMode playback_mode,
|
||||||
|
bool clear_caches) {
|
||||||
auto memory = graphics_system_->memory();
|
auto memory = graphics_system_->memory();
|
||||||
auto command_processor = graphics_system_->command_processor();
|
auto command_processor = graphics_system_->command_processor();
|
||||||
|
|
||||||
|
if (clear_caches) {
|
||||||
|
command_processor->ClearCaches();
|
||||||
|
}
|
||||||
|
|
||||||
command_processor->set_swap_mode(SwapMode::kIgnored);
|
command_processor->set_swap_mode(SwapMode::kIgnored);
|
||||||
playback_percent_ = 0;
|
playback_percent_ = 0;
|
||||||
auto trace_end = trace_data + trace_size;
|
auto trace_end = trace_data + trace_size;
|
||||||
|
|
|
@ -50,9 +50,9 @@ class TracePlayer : public TraceReader {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void PlayTrace(const uint8_t* trace_data, size_t trace_size,
|
void PlayTrace(const uint8_t* trace_data, size_t trace_size,
|
||||||
TracePlaybackMode playback_mode);
|
TracePlaybackMode playback_mode, bool clear_caches);
|
||||||
void PlayTraceOnThread(const uint8_t* trace_data, size_t trace_size,
|
void PlayTraceOnThread(const uint8_t* trace_data, size_t trace_size,
|
||||||
TracePlaybackMode playback_mode);
|
TracePlaybackMode playback_mode, bool clear_caches);
|
||||||
|
|
||||||
xe::ui::Loop* loop_;
|
xe::ui::Loop* loop_;
|
||||||
GraphicsSystem* graphics_system_;
|
GraphicsSystem* graphics_system_;
|
||||||
|
|
|
@ -75,6 +75,10 @@ void TraceReader::ParseTrace() {
|
||||||
const uint8_t* packet_start_ptr = nullptr;
|
const uint8_t* packet_start_ptr = nullptr;
|
||||||
const uint8_t* last_ptr = trace_ptr;
|
const uint8_t* last_ptr = trace_ptr;
|
||||||
bool pending_break = false;
|
bool pending_break = false;
|
||||||
|
auto current_command_buffer = new CommandBuffer();
|
||||||
|
current_frame.command_tree =
|
||||||
|
std::unique_ptr<CommandBuffer>(current_command_buffer);
|
||||||
|
|
||||||
while (trace_ptr < trace_data_ + trace_size_) {
|
while (trace_ptr < trace_data_ + trace_size_) {
|
||||||
++current_frame.command_count;
|
++current_frame.command_count;
|
||||||
auto type = static_cast<TraceCommandType>(xe::load<uint32_t>(trace_ptr));
|
auto type = static_cast<TraceCommandType>(xe::load<uint32_t>(trace_ptr));
|
||||||
|
@ -94,11 +98,24 @@ void TraceReader::ParseTrace() {
|
||||||
auto cmd =
|
auto cmd =
|
||||||
reinterpret_cast<const IndirectBufferStartCommand*>(trace_ptr);
|
reinterpret_cast<const IndirectBufferStartCommand*>(trace_ptr);
|
||||||
trace_ptr += sizeof(*cmd) + cmd->count * 4;
|
trace_ptr += sizeof(*cmd) + cmd->count * 4;
|
||||||
|
|
||||||
|
// Traverse down a level.
|
||||||
|
auto sub_command_buffer = new CommandBuffer();
|
||||||
|
sub_command_buffer->parent = current_command_buffer;
|
||||||
|
current_command_buffer->commands.push_back(
|
||||||
|
CommandBuffer::Command(sub_command_buffer));
|
||||||
|
current_command_buffer = sub_command_buffer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TraceCommandType::kIndirectBufferEnd: {
|
case TraceCommandType::kIndirectBufferEnd: {
|
||||||
auto cmd = reinterpret_cast<const IndirectBufferEndCommand*>(trace_ptr);
|
auto cmd = reinterpret_cast<const IndirectBufferEndCommand*>(trace_ptr);
|
||||||
trace_ptr += sizeof(*cmd);
|
trace_ptr += sizeof(*cmd);
|
||||||
|
|
||||||
|
// Go back up a level. If parent is null, this frame started in an
|
||||||
|
// indirect buffer.
|
||||||
|
if (current_command_buffer->parent) {
|
||||||
|
current_command_buffer = current_command_buffer->parent;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TraceCommandType::kPacketStart: {
|
case TraceCommandType::kPacketStart: {
|
||||||
|
@ -125,6 +142,8 @@ void TraceReader::ParseTrace() {
|
||||||
command.end_ptr = trace_ptr;
|
command.end_ptr = trace_ptr;
|
||||||
current_frame.commands.push_back(std::move(command));
|
current_frame.commands.push_back(std::move(command));
|
||||||
last_ptr = trace_ptr;
|
last_ptr = trace_ptr;
|
||||||
|
current_command_buffer->commands.push_back(CommandBuffer::Command(
|
||||||
|
uint32_t(current_frame.commands.size() - 1)));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PacketCategory::kSwap:
|
case PacketCategory::kSwap:
|
||||||
|
@ -136,6 +155,9 @@ void TraceReader::ParseTrace() {
|
||||||
if (pending_break) {
|
if (pending_break) {
|
||||||
current_frame.end_ptr = trace_ptr;
|
current_frame.end_ptr = trace_ptr;
|
||||||
frames_.push_back(std::move(current_frame));
|
frames_.push_back(std::move(current_frame));
|
||||||
|
current_command_buffer = new CommandBuffer();
|
||||||
|
current_frame.command_tree =
|
||||||
|
std::unique_ptr<CommandBuffer>(current_command_buffer);
|
||||||
current_frame.start_ptr = trace_ptr;
|
current_frame.start_ptr = trace_ptr;
|
||||||
current_frame.end_ptr = nullptr;
|
current_frame.end_ptr = nullptr;
|
||||||
current_frame.command_count = 0;
|
current_frame.command_count = 0;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define XENIA_GPU_TRACE_READER_H_
|
#define XENIA_GPU_TRACE_READER_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "xenia/base/mapped_memory.h"
|
#include "xenia/base/mapped_memory.h"
|
||||||
#include "xenia/gpu/trace_protocol.h"
|
#include "xenia/gpu/trace_protocol.h"
|
||||||
|
@ -51,6 +52,42 @@ namespace gpu {
|
||||||
|
|
||||||
class TraceReader {
|
class TraceReader {
|
||||||
public:
|
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 Frame {
|
||||||
struct Command {
|
struct Command {
|
||||||
enum class Type {
|
enum class Type {
|
||||||
|
@ -74,7 +111,12 @@ class TraceReader {
|
||||||
const uint8_t* start_ptr = nullptr;
|
const uint8_t* start_ptr = nullptr;
|
||||||
const uint8_t* end_ptr = nullptr;
|
const uint8_t* end_ptr = nullptr;
|
||||||
int command_count = 0;
|
int command_count = 0;
|
||||||
|
|
||||||
|
// Flat list of all commands in this frame.
|
||||||
std::vector<Command> commands;
|
std::vector<Command> commands;
|
||||||
|
|
||||||
|
// Tree of all command buffers
|
||||||
|
std::unique_ptr<CommandBuffer> command_tree;
|
||||||
};
|
};
|
||||||
|
|
||||||
TraceReader() = default;
|
TraceReader() = default;
|
||||||
|
|
|
@ -390,6 +390,66 @@ void TraceViewer::DrawPacketDisassemblerUI() {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int TraceViewer::RecursiveDrawCommandBufferUI(
|
||||||
|
const TraceReader::Frame* frame, TraceReader::CommandBuffer* buffer) {
|
||||||
|
int selected_id = -1;
|
||||||
|
int column_width = int(ImGui::GetContentRegionMax().x);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < buffer->commands.size(); i++) {
|
||||||
|
switch (buffer->commands[i].type) {
|
||||||
|
case TraceReader::CommandBuffer::Command::Type::kBuffer: {
|
||||||
|
auto subtree = buffer->commands[i].command_subtree.get();
|
||||||
|
if (!subtree->commands.size()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PushID(int(i));
|
||||||
|
if (ImGui::TreeNode((void*)0, "Indirect Buffer %d", i)) {
|
||||||
|
ImGui::Indent();
|
||||||
|
auto id = RecursiveDrawCommandBufferUI(
|
||||||
|
frame, buffer->commands[i].command_subtree.get());
|
||||||
|
ImGui::Unindent();
|
||||||
|
ImGui::TreePop();
|
||||||
|
|
||||||
|
if (id != -1) {
|
||||||
|
selected_id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case TraceReader::CommandBuffer::Command::Type::kCommand: {
|
||||||
|
uint32_t command_id = buffer->commands[i].command_id;
|
||||||
|
|
||||||
|
const auto& command = frame->commands[command_id];
|
||||||
|
bool is_selected = command_id == player_->current_command_index();
|
||||||
|
const char* label;
|
||||||
|
switch (command.type) {
|
||||||
|
case TraceReader::Frame::Command::Type::kDraw:
|
||||||
|
label = "Draw";
|
||||||
|
break;
|
||||||
|
case TraceReader::Frame::Command::Type::kSwap:
|
||||||
|
label = "Swap";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PushID(command_id);
|
||||||
|
if (ImGui::Selectable(label, &is_selected)) {
|
||||||
|
selected_id = command_id;
|
||||||
|
}
|
||||||
|
ImGui::SameLine(column_width - 60.0f);
|
||||||
|
ImGui::Text("%d", command_id);
|
||||||
|
ImGui::PopID();
|
||||||
|
// if (did_seek && target_command == i) {
|
||||||
|
// ImGui::SetScrollPosHere();
|
||||||
|
// }
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return selected_id;
|
||||||
|
}
|
||||||
|
|
||||||
void TraceViewer::DrawCommandListUI() {
|
void TraceViewer::DrawCommandListUI() {
|
||||||
ImGui::SetNextWindowPos(ImVec2(5, 70), ImGuiSetCond_FirstUseEver);
|
ImGui::SetNextWindowPos(ImVec2(5, 70), ImGuiSetCond_FirstUseEver);
|
||||||
if (!ImGui::Begin("Command List", nullptr, ImVec2(200, 640))) {
|
if (!ImGui::Begin("Command List", nullptr, ImVec2(200, 640))) {
|
||||||
|
@ -473,31 +533,12 @@ void TraceViewer::DrawCommandListUI() {
|
||||||
ImGui::SetScrollPosHere();
|
ImGui::SetScrollPosHere();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < int(frame->commands.size()); ++i) {
|
auto id = RecursiveDrawCommandBufferUI(frame, frame->command_tree.get());
|
||||||
ImGui::PushID(i);
|
if (id != -1 && id != player_->current_command_index() &&
|
||||||
is_selected = i == player_->current_command_index();
|
!player_->is_playing_trace()) {
|
||||||
const auto& command = frame->commands[i];
|
player_->SeekCommand(id);
|
||||||
const char* label;
|
|
||||||
switch (command.type) {
|
|
||||||
case TraceReader::Frame::Command::Type::kDraw:
|
|
||||||
label = "Draw";
|
|
||||||
break;
|
|
||||||
case TraceReader::Frame::Command::Type::kSwap:
|
|
||||||
label = "Swap";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (ImGui::Selectable(label, &is_selected)) {
|
|
||||||
if (!player_->is_playing_trace()) {
|
|
||||||
player_->SeekCommand(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ImGui::SameLine(column_width - 60.0f);
|
|
||||||
ImGui::Text("%d", i);
|
|
||||||
ImGui::PopID();
|
|
||||||
if (did_seek && target_command == i) {
|
|
||||||
ImGui::SetScrollPosHere();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
@ -639,8 +680,8 @@ void TraceViewer::DrawTextureInfo(
|
||||||
|
|
||||||
ImGui::Columns(2);
|
ImGui::Columns(2);
|
||||||
ImVec2 button_size(256, 256);
|
ImVec2 button_size(256, 256);
|
||||||
if (ImGui::ImageButton(ImTextureID(texture | ui::ImGuiDrawer::kIgnoreAlpha),
|
if (ImGui::ImageButton(ImTextureID(texture), button_size, ImVec2(0, 0),
|
||||||
button_size, ImVec2(0, 0), ImVec2(1, 1))) {
|
ImVec2(1, 1))) {
|
||||||
// show viewer
|
// show viewer
|
||||||
}
|
}
|
||||||
ImGui::NextColumn();
|
ImGui::NextColumn();
|
||||||
|
@ -1108,11 +1149,14 @@ void TraceViewer::DrawStateUI() {
|
||||||
((window_scissor_br >> 16) & 0x7FFF) -
|
((window_scissor_br >> 16) & 0x7FFF) -
|
||||||
((window_scissor_tl >> 16) & 0x7FFF));
|
((window_scissor_tl >> 16) & 0x7FFF));
|
||||||
uint32_t surface_info = regs[XE_GPU_REG_RB_SURFACE_INFO].u32;
|
uint32_t surface_info = regs[XE_GPU_REG_RB_SURFACE_INFO].u32;
|
||||||
|
uint32_t surface_actual = (surface_info >> 18) & 0x3FFF;
|
||||||
uint32_t surface_pitch = surface_info & 0x3FFF;
|
uint32_t surface_pitch = surface_info & 0x3FFF;
|
||||||
auto surface_msaa = (surface_info >> 16) & 0x3;
|
auto surface_msaa = (surface_info >> 16) & 0x3;
|
||||||
static const char* kMsaaNames[] = {
|
static const char* kMsaaNames[] = {
|
||||||
"1X", "2X", "4X",
|
"1X", "2X", "4X",
|
||||||
};
|
};
|
||||||
|
ImGui::BulletText("Surface Pitch - Actual: %d - %d", surface_pitch,
|
||||||
|
surface_actual);
|
||||||
ImGui::BulletText("Surface MSAA: %s", kMsaaNames[surface_msaa]);
|
ImGui::BulletText("Surface MSAA: %s", kMsaaNames[surface_msaa]);
|
||||||
uint32_t vte_control = regs[XE_GPU_REG_PA_CL_VTE_CNTL].u32;
|
uint32_t vte_control = regs[XE_GPU_REG_PA_CL_VTE_CNTL].u32;
|
||||||
bool vport_xscale_enable = (vte_control & (1 << 0)) > 0;
|
bool vport_xscale_enable = (vte_control & (1 << 0)) > 0;
|
||||||
|
@ -1124,6 +1168,9 @@ void TraceViewer::DrawStateUI() {
|
||||||
assert_true(vport_xscale_enable == vport_yscale_enable ==
|
assert_true(vport_xscale_enable == vport_yscale_enable ==
|
||||||
vport_zscale_enable == vport_xoffset_enable ==
|
vport_zscale_enable == vport_xoffset_enable ==
|
||||||
vport_yoffset_enable == vport_zoffset_enable);
|
vport_yoffset_enable == vport_zoffset_enable);
|
||||||
|
if (!vport_xscale_enable) {
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, kColorIgnored);
|
||||||
|
}
|
||||||
ImGui::BulletText(
|
ImGui::BulletText(
|
||||||
"Viewport Offset: %f, %f, %f",
|
"Viewport Offset: %f, %f, %f",
|
||||||
vport_xoffset_enable ? regs[XE_GPU_REG_PA_CL_VPORT_XOFFSET].f32 : 0,
|
vport_xoffset_enable ? regs[XE_GPU_REG_PA_CL_VPORT_XOFFSET].f32 : 0,
|
||||||
|
@ -1134,6 +1181,10 @@ void TraceViewer::DrawStateUI() {
|
||||||
vport_xscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32 : 1,
|
vport_xscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_XSCALE].f32 : 1,
|
||||||
vport_yscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_YSCALE].f32 : 1,
|
vport_yscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_YSCALE].f32 : 1,
|
||||||
vport_zscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32 : 1);
|
vport_zscale_enable ? regs[XE_GPU_REG_PA_CL_VPORT_ZSCALE].f32 : 1);
|
||||||
|
if (!vport_xscale_enable) {
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::BulletText("Vertex Format: %s, %s, %s, %s",
|
ImGui::BulletText("Vertex Format: %s, %s, %s, %s",
|
||||||
((vte_control >> 8) & 0x1) ? "x/w0" : "x",
|
((vte_control >> 8) & 0x1) ? "x/w0" : "x",
|
||||||
((vte_control >> 8) & 0x1) ? "y/w0" : "y",
|
((vte_control >> 8) & 0x1) ? "y/w0" : "y",
|
||||||
|
@ -1318,7 +1369,7 @@ void TraceViewer::DrawStateUI() {
|
||||||
if (write_mask) {
|
if (write_mask) {
|
||||||
auto color_target = GetColorRenderTarget(surface_pitch, surface_msaa,
|
auto color_target = GetColorRenderTarget(surface_pitch, surface_msaa,
|
||||||
color_base, color_format);
|
color_base, color_format);
|
||||||
tex = ImTextureID(color_target | ui::ImGuiDrawer::kIgnoreAlpha);
|
tex = ImTextureID(color_target);
|
||||||
if (ImGui::ImageButton(tex, button_size, ImVec2(0, 0),
|
if (ImGui::ImageButton(tex, button_size, ImVec2(0, 0),
|
||||||
ImVec2(1, 1))) {
|
ImVec2(1, 1))) {
|
||||||
// show viewer
|
// show viewer
|
||||||
|
@ -1330,10 +1381,9 @@ void TraceViewer::DrawStateUI() {
|
||||||
}
|
}
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
ImGui::Text(
|
ImGui::Text("Color Target %d (%s), base %.4X, pitch %d, format %d", i,
|
||||||
"Color Target %d (%s), base %.4X, pitch %d, msaa %d, format %d",
|
write_mask ? "enabled" : "disabled", color_base,
|
||||||
i, write_mask ? "enabled" : "disabled", color_base, surface_pitch,
|
surface_pitch, color_format);
|
||||||
surface_msaa, color_format);
|
|
||||||
|
|
||||||
if (tex) {
|
if (tex) {
|
||||||
ImVec2 rel_pos;
|
ImVec2 rel_pos;
|
||||||
|
@ -1407,17 +1457,19 @@ void TraceViewer::DrawStateUI() {
|
||||||
|
|
||||||
auto button_pos = ImGui::GetCursorScreenPos();
|
auto button_pos = ImGui::GetCursorScreenPos();
|
||||||
ImVec2 button_size(256, 256);
|
ImVec2 button_size(256, 256);
|
||||||
ImGui::ImageButton(
|
ImGui::ImageButton(ImTextureID(depth_target), button_size, ImVec2(0, 0),
|
||||||
ImTextureID(depth_target | ui::ImGuiDrawer::kIgnoreAlpha),
|
ImVec2(1, 1));
|
||||||
button_size, ImVec2(0, 0), ImVec2(1, 1));
|
|
||||||
if (ImGui::IsItemHovered()) {
|
if (ImGui::IsItemHovered()) {
|
||||||
ImGui::BeginTooltip();
|
ImGui::BeginTooltip();
|
||||||
|
|
||||||
|
ImGui::Text("Depth Target: base %.4X, pitch %d, format %d", depth_base,
|
||||||
|
surface_pitch, depth_format);
|
||||||
|
|
||||||
ImVec2 rel_pos;
|
ImVec2 rel_pos;
|
||||||
rel_pos.x = ImGui::GetMousePos().x - button_pos.x;
|
rel_pos.x = ImGui::GetMousePos().x - button_pos.x;
|
||||||
rel_pos.y = ImGui::GetMousePos().y - button_pos.y;
|
rel_pos.y = ImGui::GetMousePos().y - button_pos.y;
|
||||||
ZoomedImage(ImTextureID(depth_target | ui::ImGuiDrawer::kIgnoreAlpha),
|
ZoomedImage(ImTextureID(depth_target), rel_pos, button_size, 32.f,
|
||||||
rel_pos, button_size, 32.f, ImVec2(256, 256));
|
ImVec2(256, 256));
|
||||||
|
|
||||||
ImGui::EndTooltip();
|
ImGui::EndTooltip();
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,8 @@ class TraceViewer {
|
||||||
void DrawUI();
|
void DrawUI();
|
||||||
void DrawControllerUI();
|
void DrawControllerUI();
|
||||||
void DrawPacketDisassemblerUI();
|
void DrawPacketDisassemblerUI();
|
||||||
|
int RecursiveDrawCommandBufferUI(const TraceReader::Frame* frame,
|
||||||
|
TraceReader::CommandBuffer* buffer);
|
||||||
void DrawCommandListUI();
|
void DrawCommandListUI();
|
||||||
void DrawStateUI();
|
void DrawStateUI();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue