Add TCS/TES support for shader patching and use LogicalStage

This commit is contained in:
Frodo Baggins 2024-12-10 20:18:29 -08:00
parent 772acf3175
commit fffe27a135
6 changed files with 32 additions and 28 deletions

View File

@ -177,10 +177,11 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
}
}
void DebugStateImpl::CollectShader(const std::string& name, vk::ShaderModule module,
std::span<const u32> spv, std::span<const u32> raw_code,
std::span<const u32> patch_spv, bool is_patched) {
shader_dump_list.emplace_back(name, module, std::vector<u32>{spv.begin(), spv.end()},
void DebugStateImpl::CollectShader(const std::string& name, Shader::LogicalStage l_stage,
vk::ShaderModule module, std::span<const u32> spv,
std::span<const u32> raw_code, std::span<const u32> patch_spv,
bool is_patched) {
shader_dump_list.emplace_back(name, l_stage, module, std::vector<u32>{spv.begin(), spv.end()},
std::vector<u32>{raw_code.begin(), raw_code.end()},
std::vector<u32>{patch_spv.begin(), patch_spv.end()}, is_patched);
}

View File

@ -76,6 +76,7 @@ struct FrameDump {
struct ShaderDump {
std::string name;
Shader::LogicalStage l_stage;
vk::ShaderModule module;
std::vector<u32> spv;
@ -90,16 +91,17 @@ struct ShaderDump {
std::string cache_isa_disasm{};
std::string cache_patch_disasm{};
ShaderDump(std::string name, vk::ShaderModule module, std::vector<u32> spv,
std::vector<u32> isa, std::vector<u32> patch_spv, bool is_patched)
: name(std::move(name)), module(module), spv(std::move(spv)), isa(std::move(isa)),
patch_spv(std::move(patch_spv)), is_patched(is_patched) {}
ShaderDump(std::string name, Shader::LogicalStage l_stage, vk::ShaderModule module,
std::vector<u32> spv, std::vector<u32> isa, std::vector<u32> patch_spv,
bool is_patched)
: name(std::move(name)), l_stage(l_stage), module(module), spv(std::move(spv)),
isa(std::move(isa)), patch_spv(std::move(patch_spv)), is_patched(is_patched) {}
ShaderDump(const ShaderDump& other) = delete;
ShaderDump(ShaderDump&& other) noexcept
: name{std::move(other.name)}, module{std::move(other.module)}, spv{std::move(other.spv)},
isa{std::move(other.isa)}, patch_spv{std::move(other.patch_spv)},
patch_source{std::move(other.patch_source)},
: name{std::move(other.name)}, l_stage(other.l_stage), module{std::move(other.module)},
spv{std::move(other.spv)}, isa{std::move(other.isa)},
patch_spv{std::move(other.patch_spv)}, patch_source{std::move(other.patch_source)},
cache_spv_disasm{std::move(other.cache_spv_disasm)},
cache_isa_disasm{std::move(other.cache_isa_disasm)},
cache_patch_disasm{std::move(other.cache_patch_disasm)} {}
@ -108,6 +110,7 @@ struct ShaderDump {
if (this == &other)
return *this;
name = std::move(other.name);
l_stage = other.l_stage;
module = std::move(other.module);
spv = std::move(other.spv);
isa = std::move(other.isa);
@ -203,7 +206,8 @@ public:
void PushRegsDump(uintptr_t base_addr, uintptr_t header_addr,
const AmdGpu::Liverpool::Regs& regs, bool is_compute = false);
void CollectShader(const std::string& name, vk::ShaderModule module, std::span<const u32> spv,
void CollectShader(const std::string& name, Shader::LogicalStage l_stage,
vk::ShaderModule module, std::span<const u32> spv,
std::span<const u32> raw_code, std::span<const u32> patch_spv,
bool is_patched);
};

View File

@ -158,16 +158,17 @@ bool ShaderList::Selection::DrawShader(DebugStateType::ShaderDump& value) {
DebugState.ShowDebugMessage(msg);
}
if (compile) {
static std::map<std::string, std::string> stage_arg = {
{"vs", "vert"},
{"gs", "geom"},
{"fs", "frag"},
{"cs", "comp"},
static std::map<Shader::LogicalStage, std::string> stage_arg = {
{Shader::LogicalStage::Vertex, "vert"},
{Shader::LogicalStage::TessellationControl, "tesc"},
{Shader::LogicalStage::TessellationEval, "tese"},
{Shader::LogicalStage::Geometry, "geom"},
{Shader::LogicalStage::Fragment, "frag"},
{Shader::LogicalStage::Compute, "comp"},
};
auto stage = stage_arg.find(value.name.substr(0, 2));
auto stage = stage_arg.find(value.l_stage);
if (stage == stage_arg.end()) {
DebugState.ShowDebugMessage(std::string{"Invalid shader stage: "} +
value.name.substr(0, 2));
DebugState.ShowDebugMessage(std::string{"Invalid shader stage"});
} else {
std::string cmd =
fmt::format("glslc --target-env=vulkan1.3 --target-spv=spv1.6 "

View File

@ -24,17 +24,15 @@ enum class Stage : u32 {
};
constexpr u32 MaxStageTypes = 7;
// Vertex intentionally comes after TCS/TES because in a tess pipeline,
// we need to find the ls_stride from tess constants V# (in order to define an output attribute
// array with correct length), and finding the tess constant V# requires analysis while compiling
// TCS/TES (for now)
// Vertex intentionally comes after TCS/TES due to order of compilation
enum class LogicalStage : u32 {
Fragment,
TessellationControl,
TessellationEval,
Vertex,
Geometry,
GsCopy,
GsCopy, // TODO delete this, but causes crash somehow (probably wrong use of Shader::Stage
// somewhere)
Compute,
};

View File

@ -512,8 +512,8 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, Shader::Runtim
const auto name = fmt::format("{}_{:#018x}_{}", info.stage, info.pgm_hash, perm_idx);
Vulkan::SetObjectName(instance.GetDevice(), module, name);
if (Config::collectShadersForDebug()) {
DebugState.CollectShader(name, module, spv, code, patch ? *patch : std::span<const u32>{},
is_patched);
DebugState.CollectShader(name, info.l_stage, module, spv, code,
patch ? *patch : std::span<const u32>{}, is_patched);
}
return module;
}

View File

@ -327,7 +327,7 @@ void Rasterizer::DispatchDirect() {
return;
}
const auto& cs = pipeline->GetStage(Shader::Stage::Compute);
const auto& cs = pipeline->GetStage(Shader::LogicalStage::Compute);
if (ExecuteShaderHLE(cs, liverpool->regs, *this)) {
return;
}