shader_recompiler: Specialize UBOs on size

* Some games can perform manual vertex pulling and thus bind read only buffers of varying size. We only recompile when the vsharp size is larger than size in shader, in opposite case its not needed
This commit is contained in:
IndecisiveTurtle 2024-12-01 16:35:38 +02:00
parent 22b816227f
commit ec514fa08e
3 changed files with 10 additions and 4 deletions

View file

@ -108,7 +108,7 @@ struct PushData {
void AddTexelOffset(u32 binding, u32 multiplier, u32 texel_offset) {
ASSERT(texel_offset < 64 && multiplier < 16);
buf_offsets[binding] = texel_offset | (std::bit_width(multiplier) << 6);
buf_offsets[binding] = texel_offset | ((std::bit_width(multiplier) - 1) << 6);
}
};
static_assert(sizeof(PushData) <= 128,

View file

@ -9,7 +9,6 @@
#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 {
@ -22,8 +21,12 @@ struct VsAttribSpecialization {
struct BufferSpecialization {
u16 stride : 14;
u16 is_storage : 1;
u32 size = 0;
auto operator<=>(const BufferSpecialization&) const = default;
bool operator==(const BufferSpecialization& other) const {
return stride == other.stride && is_storage == other.is_storage &&
(size >= other.is_storage || is_storage);
}
};
struct TextureBufferSpecialization {
@ -86,6 +89,9 @@ struct StageSpecialization {
[](auto& spec, const auto& desc, AmdGpu::Buffer sharp) {
spec.stride = sharp.GetStride();
spec.is_storage = desc.IsStorage(sharp);
if (!spec.is_storage) {
spec.size = sharp.GetSize();
}
});
ForEachSharp(binding, tex_buffers, info->texture_buffers,
[](auto& spec, const auto& desc, AmdGpu::Buffer sharp) {

View file

@ -549,7 +549,7 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
vsharp.base_address, vsharp.GetSize(), desc.is_written, true, buffer_id);
const u32 fmt_stride = AmdGpu::NumBits(vsharp.GetDataFmt()) >> 3;
const u32 buf_stride = vsharp.GetStride();
ASSERT_MSG(buf_stride % fmt_stride, "Texel buffer stride must match format stride");
ASSERT_MSG(buf_stride % fmt_stride == 0, "Texel buffer stride must match format stride");
const u32 offset_aligned = Common::AlignDown(offset, alignment);
const u32 adjust = offset - offset_aligned;
ASSERT(adjust % fmt_stride == 0);