mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
shader: V_CMP_NGT_F16
This commit is contained in:
@@ -378,6 +378,7 @@ enum class Opcode {
|
|||||||
V_CMP_GT_F16,
|
V_CMP_GT_F16,
|
||||||
V_CMP_LG_F16,
|
V_CMP_LG_F16,
|
||||||
V_CMP_GE_F16,
|
V_CMP_GE_F16,
|
||||||
|
V_CMP_NGT_F16,
|
||||||
V_CMP_NEQ_F16,
|
V_CMP_NEQ_F16,
|
||||||
V_CMPX_LT_F16,
|
V_CMPX_LT_F16,
|
||||||
V_CMPX_EQ_F16,
|
V_CMPX_EQ_F16,
|
||||||
|
|||||||
@@ -250,7 +250,8 @@ constexpr VopcOpcodeInfo VOPC_OPCODE_LIST[] = {
|
|||||||
{0xf5u, Opcode::V_CMPX_NE_U64, false}, {0xc9u, Opcode::V_CMP_LT_F16},
|
{0xf5u, Opcode::V_CMPX_NE_U64, false}, {0xc9u, Opcode::V_CMP_LT_F16},
|
||||||
{0xcau, Opcode::V_CMP_EQ_F16}, {0xcbu, Opcode::V_CMP_LE_F16},
|
{0xcau, Opcode::V_CMP_EQ_F16}, {0xcbu, Opcode::V_CMP_LE_F16},
|
||||||
{0xccu, Opcode::V_CMP_GT_F16}, {0xcdu, Opcode::V_CMP_LG_F16},
|
{0xccu, Opcode::V_CMP_GT_F16}, {0xcdu, Opcode::V_CMP_LG_F16},
|
||||||
{0xceu, Opcode::V_CMP_GE_F16}, {0xedu, Opcode::V_CMP_NEQ_F16},
|
{0xceu, Opcode::V_CMP_GE_F16}, {0xebu, Opcode::V_CMP_NGT_F16},
|
||||||
|
{0xedu, Opcode::V_CMP_NEQ_F16},
|
||||||
{0xd9u, Opcode::V_CMPX_LT_F16}, {0xdau, Opcode::V_CMPX_EQ_F16},
|
{0xd9u, Opcode::V_CMPX_LT_F16}, {0xdau, Opcode::V_CMPX_EQ_F16},
|
||||||
{0xdbu, Opcode::V_CMPX_LE_F16}, {0xdcu, Opcode::V_CMPX_GT_F16},
|
{0xdbu, Opcode::V_CMPX_LE_F16}, {0xdcu, Opcode::V_CMPX_GT_F16},
|
||||||
{0xdeu, Opcode::V_CMPX_GE_F16}, {0xfbu, Opcode::V_CMPX_NGT_F16},
|
{0xdeu, Opcode::V_CMPX_GE_F16}, {0xfbu, Opcode::V_CMPX_NGT_F16},
|
||||||
@@ -824,6 +825,7 @@ bool IsVopcFloatCompareOpcode(Opcode opcode) {
|
|||||||
case Opcode::V_CMP_GT_F16:
|
case Opcode::V_CMP_GT_F16:
|
||||||
case Opcode::V_CMP_LG_F16:
|
case Opcode::V_CMP_LG_F16:
|
||||||
case Opcode::V_CMP_GE_F16:
|
case Opcode::V_CMP_GE_F16:
|
||||||
|
case Opcode::V_CMP_NGT_F16:
|
||||||
case Opcode::V_CMP_NEQ_F16:
|
case Opcode::V_CMP_NEQ_F16:
|
||||||
case Opcode::V_CMPX_LT_F16:
|
case Opcode::V_CMPX_LT_F16:
|
||||||
case Opcode::V_CMPX_EQ_F16:
|
case Opcode::V_CMPX_EQ_F16:
|
||||||
|
|||||||
@@ -264,6 +264,9 @@ bool Translator::EmitVector(const Decoder::Instruction& inst) {
|
|||||||
case O::V_CMPX_LE_F16:
|
case O::V_CMPX_LE_F16:
|
||||||
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdLessThanEqual32, true, true);
|
EmitFloatCompare(inst, IR::ValueOpcode::FPOrdLessThanEqual32, true, true);
|
||||||
return true;
|
return true;
|
||||||
|
case O::V_CMP_NGT_F16:
|
||||||
|
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordLessThanEqual32, true, false);
|
||||||
|
return true;
|
||||||
case O::V_CMPX_NGT_F16:
|
case O::V_CMPX_NGT_F16:
|
||||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordLessThanEqual32, true, true);
|
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordLessThanEqual32, true, true);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -15740,6 +15740,7 @@ CoverageClass ClassifyOpcode(ShaderOpcode opcode,
|
|||||||
case Opcode::V_CMP_GT_F16:
|
case Opcode::V_CMP_GT_F16:
|
||||||
case Opcode::V_CMP_LG_F16:
|
case Opcode::V_CMP_LG_F16:
|
||||||
case Opcode::V_CMP_GE_F16:
|
case Opcode::V_CMP_GE_F16:
|
||||||
|
case Opcode::V_CMP_NGT_F16:
|
||||||
case Opcode::V_CMP_NEQ_F16:
|
case Opcode::V_CMP_NEQ_F16:
|
||||||
case Opcode::V_CMPX_LT_F16:
|
case Opcode::V_CMPX_LT_F16:
|
||||||
case Opcode::V_CMPX_EQ_F16:
|
case Opcode::V_CMPX_EQ_F16:
|
||||||
@@ -21264,6 +21265,92 @@ TestCase VectorVopcCmpxLtU16CapturedSdwaExecMask() {
|
|||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase VectorVopcCmpNgtF16CapturedSdwaAndEdges() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
enum Encoding { Captured, Compact, Vop3NegAbs, HighWord, ScalarDst, SdwaNegAbs };
|
||||||
|
struct CompareCase {
|
||||||
|
u32 lhs;
|
||||||
|
u32 rhs;
|
||||||
|
u32 expected;
|
||||||
|
Encoding encoding = Captured;
|
||||||
|
u32 exec = 1;
|
||||||
|
};
|
||||||
|
const std::array<CompareCase, 17> cases{{
|
||||||
|
{0x7e003c00u, 0, 0}, // +1; ignore NaN in the upper half.
|
||||||
|
{0x3c00bc00u, 0, 1}, // -1
|
||||||
|
{0x3c000000u, 0, 1}, // +0
|
||||||
|
{0x3c008000u, 0, 1}, // -0
|
||||||
|
{0x3c007e00u, 0, 1}, // Quiet NaN: NGT differs from ordered LE.
|
||||||
|
{0x3c007c01u, 0, 1}, // Signaling NaN
|
||||||
|
{0x00007c00u, 0, 0}, // +infinity
|
||||||
|
{0x0000fc00u, 0, 1}, // -infinity
|
||||||
|
{0x0000bc00u, 0, 0, Captured, 0}, // Inactive lane contributes no VCC bit.
|
||||||
|
{0x00003c00u, 0x00007e00u, 1, Compact}, // NaN in src1.
|
||||||
|
{0x00004000u, 0x00003c00u, 0, Compact}, // +2 > +1
|
||||||
|
{0x0000bc00u, 0, 1, Vop3NegAbs}, // -abs(-1)
|
||||||
|
{0x00003c00u, 0, 1, Vop3NegAbs}, // -abs(+1)
|
||||||
|
{0xbc004000u, 0x3c00c000u, 1, HighWord}, // Select both upper halves.
|
||||||
|
{0x00004000u, 0x00003c00u, 0, ScalarDst},
|
||||||
|
{0x00003c00u, 0x00004000u, 1, ScalarDst},
|
||||||
|
{0x0000bc00u, 0, 1, SdwaNegAbs},
|
||||||
|
}};
|
||||||
|
constexpr u32 vcc_sentinel = 0x89abcdefu;
|
||||||
|
TestCase test;
|
||||||
|
test.name = "VectorVopcCmpNgtF16CapturedSdwaAndEdges";
|
||||||
|
for (const auto &entry : cases) {
|
||||||
|
test.initial.insert(test.initial.end(), {entry.lhs, entry.rhs});
|
||||||
|
}
|
||||||
|
test.expected = test.initial;
|
||||||
|
auto &code = test.code;
|
||||||
|
for (u32 i = 0; i < cases.size(); ++i) {
|
||||||
|
const auto &entry = cases[i];
|
||||||
|
AppendVMovU32(&code, 30, i * 8u);
|
||||||
|
AppendBufferLoadDword(&code, 21, 30); // Runtime inputs prevent constant folding.
|
||||||
|
AppendVMovU32(&code, 30, i * 8u + 4u);
|
||||||
|
AppendBufferLoadDword(&code, 1, 30);
|
||||||
|
AppendSMovLiteral(&code, 106, vcc_sentinel);
|
||||||
|
AppendSMovLiteral(&code, 107, vcc_sentinel);
|
||||||
|
code.push_back(EncodeSMovB32(126, InlineU32(entry.exec)));
|
||||||
|
switch (entry.encoding) {
|
||||||
|
case Captured: code.insert(code.end(), {0x7dd700f9u, 0x86060015u}); break;
|
||||||
|
case Compact: code.push_back(EncodeVopc(0xeb, Vgpr(21), 1)); break;
|
||||||
|
case Vop3NegAbs:
|
||||||
|
AppendVop3(&code, 0xeb, 106, Vgpr(21), Vgpr(1), 0, 1, 0, false, 0, 1);
|
||||||
|
break;
|
||||||
|
case HighWord:
|
||||||
|
code.push_back(EncodeVopc(0xeb, 249, 1));
|
||||||
|
code.push_back(EncodeVopcSdwa(21, 0, 0, 5, 5));
|
||||||
|
break;
|
||||||
|
case ScalarDst:
|
||||||
|
code.push_back(EncodeVopc(0xeb, 249, 1));
|
||||||
|
code.push_back(EncodeVopcSdwa(21, 22, 1));
|
||||||
|
break;
|
||||||
|
case SdwaNegAbs:
|
||||||
|
code.push_back(EncodeVopc(0xeb, 249, 1));
|
||||||
|
code.push_back(EncodeVopcSdwa(21, 0, 0, 6, 6, 0, 0, 1, 1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
code.push_back(EncodeSMovB32(20, entry.encoding == ScalarDst ? 22 : 106));
|
||||||
|
code.push_back(EncodeSMovB32(21, 126)); // CMP must preserve EXEC even if false.
|
||||||
|
code.push_back(EncodeSMovB32(126, InlineU32(1)));
|
||||||
|
const u32 out = static_cast<u32>(test.initial.size()) + i * 4u;
|
||||||
|
AppendStoreSgprPair(&code, 20, out);
|
||||||
|
AppendStoreSgprPair(&code, 106, out + 2u);
|
||||||
|
test.expected.insert(test.expected.end(),
|
||||||
|
{entry.expected, entry.exec,
|
||||||
|
entry.encoding == ScalarDst ? vcc_sentinel : entry.expected,
|
||||||
|
vcc_sentinel});
|
||||||
|
}
|
||||||
|
AppendEnd(&code);
|
||||||
|
test.opcodes = {O::V_MOV_B32, O::S_MOV_B32, O::BUFFER_LOAD_DWORD,
|
||||||
|
O::V_CMP_NGT_F16, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||||
|
test.decoded_counts = {{"V_CMP_NGT_F16", cases.size()}};
|
||||||
|
test.required_spirv = {"OpFUnordLessThanEqual"};
|
||||||
|
test.compute_info.wave_size = 32;
|
||||||
|
test.has_compute_info = true;
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
TestCase VectorVopcCmpxNgtF16CapturedSdwaExecMask() {
|
TestCase VectorVopcCmpxNgtF16CapturedSdwaExecMask() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -26773,6 +26860,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(VectorVopcSdwaCmpxWritesExecMask);
|
AddCase(VectorVopcSdwaCmpxWritesExecMask);
|
||||||
AddCase(VectorVopcCmpxGtU16CapturedSdwaExecMask);
|
AddCase(VectorVopcCmpxGtU16CapturedSdwaExecMask);
|
||||||
AddCase(VectorVopcCmpxLtU16CapturedSdwaExecMask);
|
AddCase(VectorVopcCmpxLtU16CapturedSdwaExecMask);
|
||||||
|
AddCase(VectorVopcCmpNgtF16CapturedSdwaAndEdges);
|
||||||
AddCase(VectorVopcCmpxNgtF16CapturedSdwaExecMask);
|
AddCase(VectorVopcCmpxNgtF16CapturedSdwaExecMask);
|
||||||
AddCase(VectorCompareInvertedMaskSelect);
|
AddCase(VectorCompareInvertedMaskSelect);
|
||||||
AddCase(BranchSelect);
|
AddCase(BranchSelect);
|
||||||
@@ -31447,6 +31535,15 @@ int main(int argc, char **argv) {
|
|||||||
RunCase(&vulkan, VectorVopcSdwaCmpxClassF32CapturedExecMask());
|
RunCase(&vulkan, VectorVopcSdwaCmpxClassF32CapturedExecMask());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (argc == 2 && std::strcmp(argv[1], "--cmp-ngt-f16-only") == 0) {
|
||||||
|
VulkanHarness vulkan;
|
||||||
|
RunCase(&vulkan, VectorVopcCmpNgtF16CapturedSdwaAndEdges());
|
||||||
|
RunCase(&vulkan, VectorVopcCmpxNgtF16CapturedSdwaExecMask());
|
||||||
|
RunCase(&vulkan, VectorCompareF16Ops());
|
||||||
|
RunCase(&vulkan, Wave32VccMasksPreserveOtherHalf());
|
||||||
|
RunCase(&vulkan, VectorVop3FloatCompareNegSourceModifier());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--fract-f16-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--fract-f16-only") == 0) {
|
||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
RunCase(&vulkan, VectorFractF16CapturedAndEdges());
|
RunCase(&vulkan, VectorFractF16CapturedAndEdges());
|
||||||
|
|||||||
Reference in New Issue
Block a user