mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 02:47:02 +02:00
shader: reuse operands and remove duplicate helpers
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
#include <iterator>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <span>
|
||||
#include <stack>
|
||||
|
||||
namespace Libs::Graphics::ShaderRecompiler::CFG {
|
||||
@@ -861,15 +862,15 @@ void ComputeNaturalLoops(Graph& graph) {
|
||||
loop.header = edge.to;
|
||||
loop.latch = edge.from;
|
||||
loop.continue_block = edge.from;
|
||||
loop.body_blocks = body;
|
||||
loop.body_blocks = std::move(body);
|
||||
|
||||
for (auto block_id: body) {
|
||||
for (auto block_id: loop.body_blocks) {
|
||||
const auto* block = graph.FindBlock(block_id);
|
||||
if (block == nullptr) {
|
||||
continue;
|
||||
}
|
||||
for (auto succ: block->successors) {
|
||||
if (!Contains(body, succ)) {
|
||||
if (!Contains(loop.body_blocks, succ)) {
|
||||
AddUnique(loop.exit_blocks, succ);
|
||||
}
|
||||
}
|
||||
@@ -1749,7 +1750,7 @@ bool RouteOneSharedArm(Graph& graph, uint32_t original_block_count, uint32_t out
|
||||
inner_is_true ? outer->terminator.false_block : outer->terminator.true_block;
|
||||
const auto* inner = graph.FindBlock(inner_id);
|
||||
if (inner == nullptr || inner->inst_begin == inner->inst_end ||
|
||||
inner->predecessors != std::vector<uint32_t> {outer_id} ||
|
||||
inner->predecessors.size() != 1u || inner->predecessors.front() != outer_id ||
|
||||
inner->terminator.kind != TerminatorKind::ConditionalBranch ||
|
||||
IsInnermostLoopControlConditional(graph, *inner)) {
|
||||
continue;
|
||||
@@ -1941,9 +1942,9 @@ Graph BuildGraph(const Decoder::Program& program) {
|
||||
graph, FailureKind::InvalidBranchTarget, UINT32_MAX,
|
||||
fmt::format("unsupported dynamic S_SETPC_B64 at pc 0x{:08x}", inst.pc));
|
||||
}
|
||||
const auto& target_pcs = target_info.indirect
|
||||
? target_info.target_pcs
|
||||
: std::vector<uint32_t> {target_info.target};
|
||||
const auto target_pcs = target_info.indirect
|
||||
? std::span<const uint32_t>(target_info.target_pcs)
|
||||
: std::span<const uint32_t>(&target_info.target, 1);
|
||||
for (const auto target: target_pcs) {
|
||||
if (!IsValidTarget(target, instruction_pcs, first_pc, end_pc)) {
|
||||
ExitBuildFailure(
|
||||
@@ -2103,11 +2104,7 @@ Graph BuildGraph(const Decoder::Program& program) {
|
||||
}
|
||||
SortUnique(graph.code_table_load_pcs);
|
||||
|
||||
ComputeDominators(graph);
|
||||
ComputePostDominators(graph);
|
||||
ComputeBackEdges(graph);
|
||||
ComputeNaturalLoops(graph);
|
||||
ComputeComponents(graph);
|
||||
RecomputeAnalyses(graph);
|
||||
|
||||
if (indirect_setpc) {
|
||||
graph.irreducible = true;
|
||||
|
||||
@@ -714,57 +714,7 @@ void DecodeVop1Dpp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_in
|
||||
ReadLiteralOperands(code, word_index, inst);
|
||||
}
|
||||
|
||||
using Vop1ModifierDecodeFn = void (*)(uint32_t pc, std::span<const uint32_t> code,
|
||||
uint32_t word_index, uint32_t opcode, uint32_t vdst,
|
||||
Instruction& inst);
|
||||
|
||||
struct Vop1ModifierDecoder {
|
||||
uint32_t escape = 0;
|
||||
Vop1ModifierDecodeFn decode = nullptr;
|
||||
};
|
||||
|
||||
constexpr Vop1ModifierDecoder VOP1_MODIFIER_DECODERS[] = {
|
||||
{249u, DecodeVop1Sdwa},
|
||||
{250u, DecodeVop1Dpp},
|
||||
};
|
||||
|
||||
bool TryDecodeVop1Modifier(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index,
|
||||
uint32_t src0, uint32_t opcode, uint32_t vdst, Instruction& inst) {
|
||||
for (const auto& decoder: VOP1_MODIFIER_DECODERS) {
|
||||
if (decoder.escape == src0) {
|
||||
decoder.decode(pc, code, word_index, opcode, vdst, inst);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsVop2FloatSourceOpcode(Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Opcode::V_ADD_F32:
|
||||
case Opcode::V_SUB_F32:
|
||||
case Opcode::V_SUBREV_F32:
|
||||
case Opcode::V_MUL_F32:
|
||||
case Opcode::V_MIN_F32:
|
||||
case Opcode::V_MAX_F32:
|
||||
case Opcode::V_MAC_F32:
|
||||
case Opcode::V_MADMK_F32:
|
||||
case Opcode::V_MADAK_F32:
|
||||
case Opcode::V_CVT_PKRTZ_F16_F32:
|
||||
case Opcode::V_ADD_F16:
|
||||
case Opcode::V_SUB_F16:
|
||||
case Opcode::V_SUBREV_F16:
|
||||
case Opcode::V_MUL_F16:
|
||||
case Opcode::V_FMAC_F16:
|
||||
case Opcode::V_FMAMK_F16:
|
||||
case Opcode::V_FMAAK_F16:
|
||||
case Opcode::V_MAX_F16:
|
||||
case Opcode::V_MIN_F16: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsVop2FloatResultOpcode(Opcode opcode) {
|
||||
bool IsVop2FloatOpcode(Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Opcode::V_ADD_F32:
|
||||
case Opcode::V_SUB_F32:
|
||||
@@ -975,12 +925,12 @@ bool ValidateVop2Sdwa(Instruction& inst, uint32_t opcode, const Vop2SdwaFields&
|
||||
SetUnsupported(inst, Family::VOP2, opcode, "VOP2 SDWA selector is invalid");
|
||||
return false;
|
||||
}
|
||||
if ((fields.clamp != 0u || fields.omod != 0u) && !IsVop2FloatResultOpcode(inst.opcode)) {
|
||||
if ((fields.clamp != 0u || fields.omod != 0u) && !IsVop2FloatOpcode(inst.opcode)) {
|
||||
SetUnsupported(inst, Family::VOP2, opcode, "VOP2 SDWA output modifiers are not supported");
|
||||
return false;
|
||||
}
|
||||
if (IsFullWidthVop2Sdwa(fields)) {
|
||||
if (!IsVop2FloatSourceOpcode(inst.opcode) && inst.opcode != Opcode::V_CNDMASK_B32 &&
|
||||
if (!IsVop2FloatOpcode(inst.opcode) && inst.opcode != Opcode::V_CNDMASK_B32 &&
|
||||
(fields.src0_neg != 0u || fields.src0_abs != 0u || fields.src1_neg != 0u ||
|
||||
fields.src1_abs != 0u)) {
|
||||
SetUnsupported(inst, Family::VOP2, opcode,
|
||||
@@ -1098,7 +1048,7 @@ void DecodeVop2Dpp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_in
|
||||
inst.src1.negate_hi = inst.src1.negate;
|
||||
}
|
||||
|
||||
if (!IsVop2FloatSourceOpcode(inst.opcode) && !packed_fmac &&
|
||||
if (!IsVop2FloatOpcode(inst.opcode) && !packed_fmac &&
|
||||
(inst.src0.negate || inst.src0.absolute || inst.src1.negate || inst.src1.absolute)) {
|
||||
SetUnsupported(inst, Family::VOP2, opcode,
|
||||
"VOP2 DPP integer source modifiers are not supported");
|
||||
@@ -1107,32 +1057,6 @@ void DecodeVop2Dpp(uint32_t pc, std::span<const uint32_t> code, uint32_t word_in
|
||||
FinalizeVop2Instruction(code, word_index, inst);
|
||||
}
|
||||
|
||||
using Vop2ModifierDecodeFn = void (*)(uint32_t pc, std::span<const uint32_t> code,
|
||||
uint32_t word_index, uint32_t opcode, uint32_t vdst,
|
||||
uint32_t vsrc1, Instruction& inst);
|
||||
|
||||
struct Vop2ModifierDecoder {
|
||||
uint32_t escape = 0;
|
||||
Vop2ModifierDecodeFn decode = nullptr;
|
||||
};
|
||||
|
||||
constexpr Vop2ModifierDecoder VOP2_MODIFIER_DECODERS[] = {
|
||||
{249u, DecodeVop2Sdwa},
|
||||
{250u, DecodeVop2Dpp},
|
||||
};
|
||||
|
||||
bool TryDecodeVop2Modifier(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index,
|
||||
uint32_t src0, uint32_t opcode, uint32_t vdst, uint32_t vsrc1,
|
||||
Instruction& inst) {
|
||||
for (const auto& decoder: VOP2_MODIFIER_DECODERS) {
|
||||
if (decoder.escape == src0) {
|
||||
decoder.decode(pc, code, word_index, opcode, vdst, vsrc1, inst);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct VopcSdwaFields {
|
||||
uint32_t src0 = 0;
|
||||
uint32_t sdst = 0;
|
||||
@@ -1543,8 +1467,10 @@ void DecodeVop2(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
||||
SetUnsupported(inst, Family::VOP2, opcode, "VOP2 opcode is not implemented");
|
||||
return;
|
||||
}
|
||||
if (TryDecodeVop2Modifier(pc, code, word_index, src0, opcode, vdst, vsrc1, inst)) {
|
||||
return;
|
||||
switch (src0) {
|
||||
case 249u: DecodeVop2Sdwa(pc, code, word_index, opcode, vdst, vsrc1, inst); return;
|
||||
case 250u: DecodeVop2Dpp(pc, code, word_index, opcode, vdst, vsrc1, inst); return;
|
||||
default: break;
|
||||
}
|
||||
|
||||
DecodeVectorGpr(vdst, inst.dst);
|
||||
@@ -1575,8 +1501,10 @@ void DecodeVop1(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
||||
inst.src_count = 0;
|
||||
return;
|
||||
}
|
||||
if (TryDecodeVop1Modifier(pc, code, word_index, src0, opcode, vdst, inst)) {
|
||||
return;
|
||||
switch (src0) {
|
||||
case 249u: DecodeVop1Sdwa(pc, code, word_index, opcode, vdst, inst); return;
|
||||
case 250u: DecodeVop1Dpp(pc, code, word_index, opcode, vdst, inst); return;
|
||||
default: break;
|
||||
}
|
||||
const bool scalar_dst = UsesScalarDestination(inst.opcode);
|
||||
if (scalar_dst) {
|
||||
|
||||
@@ -89,10 +89,10 @@ void Translator::V_CVT_16_F16(const Decoder::Instruction& inst, bool signed_valu
|
||||
if (signed_value) {
|
||||
const auto converted =
|
||||
ConvertF32ToI32Saturated(value, -32768.0f, 32768.0f, 32767.0f, 0xffff8000u, 0x7fffu);
|
||||
WriteU16(DestinationOperand(inst), ir.BitwiseAnd(converted, IR::U32(IR::Value(0xffffu))));
|
||||
Write16Bits(DestinationOperand(inst), ir.BitwiseAnd(converted, IR::U32(IR::Value(0xffffu))));
|
||||
return;
|
||||
}
|
||||
WriteU16(DestinationOperand(inst),
|
||||
Write16Bits(DestinationOperand(inst),
|
||||
ConvertF32ToU32Saturated(value, 65536.0f, 65535.0f, 0xffffu));
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ bool Translator::Float16Unary(const Decoder::Instruction& inst, IR::ValueOpcode
|
||||
result = ApplyF32ResultModifiers(inst.dst, result);
|
||||
const auto bits = PackHalf2x16(result, IR::F32(IR::Value::F32(0.0f)));
|
||||
const auto invalid = IR::U32(IR::Value(inst.dst.clamp ? 0u : 0xfe00u));
|
||||
WriteU16(DestinationOperand(inst), ir.Select(negative, invalid, bits));
|
||||
Write16Bits(DestinationOperand(inst), ir.Select(negative, invalid, bits));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ bool Translator::Float16Trig(const Decoder::Instruction& inst, IR::ValueOpcode o
|
||||
result = ApplyF32ResultModifiers(inst.dst, result);
|
||||
const auto bits = PackHalf2x16(result, IR::F32(IR::Value::F32(0.0f)));
|
||||
const auto invalid = IR::U32(IR::Value(inst.dst.clamp ? 0u : 0xfe00u));
|
||||
WriteU16(DestinationOperand(inst), ir.Select(infinite, invalid, bits));
|
||||
Write16Bits(DestinationOperand(inst), ir.Select(infinite, invalid, bits));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ bool Translator::Float16Ternary(const Decoder::Instruction& inst, IR::ValueOpcod
|
||||
bool accumulator, bool mix) {
|
||||
std::array<IR::Value, 3> args;
|
||||
for (uint32_t index = 0; index < args.size(); index++) {
|
||||
const auto operand = accumulator && index == 2u ? inst.dst : SourceAt(inst, index);
|
||||
const auto& operand = accumulator && index == 2u ? inst.dst : SourceAt(inst, index);
|
||||
args[index] = mix ? IR::Value(ReadMixF32(operand)) : IR::Value(ReadF16AsF32(operand));
|
||||
}
|
||||
WriteF16(DestinationOperand(inst), IR::F32(ir.Emit(opcode, {args[0], args[1], args[2]})));
|
||||
@@ -128,7 +128,7 @@ bool Translator::FloatBinary(const Decoder::Instruction& inst, IR::ValueOpcode o
|
||||
bool reverse) {
|
||||
std::array<IR::Value, 2> args;
|
||||
for (uint32_t index = 0; index < args.size(); index++) {
|
||||
const auto operand = SourceAt(inst, reverse ? 1u - index : index);
|
||||
const auto& operand = SourceAt(inst, reverse ? 1u - index : index);
|
||||
args[index] = ReadOperand(operand, IR::ArgTypeOf(opcode, index));
|
||||
}
|
||||
WriteOperand(DestinationOperand(inst), ir.Emit(opcode, {args[0], args[1]}));
|
||||
@@ -139,7 +139,7 @@ bool Translator::FloatTernary(const Decoder::Instruction& inst, IR::ValueOpcode
|
||||
bool accumulator, bool mix) {
|
||||
std::array<IR::Value, 3> args;
|
||||
for (uint32_t index = 0; index < args.size(); index++) {
|
||||
const auto operand = accumulator && index == 2u ? inst.dst : SourceAt(inst, index);
|
||||
const auto& operand = accumulator && index == 2u ? inst.dst : SourceAt(inst, index);
|
||||
const auto type = IR::ArgTypeOf(opcode, index);
|
||||
args[index] = type == IR::Type::F32 && mix ? IR::Value(ReadMixF32(operand))
|
||||
: ReadOperand(operand, type);
|
||||
@@ -203,9 +203,6 @@ bool Translator::V_CUBEMA_F32(const Decoder::Instruction& inst) {
|
||||
}
|
||||
|
||||
bool Translator::FloatCube(const Decoder::Instruction& inst, uint32_t result_kind) {
|
||||
const auto select_f32 = [&](IR::U1 condition, IR::F32 true_value, IR::F32 false_value) {
|
||||
return IR::F32(ir.Emit(IR::ValueOpcode::SelectF32, {condition, true_value, false_value}));
|
||||
};
|
||||
const auto x = ReadMixF32(inst.src0);
|
||||
const auto y = ReadMixF32(inst.src1);
|
||||
const auto z = ReadMixF32(inst.src2);
|
||||
@@ -223,18 +220,18 @@ bool Translator::FloatCube(const Decoder::Instruction& inst, uint32_t result_kin
|
||||
const auto y_neg = IR::U1(ir.Emit(IR::ValueOpcode::FPOrdLessThan32, {y, IR::Value::F32(0.0f)}));
|
||||
const auto z_neg = IR::U1(ir.Emit(IR::ValueOpcode::FPOrdLessThan32, {z, IR::Value::F32(0.0f)}));
|
||||
const auto select_face = [&](IR::F32 x_value, IR::F32 y_value, IR::F32 z_value) {
|
||||
return select_f32(z_face, z_value, select_f32(y_face, y_value, x_value));
|
||||
return SelectF32(z_face, z_value, SelectF32(y_face, y_value, x_value));
|
||||
};
|
||||
IR::F32 result;
|
||||
switch (result_kind) {
|
||||
case 0u:
|
||||
result = select_face(
|
||||
select_f32(x_neg, IR::F32(IR::Value::F32(1.0f)), IR::F32(IR::Value::F32(0.0f))),
|
||||
select_f32(y_neg, IR::F32(IR::Value::F32(3.0f)), IR::F32(IR::Value::F32(2.0f))),
|
||||
select_f32(z_neg, IR::F32(IR::Value::F32(5.0f)), IR::F32(IR::Value::F32(4.0f))));
|
||||
SelectF32(x_neg, IR::F32(IR::Value::F32(1.0f)), IR::F32(IR::Value::F32(0.0f))),
|
||||
SelectF32(y_neg, IR::F32(IR::Value::F32(3.0f)), IR::F32(IR::Value::F32(2.0f))),
|
||||
SelectF32(z_neg, IR::F32(IR::Value::F32(5.0f)), IR::F32(IR::Value::F32(4.0f))));
|
||||
break;
|
||||
case 1u: result = select_face(select_f32(x_neg, z, nz), x, select_f32(z_neg, nx, x)); break;
|
||||
case 2u: result = select_face(ny, select_f32(y_neg, nz, z), ny); break;
|
||||
case 1u: result = select_face(SelectF32(x_neg, z, nz), x, SelectF32(z_neg, nx, x)); break;
|
||||
case 2u: result = select_face(ny, SelectF32(y_neg, nz, z), ny); break;
|
||||
case 3u: {
|
||||
const auto two = IR::F32(IR::Value::F32(2.0f));
|
||||
result = select_face(IR::F32(ir.Emit(IR::ValueOpcode::FPMul32, {x, two})),
|
||||
|
||||
@@ -9,7 +9,7 @@ bool Translator::Integer16Shift(const Decoder::Instruction& inst, IR::ValueOpcod
|
||||
const auto value = ReadU16AsU32(inst.src1, arithmetic);
|
||||
const auto count = ir.BitwiseAnd(ReadU16AsU32(inst.src0, false), IR::U32(IR::Value(15u)));
|
||||
const auto result = IR::U32(ir.Emit(opcode, {value, count}));
|
||||
WriteU16(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu))));
|
||||
Write16Bits(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu))));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ bool Translator::Integer16Binary(const Decoder::Instruction& inst, IR::ValueOpco
|
||||
const auto lhs = ReadU16AsU32(inst.src0, sign);
|
||||
const auto rhs = ReadU16AsU32(inst.src1, sign);
|
||||
const auto result = IR::U32(ir.Emit(opcode, {lhs, rhs}));
|
||||
WriteU16(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu))));
|
||||
Write16Bits(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu))));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ bool Translator::V_MED3_I16(const Decoder::Instruction& inst) {
|
||||
const auto result = IR::U32(ir.Emit(
|
||||
IR::ValueOpcode::SMedTri32, {ReadU16AsU32(inst.src0, true), ReadU16AsU32(inst.src1, true),
|
||||
ReadU16AsU32(inst.src2, true)}));
|
||||
WriteU16(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu))));
|
||||
Write16Bits(DestinationOperand(inst), ir.BitwiseAnd(result, IR::U32(IR::Value(0xffffu))));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ bool Translator::SimpleInteger(const Decoder::Instruction& inst, IR::ValueOpcode
|
||||
std::array<IR::Value, 3> args;
|
||||
for (uint32_t index = 0; index < inst.src_count; index++) {
|
||||
const auto arg_type = IR::ArgTypeOf(opcode, index);
|
||||
const auto operand = SourceAt(inst, reverse && index < 2u ? 1u - index : index);
|
||||
const auto& operand = SourceAt(inst, reverse && index < 2u ? 1u - index : index);
|
||||
args[index] = ReadOperand(operand, arg_type == IR::Type::Void ? type : arg_type);
|
||||
if (mask_shift_count && index == 1u) {
|
||||
args[index] = ir.BitwiseAnd(IR::U32(args[index]), IR::U32(IR::Value(31u)));
|
||||
@@ -563,10 +563,8 @@ bool Translator::PackB16(const Decoder::Instruction& inst, bool high0, bool high
|
||||
: ReadU32(inst.src0);
|
||||
const auto hi = high1 ? ir.ShiftRightLogical(ReadU32(inst.src1), IR::U32(IR::Value(16u)))
|
||||
: ReadU32(inst.src1);
|
||||
const auto low_bits = ir.BitwiseAnd(lo, IR::U32(IR::Value(0xffffu)));
|
||||
const auto high_bits = ir.ShiftLeftLogical(ir.BitwiseAnd(hi, IR::U32(IR::Value(0xffffu))),
|
||||
IR::U32(IR::Value(16u)));
|
||||
WriteOperand(DestinationOperand(inst), ir.BitwiseOr(low_bits, high_bits));
|
||||
const auto result = PackU16Lanes(lo, hi);
|
||||
WriteOperand(DestinationOperand(inst), result);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -71,16 +71,22 @@ ResourceKind FlatSegmentResourceKind(uint32_t segment) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsScalarAddressLoad(Decoder::Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Decoder::Opcode::S_LOAD_DWORD:
|
||||
case Decoder::Opcode::S_LOAD_DWORDX2:
|
||||
case Decoder::Opcode::S_LOAD_DWORDX4:
|
||||
case Decoder::Opcode::S_LOAD_DWORDX8:
|
||||
case Decoder::Opcode::S_LOAD_DWORDX16: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
ResourceKind MemoryKind(const Decoder::Instruction& decoded) {
|
||||
switch (decoded.family) {
|
||||
case Decoder::Family::SMEM:
|
||||
return decoded.opcode == Decoder::Opcode::S_LOAD_DWORD ||
|
||||
decoded.opcode == Decoder::Opcode::S_LOAD_DWORDX2 ||
|
||||
decoded.opcode == Decoder::Opcode::S_LOAD_DWORDX4 ||
|
||||
decoded.opcode == Decoder::Opcode::S_LOAD_DWORDX8 ||
|
||||
decoded.opcode == Decoder::Opcode::S_LOAD_DWORDX16
|
||||
? ResourceKind::ScalarAddress
|
||||
: ResourceKind::ScalarBuffer;
|
||||
return IsScalarAddressLoad(decoded.opcode) ? ResourceKind::ScalarAddress
|
||||
: ResourceKind::ScalarBuffer;
|
||||
case Decoder::Family::MUBUF:
|
||||
case Decoder::Family::MTBUF: return ResourceKind::Buffer;
|
||||
case Decoder::Family::FLAT: return FlatSegmentResourceKind(decoded.memory_segment);
|
||||
@@ -146,16 +152,6 @@ IR::MemoryInfo MemoryInfoFromDecoded(const Decoder::Instruction& decoded) {
|
||||
return memory;
|
||||
}
|
||||
|
||||
bool IsScalarAddressLoad(Decoder::Opcode opcode) {
|
||||
switch (opcode) {
|
||||
case Decoder::Opcode::S_LOAD_DWORD:
|
||||
case Decoder::Opcode::S_LOAD_DWORDX2:
|
||||
case Decoder::Opcode::S_LOAD_DWORDX4:
|
||||
case Decoder::Opcode::S_LOAD_DWORDX8:
|
||||
case Decoder::Opcode::S_LOAD_DWORDX16: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsScalarBufferLoad(Decoder::Opcode opcode) {
|
||||
switch (opcode) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
namespace Libs::Graphics::ShaderRecompiler::Frontend {
|
||||
|
||||
Decoder::Operand Translator::SourceAt(const Decoder::Instruction& inst, uint32_t index) {
|
||||
const Decoder::Operand& Translator::SourceAt(const Decoder::Instruction& inst, uint32_t index) {
|
||||
switch (index) {
|
||||
case 0: return inst.src0;
|
||||
case 1: return inst.src1;
|
||||
@@ -25,7 +25,7 @@ Decoder::Operand Translator::DestinationOperand(const Decoder::Instruction& inst
|
||||
return destination;
|
||||
}
|
||||
for (uint32_t index = 0; index < std::min(inst.src_count, 3u); index++) {
|
||||
const auto source = SourceAt(inst, index);
|
||||
const auto& source = SourceAt(inst, index);
|
||||
if (!source.dpp) {
|
||||
continue;
|
||||
}
|
||||
@@ -440,10 +440,6 @@ void Translator::WriteF16(const Decoder::Operand& operand, IR::F32 value) {
|
||||
Write16Bits(operand, bits);
|
||||
}
|
||||
|
||||
void Translator::WriteU16(const Decoder::Operand& operand, IR::U32 value) {
|
||||
Write16Bits(operand, value);
|
||||
}
|
||||
|
||||
IR::U32 Translator::ReadU32(const Decoder::Operand& operand) {
|
||||
return IR::U32(ReadOperand(operand, IR::Type::U32));
|
||||
}
|
||||
@@ -604,10 +600,6 @@ IR::U1 Translator::ThreadBit(const std::array<IR::U32, 2>& mask) {
|
||||
IR::U32(IR::Value(0u)));
|
||||
}
|
||||
|
||||
IR::U1 Translator::ReadCondition(const Decoder::Operand& operand) {
|
||||
return IR::U1(ReadOperand(operand, IR::Type::U1));
|
||||
}
|
||||
|
||||
IR::U32 Translator::ConditionBit(const Decoder::Operand& operand) {
|
||||
return ir.Select(ReadMask(operand), IR::U32(IR::Value(1u)), IR::U32(IR::Value(0u)));
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
void AddBranchCondition(const CFG::BasicBlock& source, IR::BlockInfo& info);
|
||||
|
||||
private:
|
||||
Decoder::Operand SourceAt(const Decoder::Instruction& inst, uint32_t index);
|
||||
const Decoder::Operand& SourceAt(const Decoder::Instruction& inst, uint32_t index);
|
||||
Decoder::Operand DestinationOperand(const Decoder::Instruction& inst);
|
||||
Decoder::Operand OffsetOperand(const Decoder::Operand& operand, uint32_t offset);
|
||||
Decoder::Operand ScalarDestinationOperand(const Decoder::Operand& operand, uint32_t offset);
|
||||
@@ -35,7 +35,6 @@ private:
|
||||
IR::U32 PackHalf2x16(IR::F32 low, IR::F32 high);
|
||||
void Write16Bits(const Decoder::Operand& operand, IR::U32 value);
|
||||
void WriteF16(const Decoder::Operand& operand, IR::F32 value);
|
||||
void WriteU16(const Decoder::Operand& operand, IR::U32 value);
|
||||
IR::U32 ReadU32(const Decoder::Operand& operand);
|
||||
std::array<IR::U32, 2> ReadU32Pair(const Decoder::Operand& operand);
|
||||
IR::U64 ReadU64(const Decoder::Operand& operand);
|
||||
@@ -48,7 +47,6 @@ private:
|
||||
IR::U32 ReadF16LaneBits(const Decoder::Operand& operand, bool high_lane);
|
||||
std::array<IR::U32, 2> ExtractU64(IR::U64 value);
|
||||
void WriteU32Pair(const Decoder::Operand& operand, const std::array<IR::U32, 2>& value);
|
||||
IR::U1 ReadCondition(const Decoder::Operand& operand);
|
||||
IR::U32 ConditionBit(const Decoder::Operand& operand);
|
||||
IR::U1 ReadMask(const Decoder::Operand& operand);
|
||||
IR::U1 ReadMaskValid(const Decoder::Operand& operand);
|
||||
|
||||
@@ -280,8 +280,7 @@ private:
|
||||
return finish(false);
|
||||
}
|
||||
}
|
||||
if (op == ValueOpcode::GetBufferResource || op == ValueOpcode::GetImageResource ||
|
||||
op == ValueOpcode::GetSamplerResource || op == ValueOpcode::GetAddressResource) {
|
||||
if (IsDescriptorHandle(op)) {
|
||||
size_t expected = 4u;
|
||||
if (op == ValueOpcode::GetImageResource) {
|
||||
expected = 8u;
|
||||
|
||||
Reference in New Issue
Block a user