mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-26 12:56:54 +01:00
shader: allow reverse left shifts to use shared SDWA partial writes
This commit is contained in:
@@ -17,7 +17,6 @@ enum class Vop2SdwaProfile {
|
|||||||
IntegerFullDestination,
|
IntegerFullDestination,
|
||||||
IntegerPartialDestination,
|
IntegerPartialDestination,
|
||||||
ReverseRightShift,
|
ReverseRightShift,
|
||||||
ReverseLogicalLeft,
|
|
||||||
Bitwise,
|
Bitwise,
|
||||||
Count,
|
Count,
|
||||||
};
|
};
|
||||||
@@ -48,7 +47,7 @@ constexpr Vop2OpcodeInfo VOP2_OPCODE_LIST[] = {
|
|||||||
{0x17u, Opcode::V_ASHR_I32},
|
{0x17u, Opcode::V_ASHR_I32},
|
||||||
{0x18u, Opcode::V_ASHRREV_I32, Vop2SdwaProfile::ReverseRightShift},
|
{0x18u, Opcode::V_ASHRREV_I32, Vop2SdwaProfile::ReverseRightShift},
|
||||||
{0x19u, Opcode::V_LSHL_B32},
|
{0x19u, Opcode::V_LSHL_B32},
|
||||||
{0x1au, Opcode::V_LSHLREV_B32, Vop2SdwaProfile::ReverseLogicalLeft},
|
{0x1au, Opcode::V_LSHLREV_B32, Vop2SdwaProfile::IntegerPartialDestination},
|
||||||
{0x1bu, Opcode::V_AND_B32, Vop2SdwaProfile::Bitwise},
|
{0x1bu, Opcode::V_AND_B32, Vop2SdwaProfile::Bitwise},
|
||||||
{0x1cu, Opcode::V_OR_B32, Vop2SdwaProfile::Bitwise},
|
{0x1cu, Opcode::V_OR_B32, Vop2SdwaProfile::Bitwise},
|
||||||
{0x1du, Opcode::V_XOR_B32, Vop2SdwaProfile::Bitwise},
|
{0x1du, Opcode::V_XOR_B32, Vop2SdwaProfile::Bitwise},
|
||||||
@@ -1041,7 +1040,6 @@ constexpr Vop2SdwaRule VOP2_SDWA_RULES[] = {
|
|||||||
{SdwaSelFull(), SdwaSelAll(), SdwaSelAll(), false, false},
|
{SdwaSelFull(), SdwaSelAll(), SdwaSelAll(), false, false},
|
||||||
{SdwaSelAll(), SdwaSelAll(), SdwaSelAll(), true, false},
|
{SdwaSelAll(), SdwaSelAll(), SdwaSelAll(), true, false},
|
||||||
{SdwaSelFull(), SdwaSelAll(), SdwaSelAll(), false, false},
|
{SdwaSelFull(), SdwaSelAll(), SdwaSelAll(), false, false},
|
||||||
{SdwaSelFull(), SdwaSelAll(), SdwaSelAll(), false, false},
|
|
||||||
// Bitwise: WriteRawU32 inserts a byte or word destination like any other partial write.
|
// Bitwise: WriteRawU32 inserts a byte or word destination like any other partial write.
|
||||||
{SdwaSelAll(), SdwaSelAll(), SdwaSelAll(), true, false},
|
{SdwaSelAll(), SdwaSelAll(), SdwaSelAll(), true, false},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23215,6 +23215,52 @@ TestCase Vop2SdwaBitwiseByteDestinations(u32 wave_size) {
|
|||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase Vop2SdwaLshlrevByteDestinations(u32 wave_size) {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
constexpr u32 sentinel = 0xa1b2c3d4u;
|
||||||
|
TestCase test;
|
||||||
|
test.name = wave_size == 64 ? "Vop2SdwaLshlrevByteDestinations64" : "Vop2SdwaLshlrevByteDestinations32";
|
||||||
|
test.initial = {0x44668122u};
|
||||||
|
test.expected = test.initial;
|
||||||
|
auto &code = test.code;
|
||||||
|
const auto store = [&](u32 reg, u32 expected) {
|
||||||
|
AppendStoreVgpr(&code, reg, static_cast<u32>(test.expected.size()));
|
||||||
|
test.expected.push_back(expected);
|
||||||
|
};
|
||||||
|
AppendBufferLoadDword(&code, 4, 30);
|
||||||
|
for (const u32 count : {6u, 7u, 39u}) {
|
||||||
|
const u32 byte = count == 6u ? 0x40u : 0x80u;
|
||||||
|
for (u32 selector = 0; selector < 4u; ++selector) {
|
||||||
|
for (u32 unused = 0; unused < 3u; ++unused) {
|
||||||
|
AppendVMovLiteral(&code, 5, sentinel);
|
||||||
|
code.push_back(EncodeVop2(0x1a, 5, 249, 4));
|
||||||
|
// count7/byte1/preserve is captured 340a08f9 01861187 at PC4e98.
|
||||||
|
code.push_back(EncodeVop2Sdwa(InlineU32(count), selector, unused, 6, 1,
|
||||||
|
0, 0, 0, 0, 0, 0, 1));
|
||||||
|
const u32 shift = selector * 8u;
|
||||||
|
const u32 fill = unused == 1u && byte == 0x80u ? 0xffffff00u : 0u;
|
||||||
|
store(5, ((byte | fill) << shift) |
|
||||||
|
(unused == 2u ? sentinel & ~(0xffu << shift) : 0u));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
code.insert(code.end(), {EncodeVop2(0x1a, 4, 249, 4), 0x01861187u});
|
||||||
|
store(4, 0x44668022u); // Source1 aliases the preserved destination.
|
||||||
|
AppendVMovLiteral(&code, 5, sentinel);
|
||||||
|
code.push_back(EncodeSMovB32(126, InlineU32(0)));
|
||||||
|
code.insert(code.end(), {0x340a08f9u, 0x01861187u});
|
||||||
|
code.push_back(EncodeSMovB32(126, InlineU32(1)));
|
||||||
|
store(5, sentinel);
|
||||||
|
AppendEnd(&code);
|
||||||
|
test.initial.resize(test.expected.size());
|
||||||
|
test.opcodes = {O::BUFFER_LOAD_DWORD, O::V_MOV_B32, O::S_MOV_B32,
|
||||||
|
O::V_LSHLREV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||||
|
test.required_spirv = {"OpShiftLeftLogical", "OpBitFieldInsert", "OpBitFieldSExtract"};
|
||||||
|
test.compute_info.wave_size = wave_size;
|
||||||
|
test.has_compute_info = true;
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
TestCase Vop1SdwaMovByteDestinations() {
|
TestCase Vop1SdwaMovByteDestinations() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -39393,6 +39439,8 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(Vop1SdwaNotPartialSourcesAndDestinations);
|
AddCase(Vop1SdwaNotPartialSourcesAndDestinations);
|
||||||
cases.push_back(Vop2SdwaBitwiseByteDestinations(32));
|
cases.push_back(Vop2SdwaBitwiseByteDestinations(32));
|
||||||
cases.push_back(Vop2SdwaBitwiseByteDestinations(64));
|
cases.push_back(Vop2SdwaBitwiseByteDestinations(64));
|
||||||
|
cases.push_back(Vop2SdwaLshlrevByteDestinations(32));
|
||||||
|
cases.push_back(Vop2SdwaLshlrevByteDestinations(64));
|
||||||
AddCase(Vop1SdwaMovByteDestinations);
|
AddCase(Vop1SdwaMovByteDestinations);
|
||||||
cases.push_back(Vop1SdwaMovByteSources(32));
|
cases.push_back(Vop1SdwaMovByteSources(32));
|
||||||
cases.push_back(Vop1SdwaMovByteSources(64));
|
cases.push_back(Vop1SdwaMovByteSources(64));
|
||||||
@@ -45801,6 +45849,8 @@ int main(int argc, char **argv) {
|
|||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
RunCase(&vulkan, Vop2SdwaBitwiseByteDestinations(32));
|
RunCase(&vulkan, Vop2SdwaBitwiseByteDestinations(32));
|
||||||
RunCase(&vulkan, Vop2SdwaBitwiseByteDestinations(64));
|
RunCase(&vulkan, Vop2SdwaBitwiseByteDestinations(64));
|
||||||
|
RunCase(&vulkan, Vop2SdwaLshlrevByteDestinations(32));
|
||||||
|
RunCase(&vulkan, Vop2SdwaLshlrevByteDestinations(64));
|
||||||
RunCase(&vulkan, Vop1SdwaNotPartialSourcesAndDestinations());
|
RunCase(&vulkan, Vop1SdwaNotPartialSourcesAndDestinations());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4705,6 +4705,26 @@ void TestNewShaderDecoderArchitecture() {
|
|||||||
byte_left_shift.src1.value == 1u,
|
byte_left_shift.src1.value == 1u,
|
||||||
"decoder rejected or misdecoded captured V_LSHLREV_B32 byte shift");
|
"decoder rejected or misdecoded captured V_LSHLREV_B32 byte shift");
|
||||||
|
|
||||||
|
const uint32_t vop2_sdwa_byte_left_destination[] = {
|
||||||
|
0x340a08f9u, 0x01861187u, // v_lshlrev_b32 v5.byte1, 7, v4.byte1; preserve
|
||||||
|
};
|
||||||
|
Instruction byte_left_destination;
|
||||||
|
ShaderRecompiler::Decoder::DecodeInstruction(vop2_sdwa_byte_left_destination, 0u,
|
||||||
|
byte_left_destination);
|
||||||
|
Check(byte_left_destination.family == Family::VOP2 &&
|
||||||
|
byte_left_destination.opcode == Opcode::V_LSHLREV_B32 &&
|
||||||
|
byte_left_destination.word_count == 2u &&
|
||||||
|
byte_left_destination.dst.reg == 5u &&
|
||||||
|
byte_left_destination.dst.sdwa_sel == 1u &&
|
||||||
|
byte_left_destination.dst.sdwa_dst_unused == 2u &&
|
||||||
|
byte_left_destination.dst.explicit_sdwa_dst &&
|
||||||
|
byte_left_destination.src0.kind == OperandKind::IntegerInlineConstant &&
|
||||||
|
byte_left_destination.src0.value == 7u &&
|
||||||
|
byte_left_destination.src0.sdwa_sel == 6u &&
|
||||||
|
byte_left_destination.src1.kind == OperandKind::Vgpr &&
|
||||||
|
byte_left_destination.src1.reg == 4u && byte_left_destination.src1.sdwa_sel == 1u,
|
||||||
|
"decoder rejected or misdecoded captured V_LSHLREV_B32 byte destination");
|
||||||
|
|
||||||
const uint32_t mimg_nsa[] = {EncodeMimg0(0x20, 0xf) | (3u << 1u),
|
const uint32_t mimg_nsa[] = {EncodeMimg0(0x20, 0xf) | (3u << 1u),
|
||||||
EncodeMimg1(4, 0, 1, 8), 0x03020100u,
|
EncodeMimg1(4, 0, 1, 8), 0x03020100u,
|
||||||
0x07060504u, 0x0b0a0908u};
|
0x07060504u, 0x0b0a0908u};
|
||||||
|
|||||||
Reference in New Issue
Block a user