shader: decode s_dcache_inv as a no-op

This commit is contained in:
Claxten
2026-10-27 03:04:24 +01:00
committed by nmzik
parent 95a507a8ff
commit 91a5ff6cb7
5 changed files with 17 additions and 7 deletions
@@ -22,7 +22,7 @@ constexpr MemoryOpcodeInfo SMEM_OPCODE_LIST[] = {
{0x04u, Opcode::S_LOAD_DWORDX16, 16, 32}, {0x08u, Opcode::S_BUFFER_LOAD_DWORD, 1, 32},
{0x09u, Opcode::S_BUFFER_LOAD_DWORDX2, 2, 32}, {0x0au, Opcode::S_BUFFER_LOAD_DWORDX4, 4, 32},
{0x0bu, Opcode::S_BUFFER_LOAD_DWORDX8, 8, 32}, {0x0cu, Opcode::S_BUFFER_LOAD_DWORDX16, 16, 32},
{0x25u, Opcode::S_MEMREALTIME, 2, 32},
{0x20u, Opcode::S_DCACHE_INV, 0, 0}, {0x25u, Opcode::S_MEMREALTIME, 2, 32},
};
constexpr MemoryOpcodeInfo MUBUF_OPCODE_LIST[] = {
@@ -286,6 +286,9 @@ void DecodeSmem(uint32_t pc, std::span<const uint32_t> code, uint32_t word_index
if (inst.opcode == Opcode::UNSUPPORTED) {
SetUnsupported(inst, Family::SMEM, opcode, "SMEM opcode is not implemented");
}
if (inst.opcode == Opcode::S_DCACHE_INV) {
return;
}
DecodeScalarDestination(sdst, pc, inst.dst);
if (inst.opcode == Opcode::S_MEMREALTIME) {
@@ -557,6 +557,7 @@ std::string InstructionToString(const Instruction& inst) {
OperandToString(inst.src0).c_str()));
case Opcode::S_BARRIER:
return WithUnsupportedReason(inst, fmt::format("0x{:08x}: s_barrier", inst.pc));
case Opcode::S_DCACHE_INV:
case Opcode::BUFFER_GL0_INV:
case Opcode::BUFFER_GL1_INV:
return fmt::format("0x{:08x}: {}", inst.pc, magic_enum::enum_name(inst.opcode));
@@ -544,6 +544,7 @@ enum class Opcode {
S_BUFFER_LOAD_DWORDX8,
S_BUFFER_LOAD_DWORDX16,
S_MEMREALTIME,
S_DCACHE_INV,
BUFFER_LOAD_FORMAT_X,
BUFFER_LOAD_FORMAT_XY,
BUFFER_LOAD_FORMAT_XYZ,
@@ -941,6 +941,8 @@ void Translator::DS_PERMUTE(const Decoder::Instruction& inst, bool backward) {
void Translator::EmitMemory(const Decoder::Instruction& inst) {
switch (inst.opcode) {
// Translated scalar loads have no cache of their own to invalidate.
case Decoder::Opcode::S_DCACHE_INV: return;
case Decoder::Opcode::BUFFER_GL0_INV:
case Decoder::Opcode::BUFFER_GL1_INV:
ir.Emit(IR::ValueOpcode::DataCacheInvalidate);
+9 -6
View File
@@ -2001,18 +2001,21 @@ void TestNggVertexEntryState() {
void TestNativeDataCacheInvalidation() {
using namespace ShaderRecompiler;
// Captured f5edf70dbb1f6057:0x194 and 0x1a4, each followed by S_WAITCNT.
// Captured f5edf70dbb1f6057:0x194 and 0x1a4, each followed by S_WAITCNT. The S_DCACHE_INV
// after them emits no fence.
const std::array cache_ops = {0xe1c40000u, 0u, 0xbf8c0000u,
0xe1c80000u, 0u, 0xbf8c0000u, EncodeSopp(0x01)};
0xe1c80000u, 0u, 0xbf8c0000u,
0xf4800000u, 0xfa000000u, EncodeSopp(0x01)};
Decoder::Program decoded;
Decoder::DecodeProgram(cache_ops, decoded);
for (const uint32_t index : {0u, 2u}) {
for (const auto [index, opcode] : {std::pair{0u, Decoder::Opcode::BUFFER_GL0_INV},
std::pair{2u, Decoder::Opcode::BUFFER_GL1_INV},
std::pair{4u, Decoder::Opcode::S_DCACHE_INV}}) {
const auto &inst = decoded.instructions[index];
Check(inst.opcode == (index == 0 ? Decoder::Opcode::BUFFER_GL0_INV
: Decoder::Opcode::BUFFER_GL1_INV) &&
Check(inst.opcode == opcode &&
inst.word_count == 2 && inst.src_count == 0 && inst.data_dwords == 0 &&
inst.dst.kind == Decoder::OperandKind::Unknown,
"RDNA2 cache invalidation acquired a buffer operand or lost its encoding");
"RDNA2 cache invalidation acquired an operand or lost its encoding");
}
auto options = MakeCompileOptions(ShaderType::Compute);