shader_recompiler: Fix handling unbound depth image. (#3143)

* shader_recompiler: Fix handling unbound depth image.

* shader_recompiler: Consolidate unbound image handling.
This commit is contained in:
squidbus 2025-06-21 22:18:00 -07:00 committed by GitHub
parent d9dac05db2
commit 669b19c2f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 20 additions and 27 deletions

View file

@ -308,17 +308,19 @@ constexpr AmdGpu::Image ImageResource::GetSharp(const Info& info) const noexcept
if (!is_r128) { if (!is_r128) {
image = info.ReadUdSharp<AmdGpu::Image>(sharp_idx); image = info.ReadUdSharp<AmdGpu::Image>(sharp_idx);
} else { } else {
AmdGpu::Buffer buf = info.ReadUdSharp<AmdGpu::Buffer>(sharp_idx); const auto buf = info.ReadUdSharp<AmdGpu::Buffer>(sharp_idx);
memcpy(&image, &buf, sizeof(buf)); memcpy(&image, &buf, sizeof(buf));
} }
if (!image.Valid()) { if (!image.Valid()) {
// Fall back to null image if unbound. // Fall back to null image if unbound.
return AmdGpu::Image::Null(); LOG_DEBUG(Render_Vulkan, "Encountered unbound image!");
} image = is_depth ? AmdGpu::Image::NullDepth() : AmdGpu::Image::Null();
const auto data_fmt = image.GetDataFmt(); } else if (is_depth) {
if (is_depth && data_fmt != AmdGpu::DataFormat::Format16 && const auto data_fmt = image.GetDataFmt();
data_fmt != AmdGpu::DataFormat::Format32) { if (data_fmt != AmdGpu::DataFormat::Format16 && data_fmt != AmdGpu::DataFormat::Format32) {
return AmdGpu::Image::NullDepth(); LOG_DEBUG(Render_Vulkan, "Encountered non-depth image used with depth instruction!");
image = AmdGpu::Image::NullDepth();
}
} }
return image; return image;
} }

View file

@ -366,19 +366,17 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors&
// Read image sharp. // Read image sharp.
const auto tsharp = TrackSharp(tsharp_handle, info); const auto tsharp = TrackSharp(tsharp_handle, info);
const auto inst_info = inst.Flags<IR::TextureInstInfo>(); const auto inst_info = inst.Flags<IR::TextureInstInfo>();
auto image = info.ReadUdSharp<AmdGpu::Image>(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 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. // Patch image instruction if image is FMask.
if (image.IsFmask()) { if (image.IsFmask()) {
@ -413,14 +411,7 @@ void PatchImageSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors&
} }
} }
u32 image_binding = descriptors.Add(ImageResource{ u32 image_binding = descriptors.Add(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),
});
IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)}; IR::IREmitter ir{block, IR::Block::InstructionList::s_iterator_to(inst)};