From 669b19c2f30d274767aaa2912ae3833cad614456 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sat, 21 Jun 2025 22:18:00 -0700 Subject: [PATCH] shader_recompiler: Fix handling unbound depth image. (#3143) * shader_recompiler: Fix handling unbound depth image. * shader_recompiler: Consolidate unbound image handling. --- src/shader_recompiler/info.h | 16 +++++----- .../ir/passes/resource_tracking_pass.cpp | 31 +++++++------------ 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index 6c931da31..6777c4769 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -308,17 +308,19 @@ constexpr AmdGpu::Image ImageResource::GetSharp(const Info& info) const noexcept if (!is_r128) { image = info.ReadUdSharp(sharp_idx); } else { - AmdGpu::Buffer buf = info.ReadUdSharp(sharp_idx); + const auto buf = info.ReadUdSharp(sharp_idx); memcpy(&image, &buf, sizeof(buf)); } if (!image.Valid()) { // Fall back to null image if unbound. - return AmdGpu::Image::Null(); - } - const auto data_fmt = image.GetDataFmt(); - if (is_depth && data_fmt != AmdGpu::DataFormat::Format16 && - data_fmt != AmdGpu::DataFormat::Format32) { - return AmdGpu::Image::NullDepth(); + LOG_DEBUG(Render_Vulkan, "Encountered unbound image!"); + image = is_depth ? AmdGpu::Image::NullDepth() : AmdGpu::Image::Null(); + } else if (is_depth) { + const auto data_fmt = image.GetDataFmt(); + if (data_fmt != AmdGpu::DataFormat::Format16 && data_fmt != AmdGpu::DataFormat::Format32) { + LOG_DEBUG(Render_Vulkan, "Encountered non-depth image used with depth instruction!"); + image = AmdGpu::Image::NullDepth(); + } } return image; } diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index e278d10f8..2e9b78f0e 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -366,19 +366,17 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& // Read image sharp. const auto tsharp = TrackSharp(tsharp_handle, info); const auto inst_info = inst.Flags(); - auto image = info.ReadUdSharp(tsharp); - if (!image.Valid()) { - LOG_ERROR(Render_Vulkan, "Shader compiled with unbound image!"); - image = AmdGpu::Image::Null(); - } - const auto data_fmt = image.GetDataFmt(); - if (inst_info.is_depth && data_fmt != AmdGpu::DataFormat::Format16 && - data_fmt != AmdGpu::DataFormat::Format32) { - LOG_ERROR(Render_Vulkan, "Shader compiled using non-depth image with depth instruction!"); - image = AmdGpu::Image::NullDepth(); - } - ASSERT(image.GetType() != AmdGpu::ImageType::Invalid); const bool is_written = inst.GetOpcode() == IR::Opcode::ImageWrite; + const ImageResource image_res = { + .sharp_idx = tsharp, + .is_depth = bool(inst_info.is_depth), + .is_atomic = IsImageAtomicInstruction(inst), + .is_array = bool(inst_info.is_array), + .is_written = is_written, + .is_r128 = bool(inst_info.is_r128), + }; + auto image = image_res.GetSharp(info); + ASSERT(image.GetType() != AmdGpu::ImageType::Invalid); // Patch image instruction if image is FMask. if (image.IsFmask()) { @@ -413,14 +411,7 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors& } } - u32 image_binding = descriptors.Add(ImageResource{ - .sharp_idx = tsharp, - .is_depth = bool(inst_info.is_depth), - .is_atomic = IsImageAtomicInstruction(inst), - .is_array = bool(inst_info.is_array), - .is_written = is_written, - .is_r128 = bool(inst_info.is_r128), - }); + u32 image_binding = descriptors.Add(image_res); IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};