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
@@ -77,8 +77,7 @@ enum class EmbeddedFetchValueType {
AttribTable,
Attrib,
BufferTable,
Buffer,
Index
Buffer
};
struct EmbeddedFetchSgprInfo {
@@ -88,10 +87,6 @@ struct EmbeddedFetchSgprInfo {
std::vector<uint32_t> prolog_loads;
};
struct EmbeddedFetchVgprInfo {
EmbeddedFetchValueType type = EmbeddedFetchValueType::Unknown;
};
using EmbeddedFetchVectorLanes = std::map<uint64_t, EmbeddedFetchSgprInfo>;
uint64_t EmbeddedFetchVectorLaneKey(uint32_t reg, uint32_t lane) {
@@ -108,7 +103,6 @@ void ClearEmbeddedFetchVectorLanes(EmbeddedFetchVectorLanes* lanes, uint32_t reg
lanes->erase(first, last);
}
using EmbeddedFetchLoad = Frontend::EmbeddedFetchLoad;
using EmbeddedFetchData = Frontend::EmbeddedFetchPlan;
bool IsDecodedSgpr(const Decoder::Operand& op) {
@@ -244,7 +238,7 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
const int buffer_reg = input_info->fetch_buffer_reg + shift_regs;
std::array<EmbeddedFetchSgprInfo, 108> sgprs {};
std::array<EmbeddedFetchVgprInfo, 256> vgprs {};
std::array<bool, 256> vgpr_is_index {};
EmbeddedFetchVectorLanes vector_lanes;
const bool track_vector_lanes =
std::none_of(decoded.instructions.begin(), decoded.instructions.end(),
@@ -299,8 +293,8 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
switch (inst.opcode) {
case Decoder::Opcode::V_WRITELANE_B32: {
uint32_t lane = 0;
if (IsDecodedVgpr(inst.dst) && inst.dst.reg < vgprs.size()) {
vgprs[inst.dst.reg] = {};
if (IsDecodedVgpr(inst.dst) && inst.dst.reg < vgpr_is_index.size()) {
vgpr_is_index[inst.dst.reg] = false;
}
if (track_vector_lanes && IsDecodedVgpr(inst.dst) && IsDecodedSgpr(inst.src0) &&
DecodedSgprReg(inst.src0) < sgprs.size() &&
@@ -405,13 +399,13 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
ClearEmbeddedFetchSgprs(sgprs, inst.dst, DecodedDstSize(inst));
}
} else if (inst.opcode == Decoder::Opcode::V_CNDMASK_B32) {
if (IsDecodedVgpr(inst.dst) && inst.dst.reg < vgprs.size()) {
if (IsDecodedVgpr(inst.dst) && inst.dst.reg < vgpr_is_index.size()) {
ClearEmbeddedFetchVectorLanes(&vector_lanes, inst.dst.reg);
}
if (IsDecodedVgpr(inst.dst) && inst.dst.reg < vgprs.size() &&
if (IsDecodedVgpr(inst.dst) && inst.dst.reg < vgpr_is_index.size() &&
IsDecodedVgpr(inst.src0) && inst.src0.reg == 8 &&
IsDecodedVgpr(inst.src1) && inst.src1.reg == 5) {
vgprs[inst.dst.reg].type = EmbeddedFetchValueType::Index;
vgpr_is_index[inst.dst.reg] = true;
}
} else if (IsEmbeddedFetchAttribPropagationAlu(inst)) {
if (IsDecodedSgpr(inst.dst) && IsDecodedSgpr(inst.src0) &&
@@ -441,16 +435,11 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
}
}
} else if (IsEmbeddedFetchBufferLoad(inst)) {
if (IsDecodedVgpr(inst.src0) && inst.src0.reg < vgprs.size() &&
vgprs[inst.src0.reg].type == EmbeddedFetchValueType::Index &&
if (IsDecodedVgpr(inst.src0) && inst.src0.reg < vgpr_is_index.size() &&
vgpr_is_index[inst.src0.reg] &&
IsDecodedSgpr(inst.src1) && DecodedSgprReg(inst.src1) < sgprs.size() &&
sgprs[DecodedSgprReg(inst.src1)].type == EmbeddedFetchValueType::Buffer) {
const auto& buffer = sgprs[DecodedSgprReg(inst.src1)];
EmbeddedFetchLoad load;
load.pc = inst.pc;
load.attrib_id = buffer.attrib_id;
load.components = DecodedDstSize(inst);
load.prolog_loads = buffer.prolog_loads;
const auto& buffer = sgprs[DecodedSgprReg(inst.src1)];
if (data.loads.empty()) {
if (!vertex_offset_conflict) {
data.vertex_offset_sgpr = vertex_offset_candidate;
@@ -459,7 +448,11 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
data.instance_offset_sgpr = instance_offset_candidate;
}
}
data.loads.push_back(load);
auto& load = data.loads.emplace_back();
load.pc = inst.pc;
load.attrib_id = buffer.attrib_id;
load.components = DecodedDstSize(inst);
load.prolog_loads = buffer.prolog_loads;
}
}
break;
@@ -467,7 +460,8 @@ EmbeddedFetchData DetectEmbeddedVertexFetch(const Decoder::Program& decoded
if (inst.opcode == Decoder::Opcode::V_MOVRELD_B32) {
vector_lanes.clear();
} else if (inst.opcode != Decoder::Opcode::V_WRITELANE_B32 && IsDecodedVgpr(inst.dst)) {
for (uint32_t i = 0; i < EmbeddedFetchDstSize(inst) && inst.dst.reg + i < vgprs.size();
for (uint32_t i = 0;
i < EmbeddedFetchDstSize(inst) && inst.dst.reg + i < vgpr_is_index.size();
i++) {
ClearEmbeddedFetchVectorLanes(&vector_lanes, inst.dst.reg + i);
}
@@ -664,11 +658,6 @@ TranslateResult TranslateProgram(std::span<const uint32_t> code, const CompileOp
IR::EliminateDeadCode(ir.blocks);
IR::TrackResources(ir);
IR::EliminateDeadCode(ir.blocks);
if (options.stage == ShaderType::Vertex) {
ir.info.vertex_offset_sgpr = embedded_fetch.vertex_offset_sgpr;
ir.info.instance_offset_sgpr = embedded_fetch.instance_offset_sgpr;
}
TranslateResult result;
result.program = std::move(ir);
if (options.dump_ir) {
@@ -10,7 +10,6 @@ void DecodeExp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index,
const uint32_t en = word0 & 0xfu;
inst.pc = pc;
inst.word = word0;
inst.word_count = 2;
inst.family = Family::EXP;
inst.opcode_id = target;
@@ -349,7 +349,6 @@ void DecodeMimg(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const auto* atomic = LookupAtomic(opcode);
inst.pc = pc;
inst.word = word0;
inst.word_count = word_count;
inst.family = Family::MIMG;
inst.opcode_id = opcode;
@@ -231,7 +231,6 @@ void DecodeSmem(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t soffset = (word1 >> 25u) & 0x7fu;
inst.pc = pc;
inst.word = word0;
inst.word_count = 2;
inst.offset = SignExtendU32(word1 & 0x1fffffu, 21u);
inst.glc = ((word0 >> 16u) & 1u) != 0;
@@ -263,7 +262,6 @@ void DecodeMubuf(uint32_t pc, std::span<const uint32_t> code, uint32_t word_inde
const uint32_t soffset = (word1 >> 24u) & 0xffu;
inst.pc = pc;
inst.word = word0;
inst.word_count = 2;
inst.offset = word0 & 0xfffu;
inst.idxen = ((word0 >> 13u) & 1u) != 0;
@@ -299,7 +297,6 @@ void DecodeMtbuf(uint32_t pc, std::span<const uint32_t> code, uint32_t word_inde
const uint32_t soffset = (word1 >> 24u) & 0xffu;
inst.pc = pc;
inst.word = word0;
inst.word_count = 2;
inst.offset = word0 & 0xfffu;
inst.idxen = ((word0 >> 13u) & 1u) != 0;
@@ -339,7 +336,6 @@ void DecodeFlat(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t addr = word1 & 0xffu;
inst.pc = pc;
inst.word = word0;
inst.word_count = 2;
inst.offset = seg == 0u ? (offset & 0x7ffu) : SignExtendU32(offset, 12u);
inst.glc = ((word0 >> 16u) & 1u) != 0;
@@ -384,7 +380,6 @@ void DecodeDs(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index,
const uint32_t addr = word1 & 0xffu;
inst.pc = pc;
inst.word = word0;
inst.word_count = 2;
inst.offset = offset0 | (offset1 << 8u);
inst.gds = ((word0 >> 17u) & 1u) != 0u;
@@ -129,7 +129,6 @@ void DecodeSop1(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t sdst = (word >> 16u) & 0x7fu;
inst.pc = pc;
inst.word = word;
inst.family = Family::SOP1;
inst.opcode_id = opcode;
inst.opcode = Detail::LookupOpcode(SOP1_OPS, opcode);
@@ -169,7 +168,6 @@ void DecodeSop2(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t sdst = (word >> 16u) & 0x7fu;
inst.pc = pc;
inst.word = word;
inst.family = Family::SOP2;
inst.opcode_id = opcode;
inst.opcode = Detail::LookupOpcode(SOP2_OPS, opcode);
@@ -194,7 +192,6 @@ void DecodeSopk(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
: static_cast<int32_t>(static_cast<int16_t>(word & 0xffffu));
inst.pc = pc;
inst.word = word;
inst.family = Family::SOPK;
inst.opcode_id = opcode;
inst.opcode = Detail::LookupOpcode(SOPK_OPS, opcode);
@@ -250,7 +247,6 @@ void DecodeSopc(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t opcode = (word >> 16u) & 0x7fu;
inst.pc = pc;
inst.word = word;
inst.family = Family::SOPC;
inst.opcode_id = opcode;
inst.opcode = Detail::LookupOpcode(SOPC_OPS, opcode);
@@ -272,7 +268,6 @@ void DecodeSopp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t simm = word & 0xffffu;
inst.pc = pc;
inst.word = word;
inst.family = Family::SOPP;
inst.opcode_id = opcode;
inst.opcode = Detail::LookupOpcode(SOPP_OPS, opcode);
@@ -288,8 +283,8 @@ void DecodeSopp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
inst.opcode == Opcode::S_TTRACEDATA || inst.opcode == Opcode::S_INST_PREFETCH)
? 1
: 0;
inst.branch_offset = static_cast<int32_t>(static_cast<int16_t>(simm)) * 4;
inst.branch_target = pc + 4u + static_cast<uint32_t>(inst.branch_offset);
const auto branch_offset = static_cast<int32_t>(static_cast<int16_t>(simm)) * 4;
inst.branch_target = pc + 4u + static_cast<uint32_t>(branch_offset);
SetRawWords(inst, code, word_index, 1);
if (inst.opcode == Opcode::UNSUPPORTED) {
@@ -47,7 +47,7 @@ void ApplyLiteral(Operand& operand, uint32_t literal) {
std::string RawWordsToString(const Instruction& inst) {
std::string text;
for (uint32_t i = 0; i < inst.raw_count; i++) {
for (uint32_t i = 0; i < inst.word_count; i++) {
if (i != 0) {
text += " ";
}
@@ -234,8 +234,7 @@ void DecodeScalarSource(uint32_t code, uint32_t pc, Operand& operand) {
if (code >= 240u && code <= 247u) {
constexpr float values[] = {0.5f, -0.5f, 1.0f, -1.0f, 2.0f, -2.0f, 4.0f, -4.0f};
operand.kind = OperandKind::FloatInlineConstant;
operand.float_val = values[code - 240u];
operand.value = FloatBits(operand.float_val);
operand.value = FloatBits(values[code - 240u]);
return;
}
if (code >= 256u && code <= 511u) {
@@ -253,8 +252,7 @@ void DecodeScalarSource(uint32_t code, uint32_t pc, Operand& operand) {
case 239u: operand.kind = OperandKind::PopsExitingWaveId; return;
case 248u:
operand.kind = OperandKind::FloatInlineConstant;
operand.float_val = 0.15915494309189535f;
operand.value = FloatBits(operand.float_val);
operand.value = FloatBits(0.15915494309189535f);
return;
case 251u: operand.kind = OperandKind::VccZ; return;
case 252u: operand.kind = OperandKind::ExecZ; return;
@@ -307,8 +305,7 @@ void ReadLiteralOperands(std::span<const uint32_t> code, uint32_t word_index, In
void SetRawWords(Instruction& inst, std::span<const uint32_t> code, uint32_t word_index,
uint32_t word_count) {
inst.word_count = word_count;
inst.raw_count = word_count;
for (uint32_t i = 0; i < inst.raw_count; i++) {
for (uint32_t i = 0; i < inst.word_count; i++) {
inst.raw[i] = code[word_index + i];
}
}
@@ -415,7 +412,9 @@ std::string OperandToString(const Operand& operand) {
case OperandKind::IntegerInlineConstant:
text = fmt::format("{}", operand.signed_val);
break;
case OperandKind::FloatInlineConstant: text = fmt::format("{:f}", operand.float_val); break;
case OperandKind::FloatInlineConstant:
text = fmt::format("{:f}", std::bit_cast<float>(operand.value));
break;
case OperandKind::Sgpr: text = fmt::format("s{}", operand.reg); break;
case OperandKind::Vgpr: text = fmt::format("v{}", operand.reg); break;
case OperandKind::VccLo: text = "vcc_lo"; break;
@@ -634,7 +634,6 @@ struct Operand {
OperandKind kind = OperandKind::Unknown;
uint32_t value = 0;
int32_t signed_val = 0;
float float_val = 0.0f;
uint32_t reg = 0;
uint32_t sdwa_sel = 6;
// Native 16-bit destinations use the same selector fields internally but preserve the
@@ -659,10 +658,8 @@ struct Operand {
struct Instruction {
uint32_t pc = 0;
uint32_t word = 0;
uint32_t word_count = 1;
uint32_t raw[MaxInstructionRawWords] = {};
uint32_t raw_count = 1;
Family family = Family::Unknown;
uint32_t opcode_id = 0;
Opcode opcode = Opcode::UNKNOWN;
@@ -696,7 +693,6 @@ struct Instruction {
bool idxen = false;
bool offen = false;
bool image_r128 = false;
int32_t branch_offset = 0;
uint32_t branch_target = 0;
struct {
uint32_t target = 0;
@@ -1534,7 +1534,6 @@ void DecodeVop2(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t vsrc1 = (word >> 9u) & 0xffu;
inst.pc = pc;
inst.word = word;
inst.family = Family::VOP2;
inst.opcode_id = opcode;
inst.opcode = LookupVop2Opcode(opcode);
@@ -1562,7 +1561,6 @@ void DecodeVop1(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t vdst = (word >> 17u) & 0xffu;
inst.pc = pc;
inst.word = word;
inst.family = Family::VOP1;
inst.opcode_id = opcode;
inst.opcode = Detail::LookupOpcode(VOP1_OPS, opcode);
@@ -1599,7 +1597,6 @@ void DecodeVopc(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t vsrc1 = (word >> 9u) & 0xffu;
inst.pc = pc;
inst.word = word;
inst.family = Family::VOPC;
inst.opcode_id = opcode;
inst.opcode = Detail::LookupOpcode(VOPC_OPS, opcode);
@@ -1638,7 +1635,6 @@ void DecodeVop3(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
const uint32_t neg = (word1 >> 29u) & 0x7u;
inst.pc = pc;
inst.word = word0;
inst.family = Family::VOP3;
inst.opcode_id = opcode;
inst.opcode = LookupVop3Opcode(opcode);
@@ -1792,7 +1788,6 @@ void DecodeVop3p(uint32_t pc, std::span<const uint32_t> code, uint32_t word_inde
const uint32_t neg = (word1 >> 29u) & 0x7u;
inst.pc = pc;
inst.word = word0;
inst.family = Family::VOP3P;
inst.opcode_id = opcode;
inst.opcode = Detail::LookupOpcode(VOP3P_OPS, opcode);
@@ -1842,7 +1837,6 @@ void DecodeVintrp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_ind
const uint32_t vsrc = word & 0xffu;
inst.pc = pc;
inst.word = word;
inst.word_count = 1;
inst.family = Family::VINTRP;
inst.opcode_id = opcode;
@@ -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
+1 -1
View File
@@ -4328,7 +4328,7 @@ void TestNewShaderRecompilerCapturedVopcSdwaCmpxClass() {
Check(decoded.family == Decoder::Family::VOPC &&
decoded.opcode == Decoder::Opcode::V_CMPX_CLASS_F32 &&
decoded.opcode_id == 0x98u && decoded.word_count == 2u &&
decoded.raw_count == 2u &&
decoded.raw[0] == shader[0] && decoded.raw[1] == shader[1] &&
decoded.dst.kind == Decoder::OperandKind::ExecLo &&
decoded.src_count == 2u &&
decoded.src0.kind == Decoder::OperandKind::Vgpr &&