From 15f593865b3d3c24a7a35a9bcd07ef1873c8ad4b Mon Sep 17 00:00:00 2001 From: kalaposfos13 <153381648+kalaposfos13@users.noreply.github.com> Date: Sat, 21 Jun 2025 19:45:00 +0200 Subject: [PATCH] Revert "Handle immediate inline samplers (#3015)" This reverts commit efa8f6a1545a1b18571fce79cce3183543e8f407. --- .../backend/spirv/spirv_emit_context.cpp | 7 +-- .../frontend/translate/vector_memory.cpp | 9 ++-- src/shader_recompiler/info.h | 13 ++--- src/shader_recompiler/ir/ir_emitter.cpp | 6 +-- src/shader_recompiler/ir/ir_emitter.h | 3 +- src/shader_recompiler/ir/opcodes.inc | 2 +- .../ir/passes/resource_tracking_pass.cpp | 52 +++++++++---------- 7 files changed, 38 insertions(+), 54 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 567c059ae..030eb6cb0 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -972,12 +972,7 @@ void EmitContext::DefineImagesAndSamplers() { const Id id{AddGlobalVariable(sampler_pointer_type, spv::StorageClass::UniformConstant)}; Decorate(id, spv::Decoration::Binding, binding.unified++); Decorate(id, spv::Decoration::DescriptorSet, 0U); - auto sharp_desc = std::holds_alternative(samp_desc.sampler) - ? fmt::format("sgpr:{}", std::get(samp_desc.sampler)) - : fmt::format("inline:{:#x}:{:#x}", - std::get(samp_desc.sampler).raw0, - std::get(samp_desc.sampler).raw1); - Name(id, fmt::format("{}_{}{}", stage, "samp", sharp_desc)); + Name(id, fmt::format("{}_{}{}", stage, "samp", samp_desc.sharp_idx)); samplers.push_back(id); interfaces.push_back(id); } diff --git a/src/shader_recompiler/frontend/translate/vector_memory.cpp b/src/shader_recompiler/frontend/translate/vector_memory.cpp index a102ebf99..cd98e2af4 100644 --- a/src/shader_recompiler/frontend/translate/vector_memory.cpp +++ b/src/shader_recompiler/frontend/translate/vector_memory.cpp @@ -539,10 +539,8 @@ IR::Value EmitImageSample(IR::IREmitter& ir, const GcnInst& inst, const IR::Scal // Load first dword of T# and S#. We will use them as the handle that will guide resource // tracking pass where to read the sharps. This will later also get patched to the SPIRV texture // binding index. - const IR::Value handle = ir.GetScalarReg(tsharp_reg); - const IR::Value inline_sampler = - ir.CompositeConstruct(ir.GetScalarReg(sampler_reg), ir.GetScalarReg(sampler_reg + 1), - ir.GetScalarReg(sampler_reg + 2), ir.GetScalarReg(sampler_reg + 3)); + const IR::Value handle = + ir.CompositeConstruct(ir.GetScalarReg(tsharp_reg), ir.GetScalarReg(sampler_reg)); // Determine how many address registers need to be passed. // The image type is unknown, so add all 4 possible base registers and resolve later. @@ -578,8 +576,7 @@ IR::Value EmitImageSample(IR::IREmitter& ir, const GcnInst& inst, const IR::Scal const IR::Value address4 = get_addr_reg(12); // Issue the placeholder IR instruction. - IR::Value texel = - ir.ImageSampleRaw(handle, address1, address2, address3, address4, inline_sampler, info); + IR::Value texel = ir.ImageSampleRaw(handle, address1, address2, address3, address4, info); if (info.is_depth && !gather) { // For non-gather depth sampling, only return a single value. texel = ir.CompositeExtract(texel, 0); diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index 6c931da31..72f818916 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -3,7 +3,6 @@ #pragma once #include -#include #include #include #include @@ -92,15 +91,11 @@ struct ImageResource { using ImageResourceList = boost::container::small_vector; struct SamplerResource { - std::variant sampler; + u32 sharp_idx; + AmdGpu::Sampler inline_sampler{}; u32 associated_image : 4; u32 disable_aniso : 1; - SamplerResource(u32 sharp_idx, u32 associated_image_, bool disable_aniso_) - : sampler{sharp_idx}, associated_image{associated_image_}, disable_aniso{disable_aniso_} {} - SamplerResource(AmdGpu::Sampler sampler_) - : sampler{sampler_}, associated_image{0}, disable_aniso(0) {} - constexpr AmdGpu::Sampler GetSharp(const Info& info) const noexcept; }; using SamplerResourceList = boost::container::small_vector; @@ -324,9 +319,7 @@ constexpr AmdGpu::Image ImageResource::GetSharp(const Info& info) const noexcept } constexpr AmdGpu::Sampler SamplerResource::GetSharp(const Info& info) const noexcept { - return std::holds_alternative(sampler) - ? std::get(sampler) - : info.ReadUdSharp(std::get(sampler)); + return inline_sampler ? inline_sampler : info.ReadUdSharp(sharp_idx); } constexpr AmdGpu::Image FMaskResource::GetSharp(const Info& info) const noexcept { diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index ab6535af2..497566d76 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -1974,9 +1974,9 @@ Value IREmitter::ImageAtomicExchange(const Value& handle, const Value& coords, c Value IREmitter::ImageSampleRaw(const Value& handle, const Value& address1, const Value& address2, const Value& address3, const Value& address4, - const Value& inline_sampler, TextureInstInfo info) { - return Inst(Opcode::ImageSampleRaw, Flags{info}, handle, address1, address2, address3, address4, - inline_sampler); + TextureInstInfo info) { + return Inst(Opcode::ImageSampleRaw, Flags{info}, handle, address1, address2, address3, + address4); } Value IREmitter::ImageSampleImplicitLod(const Value& handle, const Value& coords, const F32& bias, diff --git a/src/shader_recompiler/ir/ir_emitter.h b/src/shader_recompiler/ir/ir_emitter.h index 9e2f79978..f5798d618 100644 --- a/src/shader_recompiler/ir/ir_emitter.h +++ b/src/shader_recompiler/ir/ir_emitter.h @@ -353,8 +353,7 @@ public: [[nodiscard]] Value ImageSampleRaw(const Value& handle, const Value& address1, const Value& address2, const Value& address3, - const Value& address4, const Value& inline_sampler, - TextureInstInfo info); + const Value& address4, TextureInstInfo info); [[nodiscard]] Value ImageSampleImplicitLod(const Value& handle, const Value& body, const F32& bias, const Value& offset, diff --git a/src/shader_recompiler/ir/opcodes.inc b/src/shader_recompiler/ir/opcodes.inc index 179a01945..45b8ed56e 100644 --- a/src/shader_recompiler/ir/opcodes.inc +++ b/src/shader_recompiler/ir/opcodes.inc @@ -414,7 +414,7 @@ OPCODE(ConvertU8U32, U8, U32, OPCODE(ConvertU32U8, U32, U8, ) // Image operations -OPCODE(ImageSampleRaw, F32x4, Opaque, F32x4, F32x4, F32x4, F32, Opaque, ) +OPCODE(ImageSampleRaw, F32x4, Opaque, F32x4, F32x4, F32x4, F32, ) OPCODE(ImageSampleImplicitLod, F32x4, Opaque, F32x4, F32, Opaque, ) OPCODE(ImageSampleExplicitLod, F32x4, Opaque, Opaque, F32, Opaque, ) OPCODE(ImageSampleDrefImplicitLod, F32x4, Opaque, Opaque, F32, F32, Opaque, ) diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index e278d10f8..43c1ebce5 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -170,7 +170,7 @@ public: u32 Add(const SamplerResource& desc) { const u32 index{Add(sampler_resources, desc, [this, &desc](const auto& existing) { - return desc.sampler == existing.sampler; + return desc.sharp_idx == existing.sharp_idx; })}; return index; } @@ -353,7 +353,8 @@ void PatchBufferSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& descriptors) { const auto pred = [](const IR::Inst* inst) -> std::optional { const auto opcode = inst->GetOpcode(); - if (opcode == IR::Opcode::ReadConst || // IMAGE_LOAD (image only) + if (opcode == IR::Opcode::CompositeConstructU32x2 || // IMAGE_SAMPLE (image+sampler) + opcode == IR::Opcode::ReadConst || // IMAGE_LOAD (image only) opcode == IR::Opcode::GetUserData) { return inst; } @@ -361,7 +362,9 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& }; const auto result = IR::BreadthFirstSearch(&inst, pred); ASSERT_MSG(result, "Unable to find image sharp source"); - const IR::Inst* tsharp_handle = result.value(); + const IR::Inst* producer = result.value(); + const bool has_sampler = producer->GetOpcode() == IR::Opcode::CompositeConstructU32x2; + const auto tsharp_handle = has_sampler ? producer->Arg(0).InstRecursive() : producer; // Read image sharp. const auto tsharp = TrackSharp(tsharp_handle, info); @@ -426,32 +429,29 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& if (inst.GetOpcode() == IR::Opcode::ImageSampleRaw) { // Read sampler sharp. - const auto sampler_binding = [&] -> u32 { - const auto sampler = inst.Arg(5).InstRecursive(); - ASSERT(sampler && sampler->GetOpcode() == IR::Opcode::CompositeConstructU32x4); - const auto handle = sampler->Arg(0); + const auto [sampler_binding, sampler] = [&] -> std::pair { + ASSERT(producer->GetOpcode() == IR::Opcode::CompositeConstructU32x2); + const IR::Value& handle = producer->Arg(1); // Inline sampler resource. if (handle.IsImmediate()) { - LOG_DEBUG(Render_Vulkan, "Inline sampler detected"); - const auto [s1, s2, s3, s4] = - std::tuple{sampler->Arg(0), sampler->Arg(1), sampler->Arg(2), sampler->Arg(3)}; - ASSERT(s1.IsImmediate() && s2.IsImmediate() && s3.IsImmediate() && - s4.IsImmediate()); - const auto inline_sampler = AmdGpu::Sampler{ - .raw0 = u64(s2.U32()) << 32 | u64(s1.U32()), - .raw1 = u64(s4.U32()) << 32 | u64(s3.U32()), - }; - const auto binding = descriptors.Add(SamplerResource{inline_sampler}); - return binding; - } else { - // Normal sampler resource. - const auto ssharp_handle = handle.InstRecursive(); - const auto& [ssharp_ud, disable_aniso] = TryDisableAnisoLod0(ssharp_handle); - const auto ssharp = TrackSharp(ssharp_ud, info); - const auto binding = - descriptors.Add(SamplerResource{ssharp, image_binding, disable_aniso}); - return binding; + LOG_WARNING(Render_Vulkan, "Inline sampler detected"); + const auto inline_sampler = AmdGpu::Sampler{.raw0 = handle.U32()}; + const auto binding = descriptors.Add(SamplerResource{ + .sharp_idx = std::numeric_limits::max(), + .inline_sampler = inline_sampler, + }); + return {binding, inline_sampler}; } + // Normal sampler resource. + const auto ssharp_handle = handle.InstRecursive(); + const auto& [ssharp_ud, disable_aniso] = TryDisableAnisoLod0(ssharp_handle); + const auto ssharp = TrackSharp(ssharp_ud, info); + const auto binding = descriptors.Add(SamplerResource{ + .sharp_idx = ssharp, + .associated_image = image_binding, + .disable_aniso = disable_aniso, + }); + return {binding, info.ReadUdSharp(ssharp)}; }(); // Patch image and sampler handle. inst.SetArg(0, ir.Imm32(image_binding | sampler_binding << 16));