mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
shader: implement RDNA2 scalar quad-mask reduction
This commit is contained in:
@@ -52,6 +52,7 @@ constexpr OpcodeMap SOP1_OPCODE_LIST[] = {
|
|||||||
{0x20u, Opcode::S_SETPC_B64},
|
{0x20u, Opcode::S_SETPC_B64},
|
||||||
{0x24u, Opcode::S_AND_SAVEEXEC_B64},
|
{0x24u, Opcode::S_AND_SAVEEXEC_B64},
|
||||||
{0x28u, Opcode::S_ORN2_SAVEEXEC_B64},
|
{0x28u, Opcode::S_ORN2_SAVEEXEC_B64},
|
||||||
|
{0x2du, Opcode::S_QUADMASK_B64},
|
||||||
{0x34u, Opcode::S_ABS_I32},
|
{0x34u, Opcode::S_ABS_I32},
|
||||||
{0x37u, Opcode::S_ANDN1_SAVEEXEC_B64},
|
{0x37u, Opcode::S_ANDN1_SAVEEXEC_B64},
|
||||||
{0x3bu, Opcode::S_BITREPLICATE_B64_B32},
|
{0x3bu, Opcode::S_BITREPLICATE_B64_B32},
|
||||||
|
|||||||
@@ -498,6 +498,7 @@ std::string InstructionToString(const Instruction& inst) {
|
|||||||
case Opcode::S_FF1_I32_B64:
|
case Opcode::S_FF1_I32_B64:
|
||||||
case Opcode::S_NOT_B64:
|
case Opcode::S_NOT_B64:
|
||||||
case Opcode::S_WQM_B64:
|
case Opcode::S_WQM_B64:
|
||||||
|
case Opcode::S_QUADMASK_B64:
|
||||||
case Opcode::S_AND_SAVEEXEC_B32:
|
case Opcode::S_AND_SAVEEXEC_B32:
|
||||||
case Opcode::S_ANDN1_SAVEEXEC_B32:
|
case Opcode::S_ANDN1_SAVEEXEC_B32:
|
||||||
case Opcode::S_AND_SAVEEXEC_B64:
|
case Opcode::S_AND_SAVEEXEC_B64:
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ enum class Opcode {
|
|||||||
S_FF1_I32_B64,
|
S_FF1_I32_B64,
|
||||||
S_FLBIT_I32_B64,
|
S_FLBIT_I32_B64,
|
||||||
S_BITREPLICATE_B64_B32,
|
S_BITREPLICATE_B64_B32,
|
||||||
|
S_QUADMASK_B64,
|
||||||
S_GETPC_B64,
|
S_GETPC_B64,
|
||||||
S_SETPC_B64,
|
S_SETPC_B64,
|
||||||
S_AND_SAVEEXEC_B32,
|
S_AND_SAVEEXEC_B32,
|
||||||
|
|||||||
@@ -469,6 +469,21 @@ bool Translator::TranslateExtendedInteger(const IR::Instruction& inst) {
|
|||||||
replicate(ir.ShiftRightLogical(source, imm(16))));
|
replicate(ir.ShiftRightLogical(source, imm(16))));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IR::Opcode::QuadmaskB64: {
|
||||||
|
const auto compact = [&](IR::U32 value) {
|
||||||
|
auto bits = ir.BitwiseOr(value, ir.ShiftRightLogical(value, imm(1)));
|
||||||
|
bits = ir.BitwiseOr(bits, ir.ShiftRightLogical(bits, imm(2)));
|
||||||
|
bits = mask(bits, 0x11111111u);
|
||||||
|
bits = mask(ir.BitwiseOr(bits, ir.ShiftRightLogical(bits, imm(3))), 0x03030303u);
|
||||||
|
bits = mask(ir.BitwiseOr(bits, ir.ShiftRightLogical(bits, imm(6))), 0x000f000fu);
|
||||||
|
return mask(ir.BitwiseOr(bits, ir.ShiftRightLogical(bits, imm(12))), 0xffu);
|
||||||
|
};
|
||||||
|
const auto source = ReadU32Pair(inst.src[0]);
|
||||||
|
const auto quads =
|
||||||
|
ir.BitwiseOr(compact(source[0]), ir.ShiftLeftLogical(compact(source[1]), imm(8)));
|
||||||
|
result = ir.ConstructU64(quads, imm(0));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case IR::Opcode::BitFieldMaskU32: {
|
case IR::Opcode::BitFieldMaskU32: {
|
||||||
const auto count = mask(ReadU32(inst.src[0]), 31u);
|
const auto count = mask(ReadU32(inst.src[0]), 31u);
|
||||||
const auto offset = mask(ReadU32(inst.src[1]), 31u);
|
const auto offset = mask(ReadU32(inst.src[1]), 31u);
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ constexpr LowerMap LOWER_OPS[] = {
|
|||||||
{Decoder::Opcode::S_FF1_I32_B64, Opcode::FindLsbU64},
|
{Decoder::Opcode::S_FF1_I32_B64, Opcode::FindLsbU64},
|
||||||
{Decoder::Opcode::S_FLBIT_I32_B64, Opcode::FindMsbFromHighU64},
|
{Decoder::Opcode::S_FLBIT_I32_B64, Opcode::FindMsbFromHighU64},
|
||||||
{Decoder::Opcode::S_BITREPLICATE_B64_B32, Opcode::BitReplicateB64B32},
|
{Decoder::Opcode::S_BITREPLICATE_B64_B32, Opcode::BitReplicateB64B32},
|
||||||
|
{Decoder::Opcode::S_QUADMASK_B64, Opcode::QuadmaskB64},
|
||||||
{Decoder::Opcode::S_NOT_B32, Opcode::BitwiseNotU32},
|
{Decoder::Opcode::S_NOT_B32, Opcode::BitwiseNotU32},
|
||||||
{Decoder::Opcode::S_NOT_B64, Opcode::BitwiseNotU64},
|
{Decoder::Opcode::S_NOT_B64, Opcode::BitwiseNotU64},
|
||||||
{Decoder::Opcode::S_ADD_U32, Opcode::IAddU32},
|
{Decoder::Opcode::S_ADD_U32, Opcode::IAddU32},
|
||||||
@@ -511,7 +512,8 @@ bool ScalarResultWritesSccNonZero(Decoder::Opcode opcode) {
|
|||||||
case Decoder::Opcode::S_LSHL_B64:
|
case Decoder::Opcode::S_LSHL_B64:
|
||||||
case Decoder::Opcode::S_LSHR_B64:
|
case Decoder::Opcode::S_LSHR_B64:
|
||||||
case Decoder::Opcode::S_BFE_U64:
|
case Decoder::Opcode::S_BFE_U64:
|
||||||
case Decoder::Opcode::S_WQM_B64: return true;
|
case Decoder::Opcode::S_WQM_B64:
|
||||||
|
case Decoder::Opcode::S_QUADMASK_B64: return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,7 +532,8 @@ bool ScalarResultIs64Bit(Decoder::Opcode opcode) {
|
|||||||
case Decoder::Opcode::S_LSHL_B64:
|
case Decoder::Opcode::S_LSHL_B64:
|
||||||
case Decoder::Opcode::S_LSHR_B64:
|
case Decoder::Opcode::S_LSHR_B64:
|
||||||
case Decoder::Opcode::S_BFE_U64:
|
case Decoder::Opcode::S_BFE_U64:
|
||||||
case Decoder::Opcode::S_WQM_B64: return true;
|
case Decoder::Opcode::S_WQM_B64:
|
||||||
|
case Decoder::Opcode::S_QUADMASK_B64: return true;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ IR_OPCODE(BitReverseU32, General, SimpleInteger)
|
|||||||
IR_OPCODE(BitCountU32, General, SimpleInteger)
|
IR_OPCODE(BitCountU32, General, SimpleInteger)
|
||||||
IR_OPCODE(BitCountU64, General, SimpleInteger)
|
IR_OPCODE(BitCountU64, General, SimpleInteger)
|
||||||
IR_OPCODE(BitReplicateB64B32, General, ExtendedInteger)
|
IR_OPCODE(BitReplicateB64B32, General, ExtendedInteger)
|
||||||
|
IR_OPCODE(QuadmaskB64, General, ExtendedInteger)
|
||||||
IR_OPCODE(BitCountAddU32, General, ExtendedInteger)
|
IR_OPCODE(BitCountAddU32, General, ExtendedInteger)
|
||||||
IR_OPCODE(MaskedBitCountLowU32, General, ExtendedInteger)
|
IR_OPCODE(MaskedBitCountLowU32, General, ExtendedInteger)
|
||||||
IR_OPCODE(MaskedBitCountHighU32, General, ExtendedInteger)
|
IR_OPCODE(MaskedBitCountHighU32, General, ExtendedInteger)
|
||||||
|
|||||||
@@ -11711,6 +11711,37 @@ TestCase ScalarNotB64UpdatesScc() {
|
|||||||
O::V_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
O::V_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase ScalarQuadmaskB64() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
|
std::vector<u32> code;
|
||||||
|
auto capture_scc = [&](u32 dst_sgpr) {
|
||||||
|
code.push_back(EncodeSop2(0x0a, dst_sgpr, InlineU32(1), InlineU32(0)));
|
||||||
|
};
|
||||||
|
|
||||||
|
AppendSMovLiteral(&code, 106, 0x80000011u);
|
||||||
|
AppendSMovLiteral(&code, 107, 0x000000f0u);
|
||||||
|
code.push_back(EncodeSop1(0x2d, 106, 106));
|
||||||
|
capture_scc(0);
|
||||||
|
AppendStoreSgprPair(&code, 106, 0);
|
||||||
|
AppendStoreSgpr(&code, 0, 2);
|
||||||
|
|
||||||
|
code.push_back(EncodeSMovB32(106, InlineU32(0)));
|
||||||
|
code.push_back(EncodeSMovB32(107, InlineU32(0)));
|
||||||
|
code.push_back(EncodeSop1(0x2d, 106, 106));
|
||||||
|
capture_scc(0);
|
||||||
|
AppendStoreSgprPair(&code, 106, 3);
|
||||||
|
AppendStoreSgpr(&code, 0, 5);
|
||||||
|
AppendEnd(&code);
|
||||||
|
|
||||||
|
return {"ScalarQuadmaskB64",
|
||||||
|
code,
|
||||||
|
{},
|
||||||
|
{0x00000283u, 0, 1, 0, 0, 0},
|
||||||
|
{O::S_MOV_B32, O::S_QUADMASK_B64, O::S_CSELECT_B32, O::V_MOV_B32,
|
||||||
|
O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||||
|
}
|
||||||
|
|
||||||
TestCase ScalarFlbitI32B64Gpu() {
|
TestCase ScalarFlbitI32B64Gpu() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -18564,6 +18595,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(ScalarCompareOps);
|
AddCase(ScalarCompareOps);
|
||||||
AddCase(ScalarShiftAddAndMaskOps);
|
AddCase(ScalarShiftAddAndMaskOps);
|
||||||
AddCase(ScalarNotB64UpdatesScc);
|
AddCase(ScalarNotB64UpdatesScc);
|
||||||
|
AddCase(ScalarQuadmaskB64);
|
||||||
AddCase(ScalarFlbitI32B64Gpu);
|
AddCase(ScalarFlbitI32B64Gpu);
|
||||||
AddCase(ScalarSaveExecOps);
|
AddCase(ScalarSaveExecOps);
|
||||||
AddCase(ScalarOrn2SaveexecUsesSourceOrNotExec);
|
AddCase(ScalarOrn2SaveexecUsesSourceOrNotExec);
|
||||||
|
|||||||
Reference in New Issue
Block a user