mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
shader: add V_CMPX_O_F32 opcode
This commit is contained in:
@@ -354,6 +354,7 @@ enum class Opcode {
|
|||||||
V_CMPX_GT_F32,
|
V_CMPX_GT_F32,
|
||||||
V_CMPX_LG_F32,
|
V_CMPX_LG_F32,
|
||||||
V_CMPX_GE_F32,
|
V_CMPX_GE_F32,
|
||||||
|
V_CMPX_O_F32,
|
||||||
V_CMPX_NGE_F32,
|
V_CMPX_NGE_F32,
|
||||||
V_CMPX_NLG_F32,
|
V_CMPX_NLG_F32,
|
||||||
V_CMPX_NGT_F32,
|
V_CMPX_NGT_F32,
|
||||||
|
|||||||
@@ -214,6 +214,7 @@ constexpr VopcOpcodeInfo VOPC_OPCODE_LIST[] = {
|
|||||||
{0x11u, Opcode::V_CMPX_LT_F32}, {0x12u, Opcode::V_CMPX_EQ_F32},
|
{0x11u, Opcode::V_CMPX_LT_F32}, {0x12u, Opcode::V_CMPX_EQ_F32},
|
||||||
{0x13u, Opcode::V_CMPX_LE_F32}, {0x14u, Opcode::V_CMPX_GT_F32},
|
{0x13u, Opcode::V_CMPX_LE_F32}, {0x14u, Opcode::V_CMPX_GT_F32},
|
||||||
{0x15u, Opcode::V_CMPX_LG_F32}, {0x16u, Opcode::V_CMPX_GE_F32},
|
{0x15u, Opcode::V_CMPX_LG_F32}, {0x16u, Opcode::V_CMPX_GE_F32},
|
||||||
|
{0x17u, Opcode::V_CMPX_O_F32},
|
||||||
{0x19u, Opcode::V_CMPX_NGE_F32}, {0x1au, Opcode::V_CMPX_NLG_F32},
|
{0x19u, Opcode::V_CMPX_NGE_F32}, {0x1au, Opcode::V_CMPX_NLG_F32},
|
||||||
{0x1bu, Opcode::V_CMPX_NGT_F32}, {0x1cu, Opcode::V_CMPX_NLE_F32},
|
{0x1bu, Opcode::V_CMPX_NGT_F32}, {0x1cu, Opcode::V_CMPX_NLE_F32},
|
||||||
{0x1du, Opcode::V_CMPX_NEQ_F32}, {0x1eu, Opcode::V_CMPX_NLT_F32},
|
{0x1du, Opcode::V_CMPX_NEQ_F32}, {0x1eu, Opcode::V_CMPX_NLT_F32},
|
||||||
@@ -820,6 +821,7 @@ bool IsVopcFloatCompareOpcode(Opcode opcode) {
|
|||||||
case Opcode::V_CMPX_GT_F32:
|
case Opcode::V_CMPX_GT_F32:
|
||||||
case Opcode::V_CMPX_LG_F32:
|
case Opcode::V_CMPX_LG_F32:
|
||||||
case Opcode::V_CMPX_GE_F32:
|
case Opcode::V_CMPX_GE_F32:
|
||||||
|
case Opcode::V_CMPX_O_F32:
|
||||||
case Opcode::V_CMPX_NGE_F32:
|
case Opcode::V_CMPX_NGE_F32:
|
||||||
case Opcode::V_CMPX_NLG_F32:
|
case Opcode::V_CMPX_NLG_F32:
|
||||||
case Opcode::V_CMPX_NGT_F32:
|
case Opcode::V_CMPX_NGT_F32:
|
||||||
@@ -1432,6 +1434,7 @@ bool IsVopcCompareExec(Opcode opcode) {
|
|||||||
case Opcode::V_CMPX_GT_F32:
|
case Opcode::V_CMPX_GT_F32:
|
||||||
case Opcode::V_CMPX_LG_F32:
|
case Opcode::V_CMPX_LG_F32:
|
||||||
case Opcode::V_CMPX_GE_F32:
|
case Opcode::V_CMPX_GE_F32:
|
||||||
|
case Opcode::V_CMPX_O_F32:
|
||||||
case Opcode::V_CMPX_NGE_F32:
|
case Opcode::V_CMPX_NGE_F32:
|
||||||
case Opcode::V_CMPX_NLG_F32:
|
case Opcode::V_CMPX_NLG_F32:
|
||||||
case Opcode::V_CMPX_NGT_F32:
|
case Opcode::V_CMPX_NGT_F32:
|
||||||
|
|||||||
@@ -47,12 +47,12 @@ void Translator::EmitFloatCompare(const Decoder::Instruction& inst, IR::ValueOpc
|
|||||||
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs})), false, cmpx);
|
EmitCompareResult(inst, IR::U1(ir.Emit(opcode, {lhs, rhs})), false, cmpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered) {
|
void Translator::EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered, bool cmpx) {
|
||||||
const auto lhs = IR::F32(ReadOperand(inst.src0, IR::Type::F32));
|
const auto lhs = IR::F32(ReadOperand(inst.src0, IR::Type::F32));
|
||||||
const auto rhs = IR::F32(ReadOperand(inst.src1, IR::Type::F32));
|
const auto rhs = IR::F32(ReadOperand(inst.src1, IR::Type::F32));
|
||||||
const auto unordered = ir.LogicalOr(IR::U1(ir.Emit(IR::ValueOpcode::FPIsNan32, {lhs})),
|
const auto unordered = ir.LogicalOr(IR::U1(ir.Emit(IR::ValueOpcode::FPIsNan32, {lhs})),
|
||||||
IR::U1(ir.Emit(IR::ValueOpcode::FPIsNan32, {rhs})));
|
IR::U1(ir.Emit(IR::ValueOpcode::FPIsNan32, {rhs})));
|
||||||
EmitCompareResult(inst, ordered ? ir.LogicalNot(unordered) : unordered, false, false);
|
EmitCompareResult(inst, ordered ? ir.LogicalNot(unordered) : unordered, false, cmpx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Translator::EmitFloatClassCompare(const Decoder::Instruction& inst, bool cmpx) {
|
void Translator::EmitFloatClassCompare(const Decoder::Instruction& inst, bool cmpx) {
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ private:
|
|||||||
bool signed_value, bool cmpx);
|
bool signed_value, bool cmpx);
|
||||||
void EmitFloatCompare(const Decoder::Instruction& inst, IR::ValueOpcode opcode, bool half,
|
void EmitFloatCompare(const Decoder::Instruction& inst, IR::ValueOpcode opcode, bool half,
|
||||||
bool cmpx);
|
bool cmpx);
|
||||||
void EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered);
|
void EmitFloatOrderedCompare(const Decoder::Instruction& inst, bool ordered, bool cmpx);
|
||||||
void EmitFloatClassCompare(const Decoder::Instruction& inst, bool cmpx);
|
void EmitFloatClassCompare(const Decoder::Instruction& inst, bool cmpx);
|
||||||
void V_CVT_F32_UBYTE(const Decoder::Instruction& inst, uint32_t byte_index);
|
void V_CVT_F32_UBYTE(const Decoder::Instruction& inst, uint32_t byte_index);
|
||||||
void V_CVT_F32_U32(const Decoder::Instruction& inst);
|
void V_CVT_F32_U32(const Decoder::Instruction& inst);
|
||||||
|
|||||||
@@ -285,8 +285,9 @@ bool Translator::EmitVector(const Decoder::Instruction& inst) {
|
|||||||
case O::V_CMPX_NLT_F16:
|
case O::V_CMPX_NLT_F16:
|
||||||
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordGreaterThanEqual32, true, true);
|
EmitFloatCompare(inst, IR::ValueOpcode::FPUnordGreaterThanEqual32, true, true);
|
||||||
return true;
|
return true;
|
||||||
case O::V_CMP_O_F32: EmitFloatOrderedCompare(inst, true); return true;
|
case O::V_CMP_O_F32: EmitFloatOrderedCompare(inst, true, false); return true;
|
||||||
case O::V_CMP_U_F32: EmitFloatOrderedCompare(inst, false); return true;
|
case O::V_CMP_U_F32: EmitFloatOrderedCompare(inst, false, false); return true;
|
||||||
|
case O::V_CMPX_O_F32: EmitFloatOrderedCompare(inst, true, true); return true;
|
||||||
case O::V_CMP_CLASS_F32: EmitFloatClassCompare(inst, false); return true;
|
case O::V_CMP_CLASS_F32: EmitFloatClassCompare(inst, false); return true;
|
||||||
case O::V_CMPX_CLASS_F32: EmitFloatClassCompare(inst, true); return true;
|
case O::V_CMPX_CLASS_F32: EmitFloatClassCompare(inst, true); return true;
|
||||||
|
|
||||||
|
|||||||
@@ -16457,6 +16457,7 @@ CoverageClass ClassifyOpcode(ShaderOpcode opcode,
|
|||||||
case Opcode::V_CMPX_GT_F32:
|
case Opcode::V_CMPX_GT_F32:
|
||||||
case Opcode::V_CMPX_LG_F32:
|
case Opcode::V_CMPX_LG_F32:
|
||||||
case Opcode::V_CMPX_GE_F32:
|
case Opcode::V_CMPX_GE_F32:
|
||||||
|
case Opcode::V_CMPX_O_F32:
|
||||||
case Opcode::V_CMPX_NGE_F32:
|
case Opcode::V_CMPX_NGE_F32:
|
||||||
case Opcode::V_CMPX_NLG_F32:
|
case Opcode::V_CMPX_NLG_F32:
|
||||||
case Opcode::V_CMPX_NGT_F32:
|
case Opcode::V_CMPX_NGT_F32:
|
||||||
@@ -22344,6 +22345,69 @@ TestCase VectorCompareExecOps() {
|
|||||||
O::S_ENDPGM}};
|
O::S_ENDPGM}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase VectorVopcCmpxOrderedCapturedExecMask() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
struct CompareCase {
|
||||||
|
u32 lhs;
|
||||||
|
u32 rhs;
|
||||||
|
u32 initial_exec;
|
||||||
|
u32 expected_exec;
|
||||||
|
bool captured;
|
||||||
|
};
|
||||||
|
constexpr std::array<CompareCase, 8> cases{{
|
||||||
|
{0x3f800000u, 0x3f800000u, 1u, 1u, true}, // Finite value.
|
||||||
|
{0x7fc00000u, 0x7fc00000u, 1u, 0u, true}, // Quiet NaN.
|
||||||
|
{0x7f800001u, 0x7f800001u, 1u, 0u, true}, // Signaling NaN.
|
||||||
|
{0x7f800000u, 0x7f800000u, 1u, 1u, true}, // Infinity is ordered.
|
||||||
|
{0x80000000u, 0x80000000u, 1u, 1u, true}, // Signed zero is ordered.
|
||||||
|
{0x3f800000u, 0x3f800000u, 0u, 0u, true}, // Inactive lane.
|
||||||
|
{0x3f800000u, 0x7fc00000u, 1u, 0u, false}, // NaN in SRC1.
|
||||||
|
{0x7fc00000u, 0x3f800000u, 1u, 0u, false}, // NaN in SRC0.
|
||||||
|
}};
|
||||||
|
constexpr u32 vcc_lo = 0x13579bdfu;
|
||||||
|
constexpr u32 vcc_hi = 0x2468ace0u;
|
||||||
|
|
||||||
|
TestCase test;
|
||||||
|
test.name = "VectorVopcCmpxOrderedCapturedExecMask";
|
||||||
|
auto &code = test.code;
|
||||||
|
for (const auto &entry : cases) {
|
||||||
|
test.initial.push_back(entry.lhs);
|
||||||
|
test.initial.push_back(entry.rhs);
|
||||||
|
}
|
||||||
|
test.expected = test.initial;
|
||||||
|
for (u32 i = 0; i < cases.size(); ++i) {
|
||||||
|
const auto &entry = cases[i];
|
||||||
|
AppendVMovU32(&code, 30, i * 8u);
|
||||||
|
AppendBufferLoadDword(&code, 1, 30);
|
||||||
|
AppendVMovU32(&code, 30, i * 8u + 4u);
|
||||||
|
AppendBufferLoadDword(&code, 2, 30);
|
||||||
|
AppendSMovLiteral(&code, 106, vcc_lo);
|
||||||
|
AppendSMovLiteral(&code, 107, vcc_hi);
|
||||||
|
code.push_back(EncodeSMovB32(126, InlineU32(entry.initial_exec)));
|
||||||
|
code.push_back(entry.captured ? 0x7c2e0301u
|
||||||
|
: EncodeVopc(0x17u, Vgpr(1), 2));
|
||||||
|
code.push_back(EncodeSMovB32(20, 126));
|
||||||
|
code.push_back(EncodeSMovB32(21, 127));
|
||||||
|
code.push_back(EncodeSMovB32(22, 106));
|
||||||
|
code.push_back(EncodeSMovB32(23, 107));
|
||||||
|
code.push_back(EncodeSMovB32(126, InlineU32(1)));
|
||||||
|
const u32 out = static_cast<u32>(cases.size()) * 2u + i * 4u;
|
||||||
|
AppendStoreSgprPair(&code, 20, out);
|
||||||
|
AppendStoreSgprPair(&code, 22, out + 2u);
|
||||||
|
test.expected.insert(test.expected.end(),
|
||||||
|
{entry.expected_exec, 0u, vcc_lo, vcc_hi});
|
||||||
|
}
|
||||||
|
test.initial.resize(test.expected.size());
|
||||||
|
AppendEnd(&code);
|
||||||
|
test.opcodes = {O::V_MOV_B32, O::S_MOV_B32, O::BUFFER_LOAD_DWORD,
|
||||||
|
O::V_CMPX_O_F32, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||||
|
test.decoded_counts = {{"V_CMPX_O_F32 exec_lo, v1, v1", 6u},
|
||||||
|
{"V_CMPX_O_F32 exec_lo, v1, v2", 2u}};
|
||||||
|
test.compute_info.wave_size = 32;
|
||||||
|
test.has_compute_info = true;
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
TestCase VectorVop3FloatCompareNegSourceModifier() {
|
TestCase VectorVop3FloatCompareNegSourceModifier() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -28651,6 +28715,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(Vop3CndmaskUsesSgprMaskLaneBits);
|
AddCase(Vop3CndmaskUsesSgprMaskLaneBits);
|
||||||
AddCase(Vop3CndmaskAllowsDataSourceModifier);
|
AddCase(Vop3CndmaskAllowsDataSourceModifier);
|
||||||
AddCase(VectorCompareExecOps);
|
AddCase(VectorCompareExecOps);
|
||||||
|
AddCase(VectorVopcCmpxOrderedCapturedExecMask);
|
||||||
AddCase(VectorVop3FloatCompareNegSourceModifier);
|
AddCase(VectorVop3FloatCompareNegSourceModifier);
|
||||||
AddCase(VectorVop3CmpxWritesExecMask);
|
AddCase(VectorVop3CmpxWritesExecMask);
|
||||||
AddCase(VectorVopcSdwaCmpxWritesExecMask);
|
AddCase(VectorVopcSdwaCmpxWritesExecMask);
|
||||||
@@ -33424,6 +33489,11 @@ int main(int argc, char **argv) {
|
|||||||
RunCase(&vulkan, VectorDppBoundsControlZeroPreservesDestination());
|
RunCase(&vulkan, VectorDppBoundsControlZeroPreservesDestination());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (argc == 2 && std::strcmp(argv[1], "--cmpx-o-f32-only") == 0) {
|
||||||
|
VulkanHarness vulkan;
|
||||||
|
RunCase(&vulkan, VectorVopcCmpxOrderedCapturedExecMask());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--buffer-snorm-store-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--buffer-snorm-store-only") == 0) {
|
||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
RunCase(&vulkan, BufferStoreFormatXyzwSnorm16CapturedSkinningVectors());
|
RunCase(&vulkan, BufferStoreFormatXyzwSnorm16CapturedSkinningVectors());
|
||||||
|
|||||||
Reference in New Issue
Block a user