mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-29 11:06:07 +00:00
Devtools IV (#1910)
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
Some checks are pending
Build and Release / reuse (push) Waiting to run
Build and Release / clang-format (push) Waiting to run
Build and Release / get-info (push) Waiting to run
Build and Release / windows-sdl (push) Blocked by required conditions
Build and Release / windows-qt (push) Blocked by required conditions
Build and Release / macos-sdl (push) Blocked by required conditions
Build and Release / macos-qt (push) Blocked by required conditions
Build and Release / linux-sdl (push) Blocked by required conditions
Build and Release / linux-qt (push) Blocked by required conditions
Build and Release / pre-release (push) Blocked by required conditions
* devtools: fix popen in non-windows environment * devtools: fix frame crash assertion when hidden * devtools: add search to shader list * devtools: add copy name to shader list * devtools: frame dump: search by shader name
This commit is contained in:
parent
0bb1c05aff
commit
edc027a8bc
|
@ -11,6 +11,7 @@
|
||||||
#include "libraries/kernel/time.h"
|
#include "libraries/kernel/time.h"
|
||||||
#include "libraries/system/msgdialog.h"
|
#include "libraries/system/msgdialog.h"
|
||||||
#include "video_core/amdgpu/pm4_cmds.h"
|
#include "video_core/amdgpu/pm4_cmds.h"
|
||||||
|
#include "video_core/renderer_vulkan/vk_pipeline_cache.h"
|
||||||
|
|
||||||
using namespace DebugStateType;
|
using namespace DebugStateType;
|
||||||
|
|
||||||
|
@ -168,8 +169,12 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
|
||||||
if ((*dump)->regs.stage_enable.IsStageEnabled(i)) {
|
if ((*dump)->regs.stage_enable.IsStageEnabled(i)) {
|
||||||
auto stage = (*dump)->regs.ProgramForStage(i);
|
auto stage = (*dump)->regs.ProgramForStage(i);
|
||||||
if (stage->address_lo != 0) {
|
if (stage->address_lo != 0) {
|
||||||
|
const auto& info = AmdGpu::Liverpool::SearchBinaryInfo(stage->Address<u32*>());
|
||||||
auto code = stage->Code();
|
auto code = stage->Code();
|
||||||
(*dump)->stages[i] = PipelineShaderProgramDump{
|
(*dump)->stages[i] = PipelineShaderProgramDump{
|
||||||
|
.name = Vulkan::PipelineCache::GetShaderName(Shader::StageFromIndex(i),
|
||||||
|
info.shader_hash),
|
||||||
|
.hash = info.shader_hash,
|
||||||
.user_data = *stage,
|
.user_data = *stage,
|
||||||
.code = std::vector<u32>{code.begin(), code.end()},
|
.code = std::vector<u32>{code.begin(), code.end()},
|
||||||
};
|
};
|
||||||
|
@ -191,7 +196,10 @@ void DebugStateImpl::PushRegsDumpCompute(uintptr_t base_addr, uintptr_t header_a
|
||||||
auto& cs = (*dump)->regs.cs_program;
|
auto& cs = (*dump)->regs.cs_program;
|
||||||
cs = cs_state;
|
cs = cs_state;
|
||||||
|
|
||||||
|
const auto& info = AmdGpu::Liverpool::SearchBinaryInfo(cs.Address<u32*>());
|
||||||
(*dump)->cs_data = PipelineComputerProgramDump{
|
(*dump)->cs_data = PipelineComputerProgramDump{
|
||||||
|
.name = Vulkan::PipelineCache::GetShaderName(Shader::Stage::Compute, info.shader_hash),
|
||||||
|
.hash = info.shader_hash,
|
||||||
.cs_program = cs,
|
.cs_program = cs,
|
||||||
.code = std::vector<u32>{cs.Code().begin(), cs.Code().end()},
|
.code = std::vector<u32>{cs.Code().begin(), cs.Code().end()},
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,11 +50,15 @@ struct QueueDump {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PipelineShaderProgramDump {
|
struct PipelineShaderProgramDump {
|
||||||
|
std::string name;
|
||||||
|
u64 hash;
|
||||||
Vulkan::Liverpool::ShaderProgram user_data{};
|
Vulkan::Liverpool::ShaderProgram user_data{};
|
||||||
std::vector<u32> code{};
|
std::vector<u32> code{};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PipelineComputerProgramDump {
|
struct PipelineComputerProgramDump {
|
||||||
|
std::string name;
|
||||||
|
u64 hash;
|
||||||
Vulkan::Liverpool::ComputeProgram cs_program{};
|
Vulkan::Liverpool::ComputeProgram cs_program{};
|
||||||
std::vector<u32> code{};
|
std::vector<u32> code{};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1174,7 +1174,7 @@ CmdListViewer::CmdListViewer(DebugStateType::FrameDump* _frame_dump,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmdListViewer::Draw(bool only_batches_view) {
|
void CmdListViewer::Draw(bool only_batches_view, CmdListFilter& filter) {
|
||||||
const auto& ctx = *GetCurrentContext();
|
const auto& ctx = *GetCurrentContext();
|
||||||
|
|
||||||
if (batch_view.open) {
|
if (batch_view.open) {
|
||||||
|
@ -1285,6 +1285,41 @@ void CmdListViewer::Draw(bool only_batches_view) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& batch = std::get<BatchInfo>(event);
|
auto& batch = std::get<BatchInfo>(event);
|
||||||
|
|
||||||
|
// filtering
|
||||||
|
{
|
||||||
|
bool remove = false;
|
||||||
|
|
||||||
|
if (filter.shader_name[0] != '\0') {
|
||||||
|
remove = true;
|
||||||
|
std::string_view shader_name{filter.shader_name};
|
||||||
|
const auto& data = frame_dump->regs.find(batch.command_addr);
|
||||||
|
if (data != frame_dump->regs.end()) {
|
||||||
|
DebugStateType::RegDump& dump = data->second;
|
||||||
|
if (dump.is_compute) {
|
||||||
|
if (dump.cs_data.name.contains(shader_name)) {
|
||||||
|
remove = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < DebugStateType::RegDump::MaxShaderStages; ++i) {
|
||||||
|
if (dump.regs.stage_enable.IsStageEnabled(i)) {
|
||||||
|
auto& stage = dump.stages[i];
|
||||||
|
if (stage.name.contains(shader_name)) {
|
||||||
|
remove = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
auto const* pm4_hdr =
|
auto const* pm4_hdr =
|
||||||
reinterpret_cast<PM4Header const*>(cmdb_addr + batch.start_addr);
|
reinterpret_cast<PM4Header const*>(cmdb_addr + batch.start_addr);
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,10 @@ void ParseDepthControl(u32 value, bool begin_table = true);
|
||||||
void ParseEqaa(u32 value, bool begin_table = true);
|
void ParseEqaa(u32 value, bool begin_table = true);
|
||||||
void ParseZInfo(u32 value, bool begin_table = true);
|
void ParseZInfo(u32 value, bool begin_table = true);
|
||||||
|
|
||||||
|
struct CmdListFilter {
|
||||||
|
char shader_name[128]{};
|
||||||
|
};
|
||||||
|
|
||||||
class CmdListViewer {
|
class CmdListViewer {
|
||||||
|
|
||||||
DebugStateType::FrameDump* frame_dump;
|
DebugStateType::FrameDump* frame_dump;
|
||||||
|
@ -70,7 +74,7 @@ public:
|
||||||
explicit CmdListViewer(DebugStateType::FrameDump* frame_dump, const std::vector<u32>& cmd_list,
|
explicit CmdListViewer(DebugStateType::FrameDump* frame_dump, const std::vector<u32>& cmd_list,
|
||||||
uintptr_t base_addr = 0, std::string name = "");
|
uintptr_t base_addr = 0, std::string name = "");
|
||||||
|
|
||||||
void Draw(bool only_batches_view = false);
|
void Draw(bool only_batches_view, CmdListFilter& filter);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core::Devtools::Widget
|
} // namespace Core::Devtools::Widget
|
||||||
|
|
|
@ -117,7 +117,7 @@ static bool IsDrawCall(AmdGpu::PM4ItOpcode opcode) {
|
||||||
inline std::optional<std::string> exec_cli(const char* cli) {
|
inline std::optional<std::string> exec_cli(const char* cli) {
|
||||||
std::array<char, 64> buffer{};
|
std::array<char, 64> buffer{};
|
||||||
std::string output;
|
std::string output;
|
||||||
const auto f = popen(cli, "rt");
|
const auto f = popen(cli, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
pclose(f);
|
pclose(f);
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -132,6 +132,15 @@ void FrameDumpViewer::Draw() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EndDisabled();
|
EndDisabled();
|
||||||
|
SameLine();
|
||||||
|
if (BeginMenu("Filter")) {
|
||||||
|
|
||||||
|
TextUnformatted("Shader name");
|
||||||
|
SameLine();
|
||||||
|
InputText("##filter_shader", filter.shader_name, sizeof(filter.shader_name));
|
||||||
|
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
TextEx("Submit num");
|
TextEx("Submit num");
|
||||||
SameLine();
|
SameLine();
|
||||||
|
@ -187,7 +196,7 @@ void FrameDumpViewer::Draw() {
|
||||||
EndGroup();
|
EndGroup();
|
||||||
}
|
}
|
||||||
if (is_showing && selected_cmd != -1) {
|
if (is_showing && selected_cmd != -1) {
|
||||||
cmd_list_viewer[selected_cmd].Draw(is_collapsed);
|
cmd_list_viewer[selected_cmd].Draw(is_collapsed, filter);
|
||||||
}
|
}
|
||||||
End();
|
End();
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,8 @@ class FrameDumpViewer {
|
||||||
s32 selected_queue_num2;
|
s32 selected_queue_num2;
|
||||||
s32 selected_cmd = -1;
|
s32 selected_cmd = -1;
|
||||||
|
|
||||||
|
CmdListFilter filter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool is_open = true;
|
bool is_open = true;
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,57 @@ constexpr float BAR_HEIGHT_MULT = 1.25f;
|
||||||
constexpr float FRAME_GRAPH_PADDING_Y = 3.0f;
|
constexpr float FRAME_GRAPH_PADDING_Y = 3.0f;
|
||||||
constexpr static float FRAME_GRAPH_HEIGHT = 50.0f;
|
constexpr static float FRAME_GRAPH_HEIGHT = 50.0f;
|
||||||
|
|
||||||
|
void FrameGraph::DrawFrameGraph() {
|
||||||
|
// Frame graph - inspired by
|
||||||
|
// https://asawicki.info/news_1758_an_idea_for_visualization_of_frame_times
|
||||||
|
const float full_width = GetContentRegionAvail().x;
|
||||||
|
auto pos = GetCursorScreenPos();
|
||||||
|
const ImVec2 size{full_width, FRAME_GRAPH_HEIGHT + FRAME_GRAPH_PADDING_Y * 2.0f};
|
||||||
|
ItemSize(size);
|
||||||
|
if (!ItemAdd({pos, pos + size}, GetID("FrameGraph"))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float target_dt = 1.0f / (TARGET_FPS * (float)Config::vblankDiv());
|
||||||
|
float cur_pos_x = pos.x + full_width;
|
||||||
|
pos.y += FRAME_GRAPH_PADDING_Y;
|
||||||
|
const float final_pos_y = pos.y + FRAME_GRAPH_HEIGHT;
|
||||||
|
|
||||||
|
auto& draw_list = *GetWindowDrawList();
|
||||||
|
draw_list.AddRectFilled({pos.x, pos.y - FRAME_GRAPH_PADDING_Y},
|
||||||
|
{pos.x + full_width, final_pos_y + FRAME_GRAPH_PADDING_Y},
|
||||||
|
IM_COL32(0x33, 0x33, 0x33, 0xFF));
|
||||||
|
draw_list.PushClipRect({pos.x, pos.y}, {pos.x + full_width, final_pos_y}, true);
|
||||||
|
for (u32 i = 0; i < FRAME_BUFFER_SIZE; ++i) {
|
||||||
|
const auto& frame_info = frame_list[(DebugState.GetFrameNum() - i) % FRAME_BUFFER_SIZE];
|
||||||
|
const float dt_factor = target_dt / frame_info.delta;
|
||||||
|
|
||||||
|
const float width = std::ceil(BAR_WIDTH_MULT / dt_factor);
|
||||||
|
const float height =
|
||||||
|
std::min(std::log2(BAR_HEIGHT_MULT / dt_factor) / 3.0f, 1.0f) * FRAME_GRAPH_HEIGHT;
|
||||||
|
|
||||||
|
ImU32 color;
|
||||||
|
if (dt_factor >= 0.95f) { // BLUE
|
||||||
|
color = IM_COL32(0x33, 0x33, 0xFF, 0xFF);
|
||||||
|
} else if (dt_factor >= 0.5f) { // GREEN <> YELLOW
|
||||||
|
float t = 1.0f - (dt_factor - 0.5f) * 2.0f;
|
||||||
|
int r = (int)(0xFF * t);
|
||||||
|
color = IM_COL32(r, 0xFF, 0, 0xFF);
|
||||||
|
} else { // YELLOW <> RED
|
||||||
|
float t = dt_factor * 2.0f;
|
||||||
|
int g = (int)(0xFF * t);
|
||||||
|
color = IM_COL32(0xFF, g, 0, 0xFF);
|
||||||
|
}
|
||||||
|
draw_list.AddRectFilled({cur_pos_x - width, final_pos_y - height}, {cur_pos_x, final_pos_y},
|
||||||
|
color);
|
||||||
|
cur_pos_x -= width;
|
||||||
|
if (cur_pos_x < width) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
draw_list.PopClipRect();
|
||||||
|
}
|
||||||
|
|
||||||
void FrameGraph::Draw() {
|
void FrameGraph::Draw() {
|
||||||
if (!is_open) {
|
if (!is_open) {
|
||||||
return;
|
return;
|
||||||
|
@ -43,55 +94,9 @@ void FrameGraph::Draw() {
|
||||||
Text("Frame time: %.3f ms (%.1f FPS)", deltaTime, frameRate);
|
Text("Frame time: %.3f ms (%.1f FPS)", deltaTime, frameRate);
|
||||||
Text("Flip frame: %d Gnm submit frame: %d", DebugState.flip_frame_count.load(),
|
Text("Flip frame: %d Gnm submit frame: %d", DebugState.flip_frame_count.load(),
|
||||||
DebugState.gnm_frame_count.load());
|
DebugState.gnm_frame_count.load());
|
||||||
|
|
||||||
SeparatorText("Frame graph");
|
SeparatorText("Frame graph");
|
||||||
|
DrawFrameGraph();
|
||||||
const float full_width = GetContentRegionAvail().x;
|
|
||||||
// Frame graph - inspired by
|
|
||||||
// https://asawicki.info/news_1758_an_idea_for_visualization_of_frame_times
|
|
||||||
auto pos = GetCursorScreenPos();
|
|
||||||
const ImVec2 size{full_width, FRAME_GRAPH_HEIGHT + FRAME_GRAPH_PADDING_Y * 2.0f};
|
|
||||||
ItemSize(size);
|
|
||||||
if (!ItemAdd({pos, pos + size}, GetID("FrameGraph"))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float target_dt = 1.0f / (TARGET_FPS * (float)Config::vblankDiv());
|
|
||||||
float cur_pos_x = pos.x + full_width;
|
|
||||||
pos.y += FRAME_GRAPH_PADDING_Y;
|
|
||||||
const float final_pos_y = pos.y + FRAME_GRAPH_HEIGHT;
|
|
||||||
|
|
||||||
draw_list.AddRectFilled({pos.x, pos.y - FRAME_GRAPH_PADDING_Y},
|
|
||||||
{pos.x + full_width, final_pos_y + FRAME_GRAPH_PADDING_Y},
|
|
||||||
IM_COL32(0x33, 0x33, 0x33, 0xFF));
|
|
||||||
draw_list.PushClipRect({pos.x, pos.y}, {pos.x + full_width, final_pos_y}, true);
|
|
||||||
for (u32 i = 0; i < FRAME_BUFFER_SIZE; ++i) {
|
|
||||||
const auto& frame_info = frame_list[(DebugState.GetFrameNum() - i) % FRAME_BUFFER_SIZE];
|
|
||||||
const float dt_factor = target_dt / frame_info.delta;
|
|
||||||
|
|
||||||
const float width = std::ceil(BAR_WIDTH_MULT / dt_factor);
|
|
||||||
const float height =
|
|
||||||
std::min(std::log2(BAR_HEIGHT_MULT / dt_factor) / 3.0f, 1.0f) * FRAME_GRAPH_HEIGHT;
|
|
||||||
|
|
||||||
ImU32 color;
|
|
||||||
if (dt_factor >= 0.95f) { // BLUE
|
|
||||||
color = IM_COL32(0x33, 0x33, 0xFF, 0xFF);
|
|
||||||
} else if (dt_factor >= 0.5f) { // GREEN <> YELLOW
|
|
||||||
float t = 1.0f - (dt_factor - 0.5f) * 2.0f;
|
|
||||||
int r = (int)(0xFF * t);
|
|
||||||
color = IM_COL32(r, 0xFF, 0, 0xFF);
|
|
||||||
} else { // YELLOW <> RED
|
|
||||||
float t = dt_factor * 2.0f;
|
|
||||||
int g = (int)(0xFF * t);
|
|
||||||
color = IM_COL32(0xFF, g, 0, 0xFF);
|
|
||||||
}
|
|
||||||
draw_list.AddRectFilled({cur_pos_x - width, final_pos_y - height},
|
|
||||||
{cur_pos_x, final_pos_y}, color);
|
|
||||||
cur_pos_x -= width;
|
|
||||||
if (cur_pos_x < width) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
draw_list.PopClipRect();
|
|
||||||
}
|
}
|
||||||
End();
|
End();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@ class FrameGraph {
|
||||||
|
|
||||||
std::array<FrameInfo, FRAME_BUFFER_SIZE> frame_list{};
|
std::array<FrameInfo, FRAME_BUFFER_SIZE> frame_list{};
|
||||||
|
|
||||||
|
void DrawFrameGraph();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool is_open = true;
|
bool is_open = true;
|
||||||
|
|
||||||
|
|
|
@ -292,6 +292,17 @@ void RegView::Draw() {
|
||||||
EndMenuBar();
|
EndMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char* shader_name = "_";
|
||||||
|
if (data.is_compute) {
|
||||||
|
shader_name = data.cs_data.name.c_str();
|
||||||
|
} else if (selected_shader >= 0) {
|
||||||
|
shader_name = data.stages[selected_shader].name.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
TextUnformatted("Shader: ");
|
||||||
|
SameLine();
|
||||||
|
TextUnformatted(shader_name);
|
||||||
|
|
||||||
if (!data.is_compute &&
|
if (!data.is_compute &&
|
||||||
BeginChild("STAGES", {},
|
BeginChild("STAGES", {},
|
||||||
ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeY)) {
|
ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeY)) {
|
||||||
|
|
|
@ -112,6 +112,10 @@ bool ShaderList::Selection::DrawShader(DebugStateType::ShaderDump& value) {
|
||||||
ReloadShader(value);
|
ReloadShader(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
SameLine();
|
||||||
|
if (Button("Copy name")) {
|
||||||
|
SetClipboardText(value.name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
if (value.is_patched) {
|
if (value.is_patched) {
|
||||||
if (BeginCombo("Shader type", showing_bin ? "SPIRV" : "GLSL",
|
if (BeginCombo("Shader type", showing_bin ? "SPIRV" : "GLSL",
|
||||||
|
@ -229,9 +233,16 @@ void ShaderList::Draw() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputTextEx("##search_shader", "Search by name", search_box, sizeof(search_box), {},
|
||||||
|
ImGuiInputTextFlags_None);
|
||||||
|
|
||||||
auto width = GetContentRegionAvail().x;
|
auto width = GetContentRegionAvail().x;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const auto& shader : DebugState.shader_dump_list) {
|
for (const auto& shader : DebugState.shader_dump_list) {
|
||||||
|
if (search_box[0] != '\0' && !shader.name.contains(search_box)) {
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
char name[128];
|
char name[128];
|
||||||
if (shader.is_patched) {
|
if (shader.is_patched) {
|
||||||
snprintf(name, sizeof(name), "%s (PATCH ON)", shader.name.c_str());
|
snprintf(name, sizeof(name), "%s (PATCH ON)", shader.name.c_str());
|
||||||
|
|
|
@ -31,6 +31,8 @@ class ShaderList {
|
||||||
|
|
||||||
std::vector<Selection> open_shaders{};
|
std::vector<Selection> open_shaders{};
|
||||||
|
|
||||||
|
char search_box[128]{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool open = false;
|
bool open = false;
|
||||||
|
|
||||||
|
|
|
@ -497,7 +497,7 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, Shader::Runtim
|
||||||
module = CompileSPV(spv, instance.GetDevice());
|
module = CompileSPV(spv, instance.GetDevice());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto name = fmt::format("{}_{:#018x}_{}", info.stage, info.pgm_hash, perm_idx);
|
const auto name = GetShaderName(info.stage, info.pgm_hash, perm_idx);
|
||||||
Vulkan::SetObjectName(instance.GetDevice(), module, name);
|
Vulkan::SetObjectName(instance.GetDevice(), module, name);
|
||||||
if (Config::collectShadersForDebug()) {
|
if (Config::collectShadersForDebug()) {
|
||||||
DebugState.CollectShader(name, info.l_stage, module, spv, code,
|
DebugState.CollectShader(name, info.l_stage, module, spv, code,
|
||||||
|
@ -572,6 +572,14 @@ std::optional<vk::ShaderModule> PipelineCache::ReplaceShader(vk::ShaderModule mo
|
||||||
return new_module;
|
return new_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string PipelineCache::GetShaderName(Shader::Stage stage, u64 hash,
|
||||||
|
std::optional<size_t> perm) {
|
||||||
|
if (perm) {
|
||||||
|
return fmt::format("{}_{:#018x}_{}", stage, hash, *perm);
|
||||||
|
}
|
||||||
|
return fmt::format("{}_{:#018x}", stage, hash);
|
||||||
|
}
|
||||||
|
|
||||||
void PipelineCache::DumpShader(std::span<const u32> code, u64 hash, Shader::Stage stage,
|
void PipelineCache::DumpShader(std::span<const u32> code, u64 hash, Shader::Stage stage,
|
||||||
size_t perm_idx, std::string_view ext) {
|
size_t perm_idx, std::string_view ext) {
|
||||||
if (!Config::dumpShaders()) {
|
if (!Config::dumpShaders()) {
|
||||||
|
@ -583,7 +591,7 @@ void PipelineCache::DumpShader(std::span<const u32> code, u64 hash, Shader::Stag
|
||||||
if (!std::filesystem::exists(dump_dir)) {
|
if (!std::filesystem::exists(dump_dir)) {
|
||||||
std::filesystem::create_directories(dump_dir);
|
std::filesystem::create_directories(dump_dir);
|
||||||
}
|
}
|
||||||
const auto filename = fmt::format("{}_{:#018x}_{}.{}", stage, hash, perm_idx, ext);
|
const auto filename = fmt::format("{}.{}", GetShaderName(stage, hash, perm_idx), ext);
|
||||||
const auto file = IOFile{dump_dir / filename, FileAccessMode::Write};
|
const auto file = IOFile{dump_dir / filename, FileAccessMode::Write};
|
||||||
file.WriteSpan(code);
|
file.WriteSpan(code);
|
||||||
}
|
}
|
||||||
|
@ -597,7 +605,7 @@ std::optional<std::vector<u32>> PipelineCache::GetShaderPatch(u64 hash, Shader::
|
||||||
if (!std::filesystem::exists(patch_dir)) {
|
if (!std::filesystem::exists(patch_dir)) {
|
||||||
std::filesystem::create_directories(patch_dir);
|
std::filesystem::create_directories(patch_dir);
|
||||||
}
|
}
|
||||||
const auto filename = fmt::format("{}_{:#018x}_{}.{}", stage, hash, perm_idx, ext);
|
const auto filename = fmt::format("{}.{}", GetShaderName(stage, hash, perm_idx), ext);
|
||||||
const auto filepath = patch_dir / filename;
|
const auto filepath = patch_dir / filename;
|
||||||
if (!std::filesystem::exists(filepath)) {
|
if (!std::filesystem::exists(filepath)) {
|
||||||
return {};
|
return {};
|
||||||
|
|
|
@ -65,6 +65,9 @@ public:
|
||||||
std::optional<vk::ShaderModule> ReplaceShader(vk::ShaderModule module,
|
std::optional<vk::ShaderModule> ReplaceShader(vk::ShaderModule module,
|
||||||
std::span<const u32> spv_code);
|
std::span<const u32> spv_code);
|
||||||
|
|
||||||
|
static std::string GetShaderName(Shader::Stage stage, u64 hash,
|
||||||
|
std::optional<size_t> perm = {});
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool RefreshGraphicsKey();
|
bool RefreshGraphicsKey();
|
||||||
bool RefreshComputeKey();
|
bool RefreshComputeKey();
|
||||||
|
|
Loading…
Reference in a new issue