mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 05:46:56 +01:00
shader: support RDNA2 V_CMPX_NE_U64
This commit is contained in:
@@ -389,6 +389,7 @@ enum class Opcode {
|
|||||||
V_CMP_EQ_I64,
|
V_CMP_EQ_I64,
|
||||||
V_CMP_GT_U64,
|
V_CMP_GT_U64,
|
||||||
V_CMP_NE_U64,
|
V_CMP_NE_U64,
|
||||||
|
V_CMPX_NE_U64,
|
||||||
V_CMPX_LT_U32,
|
V_CMPX_LT_U32,
|
||||||
V_CMPX_EQ_U32,
|
V_CMPX_EQ_U32,
|
||||||
V_CMPX_LE_U32,
|
V_CMPX_LE_U32,
|
||||||
|
|||||||
@@ -233,6 +233,7 @@ constexpr VopcOpcodeInfo VOPC_OPCODE_LIST[] = {
|
|||||||
{0xd3u, Opcode::V_CMPX_LE_U32}, {0xd4u, Opcode::V_CMPX_GT_U32},
|
{0xd3u, Opcode::V_CMPX_LE_U32}, {0xd4u, Opcode::V_CMPX_GT_U32},
|
||||||
{0xd5u, Opcode::V_CMPX_NE_U32}, {0xd6u, Opcode::V_CMPX_GE_U32},
|
{0xd5u, Opcode::V_CMPX_NE_U32}, {0xd6u, Opcode::V_CMPX_GE_U32},
|
||||||
{0xe4u, Opcode::V_CMP_GT_U64, false}, {0xe5u, Opcode::V_CMP_NE_U64, false},
|
{0xe4u, Opcode::V_CMP_GT_U64, false}, {0xe5u, Opcode::V_CMP_NE_U64, false},
|
||||||
|
{0xf5u, Opcode::V_CMPX_NE_U64, false},
|
||||||
{0xc9u, Opcode::V_CMP_LT_F16}, {0xcau, Opcode::V_CMP_EQ_F16},
|
{0xc9u, Opcode::V_CMP_LT_F16}, {0xcau, Opcode::V_CMP_EQ_F16},
|
||||||
{0xcbu, Opcode::V_CMP_LE_F16}, {0xccu, Opcode::V_CMP_GT_F16},
|
{0xcbu, Opcode::V_CMP_LE_F16}, {0xccu, Opcode::V_CMP_GT_F16},
|
||||||
{0xcdu, Opcode::V_CMP_LG_F16}, {0xceu, Opcode::V_CMP_GE_F16},
|
{0xcdu, Opcode::V_CMP_LG_F16}, {0xceu, Opcode::V_CMP_GE_F16},
|
||||||
@@ -1498,6 +1499,7 @@ bool IsVopcCompareExec(Opcode opcode) {
|
|||||||
case Opcode::V_CMPX_GT_U32:
|
case Opcode::V_CMPX_GT_U32:
|
||||||
case Opcode::V_CMPX_NE_U32:
|
case Opcode::V_CMPX_NE_U32:
|
||||||
case Opcode::V_CMPX_GE_U32:
|
case Opcode::V_CMPX_GE_U32:
|
||||||
|
case Opcode::V_CMPX_NE_U64:
|
||||||
case Opcode::V_CMPX_LT_F16:
|
case Opcode::V_CMPX_LT_F16:
|
||||||
case Opcode::V_CMPX_EQ_F16:
|
case Opcode::V_CMPX_EQ_F16:
|
||||||
case Opcode::V_CMPX_LE_F16:
|
case Opcode::V_CMPX_LE_F16:
|
||||||
|
|||||||
@@ -338,6 +338,7 @@ constexpr LowerMap LOWER_OPS[] = {
|
|||||||
{Decoder::Opcode::V_CMP_EQ_I64, Opcode::CompareEqU64},
|
{Decoder::Opcode::V_CMP_EQ_I64, Opcode::CompareEqU64},
|
||||||
{Decoder::Opcode::V_CMP_GT_U64, Opcode::CompareGtU64},
|
{Decoder::Opcode::V_CMP_GT_U64, Opcode::CompareGtU64},
|
||||||
{Decoder::Opcode::V_CMP_NE_U64, Opcode::CompareNeU64},
|
{Decoder::Opcode::V_CMP_NE_U64, Opcode::CompareNeU64},
|
||||||
|
{Decoder::Opcode::V_CMPX_NE_U64, Opcode::CompareNeU64},
|
||||||
{Decoder::Opcode::V_CMPX_LT_U32, Opcode::CompareMaskLtU32},
|
{Decoder::Opcode::V_CMPX_LT_U32, Opcode::CompareMaskLtU32},
|
||||||
{Decoder::Opcode::V_CMPX_EQ_U32, Opcode::CompareMaskEqU32},
|
{Decoder::Opcode::V_CMPX_EQ_U32, Opcode::CompareMaskEqU32},
|
||||||
{Decoder::Opcode::V_CMPX_LE_U32, Opcode::CompareMaskLeU32},
|
{Decoder::Opcode::V_CMPX_LE_U32, Opcode::CompareMaskLeU32},
|
||||||
|
|||||||
@@ -14720,6 +14720,34 @@ TestCase VectorVop3CompareNeU64OnGpu() {
|
|||||||
O::S_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
O::S_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase VectorVopcCmpxNeU64CapturedExecMask() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
|
std::vector<u32> code;
|
||||||
|
AppendVMovU32(&code, 7, 0);
|
||||||
|
AppendVMovU32(&code, 8, 0);
|
||||||
|
AppendVMovU32(&code, 31, 0);
|
||||||
|
code.push_back(0x7dea0e80u); // v_cmpx_ne_u64 exec, 0, v[7:8]
|
||||||
|
AppendBufferStoreDword(&code, 8, 31);
|
||||||
|
|
||||||
|
code.push_back(EncodeSMovB32(126, InlineU32(1)));
|
||||||
|
AppendVMovU32(&code, 8, 1);
|
||||||
|
AppendVMovU32(&code, 31, 4);
|
||||||
|
code.push_back(0x7dea0e80u); // v_cmpx_ne_u64 exec, 0, v[7:8]
|
||||||
|
AppendBufferStoreDword(&code, 8, 31);
|
||||||
|
AppendEnd(&code);
|
||||||
|
|
||||||
|
TestCase test{"VectorVopcCmpxNeU64CapturedExecMask",
|
||||||
|
code,
|
||||||
|
{0x11223344u, 0x55667788u},
|
||||||
|
{0x11223344u, 1u},
|
||||||
|
{O::V_MOV_B32, O::V_CMPX_NE_U64, O::BUFFER_STORE_DWORD,
|
||||||
|
O::S_MOV_B32, O::S_ENDPGM}};
|
||||||
|
test.decoded_counts = {{"V_CMPX_NE_U64 exec_lo, 0, v7", 2}};
|
||||||
|
test.native_ir_counts = {{"CompareNeU64 exec_lo, 0x00000000, v7", 2}};
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
TestCase VectorVop3CompareGtU64OnGpu() {
|
TestCase VectorVop3CompareGtU64OnGpu() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -19564,6 +19592,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(VectorVop3CompareEqI64OnGpu);
|
AddCase(VectorVop3CompareEqI64OnGpu);
|
||||||
AddCase(VectorVop3CompareGtU64OnGpu);
|
AddCase(VectorVop3CompareGtU64OnGpu);
|
||||||
AddCase(VectorVop3CompareNeU64OnGpu);
|
AddCase(VectorVop3CompareNeU64OnGpu);
|
||||||
|
AddCase(VectorVopcCmpxNeU64CapturedExecMask);
|
||||||
AddCase(VectorCompareClassF32);
|
AddCase(VectorCompareClassF32);
|
||||||
AddCase(VectorCompareF16Ops);
|
AddCase(VectorCompareF16Ops);
|
||||||
AddCase(Vop2SdwaCndmaskSourceModifier);
|
AddCase(Vop2SdwaCndmaskSourceModifier);
|
||||||
|
|||||||
@@ -4043,7 +4043,8 @@ void TestNewShaderDecoderArchitecture() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TestNewShaderRecompilerRejectsDppOn64BitCompares() {
|
void TestNewShaderRecompilerRejectsDppOn64BitCompares() {
|
||||||
const uint32_t opcodes[] = {0xa2u, 0xe4u, 0xe5u}; // eq_i64, gt_u64, ne_u64
|
const uint32_t opcodes[] = {0xa2u, 0xe4u, 0xe5u,
|
||||||
|
0xf5u}; // eq_i64, gt_u64, ne_u64, cmpx_ne_u64
|
||||||
for (const auto opcode : opcodes) {
|
for (const auto opcode : opcodes) {
|
||||||
const uint32_t shader[] = {
|
const uint32_t shader[] = {
|
||||||
EncodeVopc(opcode, 250u, 0u), // DPP escape in SRC0
|
EncodeVopc(opcode, 250u, 0u), // DPP escape in SRC0
|
||||||
@@ -8360,10 +8361,42 @@ void TestNewShaderRecompilerDispatcherSpillsU32x3() {
|
|||||||
void TestNewShaderRecompilerU64PairLowering() {
|
void TestNewShaderRecompilerU64PairLowering() {
|
||||||
using namespace ShaderRecompiler;
|
using namespace ShaderRecompiler;
|
||||||
|
|
||||||
const uint32_t empty_shader[] = {EncodeSopp(0x01)};
|
|
||||||
auto options = MakeCompileOptions(ShaderType::Compute);
|
auto options = MakeCompileOptions(ShaderType::Compute);
|
||||||
|
options.dump_ir = true;
|
||||||
CompileResult result;
|
CompileResult result;
|
||||||
std::string error;
|
std::string error;
|
||||||
|
|
||||||
|
const uint32_t cmpx_shader[] = {
|
||||||
|
0x7dea0e80u, // v_cmpx_ne_u64 exec, 0, v[7:8]
|
||||||
|
EncodeSopp(0x01),
|
||||||
|
};
|
||||||
|
Decoder::Instruction decoded_cmpx;
|
||||||
|
Check(Decoder::DecodeInstruction(cmpx_shader, 0u, decoded_cmpx, &error),
|
||||||
|
error.c_str());
|
||||||
|
Check(decoded_cmpx.opcode == Decoder::Opcode::V_CMPX_NE_U64 &&
|
||||||
|
decoded_cmpx.dst.kind == Decoder::OperandKind::ExecLo &&
|
||||||
|
decoded_cmpx.src0.value == 0u &&
|
||||||
|
decoded_cmpx.src1.kind == Decoder::OperandKind::Vgpr &&
|
||||||
|
decoded_cmpx.src1.reg == 7u,
|
||||||
|
"decoder rejected captured V_CMPX_NE_U64 fields");
|
||||||
|
Check(TryRecompile(cmpx_shader, options, result, &error), error.c_str());
|
||||||
|
Decoder::Program decoded_program;
|
||||||
|
CFG::Graph graph;
|
||||||
|
IR::Program native;
|
||||||
|
Check(Decoder::DecodeProgram(cmpx_shader, decoded_program, &error),
|
||||||
|
error.c_str());
|
||||||
|
Check(CFG::BuildGraph(decoded_program, graph, &error) &&
|
||||||
|
CFG::Structurize(graph, &error),
|
||||||
|
error.c_str());
|
||||||
|
Check(IR::LowerProgram(decoded_program, graph, ShaderType::Compute, 64u,
|
||||||
|
native, &error),
|
||||||
|
error.c_str());
|
||||||
|
Check(Common::ContainsStr(IR::ProgramToString(native),
|
||||||
|
"CompareNeU64 exec_lo, 0x00000000, v7"),
|
||||||
|
"V_CMPX_NE_U64 did not lower to masked 64-bit inequality");
|
||||||
|
CheckSpirvBinaryValidates(result.spirv);
|
||||||
|
|
||||||
|
const uint32_t empty_shader[] = {EncodeSopp(0x01)};
|
||||||
Check(TryRecompile(empty_shader, options, result, &error), error.c_str());
|
Check(TryRecompile(empty_shader, options, result, &error), error.c_str());
|
||||||
|
|
||||||
auto program = result.program;
|
auto program = result.program;
|
||||||
|
|||||||
Reference in New Issue
Block a user