shader_recompiler: Read image format info directly from sharps instead of storing in shader info.

This commit is contained in:
squidbus 2024-12-02 17:06:54 -08:00
parent f0b75289c8
commit 8ac7ffd859
11 changed files with 30 additions and 32 deletions

View File

@ -187,7 +187,8 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, const
Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool has_mips) { Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool has_mips) {
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 type = ctx.info.images[handle & 0xFFFF].type; 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{type != AmdGpu::ImageType::Color2DMsaa && !texture.is_storage};

View File

@ -282,7 +282,8 @@ void EmitContext::DefineInputs() {
for (const auto& input : info.vs_inputs) { for (const auto& input : info.vs_inputs) {
ASSERT(input.binding < IR::NumParams); ASSERT(input.binding < IR::NumParams);
const Id type{GetAttributeType(*this, input.fmt)[4]}; const auto sharp = input.GetSharp(info);
const Id type{GetAttributeType(*this, sharp.GetNumberFmt())[4]};
if (input.instance_step_rate == Info::VsInput::InstanceIdType::OverStepRate0 || if (input.instance_step_rate == Info::VsInput::InstanceIdType::OverStepRate0 ||
input.instance_step_rate == Info::VsInput::InstanceIdType::OverStepRate1) { input.instance_step_rate == Info::VsInput::InstanceIdType::OverStepRate1) {
@ -306,7 +307,7 @@ void EmitContext::DefineInputs() {
} else { } else {
Name(id, fmt::format("vs_in_attr{}", input.binding)); Name(id, fmt::format("vs_in_attr{}", input.binding));
} }
input_params[input.binding] = GetAttributeInfo(input.fmt, id, 4, false); input_params[input.binding] = GetAttributeInfo(sharp.GetNumberFmt(), id, 4, false);
interfaces.push_back(id); interfaces.push_back(id);
} }
} }
@ -553,9 +554,10 @@ void EmitContext::DefineBuffers() {
void EmitContext::DefineTextureBuffers() { void EmitContext::DefineTextureBuffers() {
for (const auto& desc : info.texture_buffers) { for (const auto& desc : info.texture_buffers) {
const bool is_integer = const auto sharp = desc.GetSharp(info);
desc.nfmt == AmdGpu::NumberFormat::Uint || desc.nfmt == AmdGpu::NumberFormat::Sint; const auto nfmt = sharp.GetNumberFmt();
const VectorIds& sampled_type{GetAttributeType(*this, desc.nfmt)}; const bool is_integer = AmdGpu::IsInteger(nfmt);
const VectorIds& sampled_type{GetAttributeType(*this, nfmt)};
const u32 sampled = desc.is_written ? 2 : 1; const u32 sampled = desc.is_written ? 2 : 1;
const Id image_type{TypeImage(sampled_type[1], spv::Dim::Buffer, false, false, false, const Id image_type{TypeImage(sampled_type[1], spv::Dim::Buffer, false, false, false,
sampled, spv::ImageFormat::Unknown)}; sampled, spv::ImageFormat::Unknown)};
@ -652,8 +654,9 @@ 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 = ctx.info.ReadUdSharp<AmdGpu::Image>(desc.sharp_idx); const auto image = ctx.info.ReadUdSharp<AmdGpu::Image>(desc.sharp_idx);
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 u32 sampled = desc.is_storage ? 2 : 1; const u32 sampled = desc.is_storage ? 2 : 1;
switch (desc.type) { switch (type) {
case AmdGpu::ImageType::Color1D: case AmdGpu::ImageType::Color1D:
return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, sampled, format); return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, sampled, format);
case AmdGpu::ImageType::Color1DArray: case AmdGpu::ImageType::Color1DArray:
@ -672,14 +675,15 @@ Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) {
default: default:
break; break;
} }
throw InvalidArgument("Invalid texture type {}", desc.type); throw InvalidArgument("Invalid texture type {}", type);
} }
void EmitContext::DefineImagesAndSamplers() { void EmitContext::DefineImagesAndSamplers() {
for (const auto& image_desc : info.images) { for (const auto& image_desc : info.images) {
const bool is_integer = image_desc.nfmt == AmdGpu::NumberFormat::Uint || const auto sharp = image_desc.GetSharp(info);
image_desc.nfmt == AmdGpu::NumberFormat::Sint; const auto nfmt = sharp.GetNumberFmt();
const VectorIds& data_types = GetAttributeType(*this, image_desc.nfmt); const bool is_integer = AmdGpu::IsInteger(nfmt);
const VectorIds& data_types = GetAttributeType(*this, nfmt);
const Id sampled_type = data_types[1]; const Id sampled_type = data_types[1];
const Id image_type{ImageType(*this, image_desc, sampled_type)}; const Id image_type{ImageType(*this, image_desc, sampled_type)};
const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)}; const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)};

View File

@ -435,7 +435,6 @@ void Translator::EmitFetch(const GcnInst& inst) {
const u32 num_components = AmdGpu::NumComponents(buffer.GetDataFmt()); const u32 num_components = AmdGpu::NumComponents(buffer.GetDataFmt());
info.vs_inputs.push_back({ info.vs_inputs.push_back({
.fmt = buffer.GetNumberFmt(),
.binding = attrib.semantic, .binding = attrib.semantic,
.num_components = std::min<u16>(attrib.num_elements, num_components), .num_components = std::min<u16>(attrib.num_elements, num_components),
.sgpr_base = attrib.sgpr_base, .sgpr_base = attrib.sgpr_base,

View File

@ -57,7 +57,6 @@ using BufferResourceList = boost::container::small_vector<BufferResource, 16>;
struct TextureBufferResource { struct TextureBufferResource {
u32 sharp_idx; u32 sharp_idx;
AmdGpu::NumberFormat nfmt;
bool is_written{}; bool is_written{};
constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept; constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept;
@ -66,8 +65,6 @@ using TextureBufferResourceList = boost::container::small_vector<TextureBufferRe
struct ImageResource { struct ImageResource {
u32 sharp_idx; u32 sharp_idx;
AmdGpu::ImageType type;
AmdGpu::NumberFormat nfmt;
bool is_storage{}; bool is_storage{};
bool is_depth{}; bool is_depth{};
bool is_atomic{}; bool is_atomic{};
@ -123,13 +120,16 @@ struct Info {
Plain = 3, Plain = 3,
}; };
AmdGpu::NumberFormat fmt;
u16 binding; u16 binding;
u16 num_components; u16 num_components;
u8 sgpr_base; u8 sgpr_base;
u8 dword_offset; u8 dword_offset;
InstanceIdType instance_step_rate; InstanceIdType instance_step_rate;
s32 instance_data_buf; s32 instance_data_buf;
[[nodiscard]] constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept {
return info.ReadUdReg<AmdGpu::Buffer>(sgpr_base, dword_offset);
}
}; };
boost::container::static_vector<VsInput, 32> vs_inputs{}; boost::container::static_vector<VsInput, 32> vs_inputs{};

View File

@ -381,7 +381,6 @@ void PatchTextureBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info,
const auto buffer = info.ReadUdSharp<AmdGpu::Buffer>(sharp); const auto buffer = info.ReadUdSharp<AmdGpu::Buffer>(sharp);
const s32 binding = descriptors.Add(TextureBufferResource{ const s32 binding = descriptors.Add(TextureBufferResource{
.sharp_idx = sharp, .sharp_idx = sharp,
.nfmt = buffer.GetNumberFmt(),
.is_written = inst.GetOpcode() == IR::Opcode::StoreBufferFormatF32, .is_written = inst.GetOpcode() == IR::Opcode::StoreBufferFormatF32,
}); });
@ -660,11 +659,8 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip
} }
} }
const auto type = image.IsPartialCubemap() ? AmdGpu::ImageType::Color2DArray : image.GetType();
u32 image_binding = descriptors.Add(ImageResource{ u32 image_binding = descriptors.Add(ImageResource{
.sharp_idx = tsharp, .sharp_idx = tsharp,
.type = type,
.nfmt = image.GetNumberFmt(),
.is_storage = is_storage, .is_storage = is_storage,
.is_depth = bool(inst_info.is_depth), .is_depth = bool(inst_info.is_depth),
.is_atomic = IsImageAtomicInstruction(inst), .is_atomic = IsImageAtomicInstruction(inst),

View File

@ -75,8 +75,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.IsPartialCubemap() ? AmdGpu::ImageType::Color2DArray spec.type = sharp.GetBoundType();
: sharp.GetType();
spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt()); spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt());
}); });
ForEachSharp(binding, fmasks, info->fmasks, ForEachSharp(binding, fmasks, info->fmasks,

View File

@ -304,6 +304,10 @@ 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

@ -157,7 +157,7 @@ bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) {
continue; continue;
} }
const auto& buffer = vs_info.ReadUdReg<AmdGpu::Buffer>(input.sgpr_base, input.dword_offset); const auto& buffer = input.GetSharp(vs_info);
if (buffer.GetSize() == 0) { if (buffer.GetSize() == 0) {
continue; continue;
} }

View File

@ -55,8 +55,7 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul
continue; continue;
} }
const auto buffer = const auto buffer = input.GetSharp(*vs_info);
vs_info->ReadUdReg<AmdGpu::Buffer>(input.sgpr_base, input.dword_offset);
if (buffer.GetSize() == 0) { if (buffer.GetSize() == 0) {
continue; continue;
} }

View File

@ -349,8 +349,7 @@ bool PipelineCache::RefreshGraphicsKey() {
input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate1) { input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate1) {
continue; continue;
} }
const auto& buffer = const auto& buffer = input.GetSharp(*vs_info);
vs_info->ReadUdReg<AmdGpu::Buffer>(input.sgpr_base, input.dword_offset);
if (buffer.GetSize() == 0) { if (buffer.GetSize() == 0) {
continue; continue;
} }

View File

@ -87,12 +87,9 @@ 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.GetType()); type = ConvertImageViewType(image.GetBoundType());
// Adjust view type for partial cubemaps and arrays // Adjust view type for arrays
if (image.IsPartialCubemap()) {
type = vk::ImageViewType::e2DArray;
}
if (type == vk::ImageViewType::eCube) { if (type == vk::ImageViewType::eCube) {
if (desc.is_array) { if (desc.is_array) {
type = vk::ImageViewType::eCubeArray; type = vk::ImageViewType::eCubeArray;