mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
graphics: implement RDNA2 64-bit first-set-bit
This commit is contained in:
@@ -27,27 +27,17 @@ constexpr OpcodeMap SOP2_OPS[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
constexpr OpcodeMap SOP1_OPS[] = {
|
constexpr OpcodeMap SOP1_OPS[] = {
|
||||||
{0x03u, Opcode::SMovB32},
|
{0x03u, Opcode::SMovB32}, {0x04u, Opcode::SMovB64},
|
||||||
{0x04u, Opcode::SMovB64},
|
{0x07u, Opcode::SNotB32}, {0x08u, Opcode::SNotB64},
|
||||||
{0x07u, Opcode::SNotB32},
|
{0x0au, Opcode::SWqmB64}, {0x0bu, Opcode::SBrevB32},
|
||||||
{0x08u, Opcode::SNotB64},
|
{0x0fu, Opcode::SBcnt1I32B32}, {0x10u, Opcode::SBcnt1I32B64},
|
||||||
{0x0au, Opcode::SWqmB64},
|
{0x13u, Opcode::SFf1I32B32}, {0x14u, Opcode::SFf1I32B64},
|
||||||
{0x0bu, Opcode::SBrevB32},
|
{0x16u, Opcode::SFlbitI32B64}, {0x1bu, Opcode::SBitset0B32},
|
||||||
{0x0fu, Opcode::SBcnt1I32B32},
|
{0x1du, Opcode::SBitset1B32}, {0x1fu, Opcode::SGetpcB64},
|
||||||
{0x10u, Opcode::SBcnt1I32B64},
|
{0x20u, Opcode::SSetpcB64}, {0x24u, Opcode::SAndSaveexecB64},
|
||||||
{0x13u, Opcode::SFf1I32B32},
|
{0x28u, Opcode::SOrn2SaveexecB64}, {0x34u, Opcode::SAbsI32},
|
||||||
{0x16u, Opcode::SFlbitI32B64},
|
{0x37u, Opcode::SAndn1SaveexecB64}, {0x3bu, Opcode::SBitreplicateB64B32},
|
||||||
{0x1bu, Opcode::SBitset0B32},
|
{0x3cu, Opcode::SAndSaveexecB32}, {0x44u, Opcode::SAndn1SaveexecB32},
|
||||||
{0x1du, Opcode::SBitset1B32},
|
|
||||||
{0x1fu, Opcode::SGetpcB64},
|
|
||||||
{0x20u, Opcode::SSetpcB64},
|
|
||||||
{0x24u, Opcode::SAndSaveexecB64},
|
|
||||||
{0x28u, Opcode::SOrn2SaveexecB64},
|
|
||||||
{0x34u, Opcode::SAbsI32},
|
|
||||||
{0x37u, Opcode::SAndn1SaveexecB64},
|
|
||||||
{0x3bu, Opcode::SBitreplicateB64B32},
|
|
||||||
{0x3cu, Opcode::SAndSaveexecB32},
|
|
||||||
{0x44u, Opcode::SAndn1SaveexecB32},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr OpcodeMap SOPC_OPS[] = {
|
constexpr OpcodeMap SOPC_OPS[] = {
|
||||||
|
|||||||
@@ -446,6 +446,7 @@ std::string OpcodeToString(Opcode opcode) {
|
|||||||
case Opcode::SBcnt1I32B32: return "s_bcnt1_i32_b32";
|
case Opcode::SBcnt1I32B32: return "s_bcnt1_i32_b32";
|
||||||
case Opcode::SBcnt1I32B64: return "s_bcnt1_i32_b64";
|
case Opcode::SBcnt1I32B64: return "s_bcnt1_i32_b64";
|
||||||
case Opcode::SFf1I32B32: return "s_ff1_i32_b32";
|
case Opcode::SFf1I32B32: return "s_ff1_i32_b32";
|
||||||
|
case Opcode::SFf1I32B64: return "s_ff1_i32_b64";
|
||||||
case Opcode::SFlbitI32B64: return "s_flbit_i32_b64";
|
case Opcode::SFlbitI32B64: return "s_flbit_i32_b64";
|
||||||
case Opcode::SBitreplicateB64B32: return "s_bitreplicate_b64_b32";
|
case Opcode::SBitreplicateB64B32: return "s_bitreplicate_b64_b32";
|
||||||
case Opcode::SGetpcB64: return "s_getpc_b64";
|
case Opcode::SGetpcB64: return "s_getpc_b64";
|
||||||
@@ -1017,6 +1018,7 @@ std::string InstructionToString(const Instruction& inst) {
|
|||||||
case Opcode::SBrevB32:
|
case Opcode::SBrevB32:
|
||||||
case Opcode::SBcnt1I32B32:
|
case Opcode::SBcnt1I32B32:
|
||||||
case Opcode::SFf1I32B32:
|
case Opcode::SFf1I32B32:
|
||||||
|
case Opcode::SFf1I32B64:
|
||||||
case Opcode::SNotB64:
|
case Opcode::SNotB64:
|
||||||
case Opcode::SWqmB64:
|
case Opcode::SWqmB64:
|
||||||
case Opcode::SAndSaveexecB32:
|
case Opcode::SAndSaveexecB32:
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ enum class Opcode {
|
|||||||
SBcnt1I32B32,
|
SBcnt1I32B32,
|
||||||
SBcnt1I32B64,
|
SBcnt1I32B64,
|
||||||
SFf1I32B32,
|
SFf1I32B32,
|
||||||
|
SFf1I32B64,
|
||||||
SFlbitI32B64,
|
SFlbitI32B64,
|
||||||
SBitreplicateB64B32,
|
SBitreplicateB64B32,
|
||||||
SGetpcB64,
|
SGetpcB64,
|
||||||
|
|||||||
@@ -320,6 +320,16 @@ bool Translator::TranslateComposedInteger(const IR::Instruction& inst) {
|
|||||||
result = ir.BitwiseXor(ir.BitwiseXor(ReadU32(inst.src[0]), ReadU32(inst.src[1])),
|
result = ir.BitwiseXor(ir.BitwiseXor(ReadU32(inst.src[0]), ReadU32(inst.src[1])),
|
||||||
ReadU32(inst.src[2]));
|
ReadU32(inst.src[2]));
|
||||||
break;
|
break;
|
||||||
|
case IR::Opcode::FindLsbU64: {
|
||||||
|
const auto source = UnpackU64(ReadU64(inst.src[0]));
|
||||||
|
const auto low_lsb = IR::U32(ir.Emit(IR::ValueOpcode::FindILsb32, {source[0]}));
|
||||||
|
const auto high_lsb = IR::U32(ir.Emit(IR::ValueOpcode::FindILsb32, {source[1]}));
|
||||||
|
const auto high_position = ir.IAdd(high_lsb, IR::U32(IR::Value(32u)));
|
||||||
|
result = ir.Select(ir.INotEqual(source[0], IR::U32(IR::Value(0u))), low_lsb,
|
||||||
|
ir.Select(ir.INotEqual(source[1], IR::U32(IR::Value(0u))),
|
||||||
|
high_position, IR::U32(IR::Value(0xffffffffu))));
|
||||||
|
break;
|
||||||
|
}
|
||||||
case IR::Opcode::FindMsbFromHighU32: {
|
case IR::Opcode::FindMsbFromHighU32: {
|
||||||
const auto source = ReadU32(inst.src[0]);
|
const auto source = ReadU32(inst.src[0]);
|
||||||
const auto msb = IR::U32(ir.Emit(IR::ValueOpcode::FindUMsb32, {source}));
|
const auto msb = IR::U32(ir.Emit(IR::ValueOpcode::FindUMsb32, {source}));
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ constexpr LowerMap LOWER_OPS[] = {
|
|||||||
{Decoder::Opcode::SBcnt1I32B32, Opcode::BitCountU32},
|
{Decoder::Opcode::SBcnt1I32B32, Opcode::BitCountU32},
|
||||||
{Decoder::Opcode::SBcnt1I32B64, Opcode::BitCountU64},
|
{Decoder::Opcode::SBcnt1I32B64, Opcode::BitCountU64},
|
||||||
{Decoder::Opcode::SFf1I32B32, Opcode::FindLsbU32},
|
{Decoder::Opcode::SFf1I32B32, Opcode::FindLsbU32},
|
||||||
|
{Decoder::Opcode::SFf1I32B64, Opcode::FindLsbU64},
|
||||||
{Decoder::Opcode::SFlbitI32B64, Opcode::FindMsbFromHighU64},
|
{Decoder::Opcode::SFlbitI32B64, Opcode::FindMsbFromHighU64},
|
||||||
{Decoder::Opcode::SBitreplicateB64B32, Opcode::BitReplicateB64B32},
|
{Decoder::Opcode::SBitreplicateB64B32, Opcode::BitReplicateB64B32},
|
||||||
{Decoder::Opcode::SNotB32, Opcode::BitwiseNotU32},
|
{Decoder::Opcode::SNotB32, Opcode::BitwiseNotU32},
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ 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)
|
||||||
IR_OPCODE(FindLsbU32, General, SimpleInteger)
|
IR_OPCODE(FindLsbU32, General, SimpleInteger)
|
||||||
|
IR_OPCODE(FindLsbU64, General, ComposedInteger)
|
||||||
IR_OPCODE(FindMsbFromHighU32, General, ComposedInteger)
|
IR_OPCODE(FindMsbFromHighU32, General, ComposedInteger)
|
||||||
IR_OPCODE(FindMsbFromHighU64, General, ComposedInteger)
|
IR_OPCODE(FindMsbFromHighU64, General, ComposedInteger)
|
||||||
IR_OPCODE(BitFieldMaskU32, General, ExtendedInteger)
|
IR_OPCODE(BitFieldMaskU32, General, ExtendedInteger)
|
||||||
|
|||||||
@@ -11080,6 +11080,19 @@ TestCase ScalarBitfieldPack() {
|
|||||||
code.push_back(EncodeSop2(0x0a, 17, InlineU32(1), InlineU32(0)));
|
code.push_back(EncodeSop2(0x0a, 17, InlineU32(1), InlineU32(0)));
|
||||||
code.push_back(EncodeSopc(0x0c, InlineU32(4), InlineU32(1)));
|
code.push_back(EncodeSopc(0x0c, InlineU32(4), InlineU32(1)));
|
||||||
code.push_back(EncodeSop2(0x0a, 18, InlineU32(1), InlineU32(0)));
|
code.push_back(EncodeSop2(0x0a, 18, InlineU32(1), InlineU32(0)));
|
||||||
|
AppendSMovLiteral(&code, 25, 0u);
|
||||||
|
AppendSMovLiteral(&code, 26, 0x00000100u);
|
||||||
|
code.push_back(EncodeSopc(0x06, InlineU32(0), InlineU32(1)));
|
||||||
|
code.push_back(EncodeSop1(0x14, 31, 25));
|
||||||
|
code.push_back(EncodeSop2(0x0a, 34, InlineU32(1), InlineU32(0)));
|
||||||
|
AppendSMovLiteral(&code, 27, 0x00000020u);
|
||||||
|
AppendSMovLiteral(&code, 28, 0x00000100u);
|
||||||
|
code.push_back(EncodeSopc(0x06, InlineU32(1), InlineU32(1)));
|
||||||
|
code.push_back(EncodeSop1(0x14, 32, 27));
|
||||||
|
code.push_back(EncodeSop2(0x0a, 35, InlineU32(1), InlineU32(0)));
|
||||||
|
AppendSMovLiteral(&code, 29, 0u);
|
||||||
|
AppendSMovLiteral(&code, 30, 0u);
|
||||||
|
code.push_back(EncodeSop1(0x14, 33, 29));
|
||||||
|
|
||||||
AppendStoreSgpr(&code, 1, 0);
|
AppendStoreSgpr(&code, 1, 0);
|
||||||
AppendStoreSgpr(&code, 3, 1);
|
AppendStoreSgpr(&code, 3, 1);
|
||||||
@@ -11095,15 +11108,22 @@ TestCase ScalarBitfieldPack() {
|
|||||||
AppendStoreSgpr(&code, 15, 12);
|
AppendStoreSgpr(&code, 15, 12);
|
||||||
AppendStoreSgpr(&code, 17, 13);
|
AppendStoreSgpr(&code, 17, 13);
|
||||||
AppendStoreSgpr(&code, 18, 14);
|
AppendStoreSgpr(&code, 18, 14);
|
||||||
|
AppendStoreSgpr(&code, 31, 15);
|
||||||
|
AppendStoreSgpr(&code, 32, 16);
|
||||||
|
AppendStoreSgpr(&code, 33, 17);
|
||||||
|
AppendStoreSgpr(&code, 34, 18);
|
||||||
|
AppendStoreSgpr(&code, 35, 19);
|
||||||
AppendEnd(&code);
|
AppendEnd(&code);
|
||||||
|
|
||||||
return {"ScalarBitfieldPack",
|
return {"ScalarBitfieldPack",
|
||||||
code,
|
code,
|
||||||
{},
|
{},
|
||||||
{0xf0000000u, 8, 9, 1, 0, 0, 0x0000000fu, 0, 0x00000f00u, 0x0000000fu,
|
{0xf0000000u, 8, 9, 1, 0, 0, 0x0000000fu, 0, 0x00000f00u, 0x0000000fu,
|
||||||
0xddddbbbbu, 0xccccbbbbu, 0xccccaaaau, 1, 1},
|
0xddddbbbbu, 0xccccbbbbu, 0xccccaaaau, 1, 1, 40, 5, 0xffffffffu, 0,
|
||||||
|
1},
|
||||||
{O::SMovB32, O::SBrevB32, O::SBcnt1I32B32, O::SBcnt1I32B64,
|
{O::SMovB32, O::SBrevB32, O::SBcnt1I32B32, O::SBcnt1I32B64,
|
||||||
O::SBitreplicateB64B32, O::SBfmB32, O::SBfeU32, O::SPackLlB32B16,
|
O::SFf1I32B64, O::SBitreplicateB64B32, O::SBfmB32, O::SBfeU32,
|
||||||
|
O::SPackLlB32B16,
|
||||||
O::SPackLhB32B16, O::SPackHhB32B16, O::SBitcmp0B32, O::SBitcmp1B32,
|
O::SPackLhB32B16, O::SPackHhB32B16, O::SBitcmp0B32, O::SBitcmp1B32,
|
||||||
O::SCselectB32, O::VMovB32, O::BufferStoreDword, O::SEndpgm}};
|
O::SCselectB32, O::VMovB32, O::BufferStoreDword, O::SEndpgm}};
|
||||||
}
|
}
|
||||||
@@ -20269,6 +20289,11 @@ int main(int argc, char **argv) {
|
|||||||
RunCase(&vulkan, VectorAlignByteUsesFiveBitByteOffset());
|
RunCase(&vulkan, VectorAlignByteUsesFiveBitByteOffset());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (argc == 2 && std::strcmp(argv[1], "--sff1-b64-only") == 0) {
|
||||||
|
VulkanHarness vulkan;
|
||||||
|
RunCase(&vulkan, ScalarBitfieldPack());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--context-state-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--context-state-only") == 0) {
|
||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
CheckPm4PolygonOffsetRegisters(vulkan.RuntimeRenderer());
|
CheckPm4PolygonOffsetRegisters(vulkan.RuntimeRenderer());
|
||||||
|
|||||||
@@ -2931,6 +2931,7 @@ void TestNewShaderRecompilerScalarB64Alu() {
|
|||||||
EncodeSop2(0x21, 26, 24, 0), // s_lshr_b64 s[26:27], s[24:25], s0
|
EncodeSop2(0x21, 26, 24, 0), // s_lshr_b64 s[26:27], s[24:25], s0
|
||||||
EncodeSop2(0x25, 28, 132, 130), // s_bfm_b64 s[28:29], 4, 2
|
EncodeSop2(0x25, 28, 132, 130), // s_bfm_b64 s[28:29], 4, 2
|
||||||
EncodeSop1(0x10, 30, 26), // s_bcnt1_i32_b64 s30, s[26:27]
|
EncodeSop1(0x10, 30, 26), // s_bcnt1_i32_b64 s30, s[26:27]
|
||||||
|
EncodeSop1(0x14, 31, 26), // s_ff1_i32_b64 s31, s[26:27]
|
||||||
EncodeSop1(0x16, 106, 26), // s_flbit_i32_b64 vcc_lo, s[26:27]
|
EncodeSop1(0x16, 106, 26), // s_flbit_i32_b64 vcc_lo, s[26:27]
|
||||||
EncodeSop1(0x3b, 32, 30), // s_bitreplicate_b64_b32 s[32:33], s30
|
EncodeSop1(0x3b, 32, 30), // s_bitreplicate_b64_b32 s[32:33], s30
|
||||||
EncodeSop2(0x29, 34, 32, 255), // s_bfe_u64 s[34:35], s[32:33], 0x00040002
|
EncodeSop2(0x29, 34, 32, 255), // s_bfe_u64 s[34:35], s[32:33], 0x00040002
|
||||||
@@ -2989,6 +2990,8 @@ void TestNewShaderRecompilerScalarB64Alu() {
|
|||||||
"new decoder did not decode old-backed S_BFM_B64");
|
"new decoder did not decode old-backed S_BFM_B64");
|
||||||
Check(Common::ContainsStr(result.decoded_dump, "s_bcnt1_i32_b64 s30, s26"),
|
Check(Common::ContainsStr(result.decoded_dump, "s_bcnt1_i32_b64 s30, s26"),
|
||||||
"new decoder did not decode old-backed S_BCNT1_I32_B64");
|
"new decoder did not decode old-backed S_BCNT1_I32_B64");
|
||||||
|
Check(Common::ContainsStr(result.decoded_dump, "s_ff1_i32_b64 s31, s26"),
|
||||||
|
"new decoder did not decode RDNA2 S_FF1_I32_B64");
|
||||||
Check(Common::ContainsStr(result.decoded_dump, "s_flbit_i32_b64 vcc_lo, s26"),
|
Check(Common::ContainsStr(result.decoded_dump, "s_flbit_i32_b64 vcc_lo, s26"),
|
||||||
"new decoder did not decode RDNA2 S_FLBIT_I32_B64");
|
"new decoder did not decode RDNA2 S_FLBIT_I32_B64");
|
||||||
Check(Common::ContainsStr(result.decoded_dump,
|
Check(Common::ContainsStr(result.decoded_dump,
|
||||||
@@ -3042,6 +3045,8 @@ void TestNewShaderRecompilerScalarB64Alu() {
|
|||||||
"S_BFM_B64 did not lower to paired-dword IR");
|
"S_BFM_B64 did not lower to paired-dword IR");
|
||||||
Check(Common::ContainsStr(result.ir_dump, "BitCountU64 s30, s26"),
|
Check(Common::ContainsStr(result.ir_dump, "BitCountU64 s30, s26"),
|
||||||
"S_BCNT1_I32_B64 did not lower to paired-source bit count IR");
|
"S_BCNT1_I32_B64 did not lower to paired-source bit count IR");
|
||||||
|
Check(Common::ContainsStr(result.ir_dump, "FindLsbU64 s31, s26"),
|
||||||
|
"S_FF1_I32_B64 did not lower to paired-source bit search IR");
|
||||||
Check(Common::ContainsStr(result.ir_dump, "FindMsbFromHighU64 vcc_lo, s26"),
|
Check(Common::ContainsStr(result.ir_dump, "FindMsbFromHighU64 vcc_lo, s26"),
|
||||||
"S_FLBIT_I32_B64 did not lower to paired-source leading-zero IR");
|
"S_FLBIT_I32_B64 did not lower to paired-source leading-zero IR");
|
||||||
Check(Common::ContainsStr(result.ir_dump, "BitReplicateB64B32 s32, s30"),
|
Check(Common::ContainsStr(result.ir_dump, "BitReplicateB64B32 s32, s30"),
|
||||||
|
|||||||
Reference in New Issue
Block a user