shader: BUFFER_LOAD_SHORT_D16_HI

This commit is contained in:
nmzik committed 2026-10-09 12:57:04 +02:00
1 parent 1bd282ec0a
commit a31e2cd361
5 files changed
+42 -27

No files matched your search

@@ -48,6 +48,7 @@ constexpr MemoryOpcodeInfo MUBUF_OPCODE_LIST[] = {
{0x1eu, Opcode::BUFFER_STORE_DWORDX4, 4, 32}, {0x1eu, Opcode::BUFFER_STORE_DWORDX4, 4, 32},
{0x1fu, Opcode::BUFFER_STORE_DWORDX3, 3, 32}, {0x1fu, Opcode::BUFFER_STORE_DWORDX3, 3, 32},
{0x24u, Opcode::BUFFER_LOAD_SHORT_D16, 1, 16}, {0x24u, Opcode::BUFFER_LOAD_SHORT_D16, 1, 16},
{0x25u, Opcode::BUFFER_LOAD_SHORT_D16_HI, 1, 16},
{0x30u, Opcode::BUFFER_ATOMIC_SWAP, 1, 32}, {0x30u, Opcode::BUFFER_ATOMIC_SWAP, 1, 32},
{0x31u, Opcode::BUFFER_ATOMIC_CMPSWAP, 1, 32}, {0x31u, Opcode::BUFFER_ATOMIC_CMPSWAP, 1, 32},
{0x32u, Opcode::BUFFER_ATOMIC_ADD, 1, 32}, {0x32u, Opcode::BUFFER_ATOMIC_ADD, 1, 32},
@@ -300,8 +301,9 @@ void DecodeMubuf(uint32_t pc, std::span<const uint32_t> code, uint32_t word_inde
DecodeVectorGpr(vdata, inst.dst); DecodeVectorGpr(vdata, inst.dst);
if (inst.opcode == Opcode::BUFFER_LOAD_FORMAT_D16_X || if (inst.opcode == Opcode::BUFFER_LOAD_FORMAT_D16_X ||
inst.opcode == Opcode::BUFFER_LOAD_SHORT_D16) { inst.opcode == Opcode::BUFFER_LOAD_SHORT_D16 ||
inst.dst.sdwa_sel = 4u; inst.opcode == Opcode::BUFFER_LOAD_SHORT_D16_HI) {
inst.dst.sdwa_sel = inst.opcode == Opcode::BUFFER_LOAD_SHORT_D16_HI ? 5u : 4u;
} }
DecodeVectorGpr(vaddr, inst.src0); DecodeVectorGpr(vaddr, inst.src0);
DecodeScalarSource(srsrc * 4u, pc, inst.src1); DecodeScalarSource(srsrc * 4u, pc, inst.src1);
@@ -628,6 +628,7 @@ std::string InstructionToString(const Instruction& inst) {
case Opcode::BUFFER_LOAD_UBYTE: case Opcode::BUFFER_LOAD_UBYTE:
case Opcode::BUFFER_LOAD_USHORT: case Opcode::BUFFER_LOAD_USHORT:
case Opcode::BUFFER_LOAD_SHORT_D16: case Opcode::BUFFER_LOAD_SHORT_D16:
case Opcode::BUFFER_LOAD_SHORT_D16_HI:
case Opcode::BUFFER_LOAD_DWORD: case Opcode::BUFFER_LOAD_DWORD:
case Opcode::BUFFER_LOAD_DWORDX2: case Opcode::BUFFER_LOAD_DWORDX2:
case Opcode::BUFFER_LOAD_DWORDX3: case Opcode::BUFFER_LOAD_DWORDX3:
@@ -519,6 +519,7 @@ enum class Opcode {
BUFFER_LOAD_USHORT, BUFFER_LOAD_USHORT,
BUFFER_LOAD_SSHORT, BUFFER_LOAD_SSHORT,
BUFFER_LOAD_SHORT_D16, BUFFER_LOAD_SHORT_D16,
BUFFER_LOAD_SHORT_D16_HI,
BUFFER_LOAD_DWORD, BUFFER_LOAD_DWORD,
BUFFER_LOAD_DWORDX2, BUFFER_LOAD_DWORDX2,
BUFFER_LOAD_DWORDX3, BUFFER_LOAD_DWORDX3,
@@ -974,6 +974,7 @@ void Translator::EmitMemory(const Decoder::Instruction& inst) {
case Decoder::Opcode::BUFFER_LOAD_USHORT: case Decoder::Opcode::BUFFER_LOAD_USHORT:
case Decoder::Opcode::BUFFER_LOAD_SSHORT: case Decoder::Opcode::BUFFER_LOAD_SSHORT:
case Decoder::Opcode::BUFFER_LOAD_SHORT_D16: case Decoder::Opcode::BUFFER_LOAD_SHORT_D16:
case Decoder::Opcode::BUFFER_LOAD_SHORT_D16_HI:
case Decoder::Opcode::BUFFER_LOAD_DWORD: case Decoder::Opcode::BUFFER_LOAD_DWORD:
case Decoder::Opcode::BUFFER_LOAD_DWORDX2: case Decoder::Opcode::BUFFER_LOAD_DWORDX2:
case Decoder::Opcode::BUFFER_LOAD_DWORDX3: case Decoder::Opcode::BUFFER_LOAD_DWORDX3:
+35 -25
View File
@@ -19135,6 +19135,7 @@ CoverageClass ClassifyOpcode(ShaderOpcode opcode,
case Opcode::BUFFER_LOAD_USHORT: case Opcode::BUFFER_LOAD_USHORT:
case Opcode::BUFFER_LOAD_SSHORT: case Opcode::BUFFER_LOAD_SSHORT:
case Opcode::BUFFER_LOAD_SHORT_D16: case Opcode::BUFFER_LOAD_SHORT_D16:
case Opcode::BUFFER_LOAD_SHORT_D16_HI:
case Opcode::BUFFER_LOAD_DWORDX2: case Opcode::BUFFER_LOAD_DWORDX2:
case Opcode::BUFFER_LOAD_DWORDX3: case Opcode::BUFFER_LOAD_DWORDX3:
case Opcode::BUFFER_LOAD_DWORDX4: case Opcode::BUFFER_LOAD_DWORDX4:
@@ -28651,41 +28652,50 @@ TestCase BufferLoadVariants() {
O::BUFFER_STORE_DWORD, O::S_ENDPGM}}; O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
} }
TestCase BufferLoadShortD16Captured() { TestCase BufferLoadShortD16Captured(bool high) {
TestCase test; TestCase test;
test.name = "BufferLoadShortD16Captured"; test.name = high ? "BufferLoadShortD16HiCaptured" : "BufferLoadShortD16Captured";
auto& code = test.code; auto& code = test.code;
AppendVMovU32(&code, 15, 1); const u32 data_reg = high ? 20u : 1u, index_reg = high ? 21u : 15u;
AppendVMovLiteral(&code, 1, 0xabcd1234u); const std::array<u32, 2> load = high ? std::array{0xe0942006u, 0x80021415u}
// Load an indexed raw halfword at record byte offset 14. : std::array{0xe090200eu, 0x8000010fu};
code.insert(code.end(), {0xe090200eu, 0x8000010fu}); AppendVMovU32(&code, index_reg, 1);
AppendStoreVgpr(&code, 1, 0); AppendVMovLiteral(&code, data_reg, 0xabcd1234u);
AppendVMovLiteral(&code, 1, 0xdeaf4321u); // Load both halves of v20 through s8:s11.
code.push_back(EncodeSop1(0x04, 8, 126)); if (high) code.insert(code.end(), {0xe090200eu, 0x80021415u});
code.insert(code.end(), load.begin(), load.end());
AppendStoreVgpr(&code, data_reg, 0);
AppendVMovLiteral(&code, data_reg, 0xdeaf4321u);
code.push_back(EncodeSop1(0x04, 32, 126));
code.push_back(EncodeSop1(0x04, 126, InlineU32(0))); code.push_back(EncodeSop1(0x04, 126, InlineU32(0)));
code.insert(code.end(), {0xe090200eu, 0x8000010fu}); code.insert(code.end(), load.begin(), load.end());
code.push_back(EncodeSop1(0x04, 126, 8)); code.push_back(EncodeSop1(0x04, 126, 32));
AppendStoreVgpr(&code, 1, 1); AppendStoreVgpr(&code, data_reg, 1);
AppendVMovU32(&code, 15, 2); AppendVMovU32(&code, index_reg, 2);
AppendVMovLiteral(&code, 1, 0xbeef5678u); AppendVMovLiteral(&code, data_reg, 0xbeef5678u);
code.insert(code.end(), {0xe090200eu, 0x8000010fu}); code.insert(code.end(), load.begin(), load.end());
AppendStoreVgpr(&code, 1, 2); AppendStoreVgpr(&code, data_reg, 2);
AppendEnd(&code); AppendEnd(&code);
test.initial.assign(20, 0xa5a5a5a5u); const u32 stride = high ? 16u : 32u;
test.initial[11] = 0x8001cafeu; // Record 1 byte 14 is the high half at byte 46. test.initial.assign(high ? 12u : 20u, 0xa5a5a5a5u);
test.initial[high ? 5u : 11u] = 0x8001cafeu;
if (high) test.initial[7] = 0xcafefaceu;
test.expected = test.initial; test.expected = test.initial;
test.expected[0] = 0xabcd8001u; test.expected[0] = high ? 0x8001cafeu : 0xabcd8001u;
test.expected[1] = 0xdeaf4321u; test.expected[1] = 0xdeaf4321u;
test.expected[2] = 0xbeef0000u; test.expected[2] = high ? 0x00005678u : 0xbeef0000u;
test.user_data = MakeStructuredStorageBufferData(32, 2); test.user_data = MakeStructuredStorageBufferData(stride, 2);
if (high) std::copy_n(test.user_data.begin(), 4, test.user_data.begin() + 8);
test.user_data[50] = static_cast<u32>(test.initial.size() * sizeof(u32)); test.user_data[50] = static_cast<u32>(test.initial.size() * sizeof(u32));
test.user_data[51] = 3u << 28u; test.user_data[51] = 3u << 28u;
test.has_user_data = true; test.has_user_data = true;
test.storage_buffer_range_bytes = 64; test.storage_buffer_range_bytes = stride * 2u;
test.opcodes = {ShaderOpcode::V_MOV_B32, ShaderOpcode::S_MOV_B64, test.opcodes = {ShaderOpcode::V_MOV_B32, ShaderOpcode::S_MOV_B64,
ShaderOpcode::BUFFER_LOAD_SHORT_D16, ShaderOpcode::BUFFER_STORE_DWORD, ShaderOpcode::BUFFER_LOAD_SHORT_D16, ShaderOpcode::BUFFER_STORE_DWORD,
ShaderOpcode::S_ENDPGM}; ShaderOpcode::S_ENDPGM};
test.decoded_counts = {{"BUFFER_LOAD_SHORT_D16 v1.sdwa(sel=4,sext=0)", 3}}; if (high) test.opcodes.push_back(ShaderOpcode::BUFFER_LOAD_SHORT_D16_HI);
test.decoded_counts = {{high ? "BUFFER_LOAD_SHORT_D16_HI v20.sdwa(sel=5,sext=0)"
: "BUFFER_LOAD_SHORT_D16 v1.sdwa(sel=4,sext=0)", 3}};
return test; return test;
} }
@@ -36694,7 +36704,7 @@ std::vector<TestCase> MakeCases() {
cases.push_back(BufferOffsetsUsePackedWords(false)); cases.push_back(BufferOffsetsUsePackedWords(false));
cases.push_back(BufferOffsetsUsePackedWords(true)); cases.push_back(BufferOffsetsUsePackedWords(true));
AddCase(BufferLoadVariants); AddCase(BufferLoadVariants);
AddCase(BufferLoadShortD16Captured); for (const bool high : {false, true}) cases.push_back(BufferLoadShortD16Captured(high));
for (const u32 component : {4u, 2u, 0u}) { for (const u32 component : {4u, 2u, 0u}) {
cases.push_back(BufferSubwordLoadsAtHostOffset(2, component, false)); cases.push_back(BufferSubwordLoadsAtHostOffset(2, component, false));
} }
@@ -42326,7 +42336,7 @@ int main(int argc, char **argv) {
} }
if (argc == 2 && std::strcmp(argv[1], "--flat-d16-only") == 0) { if (argc == 2 && std::strcmp(argv[1], "--flat-d16-only") == 0) {
VulkanHarness vulkan; VulkanHarness vulkan;
RunCase(&vulkan, BufferLoadShortD16Captured()); for (const bool high : {false, true}) RunCase(&vulkan, BufferLoadShortD16Captured(high));
RunCase(&vulkan, FlatStoreSlcCaptured()); RunCase(&vulkan, FlatStoreSlcCaptured());
RunCase(&vulkan, FlatLoadDlcCaptured(32)); RunCase(&vulkan, FlatLoadDlcCaptured(32));
RunCase(&vulkan, FlatLoadDlcCaptured(64)); RunCase(&vulkan, FlatLoadDlcCaptured(64));