shader: support single and split NGG shaders for PPSA11142

This commit is contained in:
nmzik
2026-09-08 14:43:07 +04:00
parent 9d550fbffa
commit ef0155636a
6 changed files with 79 additions and 27 deletions
@@ -535,7 +535,7 @@ TranslateResult TranslateProgram(std::span<const uint32_t> code, const CompileOp
Decoder::Program decoded;
std::vector<uint32_t> joined_code;
if (options.stage == ShaderType::Mesh) {
if (!options.back_code.empty()) {
decoded = DecodeFusedProgram(code, options.back_code, joined_code);
} else {
Decoder::DecodeProgram(code, decoded);
@@ -1109,7 +1109,7 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
: u32(0);
const auto vertex = entry_ir.IMul(local, step);
const auto first = entry_ir.IAdd(vertex, parity);
const auto second = mesh.InputPrimitiveSize() == 3u
const auto second = mesh.InputPrimitiveSize() >= 2u
? entry_ir.ISub(entry_ir.IAdd(vertex, u32(1)), parity)
: u32(0);
const auto third = mesh.InputPrimitiveSize() == 3u
+17 -13
View File
@@ -755,19 +755,9 @@ ShaderParams PrepareProgram(const HW::VertexShaderInfo& regs, const HW::Context&
}
return params;
}
EXIT_IF(regs.gs_regs.data_addr == 0);
const auto back = ShaderGetMappedData(regs.gs_regs.data_addr, "ShaderGetInputInfoGS():");
const auto back_params =
GetShaderParams(regs.gs_regs.data_addr, "ShaderRecompiler GS",
GetDeclaredShaderHash(regs.gs_regs.data_addr), {}, back);
params.back_code = back_params.code;
// Merged shaders receive the GS-back user-data pointer in s0:s1, followed
// by the ordinary user SGPRs at s8. Keep both in the runtime register snapshot.
// NGG user SGPRs start at s8; a separately compiled GS back half also receives
// its user-data pointer in s0:s1.
params.user_data.insert(params.user_data.begin(), 8u, 0u);
params.user_data[0] = static_cast<uint32_t>(regs.gs_regs.user_data_addr);
params.user_data[1] = static_cast<uint32_t>(regs.gs_regs.user_data_addr >> 32u);
const uint64_t hashes[] = {params.hash, back_params.hash};
params.hash = XXH3_64bits(hashes, sizeof(hashes));
info = {};
info.pa_cl_vs_out_cntl = sh.m_paClVsOutCntl;
auto& mesh = info.mesh;
@@ -776,11 +766,25 @@ ShaderParams PrepareProgram(const HW::VertexShaderInfo& regs, const HW::Context&
mesh.max_vertices = sh.m_geMaxOutputPerSubgroup;
mesh.provoking_vertex = context.GetModeControl().provoking_vtx_last ? 2u : 0u;
mesh.lds_size_dwords = static_cast<uint32_t>(regs.gs_regs.rsrc2.lds_size) * 128u;
mesh.scratch_size_dwords = std::max(data.scratch_size_dwords, back.scratch_size_dwords);
mesh.scratch_size_dwords = data.scratch_size_dwords;
if (data.type == Prospero::ShaderBinaryType::kGsFront) {
EXIT_IF(regs.gs_regs.data_addr == 0);
const auto back = ShaderGetMappedData(regs.gs_regs.data_addr, "ShaderGetInputInfoGS():");
const auto back_params =
GetShaderParams(regs.gs_regs.data_addr, "ShaderRecompiler GS",
GetDeclaredShaderHash(regs.gs_regs.data_addr), {}, back);
params.back_code = back_params.code;
params.user_data[0] = static_cast<uint32_t>(regs.gs_regs.user_data_addr);
params.user_data[1] = static_cast<uint32_t>(regs.gs_regs.user_data_addr >> 32u);
const uint64_t hashes[] = {params.hash, back_params.hash};
params.hash = XXH3_64bits(hashes, sizeof(hashes));
mesh.scratch_size_dwords = std::max(mesh.scratch_size_dwords, back.scratch_size_dwords);
}
EXIT_NOT_IMPLEMENTED(regs.gs_regs.rsrc1.gs_vgpr_component_count != 3u ||
regs.gs_regs.rsrc2.es_vgpr_component_count != 3u);
const auto& group = user_config.GetGeControl();
if ((user_config.GetPrimType() != Prospero::PrimitiveType::kPointList &&
user_config.GetPrimType() != Prospero::PrimitiveType::kLineList &&
user_config.GetPrimType() != Prospero::PrimitiveType::kTriStrip &&
user_config.GetPrimType() != Prospero::PrimitiveType::kTriList) ||
sh.m_vgtGsOutPrimType != 2u || sh.m_vgtGsMaxVertOut < 3u ||
+8 -2
View File
@@ -80,10 +80,15 @@ struct ShaderMeshInputInfo: ShaderWorkgroupInputInfo {
uint32_t provoking_vertex = 0;
[[nodiscard]] constexpr uint32_t InputPrimitiveSize() const {
return input_primitive == static_cast<uint32_t>(Prospero::PrimitiveType::kPointList) ? 1u : 3u;
switch (static_cast<Prospero::PrimitiveType>(input_primitive)) {
case Prospero::PrimitiveType::kPointList: return 1u;
case Prospero::PrimitiveType::kLineList: return 2u;
default: return 3u;
}
}
[[nodiscard]] constexpr uint32_t InputPrimitiveStep() const {
return input_primitive == static_cast<uint32_t>(Prospero::PrimitiveType::kTriList) ? 3u : 1u;
return input_primitive == static_cast<uint32_t>(Prospero::PrimitiveType::kTriStrip)
? 1u : InputPrimitiveSize();
}
[[nodiscard]] constexpr uint32_t InputPrimitiveCount(uint32_t vertices) const {
const auto size = InputPrimitiveSize();
@@ -257,6 +262,7 @@ struct Shader {
};
struct ShaderMappedData {
Prospero::ShaderBinaryType type {};
ShaderUserData* user_data = nullptr;
ShaderSemantic* input_semantics = nullptr;
uint32_t num_input_semantics = 0;