shader: preserve full region addresses for LDS and GDS reads and writes

This commit is contained in:
nmzik
2026-10-12 19:31:20 +02:00
parent 460a196fca
commit d692d8ee08
2 changed files with 52 additions and 8 deletions
+45
View File
@@ -32259,6 +32259,45 @@ TestCase DsReadWriteVariants() {
O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
}
TestCase DsReadWriteFullRegionAddress(u32 wave_size, bool gds) {
using O = ShaderOpcode;
TestCase test;
test.name = gds ? (wave_size == 32u ? "DsGdsFullAddress32" : "DsGdsFullAddress64")
: (wave_size == 32u ? "DsLdsFullAddress32" : "DsLdsFullAddress64");
auto &code = test.code;
code.push_back(EncodeVop2(0x1a, 1, InlineU32(2), 0));
code.push_back(EncodeVop2(0x25, 2, InlineU32(1), 0));
code.insert(code.end(), {EncodeDs0(0x0d, 4, gds), EncodeDs1(0, 2, 1)});
AppendVMovLiteral(&code, 3, 0x10000u);
code.push_back(EncodeVop2(0x25, 3, Vgpr(1), 3));
AppendVMovLiteral(&code, 4, 0xdeadbeefu);
// A high region address must not alias the valid word in the same lane.
code.insert(code.end(), {EncodeDs0(0x0d, 4, gds), EncodeDs1(0, 4, 3),
EncodeDs0(0x36, 4, gds), EncodeDs1(5, 0, 1),
EncodeDs0(0x36, 4, gds), EncodeDs1(6, 0, 3)});
AppendStoreVgprAtLaneDwordOffset(&code, 5, 0, 0);
AppendStoreVgprAtLaneDwordOffset(&code, 6, 0, wave_size);
AppendEnd(&code);
test.initial.assign(wave_size * 2u, 0xdeadbeefu);
test.expected.resize(wave_size * 2u);
std::iota(test.expected.begin(), test.expected.begin() + wave_size, 1u);
test.compute_info.threads_num[0] = wave_size;
test.compute_info.threads_num[1] = test.compute_info.threads_num[2] = 1u;
test.compute_info.thread_ids_num = 1;
test.compute_info.wave_size = wave_size;
test.compute_info.lds_size_dwords = wave_size + 1u;
test.has_compute_info = true;
if (gds) {
test.gds_initial.resize(wave_size + 1u);
test.expected_gds.resize(wave_size + 1u);
std::iota(test.expected_gds.begin(), test.expected_gds.end(), 0u);
}
test.opcodes = {O::V_LSHLREV_B32, O::V_ADD_NC_U32, O::V_MOV_B32, O::DS_WRITE_B32,
O::DS_READ_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
test.forbidden_spirv = {"%uint_65535"};
return test;
}
TestCase DsReadU16D16CapturedPreservesHighHalf() {
using O = ShaderOpcode;
@@ -38119,6 +38158,9 @@ std::vector<TestCase> MakeCases() {
}
}
AddCase(DsReadWriteVariants);
for (u32 wave_size : {32u, 64u})
for (bool gds : {false, true})
cases.push_back(DsReadWriteFullRegionAddress(wave_size, gds));
AddCase(DsWriteB16D16HiCapturedUsesHighHalf);
AddCase(DsWriteB8D16HiWritesByteTwo);
AddCase(DsReadU16D16CapturedPreservesHighHalf);
@@ -43566,6 +43608,9 @@ int main(int argc, char **argv) {
if (argc == 2 && std::strcmp(argv[1], "--lds-limit-only") == 0) {
VulkanHarness vulkan;
CheckComputeLdsLimit(vulkan);
for (u32 wave_size : {32u, 64u})
for (bool gds : {false, true})
RunCase(&vulkan, DsReadWriteFullRegionAddress(wave_size, gds));
RunCase(&vulkan, DsWideLdsPartialBounds());
RunCase(&vulkan, DsAtomic64Bounds(false));
RunCase(&vulkan, DsAtomic64Bounds(true));