shader: remove redundant decoder and translator state

This commit is contained in:
nmzik
2026-09-08 11:43:13 +04:00
parent 80a18e82b7
commit 72963b01e1
13 changed files with 47 additions and 85 deletions
@@ -33,7 +33,7 @@ void Translator::S_SAVEEXEC(const Decoder::Instruction& inst, IR::ValueOpcode op
WriteMask(inst.dst, old, true);
} else {
WriteRawU32(inst.dst, ir.GetExecLo());
if (current_wave_size == 64u) {
if (program.wave_size == 64u) {
const auto low_half =
ir.ULessThan(IR::U32(ir.Emit(IR::ValueOpcode::LaneId)), IR::U32(IR::Value(32u)));
result = IR::U1(ir.Emit(IR::ValueOpcode::SelectU1, {low_half, result, old}));
@@ -328,7 +328,7 @@ void Translator::V_READFIRSTLANE_B32(const Decoder::Instruction& inst) {
}
void Translator::V_READLANE_B32(const Decoder::Instruction& inst) {
const auto lane_mask = IR::U32(IR::Value(current_wave_size == 32u ? 31u : 63u));
const auto lane_mask = IR::U32(IR::Value(program.wave_size == 32u ? 31u : 63u));
const auto lane = ir.BitwiseAnd(ReadU32(inst.src1), lane_mask);
WriteOperand(DestinationOperand(inst),
ir.Emit(IR::ValueOpcode::ReadLane, {ReadU32(inst.src0), lane}));
@@ -336,7 +336,7 @@ void Translator::V_READLANE_B32(const Decoder::Instruction& inst) {
void Translator::V_WRITELANE_B32(const Decoder::Instruction& inst) {
EXIT_IF(inst.dst.kind != Decoder::OperandKind::Vgpr);
const auto lane_mask = IR::U32(IR::Value(current_wave_size == 32u ? 31u : 63u));
const auto lane_mask = IR::U32(IR::Value(program.wave_size == 32u ? 31u : 63u));
const auto reg = static_cast<IR::VectorReg>(inst.dst.reg);
const auto lane = ir.BitwiseAnd(ReadU32(inst.src1), lane_mask);
const auto result = IR::U32(
@@ -290,15 +290,15 @@ IR::Value Translator::GetAddressResource(IR::Value low, IR::Value high) {
Translator::AddressOperands Translator::ReadAddressOperands(const Decoder::Instruction& inst,
uint32_t first_source) {
const auto memory = MemoryInfoFromDecoded(inst);
const auto kind = MemoryKind(inst);
const auto low = ReadU32(MemorySourceAt(inst, first_source));
const auto high_or_base = MemorySourceAt(inst, first_source + 1u);
if (memory.kind == IR::ResourceKind::Scratch) {
if (kind == IR::ResourceKind::Scratch) {
const auto offset =
high_or_base.kind != Decoder::OperandKind::Vgpr ? ReadU32(high_or_base) : low;
return {ir.Emit(IR::ValueOpcode::GetScratchResource), offset, IR::Value(0u)};
}
if (memory.kind == IR::ResourceKind::Global &&
if (kind == IR::ResourceKind::Global &&
high_or_base.kind != Decoder::OperandKind::Vgpr) {
const auto base_low = ReadU32(high_or_base);
const auto base_high = ReadU32(OffsetOperand(high_or_base, 1u));
@@ -329,18 +329,17 @@ IR::Value Translator::GetSamplerResource(const IR::MemoryInfo& memory) {
IR::Value Translator::MakeImageAddress(const Decoder::Instruction& inst,
const Decoder::Operand& base) {
const auto memory = MemoryInfoFromDecoded(inst);
std::array<IR::Value, 13> components {};
components.fill(IR::Value(0u));
const auto count =
Decoder::ImageAddressDwordCount(memory.image_sample_flags, memory.image_address_components);
Decoder::ImageAddressDwordCount(inst.image_sample_flags, inst.image_address_components);
EXIT_IF(count > components.size());
const auto nsa_components =
std::min(memory.image_nsa_dwords * 4u, Decoder::MaxImageNsaAddressComponents);
std::min(inst.image_nsa_dwords * 4u, Decoder::MaxImageNsaAddressComponents);
for (uint32_t index = 0; index < count; index++) {
if (index != 0u && index - 1u < nsa_components) {
components[index] =
ir.GetVectorReg(static_cast<IR::VectorReg>(memory.image_nsa_addr[index - 1u]));
ir.GetVectorReg(static_cast<IR::VectorReg>(inst.image_nsa_addr[index - 1u]));
} else {
components[index] = ReadRawU32(OffsetOperand(PlainOperand(base), index));
}
@@ -384,11 +383,10 @@ void Translator::WriteImageComponents(const Decoder::Operand& dst, IR::Value val
Translator::BufferAddress Translator::ReadBufferAddress(const Decoder::Instruction& inst,
uint32_t first_source) {
const auto memory = MemoryInfoFromDecoded(inst);
uint32_t cursor = first_source;
const auto next = [&]() { return ReadU32(MemorySourceAt(inst, cursor++)); };
const auto index = memory.idxen ? next() : IR::U32(IR::Value(0u));
const auto offset = memory.offen ? next() : IR::U32(IR::Value(0u));
const auto index = inst.idxen ? next() : IR::U32(IR::Value(0u));
const auto offset = inst.offen ? next() : IR::U32(IR::Value(0u));
const auto soffset = next();
return {index, offset, soffset};
}
@@ -112,7 +112,7 @@ Decoder::Operand Translator::PlainOperand(const Decoder::Operand& operand) {
std::array<IR::U32, 2> Translator::BallotMask(IR::U1 value) {
const auto mask = ir.Emit(IR::ValueOpcode::Ballot, {value});
return {ir.CompositeExtract(mask, 0),
current_wave_size == 64u ? ir.CompositeExtract(mask, 1) : IR::U32(IR::Value(0u))};
program.wave_size == 64u ? ir.CompositeExtract(mask, 1) : IR::U32(IR::Value(0u))};
}
IR::U32 Translator::ReadRawU32(const Decoder::Operand& operand) {
@@ -596,7 +596,7 @@ void Translator::WriteU32Pair(const Decoder::Operand& operand,
IR::U1 Translator::ThreadBit(const std::array<IR::U32, 2>& mask) {
const auto lane = IR::U32(ir.Emit(IR::ValueOpcode::LaneId));
const auto word = current_wave_size == 64u
const auto word = program.wave_size == 64u
? ir.Select(ir.ULessThan(lane, IR::U32(IR::Value(32u))), mask[0], mask[1])
: mask[0];
const auto bit = ir.BitwiseAnd(lane, IR::U32(IR::Value(31u)));
@@ -621,7 +621,7 @@ IR::U1 Translator::ReadMask(const Decoder::Operand& operand) {
switch (operand.kind) {
case Decoder::OperandKind::Sgpr: {
const auto reg = static_cast<IR::ScalarReg>(operand.reg);
const auto mask = current_wave_size == 64u
const auto mask = program.wave_size == 64u
? ReadU32Pair(operand)
: std::array {ReadRawU32(operand), IR::U32(IR::Value(0u))};
return IR::U1(ir.Emit(
@@ -632,7 +632,7 @@ IR::U1 Translator::ReadMask(const Decoder::Operand& operand) {
case Decoder::OperandKind::ExecHi: return ir.GetExec();
case Decoder::OperandKind::VccLo:
case Decoder::OperandKind::VccHi:
return current_wave_size == 32u
return program.wave_size == 32u
? ThreadBit({ReadRawU32(operand), IR::U32(IR::Value(0u))})
: ir.GetVcc();
case Decoder::OperandKind::Scc: return ir.GetScc();
@@ -682,7 +682,7 @@ std::array<IR::U32, 2> Translator::WriteMask(const Decoder::Operand& operand, IR
}
ir.SetScalarReg(reg, mask[0]);
// A wave32 VALU mask destination must not overwrite the neighboring SGPR.
if ((write_64 || current_wave_size == 64u) &&
if ((write_64 || program.wave_size == 64u) &&
IR::RegIndex(reg) + 1u < IR::NumScalarRegs) {
const auto high = static_cast<IR::ScalarReg>(IR::RegIndex(reg) + 1u);
ir.SetScalarReg(high, mask[1]);
@@ -700,7 +700,7 @@ std::array<IR::U32, 2> Translator::WriteMask(const Decoder::Operand& operand, IR
}
case Decoder::OperandKind::VccLo:
case Decoder::OperandKind::VccHi: {
if (!write_64 && current_wave_size == 32u) {
if (!write_64 && program.wave_size == 32u) {
WriteRawU32(operand, mask[0]);
return mask;
}
@@ -1198,7 +1198,7 @@ IR::Program TranslateProgram(const Decoder::Program& decoded, const CFG::Graph&
}
for (const auto& cfg_block: cfg.blocks) {
const auto typed_index = block_indices.at(cfg_block.id);
Translator translator(result, result.blocks[typed_index], vector_limit, options.wave_size);
Translator translator(result, result.blocks[typed_index], vector_limit);
for (uint32_t index = cfg_block.inst_begin; index < cfg_block.inst_end; index++) {
const auto& instruction = decoded.instructions[index];
if (IsCodeTableLoad(cfg, instruction.pc)) {
@@ -9,9 +9,8 @@ namespace Libs::Graphics::ShaderRecompiler::Frontend {
class Translator {
public:
Translator(IR::Program& program, IR::Block* block, uint32_t vector_limit, uint32_t wave_size)
: program(program), ir(block), current_vector_limit(vector_limit),
current_wave_size(wave_size) {}
Translator(IR::Program& program, IR::Block* block, uint32_t vector_limit)
: program(program), ir(block), current_vector_limit(vector_limit) {}
void TranslateInstruction(const Decoder::Instruction& inst);
void TranslateEmbeddedFetch(const Decoder::Instruction& inst, uint32_t attribute,
@@ -258,7 +257,6 @@ private:
Decoder::Opcode current_opcode = Decoder::Opcode::UNKNOWN;
uint32_t current_pc = 0;
uint32_t current_vector_limit = 1;
uint32_t current_wave_size = 64;
};
} // namespace Libs::Graphics::ShaderRecompiler::Frontend