mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
shader: support VOP1/VOP2 DPP8 fetch-inactive
This commit is contained in:
@@ -776,9 +776,10 @@ void DecodeVop1Sdwa(uint32_t pc, std::span<const uint32_t> code, uint32_t word_i
|
|||||||
|
|
||||||
void ApplyDppModifier(Operand& operand, uint32_t modifier, uint32_t encoding) {
|
void ApplyDppModifier(Operand& operand, uint32_t modifier, uint32_t encoding) {
|
||||||
operand.dpp = true;
|
operand.dpp = true;
|
||||||
if (encoding == 233u) {
|
if (encoding == 233u || encoding == 234u) {
|
||||||
operand.dpp8 = true;
|
operand.dpp8 = true;
|
||||||
operand.dpp_ctrl = modifier >> 8u;
|
operand.dpp_ctrl = modifier >> 8u;
|
||||||
|
operand.dpp_fetch_inactive = encoding == 234u;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
operand.negate = ((modifier >> 20u) & 0x1u) != 0u;
|
operand.negate = ((modifier >> 20u) & 0x1u) != 0u;
|
||||||
@@ -1686,7 +1687,8 @@ void DecodeVop2(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (src0) {
|
switch (src0) {
|
||||||
case 233u: DecodeVop2Dpp(pc, code, word_index, opcode, vdst, vsrc1, inst); return;
|
case 233u:
|
||||||
|
case 234u: DecodeVop2Dpp(pc, code, word_index, opcode, vdst, vsrc1, inst); return;
|
||||||
case 249u: DecodeVop2Sdwa(pc, code, word_index, opcode, vdst, vsrc1, inst); return;
|
case 249u: DecodeVop2Sdwa(pc, code, word_index, opcode, vdst, vsrc1, inst); return;
|
||||||
case 250u: DecodeVop2Dpp(pc, code, word_index, opcode, vdst, vsrc1, inst); return;
|
case 250u: DecodeVop2Dpp(pc, code, word_index, opcode, vdst, vsrc1, inst); return;
|
||||||
default: break;
|
default: break;
|
||||||
@@ -1721,7 +1723,8 @@ void DecodeVop1(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (src0) {
|
switch (src0) {
|
||||||
case 233u: DecodeVop1Dpp(pc, code, word_index, opcode, vdst, inst); return;
|
case 233u:
|
||||||
|
case 234u: DecodeVop1Dpp(pc, code, word_index, opcode, vdst, inst); return;
|
||||||
case 249u: DecodeVop1Sdwa(pc, code, word_index, opcode, vdst, inst); return;
|
case 249u: DecodeVop1Sdwa(pc, code, word_index, opcode, vdst, inst); return;
|
||||||
case 250u: DecodeVop1Dpp(pc, code, word_index, opcode, vdst, inst); return;
|
case 250u: DecodeVop1Dpp(pc, code, word_index, opcode, vdst, inst); return;
|
||||||
default: break;
|
default: break;
|
||||||
|
|||||||
@@ -24786,11 +24786,12 @@ TestCase VectorPermlane16FetchInactiveFi() {
|
|||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
TestCase VectorDpp8Captured(bool masked_exec) {
|
TestCase VectorDpp8Captured(bool masked_exec, u32 wave_size = 64, bool fi = false) {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
constexpr u32 sentinel = 0xaaaaaaaau;
|
constexpr u32 sentinel = 0xaaaaaaaau;
|
||||||
const u32 masks[] = {masked_exec ? 0x0f0f0f0fu : 0xffffffffu,
|
// Both wave halves contain active and inactive lane-3 sources for the ADD.
|
||||||
masked_exec ? 0xf0f0f0f0u : 0xffffffffu};
|
const u32 masks[] = {masked_exec ? 0x0f0ff0f0u : 0xffffffffu,
|
||||||
|
masked_exec ? 0xf0f00f0fu : 0xffffffffu};
|
||||||
std::vector<u32> code;
|
std::vector<u32> code;
|
||||||
AppendVMovU32(&code, 5, 100);
|
AppendVMovU32(&code, 5, 100);
|
||||||
code.push_back(EncodeVop2(0x25, 5, Vgpr(0), 5));
|
code.push_back(EncodeVop2(0x25, 5, Vgpr(0), 5));
|
||||||
@@ -24799,20 +24800,21 @@ TestCase VectorDpp8Captured(bool masked_exec) {
|
|||||||
AppendVMovLiteral(&code, 3, sentinel);
|
AppendVMovLiteral(&code, 3, sentinel);
|
||||||
AppendVMovLiteral(&code, 8, sentinel);
|
AppendVMovLiteral(&code, 8, sentinel);
|
||||||
AppendSMovLiteral(&code, 126, masks[0]);
|
AppendSMovLiteral(&code, 126, masks[0]);
|
||||||
AppendSMovLiteral(&code, 127, masks[1]);
|
if (wave_size == 64) AppendSMovLiteral(&code, 127, masks[1]);
|
||||||
// Captured DPP8 selectors broadcast each group's upper/lower four lanes.
|
// Captured DPP8 selectors broadcast each group's upper/lower four lanes.
|
||||||
code.push_back(EncodeVop1(0x01, 2, 233));
|
const u32 encoding = fi ? 234u : 233u;
|
||||||
|
code.push_back(EncodeVop1(0x01, 2, encoding));
|
||||||
code.push_back(0xfacfac05u);
|
code.push_back(0xfacfac05u);
|
||||||
code.push_back(EncodeVop1(0x01, 3, 233));
|
code.push_back(EncodeVop1(0x01, 3, encoding));
|
||||||
code.push_back(0x68868805u);
|
code.push_back(0x68868805u);
|
||||||
// CS 6babb2a8915d35c4, pc 0xcc: add lane 3 of each group to its own v7.
|
// CS 6babb2a8915d35c4, pc 0xcc: add lane 3 of each group to its own v7.
|
||||||
code.push_back(0x4a100ee9u);
|
code.push_back(EncodeVop2(0x25, 8, encoding, 7));
|
||||||
code.push_back(0x6db6db07u);
|
code.push_back(0x6db6db07u);
|
||||||
AppendSMovLiteral(&code, 126, 0xffffffffu);
|
AppendSMovLiteral(&code, 126, 0xffffffffu);
|
||||||
AppendSMovLiteral(&code, 127, 0xffffffffu);
|
if (wave_size == 64) AppendSMovLiteral(&code, 127, 0xffffffffu);
|
||||||
code.push_back(EncodeVop2(0x1a, 6, InlineU32(2), 0));
|
code.push_back(EncodeVop2(0x1a, 6, InlineU32(2), 0));
|
||||||
AppendBufferStoreDword(&code, 2, 6);
|
AppendBufferStoreDword(&code, 2, 6);
|
||||||
AppendVMovU32(&code, 7, 64u * sizeof(u32));
|
AppendVMovU32(&code, 7, wave_size * sizeof(u32));
|
||||||
code.push_back(EncodeVop2(0x25, 6, Vgpr(7), 6));
|
code.push_back(EncodeVop2(0x25, 6, Vgpr(7), 6));
|
||||||
AppendBufferStoreDword(&code, 3, 6);
|
AppendBufferStoreDword(&code, 3, 6);
|
||||||
code.push_back(EncodeVop2(0x25, 6, Vgpr(7), 6));
|
code.push_back(EncodeVop2(0x25, 6, Vgpr(7), 6));
|
||||||
@@ -24820,11 +24822,13 @@ TestCase VectorDpp8Captured(bool masked_exec) {
|
|||||||
AppendEnd(&code);
|
AppendEnd(&code);
|
||||||
|
|
||||||
TestCase test;
|
TestCase test;
|
||||||
test.name = masked_exec ? "VectorDpp8CapturedMaskedExec"
|
const char *names[2][2] = {
|
||||||
: "VectorDpp8Captured";
|
{"VectorDpp8Wave32MaskedExec", "VectorDpp8Wave64MaskedExec"},
|
||||||
|
{"VectorDpp8FiWave32MaskedExec", "VectorDpp8FiWave64MaskedExec"}};
|
||||||
|
test.name = masked_exec ? names[fi][wave_size == 64] : "VectorDpp8Captured";
|
||||||
test.code = std::move(code);
|
test.code = std::move(code);
|
||||||
test.expected.resize(192, sentinel);
|
test.expected.resize(3 * wave_size, sentinel);
|
||||||
for (u32 lane = 0; lane < 64; ++lane) {
|
for (u32 lane = 0; lane < wave_size; ++lane) {
|
||||||
const auto mask = masks[lane / 32u];
|
const auto mask = masks[lane / 32u];
|
||||||
if ((mask & (1u << (lane % 32u))) == 0) {
|
if ((mask & (1u << (lane % 32u))) == 0) {
|
||||||
continue;
|
continue;
|
||||||
@@ -24833,20 +24837,20 @@ TestCase VectorDpp8Captured(bool masked_exec) {
|
|||||||
(lane & ~7u) | (lane & 3u)};
|
(lane & ~7u) | (lane & 3u)};
|
||||||
for (u32 permutation = 0; permutation < 2; ++permutation) {
|
for (u32 permutation = 0; permutation < 2; ++permutation) {
|
||||||
const auto source = sources[permutation];
|
const auto source = sources[permutation];
|
||||||
test.expected[permutation * 64u + lane] =
|
test.expected[permutation * wave_size + lane] =
|
||||||
(mask & (1u << (source % 32u))) != 0 ? 100u + source : 0u;
|
fi || (mask & (1u << (source % 32u))) != 0 ? 100u + source : 0u;
|
||||||
}
|
}
|
||||||
const u32 source = (lane & ~7u) | 3u;
|
const u32 source = (lane & ~7u) | 3u;
|
||||||
test.expected[128u + lane] = 100u + lane;
|
test.expected[2 * wave_size + lane] = 100u + lane;
|
||||||
if ((mask & (1u << (source % 32u))) != 0) {
|
if (fi || (mask & (1u << (source % 32u))) != 0) {
|
||||||
test.expected[128u + lane] += 100u + source;
|
test.expected[2 * wave_size + lane] += 100u + source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
test.opcodes = {O::V_MOV_B32, O::V_ADD_NC_U32, O::S_MOV_B32,
|
test.opcodes = {O::V_MOV_B32, O::V_ADD_NC_U32, O::S_MOV_B32,
|
||||||
O::V_LSHLREV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
O::V_LSHLREV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||||
test.decoded_counts = {{".dpp8(", 3}};
|
test.decoded_counts = {{".dpp8(", 3}};
|
||||||
test.compute_info.wave_size = 64;
|
test.compute_info.wave_size = wave_size;
|
||||||
test.compute_info.threads_num[0] = 64;
|
test.compute_info.threads_num[0] = wave_size;
|
||||||
test.compute_info.threads_num[1] = 1;
|
test.compute_info.threads_num[1] = 1;
|
||||||
test.compute_info.threads_num[2] = 1;
|
test.compute_info.threads_num[2] = 1;
|
||||||
test.compute_info.thread_ids_num = 1;
|
test.compute_info.thread_ids_num = 1;
|
||||||
@@ -37171,7 +37175,9 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(VectorPermlane16FetchInactiveZero);
|
AddCase(VectorPermlane16FetchInactiveZero);
|
||||||
AddCase(VectorPermlane16FetchInactiveFi);
|
AddCase(VectorPermlane16FetchInactiveFi);
|
||||||
cases.push_back(VectorDpp8Captured(false));
|
cases.push_back(VectorDpp8Captured(false));
|
||||||
cases.push_back(VectorDpp8Captured(true));
|
for (const u32 wave_size : {32u, 64u})
|
||||||
|
for (const bool fi : {false, true})
|
||||||
|
cases.push_back(VectorDpp8Captured(true, wave_size, fi));
|
||||||
AddCase(VectorDppQuadPermuteReverse);
|
AddCase(VectorDppQuadPermuteReverse);
|
||||||
AddCase(VectorDppRowXmask);
|
AddCase(VectorDppRowXmask);
|
||||||
cases.push_back(VectorDppRowShare(32));
|
cases.push_back(VectorDppRowShare(32));
|
||||||
@@ -42852,7 +42858,9 @@ int main(int argc, char **argv) {
|
|||||||
if (argc == 2 && std::strcmp(argv[1], "--dpp-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--dpp-only") == 0) {
|
||||||
VulkanHarness vulkan;
|
VulkanHarness vulkan;
|
||||||
RunCase(&vulkan, VectorDpp8Captured(false));
|
RunCase(&vulkan, VectorDpp8Captured(false));
|
||||||
RunCase(&vulkan, VectorDpp8Captured(true));
|
for (const u32 wave_size : {32u, 64u})
|
||||||
|
for (const bool fi : {false, true})
|
||||||
|
RunCase(&vulkan, VectorDpp8Captured(true, wave_size, fi));
|
||||||
RunCase(&vulkan, VectorDppQuadPermuteReverse());
|
RunCase(&vulkan, VectorDppQuadPermuteReverse());
|
||||||
RunCase(&vulkan, VectorDppRowXmask());
|
RunCase(&vulkan, VectorDppRowXmask());
|
||||||
RunCase(&vulkan, VectorDppRowShare(32));
|
RunCase(&vulkan, VectorDppRowShare(32));
|
||||||
|
|||||||
Reference in New Issue
Block a user