mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-29 06:16:55 +01:00
shader: implement V_ASHRREV_I64 (VOP3 0x301)
This commit is contained in:
@@ -26927,6 +26927,67 @@ TestCase VectorVop3LshlrevB64Captured() {
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase VectorVop3AshrrevI64Operands() {
|
||||
using O = ShaderOpcode;
|
||||
TestCase test;
|
||||
test.name = "VectorVop3AshrrevI64Operands";
|
||||
test.initial = {33u, 0x89abcdefu, 0xfedcba98u};
|
||||
test.expected = test.initial;
|
||||
auto &code = test.code;
|
||||
const auto store_result = [&](u32 dst, uint64_t value, u32 count) {
|
||||
const auto output = static_cast<u32>(test.expected.size());
|
||||
AppendStoreVgpr(&code, dst, output);
|
||||
AppendStoreVgpr(&code, dst + 1u, output + 1u);
|
||||
const auto expected = ReferenceAshrI64(value, count);
|
||||
test.expected.push_back(static_cast<u32>(expected));
|
||||
test.expected.push_back(static_cast<u32>(expected >> 32u));
|
||||
};
|
||||
|
||||
constexpr uint64_t value = 0xfedcba9889abcdefull;
|
||||
AppendVMovU32(&code, 30, sizeof(u32));
|
||||
AppendBufferLoadDword(&code, 2, 30);
|
||||
AppendVMovU32(&code, 30, 2u * sizeof(u32));
|
||||
AppendBufferLoadDword(&code, 3, 30);
|
||||
code.push_back(0xd7010007u);
|
||||
code.push_back(0x00020498u);
|
||||
store_result(7, value, 24u);
|
||||
|
||||
AppendSMovLiteral(&code, 106, static_cast<u32>(value));
|
||||
AppendSMovLiteral(&code, 107, static_cast<u32>(value >> 32u));
|
||||
AppendVMovU32(&code, 12, 68);
|
||||
code.push_back(0xd7010001u);
|
||||
code.push_back(0x0000d50cu);
|
||||
store_result(1, value, 68u);
|
||||
|
||||
AppendVMovU32(&code, 30, 0);
|
||||
AppendBufferLoadDword(&code, 12, 30);
|
||||
for (const u32 literal : {0u, 0x7fffffffu, 0x80000000u, 0xffffffffu}) {
|
||||
const uint64_t extended =
|
||||
literal | ((literal & 0x80000000u) != 0 ? 0xffffffff00000000ull : 0ull);
|
||||
for (const u32 count : {0u, 1u, 31u, 32u, 63u, 64u}) {
|
||||
AppendVop3(&code, 0x301, 7, InlineU32(count), 255u);
|
||||
code.push_back(literal);
|
||||
store_result(7, extended, count);
|
||||
}
|
||||
AppendVop3(&code, 0x301, 7, Vgpr(12), 255u);
|
||||
code.push_back(literal);
|
||||
store_result(7, extended, 33u);
|
||||
}
|
||||
AppendVop3(&code, 0x301, 7, Vgpr(12), 193u);
|
||||
store_result(7, UINT64_MAX, 33u);
|
||||
AppendVMovLiteral(&code, 7, static_cast<u32>(value));
|
||||
AppendVMovLiteral(&code, 8, static_cast<u32>(value >> 32u));
|
||||
AppendVop3(&code, 0x301, 7, Vgpr(12), Vgpr(7));
|
||||
store_result(7, value, 33u);
|
||||
|
||||
AppendEnd(&code);
|
||||
test.initial.resize(test.expected.size());
|
||||
test.opcodes = {O::S_MOV_B32, O::V_MOV_B32, O::BUFFER_LOAD_DWORD,
|
||||
O::V_ASHRREV_I64, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
test.required_spirv = {"OpShiftRightArithmetic", "OpTypeInt 64 0"};
|
||||
return test;
|
||||
}
|
||||
|
||||
TestCase VectorDynamicU64ShiftEdges() {
|
||||
using O = ShaderOpcode;
|
||||
TestCase test;
|
||||
@@ -26944,10 +27005,12 @@ TestCase VectorDynamicU64ShiftEdges() {
|
||||
// A buffer load prevents the constant-shift specialization.
|
||||
AppendVMovU32(&code, 30, index * sizeof(u32));
|
||||
AppendBufferLoadDword(&code, 3, 30);
|
||||
for (const bool left : {true, false}) {
|
||||
AppendVop3(&code, left ? 0x2ff : 0x300, 33, Vgpr(3), Vgpr(4));
|
||||
for (const u32 opcode : {0x2ffu, 0x300u, 0x301u}) {
|
||||
AppendVop3(&code, opcode, 33, Vgpr(3), Vgpr(4));
|
||||
const auto amount = test.initial[index] & 63u;
|
||||
const auto expected = left ? source << amount : source >> amount;
|
||||
const auto expected = opcode == 0x2ffu ? source << amount
|
||||
: opcode == 0x300u ? source >> amount
|
||||
: ReferenceAshrI64(source, amount);
|
||||
const auto output = static_cast<u32>(test.expected.size());
|
||||
AppendStoreVgpr(&code, 33, output);
|
||||
AppendStoreVgpr(&code, 34, output + 1u);
|
||||
@@ -26959,9 +27022,10 @@ TestCase VectorDynamicU64ShiftEdges() {
|
||||
AppendEnd(&code);
|
||||
test.initial.resize(test.expected.size());
|
||||
test.opcodes = {O::V_MOV_B32, O::BUFFER_LOAD_DWORD, O::V_LSHLREV_B64,
|
||||
O::V_LSHRREV_B64, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
O::V_LSHRREV_B64, O::V_ASHRREV_I64,
|
||||
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||
test.required_spirv = {"OpShiftLeftLogical", "OpShiftRightLogical",
|
||||
"OpTypeInt 64 0"};
|
||||
"OpShiftRightArithmetic", "OpTypeInt 64 0"};
|
||||
return test;
|
||||
}
|
||||
|
||||
@@ -45911,6 +45975,7 @@ std::vector<TestCase> MakeCases() {
|
||||
cases.push_back(ScalarAshrI64Masks(32));
|
||||
cases.push_back(ScalarAshrI64Masks(64));
|
||||
AddCase(VectorDynamicU64ShiftEdges);
|
||||
AddCase(VectorVop3AshrrevI64Operands);
|
||||
AddCase(ScalarConditionalMoveB64);
|
||||
AddCase(ScalarConditionalMoveB64PreservesMasks);
|
||||
AddCase(ScalarAndn2B64SccUsesMaskShadow);
|
||||
@@ -53094,6 +53159,7 @@ int main(int argc, char **argv) {
|
||||
VulkanHarness vulkan;
|
||||
RunCase(&vulkan, ScalarDynamic64BitOps());
|
||||
RunCase(&vulkan, VectorDynamicU64ShiftEdges());
|
||||
RunCase(&vulkan, VectorVop3AshrrevI64Operands());
|
||||
RunCase(&vulkan, ScalarAshrI64Edges(false));
|
||||
RunCase(&vulkan, ScalarAshrI64Edges(true));
|
||||
RunCase(&vulkan, VectorCompareInteger64Edges());
|
||||
|
||||
@@ -10550,6 +10550,43 @@ void TestNewShaderRecompilerNativeU64Translation() {
|
||||
"captured VOP3 V_LSHLREV_B64 was not present in the decoded dump");
|
||||
CheckSpirvBinaryValidates(result.spirv);
|
||||
|
||||
const uint32_t ashrrev_i64_shader[] = {
|
||||
0xd7010001u, 0x0000d50cu,
|
||||
EncodeSopp(0x01),
|
||||
};
|
||||
Decoder::Instruction decoded_ashrrev_i64;
|
||||
ShaderRecompiler::Decoder::DecodeInstruction(ashrrev_i64_shader, 0u,
|
||||
decoded_ashrrev_i64);
|
||||
Check(decoded_ashrrev_i64.opcode == Decoder::Opcode::V_ASHRREV_I64 &&
|
||||
decoded_ashrrev_i64.dst.kind == Decoder::OperandKind::Vgpr &&
|
||||
decoded_ashrrev_i64.dst.reg == 1u &&
|
||||
decoded_ashrrev_i64.src_count == 2u &&
|
||||
decoded_ashrrev_i64.src0.kind == Decoder::OperandKind::Vgpr &&
|
||||
decoded_ashrrev_i64.src0.reg == 12u &&
|
||||
decoded_ashrrev_i64.src1.kind == Decoder::OperandKind::VccLo,
|
||||
"decoder rejected VOP3 V_ASHRREV_I64 fields");
|
||||
result = RecompileForTest(ashrrev_i64_shader, options);
|
||||
Check((result.decoded_dump.find("V_ASHRREV_I64 v1, v12, vcc_lo") != std::string::npos),
|
||||
"VOP3 V_ASHRREV_I64 was not present in the decoded dump");
|
||||
CheckSpirvBinaryValidates(result.spirv);
|
||||
|
||||
const uint32_t ashrrev_captured[] = {0xd7010007u, 0x00020498u, EncodeSopp(0x01)};
|
||||
Decoder::Instruction decoded_ashrrev_captured;
|
||||
ShaderRecompiler::Decoder::DecodeInstruction(ashrrev_captured, 0u,
|
||||
decoded_ashrrev_captured);
|
||||
Check(decoded_ashrrev_captured.opcode == Decoder::Opcode::V_ASHRREV_I64 &&
|
||||
decoded_ashrrev_captured.family == Decoder::Family::VOP3 &&
|
||||
decoded_ashrrev_captured.src_count == 2u &&
|
||||
decoded_ashrrev_captured.dst.kind == Decoder::OperandKind::Vgpr &&
|
||||
decoded_ashrrev_captured.dst.reg == 7u &&
|
||||
decoded_ashrrev_captured.src0.kind == Decoder::OperandKind::IntegerInlineConstant &&
|
||||
decoded_ashrrev_captured.src0.value == 24u &&
|
||||
decoded_ashrrev_captured.src1.kind == Decoder::OperandKind::Vgpr &&
|
||||
decoded_ashrrev_captured.src1.reg == 2u,
|
||||
"captured VOP3 V_ASHRREV_I64 opcode 0x301 was not decoded");
|
||||
result = RecompileForTest(ashrrev_captured, options);
|
||||
CheckSpirvBinaryValidates(result.spirv);
|
||||
|
||||
const uint32_t cmpx_i64_shader[] = {
|
||||
0xd4b5007eu, 0x00020e80u, // v_cmpx_ne_i64 exec, 0, v[7:8]
|
||||
EncodeSopp(0x01),
|
||||
|
||||
Reference in New Issue
Block a user