From 2091bc56513fd072ae8477b51c9a20be7817e618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Miko=C5=82ajczyk?= Date: Fri, 30 May 2025 01:56:24 +0200 Subject: [PATCH] Handle R128 bit in MIMG instructions (#3010) --- src/shader_recompiler/frontend/decode.cpp | 1 - .../frontend/translate/vector_memory.cpp | 5 +++++ src/shader_recompiler/info.h | 9 ++++++++- .../ir/passes/resource_tracking_pass.cpp | 1 + src/shader_recompiler/ir/reg.h | 1 + 5 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/shader_recompiler/frontend/decode.cpp b/src/shader_recompiler/frontend/decode.cpp index 20b78e869..37e8a0973 100644 --- a/src/shader_recompiler/frontend/decode.cpp +++ b/src/shader_recompiler/frontend/decode.cpp @@ -1032,7 +1032,6 @@ void GcnDecodeContext::decodeInstructionMIMG(uint64_t hexInstruction) { m_instruction.control.mimg = *reinterpret_cast(&hexInstruction); m_instruction.control.mimg.mod = getMimgModifier(m_instruction.opcode); - ASSERT(m_instruction.control.mimg.r128 == 0); } void GcnDecodeContext::decodeInstructionDS(uint64_t hexInstruction) { diff --git a/src/shader_recompiler/frontend/translate/vector_memory.cpp b/src/shader_recompiler/frontend/translate/vector_memory.cpp index 5639bc56a..8c1946390 100644 --- a/src/shader_recompiler/frontend/translate/vector_memory.cpp +++ b/src/shader_recompiler/frontend/translate/vector_memory.cpp @@ -377,6 +377,7 @@ void Translator::IMAGE_LOAD(bool has_mip, const GcnInst& inst) { IR::TextureInstInfo info{}; info.has_lod.Assign(has_mip); info.is_array.Assign(mimg.da); + info.is_r128.Assign(mimg.r128); const IR::Value texel = ir.ImageRead(handle, body, {}, {}, info); for (u32 i = 0; i < 4; i++) { @@ -426,6 +427,7 @@ void Translator::IMAGE_GET_RESINFO(const GcnInst& inst) { IR::TextureInstInfo info{}; info.is_array.Assign(mimg.da); + info.is_r128.Assign(mimg.r128); const IR::Value size = ir.ImageQueryDimension(tsharp, lod, ir.Imm1(has_mips), info); @@ -451,6 +453,7 @@ void Translator::IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst) { IR::TextureInstInfo info{}; info.is_array.Assign(mimg.da); + info.is_r128.Assign(mimg.r128); const IR::Value value = ir.GetVectorReg(val_reg); const IR::Value handle = ir.GetScalarReg(tsharp_reg); @@ -509,6 +512,7 @@ IR::Value EmitImageSample(IR::IREmitter& ir, const GcnInst& inst, const IR::Scal info.has_lod.Assign(flags.any(MimgModifier::Lod)); info.is_array.Assign(mimg.da); info.is_unnormalized.Assign(mimg.unrm); + info.is_r128.Assign(mimg.r128); if (gather) { info.gather_comp.Assign(std::bit_width(mimg.dmask) - 1); @@ -617,6 +621,7 @@ void Translator::IMAGE_GET_LOD(const GcnInst& inst) { IR::TextureInstInfo info{}; info.is_array.Assign(mimg.da); + info.is_r128.Assign(mimg.r128); const IR::Value handle = ir.GetScalarReg(tsharp_reg); const IR::Value body = ir.CompositeConstruct( diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index d349d7827..24e0741c1 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -84,6 +84,7 @@ struct ImageResource { bool is_atomic{}; bool is_array{}; bool is_written{}; + bool is_r128{}; [[nodiscard]] constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept; }; @@ -293,7 +294,13 @@ constexpr AmdGpu::Buffer BufferResource::GetSharp(const Info& info) const noexce } constexpr AmdGpu::Image ImageResource::GetSharp(const Info& info) const noexcept { - const auto image = info.ReadUdSharp(sharp_idx); + AmdGpu::Image image{0}; + if (!is_r128) { + image = info.ReadUdSharp(sharp_idx); + } else { + AmdGpu::Buffer buf = info.ReadUdSharp(sharp_idx); + memcpy(&image, &buf, sizeof(buf)); + } if (!image.Valid()) { // Fall back to null image if unbound. return AmdGpu::Image::Null(); diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index cc0bf83d3..18c77e600 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -411,6 +411,7 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& .is_atomic = IsImageAtomicInstruction(inst), .is_array = bool(inst_info.is_array), .is_written = is_written, + .is_r128 = bool(inst_info.is_r128), }); IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; diff --git a/src/shader_recompiler/ir/reg.h b/src/shader_recompiler/ir/reg.h index 622190cf0..82aa436a7 100644 --- a/src/shader_recompiler/ir/reg.h +++ b/src/shader_recompiler/ir/reg.h @@ -44,6 +44,7 @@ union TextureInstInfo { BitField<9, 1, u32> is_array; BitField<10, 1, u32> is_unnormalized; BitField<11, 1, u32> is_gather; + BitField<12, 1, u32> is_r128; }; union BufferInstInfo {