mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-05 10:13:15 +00:00
More devtools stuff (#1637)
* devtools: memory map viewer * devtools: batch highlight only for non-group viewer * devtools: fix not showing entire user data * devtools: shader debug viewer * devtools: add more reg naming
This commit is contained in:
parent
f658fc58d1
commit
0835dc71b3
18 changed files with 491 additions and 65 deletions
|
@ -289,6 +289,16 @@ const char* GetContextRegName(u32 reg_offset) {
|
|||
return "mmSPI_PS_INPUT_CNTL_2";
|
||||
case mmSPI_PS_INPUT_CNTL_3:
|
||||
return "mmSPI_PS_INPUT_CNTL_3";
|
||||
case mmPA_SU_POLY_OFFSET_FRONT_SCALE:
|
||||
return "mmPA_SU_POLY_OFFSET_FRONT_SCALE";
|
||||
case mmPA_SU_POLY_OFFSET_FRONT_OFFSET:
|
||||
return "mmPA_SU_POLY_OFFSET_FRONT_OFFSET";
|
||||
case mmPA_SU_POLY_OFFSET_BACK_SCALE:
|
||||
return "mmPA_SU_POLY_OFFSET_BACK_SCALE";
|
||||
case mmPA_SU_POLY_OFFSET_BACK_OFFSET:
|
||||
return "mmPA_SU_POLY_OFFSET_BACK_OFFSET";
|
||||
case mmPA_SU_POLY_OFFSET_CLAMP:
|
||||
return "mmPA_SU_POLY_OFFSET_CLAMP";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "layer.h"
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "common/config.h"
|
||||
|
@ -9,11 +11,12 @@
|
|||
#include "core/debug_state.h"
|
||||
#include "imgui/imgui_std.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "layer.h"
|
||||
#include "options.h"
|
||||
#include "video_core/renderer_vulkan/vk_presenter.h"
|
||||
#include "widget/frame_dump.h"
|
||||
#include "widget/frame_graph.h"
|
||||
#include "widget/memory_map.h"
|
||||
#include "widget/shader_list.h"
|
||||
|
||||
extern std::unique_ptr<Vulkan::Presenter> presenter;
|
||||
|
||||
|
@ -35,6 +38,9 @@ static float debug_popup_timing = 3.0f;
|
|||
|
||||
static bool just_opened_options = false;
|
||||
|
||||
static Widget::MemoryMapViewer memory_map;
|
||||
static Widget::ShaderList shader_list;
|
||||
|
||||
// clang-format off
|
||||
static std::string help_text =
|
||||
#include "help.txt"
|
||||
|
@ -63,6 +69,7 @@ void L::DrawMenuBar() {
|
|||
}
|
||||
if (BeginMenu("GPU Tools")) {
|
||||
MenuItem("Show frame info", nullptr, &frame_graph.is_open);
|
||||
MenuItem("Show loaded shaders", nullptr, &shader_list.open);
|
||||
if (BeginMenu("Dump frames")) {
|
||||
SliderInt("Count", &dump_frame_count, 1, 5);
|
||||
if (MenuItem("Dump", "Ctrl+Alt+F9", nullptr, !DebugState.DumpingCurrentFrame())) {
|
||||
|
@ -81,6 +88,12 @@ void L::DrawMenuBar() {
|
|||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
if (BeginMenu("Debug")) {
|
||||
if (MenuItem("Memory map")) {
|
||||
memory_map.open = true;
|
||||
}
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
EndMainMenuBar();
|
||||
}
|
||||
|
||||
|
@ -175,19 +188,29 @@ void L::DrawAdvanced() {
|
|||
bool close_popup_options = true;
|
||||
if (BeginPopupModal("GPU Tools Options", &close_popup_options,
|
||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) {
|
||||
static char disassembly_cli[512];
|
||||
static char disassembler_cli_isa[512];
|
||||
static char disassembler_cli_spv[512];
|
||||
static bool frame_dump_render_on_collapse;
|
||||
|
||||
if (just_opened_options) {
|
||||
just_opened_options = false;
|
||||
auto s = Options.disassembly_cli.copy(disassembly_cli, sizeof(disassembly_cli) - 1);
|
||||
disassembly_cli[s] = '\0';
|
||||
auto s = Options.disassembler_cli_isa.copy(disassembler_cli_isa,
|
||||
sizeof(disassembler_cli_isa) - 1);
|
||||
disassembler_cli_isa[s] = '\0';
|
||||
s = Options.disassembler_cli_spv.copy(disassembler_cli_spv,
|
||||
sizeof(disassembler_cli_spv) - 1);
|
||||
disassembler_cli_spv[s] = '\0';
|
||||
frame_dump_render_on_collapse = Options.frame_dump_render_on_collapse;
|
||||
}
|
||||
|
||||
InputText("Shader disassembler: ", disassembly_cli, sizeof(disassembly_cli));
|
||||
InputText("Shader isa disassembler: ", disassembler_cli_isa, sizeof(disassembler_cli_isa));
|
||||
if (IsItemHovered()) {
|
||||
SetTooltip(R"(Command to disassemble shaders. Example "dis.exe" --raw "{src}")");
|
||||
SetTooltip(R"(Command to disassemble shaders. Example: dis.exe --raw "{src}")");
|
||||
}
|
||||
InputText("Shader SPIRV disassembler: ", disassembler_cli_spv,
|
||||
sizeof(disassembler_cli_spv));
|
||||
if (IsItemHovered()) {
|
||||
SetTooltip(R"(Command to disassemble shaders. Example: spirv-cross -V "{src}")");
|
||||
}
|
||||
Checkbox("Show frame dump popups even when collapsed", &frame_dump_render_on_collapse);
|
||||
if (IsItemHovered()) {
|
||||
|
@ -196,7 +219,8 @@ void L::DrawAdvanced() {
|
|||
}
|
||||
|
||||
if (Button("Save")) {
|
||||
Options.disassembly_cli = disassembly_cli;
|
||||
Options.disassembler_cli_isa = disassembler_cli_isa;
|
||||
Options.disassembler_cli_spv = disassembler_cli_spv;
|
||||
Options.frame_dump_render_on_collapse = frame_dump_render_on_collapse;
|
||||
SaveIniSettingsToDisk(io.IniFilename);
|
||||
CloseCurrentPopup();
|
||||
|
@ -219,6 +243,13 @@ void L::DrawAdvanced() {
|
|||
|
||||
EndPopup();
|
||||
}
|
||||
|
||||
if (memory_map.open) {
|
||||
memory_map.Draw();
|
||||
}
|
||||
if (shader_list.open) {
|
||||
shader_list.Draw();
|
||||
}
|
||||
}
|
||||
|
||||
void L::DrawSimple() {
|
||||
|
|
|
@ -12,8 +12,12 @@ TOptions Options;
|
|||
void LoadOptionsConfig(const char* line) {
|
||||
char str[512];
|
||||
int i;
|
||||
if (sscanf(line, "disassembly_cli=%511[^\n]", str) == 1) {
|
||||
Options.disassembly_cli = str;
|
||||
if (sscanf(line, "disassembler_cli_isa=%511[^\n]", str) == 1) {
|
||||
Options.disassembler_cli_isa = str;
|
||||
return;
|
||||
}
|
||||
if (sscanf(line, "disassembler_cli_spv=%511[^\n]", str) == 1) {
|
||||
Options.disassembler_cli_spv = str;
|
||||
return;
|
||||
}
|
||||
if (sscanf(line, "frame_dump_render_on_collapse=%d", &i) == 1) {
|
||||
|
@ -23,7 +27,8 @@ void LoadOptionsConfig(const char* line) {
|
|||
}
|
||||
|
||||
void SerializeOptionsConfig(ImGuiTextBuffer* buf) {
|
||||
buf->appendf("disassembly_cli=%s\n", Options.disassembly_cli.c_str());
|
||||
buf->appendf("disassembler_cli_isa=%s\n", Options.disassembler_cli_isa.c_str());
|
||||
buf->appendf("disassembler_cli_spv=%s\n", Options.disassembler_cli_spv.c_str());
|
||||
buf->appendf("frame_dump_render_on_collapse=%d\n", Options.frame_dump_render_on_collapse);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ struct ImGuiTextBuffer;
|
|||
namespace Core::Devtools {
|
||||
|
||||
struct TOptions {
|
||||
std::string disassembly_cli{};
|
||||
std::string disassembler_cli_isa{"clrxdisasm --raw \"{src}\""};
|
||||
std::string disassembler_cli_spv{"spirv-cross -V \"{src}\""};
|
||||
bool frame_dump_render_on_collapse{false};
|
||||
};
|
||||
|
||||
|
|
|
@ -1306,7 +1306,7 @@ void CmdListViewer::Draw(bool only_batches_view) {
|
|||
if (batch.id == batch_bp) { // highlight batch at breakpoint
|
||||
PushStyleColor(ImGuiCol_Header, ImVec4{1.0f, 0.5f, 0.5f, 0.5f});
|
||||
}
|
||||
if (batch.id == highlight_batch) {
|
||||
if (batch.id == highlight_batch && !group_batches) {
|
||||
PushStyleColor(ImGuiCol_Text, ImVec4{1.0f, 0.7f, 0.7f, 1.0f});
|
||||
}
|
||||
|
||||
|
@ -1459,7 +1459,7 @@ void CmdListViewer::Draw(bool only_batches_view) {
|
|||
}
|
||||
}
|
||||
|
||||
if (batch.id == highlight_batch) {
|
||||
if (batch.id == highlight_batch && !group_batches) {
|
||||
PopStyleColor();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
|
@ -10,9 +11,16 @@
|
|||
#include <magic_enum.hpp>
|
||||
|
||||
#include "common/bit_field.h"
|
||||
#include "common/io_file.h"
|
||||
#include "common/types.h"
|
||||
#include "core/debug_state.h"
|
||||
#include "video_core/amdgpu/pm4_opcodes.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define popen _popen
|
||||
#define pclose _pclose
|
||||
#endif
|
||||
|
||||
namespace Core::Devtools::Widget {
|
||||
/*
|
||||
* Generic PM4 header
|
||||
|
@ -106,4 +114,53 @@ static bool IsDrawCall(AmdGpu::PM4ItOpcode opcode) {
|
|||
}
|
||||
}
|
||||
|
||||
inline std::optional<std::string> exec_cli(const char* cli) {
|
||||
std::array<char, 64> buffer{};
|
||||
std::string output;
|
||||
const auto f = popen(cli, "r");
|
||||
if (!f) {
|
||||
pclose(f);
|
||||
return {};
|
||||
}
|
||||
while (fgets(buffer.data(), buffer.size(), f)) {
|
||||
output += buffer.data();
|
||||
}
|
||||
pclose(f);
|
||||
return output;
|
||||
}
|
||||
|
||||
inline std::string RunDisassembler(const std::string& disassembler_cli,
|
||||
const std::vector<u32>& shader_code) {
|
||||
std::string shader_dis;
|
||||
|
||||
if (disassembler_cli.empty()) {
|
||||
shader_dis = "No disassembler set";
|
||||
} else {
|
||||
auto bin_path = std::filesystem::temp_directory_path() / "shadps4_tmp_shader.bin";
|
||||
|
||||
constexpr std::string_view src_arg = "{src}";
|
||||
std::string cli = disassembler_cli;
|
||||
const auto pos = cli.find(src_arg);
|
||||
if (pos == std::string::npos) {
|
||||
DebugState.ShowDebugMessage("Disassembler CLI does not contain {src} argument\n" +
|
||||
disassembler_cli);
|
||||
} else {
|
||||
cli.replace(pos, src_arg.size(), "\"" + bin_path.string() + "\"");
|
||||
Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Write);
|
||||
file.Write(shader_code);
|
||||
file.Close();
|
||||
|
||||
auto result = exec_cli(cli.c_str());
|
||||
shader_dis = result.value_or("Could not disassemble shader");
|
||||
if (shader_dis.empty()) {
|
||||
shader_dis = "Disassembly empty or failed";
|
||||
}
|
||||
|
||||
std::filesystem::remove(bin_path);
|
||||
}
|
||||
}
|
||||
|
||||
return shader_dis;
|
||||
}
|
||||
|
||||
} // namespace Core::Devtools::Widget
|
134
src/core/devtools/widget/memory_map.cpp
Normal file
134
src/core/devtools/widget/memory_map.cpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <imgui.h>
|
||||
#include <magic_enum.hpp>
|
||||
|
||||
#include "core/debug_state.h"
|
||||
#include "core/memory.h"
|
||||
#include "memory_map.h"
|
||||
|
||||
using namespace ImGui;
|
||||
|
||||
namespace Core::Devtools::Widget {
|
||||
|
||||
bool MemoryMapViewer::Iterator::DrawLine() {
|
||||
if (is_vma) {
|
||||
if (vma.it == vma.end) {
|
||||
return false;
|
||||
}
|
||||
auto m = vma.it->second;
|
||||
if (m.type == VMAType::Free) {
|
||||
++vma.it;
|
||||
return DrawLine();
|
||||
}
|
||||
TableNextColumn();
|
||||
Text("%zX", m.base);
|
||||
TableNextColumn();
|
||||
Text("%zX", m.size);
|
||||
TableNextColumn();
|
||||
Text("%s", magic_enum::enum_name(m.type).data());
|
||||
TableNextColumn();
|
||||
Text("%s", magic_enum::enum_name(m.prot).data());
|
||||
TableNextColumn();
|
||||
if (m.is_exec) {
|
||||
Text("X");
|
||||
}
|
||||
TableNextColumn();
|
||||
Text("%s", m.name.c_str());
|
||||
++vma.it;
|
||||
return true;
|
||||
}
|
||||
if (dmem.it == dmem.end) {
|
||||
return false;
|
||||
}
|
||||
auto m = dmem.it->second;
|
||||
if (m.is_free) {
|
||||
++dmem.it;
|
||||
return DrawLine();
|
||||
}
|
||||
TableNextColumn();
|
||||
Text("%llX", m.base);
|
||||
TableNextColumn();
|
||||
Text("%llX", m.size);
|
||||
TableNextColumn();
|
||||
auto type = static_cast<::Libraries::Kernel::MemoryTypes>(m.memory_type);
|
||||
Text("%s", magic_enum::enum_name(type).data());
|
||||
TableNextColumn();
|
||||
Text("%d", m.is_pooled);
|
||||
++dmem.it;
|
||||
return true;
|
||||
}
|
||||
|
||||
void MemoryMapViewer::Draw() {
|
||||
SetNextWindowSize({600.0f, 500.0f}, ImGuiCond_FirstUseEver);
|
||||
if (!Begin("Memory map", &open)) {
|
||||
End();
|
||||
return;
|
||||
}
|
||||
|
||||
auto mem = Memory::Instance();
|
||||
std::scoped_lock lck{mem->mutex};
|
||||
|
||||
{
|
||||
bool next_showing_vma = showing_vma;
|
||||
if (showing_vma) {
|
||||
PushStyleColor(ImGuiCol_Button, ImVec4{1.0f, 0.7f, 0.7f, 1.0f});
|
||||
}
|
||||
if (Button("VMem")) {
|
||||
next_showing_vma = true;
|
||||
}
|
||||
if (showing_vma) {
|
||||
PopStyleColor();
|
||||
}
|
||||
SameLine();
|
||||
if (!showing_vma) {
|
||||
PushStyleColor(ImGuiCol_Button, ImVec4{1.0f, 0.7f, 0.7f, 1.0f});
|
||||
}
|
||||
if (Button("DMem")) {
|
||||
next_showing_vma = false;
|
||||
}
|
||||
if (!showing_vma) {
|
||||
PopStyleColor();
|
||||
}
|
||||
showing_vma = next_showing_vma;
|
||||
}
|
||||
|
||||
Iterator it{};
|
||||
if (showing_vma) {
|
||||
it.is_vma = true;
|
||||
it.vma.it = mem->vma_map.begin();
|
||||
it.vma.end = mem->vma_map.end();
|
||||
} else {
|
||||
it.is_vma = false;
|
||||
it.dmem.it = mem->dmem_map.begin();
|
||||
it.dmem.end = mem->dmem_map.end();
|
||||
}
|
||||
|
||||
if (BeginTable("memory_view_table", showing_vma ? 6 : 4,
|
||||
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg |
|
||||
ImGuiTableFlags_SizingFixedFit)) {
|
||||
if (showing_vma) {
|
||||
TableSetupColumn("Address");
|
||||
TableSetupColumn("Size");
|
||||
TableSetupColumn("Type");
|
||||
TableSetupColumn("Prot");
|
||||
TableSetupColumn("Is Exec");
|
||||
TableSetupColumn("Name");
|
||||
} else {
|
||||
TableSetupColumn("Address");
|
||||
TableSetupColumn("Size");
|
||||
TableSetupColumn("Type");
|
||||
TableSetupColumn("Pooled");
|
||||
}
|
||||
TableHeadersRow();
|
||||
|
||||
while (it.DrawLine())
|
||||
;
|
||||
EndTable();
|
||||
}
|
||||
|
||||
End();
|
||||
}
|
||||
|
||||
} // namespace Core::Devtools::Widget
|
33
src/core/devtools/widget/memory_map.h
Normal file
33
src/core/devtools/widget/memory_map.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace Core::Devtools::Widget {
|
||||
|
||||
class MemoryMapViewer {
|
||||
struct Iterator {
|
||||
bool is_vma;
|
||||
struct {
|
||||
MemoryManager::DMemMap::iterator it;
|
||||
MemoryManager::DMemMap::iterator end;
|
||||
} dmem;
|
||||
struct {
|
||||
MemoryManager::VMAMap::iterator it;
|
||||
MemoryManager::VMAMap::iterator end;
|
||||
} vma;
|
||||
|
||||
bool DrawLine();
|
||||
};
|
||||
|
||||
bool showing_vma = true;
|
||||
|
||||
public:
|
||||
bool open = false;
|
||||
|
||||
void Draw();
|
||||
};
|
||||
|
||||
} // namespace Core::Devtools::Widget
|
|
@ -25,21 +25,6 @@ using magic_enum::enum_name;
|
|||
|
||||
constexpr auto depth_id = 0xF3;
|
||||
|
||||
static std::optional<std::string> exec_cli(const char* cli) {
|
||||
std::array<char, 64> buffer{};
|
||||
std::string output;
|
||||
const auto f = popen(cli, "r");
|
||||
if (!f) {
|
||||
pclose(f);
|
||||
return {};
|
||||
}
|
||||
while (fgets(buffer.data(), buffer.size(), f)) {
|
||||
output += buffer.data();
|
||||
}
|
||||
pclose(f);
|
||||
return output;
|
||||
}
|
||||
|
||||
namespace Core::Devtools::Widget {
|
||||
|
||||
void RegView::ProcessShader(int shader_id) {
|
||||
|
@ -54,38 +39,12 @@ void RegView::ProcessShader(int shader_id) {
|
|||
user_data = s.user_data.user_data;
|
||||
}
|
||||
|
||||
std::string shader_dis;
|
||||
|
||||
if (Options.disassembly_cli.empty()) {
|
||||
shader_dis = "No disassembler set";
|
||||
} else {
|
||||
auto bin_path = std::filesystem::temp_directory_path() / "shadps4_tmp_shader.bin";
|
||||
|
||||
constexpr std::string_view src_arg = "{src}";
|
||||
std::string cli = Options.disassembly_cli;
|
||||
const auto pos = cli.find(src_arg);
|
||||
if (pos == std::string::npos) {
|
||||
DebugState.ShowDebugMessage("Disassembler CLI does not contain {src} argument");
|
||||
} else {
|
||||
cli.replace(pos, src_arg.size(), "\"" + bin_path.string() + "\"");
|
||||
Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Write);
|
||||
file.Write(shader_code);
|
||||
file.Close();
|
||||
|
||||
auto result = exec_cli(cli.c_str());
|
||||
shader_dis = result.value_or("Could not disassemble shader");
|
||||
if (shader_dis.empty()) {
|
||||
shader_dis = "Disassembly empty or failed";
|
||||
}
|
||||
|
||||
std::filesystem::remove(bin_path);
|
||||
}
|
||||
}
|
||||
std::string shader_dis = RunDisassembler(Options.disassembler_cli_isa, shader_code);
|
||||
|
||||
MemoryEditor hex_view;
|
||||
hex_view.Open = true;
|
||||
hex_view.ReadOnly = true;
|
||||
hex_view.Cols = 8;
|
||||
hex_view.Cols = 16;
|
||||
hex_view.OptShowAscii = false;
|
||||
hex_view.OptShowOptions = false;
|
||||
|
||||
|
@ -376,7 +335,9 @@ void RegView::Draw() {
|
|||
if (!shader) {
|
||||
Text("Stage not selected");
|
||||
} else {
|
||||
shader->hex_view.DrawContents(shader->user_data.data(), shader->user_data.size());
|
||||
shader->hex_view.DrawContents(shader->user_data.data(),
|
||||
shader->user_data.size() *
|
||||
sizeof(Vulkan::Liverpool::UserData::value_type));
|
||||
}
|
||||
}
|
||||
End();
|
||||
|
|
95
src/core/devtools/widget/shader_list.cpp
Normal file
95
src/core/devtools/widget/shader_list.cpp
Normal file
|
@ -0,0 +1,95 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "shader_list.h"
|
||||
|
||||
#include <imgui.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "common/config.h"
|
||||
#include "core/debug_state.h"
|
||||
#include "core/devtools/options.h"
|
||||
#include "imgui/imgui_std.h"
|
||||
|
||||
using namespace ImGui;
|
||||
|
||||
namespace Core::Devtools::Widget {
|
||||
|
||||
void ShaderList::DrawShader(DebugStateType::ShaderDump& value) {
|
||||
if (!loaded_data) {
|
||||
loaded_data = true;
|
||||
if (value.cache_raw_disasm.empty()) {
|
||||
value.cache_raw_disasm = RunDisassembler(Options.disassembler_cli_isa, value.raw_code);
|
||||
}
|
||||
isa_editor.SetText(value.cache_raw_disasm);
|
||||
|
||||
if (value.cache_spv_disasm.empty()) {
|
||||
value.cache_spv_disasm = RunDisassembler(Options.disassembler_cli_spv, value.spv);
|
||||
}
|
||||
spv_editor.SetText(value.cache_spv_disasm);
|
||||
}
|
||||
|
||||
if (SmallButton("<-")) {
|
||||
selected_shader = -1;
|
||||
}
|
||||
SameLine();
|
||||
Text("%s", value.name.c_str());
|
||||
SameLine(0.0f, 7.0f);
|
||||
if (BeginCombo("Shader type", showing_isa ? "ISA" : "SPIRV", ImGuiComboFlags_WidthFitPreview)) {
|
||||
if (Selectable("SPIRV")) {
|
||||
showing_isa = false;
|
||||
}
|
||||
if (Selectable("ISA")) {
|
||||
showing_isa = true;
|
||||
}
|
||||
EndCombo();
|
||||
}
|
||||
|
||||
if (showing_isa) {
|
||||
isa_editor.Render("ISA", GetContentRegionAvail());
|
||||
} else {
|
||||
spv_editor.Render("SPIRV", GetContentRegionAvail());
|
||||
}
|
||||
}
|
||||
|
||||
ShaderList::ShaderList() {
|
||||
isa_editor.SetPalette(TextEditor::GetDarkPalette());
|
||||
isa_editor.SetReadOnly(true);
|
||||
spv_editor.SetPalette(TextEditor::GetDarkPalette());
|
||||
spv_editor.SetReadOnly(true);
|
||||
spv_editor.SetLanguageDefinition(TextEditor::LanguageDefinition::GLSL());
|
||||
}
|
||||
|
||||
void ShaderList::Draw() {
|
||||
SetNextWindowSize({500.0f, 600.0f}, ImGuiCond_FirstUseEver);
|
||||
if (!Begin("Shader list", &open)) {
|
||||
End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Config::collectShadersForDebug()) {
|
||||
DrawCenteredText("Enable 'CollectShader' in config to see shaders");
|
||||
End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected_shader >= 0) {
|
||||
DrawShader(DebugState.shader_dump_list[selected_shader]);
|
||||
End();
|
||||
return;
|
||||
}
|
||||
|
||||
auto width = GetContentRegionAvail().x;
|
||||
int i = 0;
|
||||
for (const auto& shader : DebugState.shader_dump_list) {
|
||||
if (ButtonEx(shader.name.c_str(), {width, 20.0f}, ImGuiButtonFlags_NoHoveredOnFocus)) {
|
||||
selected_shader = i;
|
||||
loaded_data = false;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
End();
|
||||
}
|
||||
|
||||
} // namespace Core::Devtools::Widget
|
28
src/core/devtools/widget/shader_list.h
Normal file
28
src/core/devtools/widget/shader_list.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/debug_state.h"
|
||||
#include "text_editor.h"
|
||||
|
||||
namespace Core::Devtools::Widget {
|
||||
|
||||
class ShaderList {
|
||||
int selected_shader = -1;
|
||||
TextEditor isa_editor{};
|
||||
TextEditor spv_editor{};
|
||||
bool loaded_data = false;
|
||||
bool showing_isa = false;
|
||||
|
||||
void DrawShader(DebugStateType::ShaderDump& value);
|
||||
|
||||
public:
|
||||
ShaderList();
|
||||
|
||||
bool open = false;
|
||||
|
||||
void Draw();
|
||||
};
|
||||
|
||||
} // namespace Core::Devtools::Widget
|
Loading…
Add table
Add a link
Reference in a new issue