shader: preserve folded native constants for descriptor provenance

This commit is contained in:
nmzik committed 2026-10-15 23:22:30 +02:00
1 parent e4019af522
commit c8caa27936
11 files changed
+111 -43

No files matched your search

@@ -679,13 +679,6 @@ void ValidateProgram(const Program& program, bool require_ssa) {
}
}
void ResolveControlFlowIdentities(Program& program) {
for (auto* block: program.blocks) {
block->condition = block->condition.Resolve();
block->indirect_target = block->indirect_target.Resolve();
}
}
std::string ProgramToString(const Program& program) {
std::map<const Inst*, size_t> ids;
size_t next_id = 1;
+1 -2
View File
@@ -701,7 +701,7 @@ struct Program: ResourcePlan {
bool dispatcher_fallback = false;
CFG::FailureKind cfg_failure_kind = CFG::FailureKind::None;
std::string fallback_reason;
struct ScalarWrite { uint32_t pc; ScalarReg reg; };
struct ScalarWrite { uint32_t pc; ScalarReg reg; Value value; };
std::vector<ScalarWrite> scalar_writes;
// Typed memory and export instructions reference shader-local metadata by dense index.
// Decoder-only details (such as NSA register numbers) have already become IR operands.
@@ -718,7 +718,6 @@ std::string ProgramToString(const Program& program);
bool HasShaderMemoryWrites(const Program& program);
void ValidateProgram(const Program& program, bool require_ssa);
void ResolveControlFlowIdentities(Program& program);
bool EquivalentValue(const ResourcePlan& program, Value left, Value right);
bool EquivalentSelectorDomain(const ResourcePlan& program,
const DescriptorSource::IndirectDescriptor& left,
@@ -1,11 +1,21 @@
#include "graphics/shader/recompiler/ir/passes/DeadCodeElimination.h"
#include "graphics/shader/recompiler/ir/ShaderIR.h"
#include <algorithm>
namespace Libs::Graphics::ShaderRecompiler::IR {
void RemoveIdentities(const BlockList& blocks) {
for (auto* block: blocks) {
void RemoveIdentities(Program& program) {
// Resolve metadata before deleting its identity nodes; retain only folded native constants.
for (auto& write: program.scalar_writes) {
const auto value = write.value.Resolve();
write.value = value.IsImmediate() && value.GetType() == Type::U32 ? value : Value {};
}
for (auto* block: program.blocks) {
block->condition = block->condition.Resolve();
block->indirect_target = block->indirect_target.Resolve();
}
for (auto* block: program.blocks) {
auto& instructions = block->Instructions();
for (auto inst = instructions.begin(); inst != instructions.end();) {
if (inst->GetOpcode() != ValueOpcode::Identity) {
@@ -4,7 +4,9 @@
namespace Libs::Graphics::ShaderRecompiler::IR {
void RemoveIdentities(const BlockList& blocks);
struct Program;
void RemoveIdentities(Program& program);
void EliminateDeadCode(const BlockList& blocks);
} // namespace Libs::Graphics::ShaderRecompiler::IR
@@ -604,9 +604,20 @@ private:
candidates.push_back(inst);
}
}
if (candidates.empty()) return value;
const auto source_at = [&](uint32_t pc) {
Value source;
bool dynamic = false;
for (auto write = std::ranges::lower_bound(m_scalar_writes, pc, {}, &Program::ScalarWrite::pc);
write != m_scalar_writes.end() && write->pc == pc; ++write) {
if (RegIndex(write->reg) != reg) continue;
if (!write->value.IsImmediate() || write->value.GetType() != Type::U32) {
dynamic = true;
continue;
}
if (!source.IsEmpty() && source != write->value) return Value {};
source = write->value;
}
if (!source.IsEmpty()) return dynamic ? Value {} : source;
const auto native = std::ranges::lower_bound(m_decoded.instructions, pc, {},
&Decoder::Instruction::pc);
for (const auto* candidate: candidates) {
@@ -644,8 +655,9 @@ private:
const auto source = source_at(pc);
if (source.IsEmpty()) return false;
if (!selected.IsEmpty()) {
const auto op = source.TryInstruction()->GetOpcode();
if ((op == ValueOpcode::LoadAddressU32 || op == ValueOpcode::ReadConstBuffer) &&
const auto* inst = source.TryInstruction();
if (inst != nullptr &&
(inst->GetOpcode() == ValueOpcode::LoadAddressU32 || inst->GetOpcode() == ValueOpcode::ReadConstBuffer) &&
selected_pc != pc) return false;
if (!EquivalentValue(m_program, selected, source)) return false;
}