renderer_vulkan: Parse fetch shader per-pipeline (#1656)

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

* renderer_vulkan: Parse fetch shader per-pipeline

* Few minor fixes.

* shader_recompiler: Specialize on vertex attribute number types.

* shader_recompiler: Move GetDrawOffsets to fetch shader
This commit is contained in:
squidbus 2024-12-04 03:03:47 -08:00 committed by GitHub
parent 74b091fd08
commit 920acb8d8b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 286 additions and 182 deletions

View file

@ -6,12 +6,19 @@
#include <bitset>
#include "common/types.h"
#include "frontend/fetch_shader.h"
#include "shader_recompiler/backend/bindings.h"
#include "shader_recompiler/info.h"
#include "shader_recompiler/ir/passes/srt.h"
namespace Shader {
struct VsAttribSpecialization {
AmdGpu::NumberClass num_class{};
auto operator<=>(const VsAttribSpecialization&) const = default;
};
struct BufferSpecialization {
u16 stride : 14;
u16 is_storage : 1;
@ -50,6 +57,8 @@ struct StageSpecialization {
const Shader::Info* info;
RuntimeInfo runtime_info;
Gcn::FetchShaderData fetch_shader_data{};
boost::container::small_vector<VsAttribSpecialization, 32> vs_attribs;
std::bitset<MaxStageResources> bitset{};
boost::container::small_vector<BufferSpecialization, 16> buffers;
boost::container::small_vector<TextureBufferSpecialization, 8> tex_buffers;
@ -57,9 +66,19 @@ struct StageSpecialization {
boost::container::small_vector<FMaskSpecialization, 8> fmasks;
Backend::Bindings start{};
explicit StageSpecialization(const Shader::Info& info_, RuntimeInfo runtime_info_,
Backend::Bindings start_)
explicit StageSpecialization(const Info& info_, RuntimeInfo runtime_info_,
const Profile& profile_, Backend::Bindings start_)
: info{&info_}, runtime_info{runtime_info_}, start{start_} {
if (const auto fetch_shader = Gcn::ParseFetchShader(info_)) {
fetch_shader_data = *fetch_shader;
if (info_.stage == Stage::Vertex && !profile_.support_legacy_vertex_attributes) {
// Specialize shader on VS input number types to follow spec.
ForEachSharp(vs_attribs, fetch_shader_data.attributes,
[](auto& spec, const auto& desc, AmdGpu::Buffer sharp) {
spec.num_class = AmdGpu::GetNumberClass(sharp.GetNumberFmt());
});
}
}
u32 binding{};
if (info->has_readconst) {
binding++;
@ -75,8 +94,7 @@ struct StageSpecialization {
});
ForEachSharp(binding, images, info->images,
[](auto& spec, const auto& desc, AmdGpu::Image sharp) {
spec.type = sharp.IsPartialCubemap() ? AmdGpu::ImageType::Color2DArray
: sharp.GetType();
spec.type = sharp.GetBoundType();
spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt());
});
ForEachSharp(binding, fmasks, info->fmasks,
@ -86,6 +104,17 @@ struct StageSpecialization {
});
}
void ForEachSharp(auto& spec_list, auto& desc_list, auto&& func) {
for (const auto& desc : desc_list) {
auto& spec = spec_list.emplace_back();
const auto sharp = desc.GetSharp(*info);
if (!sharp) {
continue;
}
func(spec, desc, sharp);
}
}
void ForEachSharp(u32& binding, auto& spec_list, auto& desc_list, auto&& func) {
for (const auto& desc : desc_list) {
auto& spec = spec_list.emplace_back();
@ -106,6 +135,14 @@ struct StageSpecialization {
if (runtime_info != other.runtime_info) {
return false;
}
if (fetch_shader_data != other.fetch_shader_data) {
return false;
}
for (u32 i = 0; i < vs_attribs.size(); i++) {
if (vs_attribs[i] != other.vs_attribs[i]) {
return false;
}
}
u32 binding{};
if (info->has_readconst != other.info->has_readconst) {
return false;