shader: remove second IR layer

This commit is contained in:
nmzik
2026-08-26 07:42:51 +02:00
parent e2c840cb23
commit ffa69d48de
49 changed files with 3691 additions and 6001 deletions
@@ -1,57 +1,73 @@
#include "graphics/shader/recompiler/frontend/translate/Translator.h"
namespace Libs::Graphics::ShaderRecompiler::Frontend::Detail {
namespace Libs::Graphics::ShaderRecompiler::Frontend {
bool Translator::TranslateU64MaskOperation(const IR::Instruction& inst) {
bool Translator::TranslateU64MaskOperation(const Decoder::Instruction& inst) {
switch (inst.opcode) {
case Decoder::Opcode::S_AND_B64:
case Decoder::Opcode::S_ANDN2_B64:
case Decoder::Opcode::S_OR_B64:
case Decoder::Opcode::S_ORN2_B64:
case Decoder::Opcode::S_XOR_B64:
case Decoder::Opcode::S_NAND_B64:
case Decoder::Opcode::S_NOR_B64:
case Decoder::Opcode::S_XNOR_B64:
case Decoder::Opcode::S_NOT_B64: break;
default: return false;
}
const auto invocation_result = EvaluateU64Mask(inst);
const auto is_exec_or_vcc = [](const IR::Operand& operand) {
return operand.kind == IR::OperandKind::Register &&
(operand.reg.file == IR::RegisterFile::Exec ||
operand.reg.file == IR::RegisterFile::Vcc);
const auto is_exec_or_vcc = [](const Decoder::Operand& operand) {
switch (operand.kind) {
case Decoder::OperandKind::ExecLo:
case Decoder::OperandKind::ExecHi:
case Decoder::OperandKind::VccLo:
case Decoder::OperandKind::VccHi: return true;
default: return false;
}
};
if (is_exec_or_vcc(inst.dst) || is_exec_or_vcc(inst.src[0]) ||
(inst.src_count > 1u && is_exec_or_vcc(inst.src[1]))) {
if (is_exec_or_vcc(inst.dst) || is_exec_or_vcc(inst.src0) ||
(inst.src_count > 1u && is_exec_or_vcc(inst.src1))) {
WriteMask64(inst.dst, invocation_result);
ir.SetScc(invocation_result);
return true;
}
const auto lhs = ReadU32Pair(inst.src[0]);
auto mask_valid = ReadMaskValid(inst.src[0]);
const auto lhs = ReadU32Pair(inst.src0);
auto mask_valid = ReadMaskValid(inst.src0);
if (inst.src_count > 1u) {
mask_valid = ir.LogicalAnd(mask_valid, ReadMaskValid(inst.src[1]));
mask_valid = ir.LogicalAnd(mask_valid, ReadMaskValid(inst.src1));
}
std::array<IR::U32, 2> result;
if (inst.op == IR::Opcode::BitwiseNotU64) {
if (inst.opcode == Decoder::Opcode::S_NOT_B64) {
result = {ir.BitwiseNot(lhs[0]), ir.BitwiseNot(lhs[1])};
} else {
const auto rhs = ReadU32Pair(inst.src[1]);
const auto rhs = ReadU32Pair(inst.src1);
for (uint32_t component = 0; component < 2u; component++) {
switch (inst.op) {
case IR::Opcode::BitwiseAndU64:
switch (inst.opcode) {
case Decoder::Opcode::S_AND_B64:
result[component] = ir.BitwiseAnd(lhs[component], rhs[component]);
break;
case IR::Opcode::BitwiseAndNotU64:
case Decoder::Opcode::S_ANDN2_B64:
result[component] =
ir.BitwiseAnd(lhs[component], ir.BitwiseNot(rhs[component]));
break;
case IR::Opcode::BitwiseOrU64:
case Decoder::Opcode::S_OR_B64:
result[component] = ir.BitwiseOr(lhs[component], rhs[component]);
break;
case IR::Opcode::BitwiseOrNotU64:
case Decoder::Opcode::S_ORN2_B64:
result[component] = ir.BitwiseOr(lhs[component], ir.BitwiseNot(rhs[component]));
break;
case IR::Opcode::BitwiseXorU64:
case Decoder::Opcode::S_XOR_B64:
result[component] = ir.BitwiseXor(lhs[component], rhs[component]);
break;
case IR::Opcode::BitwiseNandU64:
case Decoder::Opcode::S_NAND_B64:
result[component] =
ir.BitwiseNot(ir.BitwiseAnd(lhs[component], rhs[component]));
break;
case IR::Opcode::BitwiseNorU64:
case Decoder::Opcode::S_NOR_B64:
result[component] = ir.BitwiseNot(ir.BitwiseOr(lhs[component], rhs[component]));
break;
case IR::Opcode::BitwiseXnorU64:
case Decoder::Opcode::S_XNOR_B64:
result[component] =
ir.BitwiseNot(ir.BitwiseXor(lhs[component], rhs[component]));
break;
@@ -60,9 +76,8 @@ bool Translator::TranslateU64MaskOperation(const IR::Instruction& inst) {
}
}
WriteU32Pair(inst.dst, result);
if (inst.dst.kind == IR::OperandKind::Register &&
inst.dst.reg.file == IR::RegisterFile::Scalar) {
const auto dst = static_cast<IR::ScalarReg>(inst.dst.reg.index);
if (inst.dst.kind == Decoder::OperandKind::Sgpr) {
const auto dst = static_cast<IR::ScalarReg>(inst.dst.reg);
ir.SetThreadBitScalarReg(dst, invocation_result);
ir.SetScalarMaskTag(dst, mask_valid);
const auto raw_nonzero =
@@ -75,29 +90,68 @@ bool Translator::TranslateU64MaskOperation(const IR::Instruction& inst) {
return true;
}
bool Translator::TranslateInstruction(const IR::Instruction& inst) {
switch (IR::GetOpcodeInfo(inst.op).lowering_class) {
case IR::LoweringClass::Control: return TranslateControlOperation(inst);
case IR::LoweringClass::Move: return TranslateMove(inst);
case IR::LoweringClass::Lane: return TranslateLaneOperation(inst);
case IR::LoweringClass::State: return TranslateStateOperation(inst);
case IR::LoweringClass::Memory: return TranslateMemoryOperation(inst);
case IR::LoweringClass::Attribute: return TranslateAttributeOperation(inst);
case IR::LoweringClass::IntegerCompare: return TranslateIntegerCompare(inst);
case IR::LoweringClass::Integer16Compare: return TranslateInteger16Compare(inst);
case IR::LoweringClass::FloatCompare: return TranslateFloatCompare(inst);
case IR::LoweringClass::Conversion: return TranslateConversion(inst);
case IR::LoweringClass::Integer16: return TranslateInteger16Operation(inst);
case IR::LoweringClass::PackedInteger16: return TranslatePackedInteger16(inst);
case IR::LoweringClass::PackedFloat16: return TranslatePackedFloat16(inst);
case IR::LoweringClass::Float16: return TranslateFloat16Operation(inst);
case IR::LoweringClass::Float: return TranslateFloatOperation(inst);
case IR::LoweringClass::U64Mask: return TranslateU64MaskOperation(inst);
case IR::LoweringClass::SimpleInteger: return TranslateSimpleInteger(inst);
case IR::LoweringClass::ComposedInteger: return TranslateComposedInteger(inst);
case IR::LoweringClass::ExtendedInteger: return TranslateExtendedInteger(inst);
bool Translator::TranslateInstruction(const Decoder::Instruction& inst, std::string* error) {
current_opcode = inst.opcode;
current_pc = inst.pc;
switch (inst.opcode) {
case Decoder::Opcode::UNKNOWN:
case Decoder::Opcode::COUNT:
if (error != nullptr) {
*error = "decoded opcode has no IR translation";
}
return false;
case Decoder::Opcode::UNSUPPORTED:
if (error != nullptr) {
*error = "unsupported decoded instruction: " + Decoder::InstructionToString(inst);
}
return false;
case Decoder::Opcode::S_GETPC_B64: return TranslateMove(inst, error);
case Decoder::Opcode::V_MOVRELS_B32:
case Decoder::Opcode::V_MOVRELD_B32: return TranslateLaneOperation(inst, error);
default: break;
}
return false;
switch (inst.family) {
case Decoder::Family::SMEM:
case Decoder::Family::MUBUF:
case Decoder::Family::MTBUF:
case Decoder::Family::FLAT:
case Decoder::Family::DS:
case Decoder::Family::MIMG: return TranslateMemoryOperation(inst, error);
case Decoder::Family::EXP: return TranslateAttributeOperation(inst, error);
default: break;
}
switch (inst.opcode) {
case Decoder::Opcode::V_INTERP_P1_F32:
case Decoder::Opcode::V_INTERP_P2_F32:
case Decoder::Opcode::V_INTERP_MOV_F32: return TranslateAttributeOperation(inst, error);
case Decoder::Opcode::S_BRANCH:
case Decoder::Opcode::S_CBRANCH_SCC0:
case Decoder::Opcode::S_CBRANCH_SCC1:
case Decoder::Opcode::S_CBRANCH_VCCZ:
case Decoder::Opcode::S_CBRANCH_VCCNZ:
case Decoder::Opcode::S_CBRANCH_EXECZ:
case Decoder::Opcode::S_CBRANCH_EXECNZ:
case Decoder::Opcode::S_SETPC_B64:
case Decoder::Opcode::S_ENDPGM: return true;
default: break;
}
const bool translated = TranslateControlOperation(inst) || TranslateStateOperation(inst) ||
TranslateMove(inst, error) || TranslateLaneOperation(inst, error) ||
TranslateIntegerCompare(inst) || TranslateInteger16Compare(inst) ||
TranslateFloatCompare(inst) || TranslateConversion(inst) ||
TranslateInteger16Operation(inst) || TranslatePackedInteger16(inst) ||
TranslatePackedFloat16(inst) || TranslateFloat16Operation(inst) ||
TranslateFloatOperation(inst) || TranslateU64MaskOperation(inst) ||
TranslateSimpleInteger(inst) || TranslateComposedInteger(inst) ||
TranslateExtendedInteger(inst);
if (!translated && error != nullptr) {
*error = "decoded opcode has no IR translation";
}
return translated;
}
} // namespace Libs::Graphics::ShaderRecompiler::Frontend::Detail
} // namespace Libs::Graphics::ShaderRecompiler::Frontend