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 auto& texture = ctx.images[handle & 0xFFFF];
const Id image = ctx.OpLoad(texture.image_type, texture.id); const Id image = ctx.OpLoad(texture.image_type, texture.id);
const auto sharp = ctx.info.images[handle & 0xFFFF].GetSharp(ctx.info); const auto sharp = ctx.info.images[handle & 0xFFFF].GetSharp(ctx.info);
const auto type = sharp.GetBoundType();
const Id zero = ctx.u32_zero_value; const Id zero = ctx.u32_zero_value;
const auto mips{[&] { return has_mips ? ctx.OpImageQueryLevels(ctx.U32[1], image) : zero; }}; 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) { const auto query{[&](Id type) {
return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod) return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod)
: ctx.OpImageQuerySize(type, image); : ctx.OpImageQuerySize(type, image);
}}; }};
switch (type) { switch (texture.bound_type) {
case AmdGpu::ImageType::Color1D: case AmdGpu::ImageType::Color1D:
return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips()); return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
case AmdGpu::ImageType::Color1DArray: 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) { Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
const auto image = desc.GetSharp(ctx.info); const auto image = desc.GetSharp(ctx.info);
const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown; 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; const u32 sampled = desc.IsStorage(image) ? 2 : 1;
switch (type) { switch (type) {
case AmdGpu::ImageType::Color1D: case AmdGpu::ImageType::Color1D:
@ -817,6 +817,7 @@ void EmitContext::DefineImagesAndSamplers() {
.sampled_type = is_storage ? sampled_type : TypeSampledImage(image_type), .sampled_type = is_storage ? sampled_type : TypeSampledImage(image_type),
.pointer_type = pointer_type, .pointer_type = pointer_type,
.image_type = image_type, .image_type = image_type,
.bound_type = image_desc.GetBoundType(sharp),
.is_integer = is_integer, .is_integer = is_integer,
.is_storage = is_storage, .is_storage = is_storage,
}); });

View File

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

View File

@ -73,9 +73,24 @@ struct ImageResource {
bool is_read{}; bool is_read{};
bool is_written{}; 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 { [[nodiscard]] bool IsStorage(const AmdGpu::Image& image) const noexcept {
// Need cube as storage when used with ImageRead. // 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; [[nodiscard]] constexpr AmdGpu::Image GetSharp(const Info& info) const noexcept;

View File

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

View File

@ -293,10 +293,6 @@ struct Image {
const auto viewed_slice = last_array - base_array + 1; const auto viewed_slice = last_array - base_array + 1;
return GetType() == ImageType::Cube && viewed_slice < 6; return GetType() == ImageType::Cube && viewed_slice < 6;
} }
ImageType GetBoundType() const noexcept {
return IsPartialCubemap() ? ImageType::Color2DArray : GetType();
}
}; };
static_assert(sizeof(Image) == 32); // 256bits 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.levels = image.last_level - image.base_level + 1;
} }
range.extent.layers = image.last_array - image.base_array + 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 // Adjust view type for arrays
if (type == vk::ImageViewType::eCube) { if (type == vk::ImageViewType::eCube) {