shader_recompiler: Account for instruction array flag in image type.

This commit is contained in:
squidbus 2025-01-07 02:50:58 -08:00
parent b0d7feb292
commit c05e48becb
7 changed files with 24 additions and 11 deletions

View File

@ -172,15 +172,15 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod
const auto& texture = ctx.images[handle & 0xFFFF];
const Id image = ctx.OpLoad(texture.image_type, texture.id);
const auto sharp = ctx.info.images[handle & 0xFFFF].GetSharp(ctx.info);
const auto type = sharp.GetBoundType();
const Id zero = ctx.u32_zero_value;
const auto mips{[&] { return has_mips ? ctx.OpImageQueryLevels(ctx.U32[1], image) : zero; }};
const bool uses_lod{type != AmdGpu::ImageType::Color2DMsaa && !texture.is_storage};
const bool uses_lod{texture.bound_type != AmdGpu::ImageType::Color2DMsaa &&
!texture.is_storage};
const auto query{[&](Id type) {
return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod)
: ctx.OpImageQuerySize(type, image);
}};
switch (type) {
switch (texture.bound_type) {
case AmdGpu::ImageType::Color1D:
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
case AmdGpu::ImageType::Color1DArray:

View File

@ -773,7 +773,7 @@ spv::ImageFormat GetFormat(const AmdGpu::Image& image) {
Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
const auto image = desc.GetSharp(ctx.info);
const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown;
const auto type = image.GetBoundType();
const auto type = desc.GetBoundType(image);
const u32 sampled = desc.IsStorage(image) ? 2 : 1;
switch (type) {
case AmdGpu::ImageType::Color1D:
@ -817,6 +817,7 @@ void EmitContext::DefineImagesAndSamplers() {
.sampled_type = is_storage ? sampled_type : TypeSampledImage(image_type),
.pointer_type = pointer_type,
.image_type = image_type,
.bound_type = image_desc.GetBoundType(sharp),
.is_integer = is_integer,
.is_storage = is_storage,
});

View File

@ -222,6 +222,7 @@ public:
Id sampled_type;
Id pointer_type;
Id image_type;
AmdGpu::ImageType bound_type;
bool is_integer = false;
bool is_storage = false;
};

View File

@ -73,9 +73,24 @@ struct ImageResource {
bool is_read{};
bool is_written{};
AmdGpu::ImageType GetBoundType(const AmdGpu::Image& image) const noexcept {
const auto base_type = image.GetType();
if (base_type == AmdGpu::ImageType::Color1DArray && !is_array) {
return AmdGpu::ImageType::Color1D;
}
if (base_type == AmdGpu::ImageType::Color2DArray && !is_array) {
return AmdGpu::ImageType::Color2D;
}
if (image.IsPartialCubemap()) {
// Partial cube map
return AmdGpu::ImageType::Color2DArray;
}
return base_type;
}
[[nodiscard]] bool IsStorage(const AmdGpu::Image& image) const noexcept {
// Need cube as storage when used with ImageRead.
return is_written || (is_read && image.GetBoundType() == AmdGpu::ImageType::Cube);
return is_written || (is_read && GetBoundType(image) == AmdGpu::ImageType::Cube);
}
[[nodiscard]] constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept;

View File

@ -113,7 +113,7 @@ struct StageSpecialization {
});
ForEachSharp(binding, images, info->images,
[](auto& spec, const auto& desc, AmdGpu::Image sharp) {
spec.type = sharp.GetBoundType();
spec.type = desc.GetBoundType(sharp);
spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt());
spec.is_storage = desc.IsStorage(sharp);
if (spec.is_storage) {

View File

@ -293,10 +293,6 @@ struct Image {
const auto viewed_slice = last_array - base_array + 1;
return GetType() == ImageType::Cube && viewed_slice < 6;
}
ImageType GetBoundType() const noexcept {
return IsPartialCubemap() ? ImageType::Color2DArray : GetType();
}
};
static_assert(sizeof(Image) == 32); // 256bits

View File

@ -51,7 +51,7 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageReso
range.extent.levels = image.last_level - image.base_level + 1;
}
range.extent.layers = image.last_array - image.base_array + 1;
type = ConvertImageViewType(image.GetBoundType());
type = ConvertImageViewType(desc.GetBoundType(image));
// Adjust view type for arrays
if (type == vk::ImageViewType::eCube) {