fix: lower UBO max size to account buffer cache offset

This commit is contained in:
psucien 2025-02-09 17:57:37 +01:00
parent 8f2883a388
commit 7c9bd08df9
4 changed files with 15 additions and 5 deletions

View File

@ -634,7 +634,7 @@ void EmitContext::DefineBuffers() {
for (const auto& desc : info.buffers) {
const auto sharp = desc.GetSharp(info);
const bool is_storage = desc.IsStorage(sharp);
const u32 array_size = sharp.NumDwords() != 0 ? sharp.NumDwords() : MaxUboDwords;
const u32 array_size = sharp.NumDwords() != 0 ? sharp.NumDwords() : Vulkan::MaxUboSize >> 2;
const auto* data_types = True(desc.used_types & IR::Type::F32) ? &F32 : &U32;
const Id data_type = (*data_types)[1];
const Id record_array_type{is_storage ? TypeRuntimeArray(data_type)

View File

@ -21,11 +21,13 @@
#include "video_core/amdgpu/liverpool.h"
#include "video_core/amdgpu/resource.h"
namespace Vulkan {
extern size_t MaxUboSize;
}
namespace Shader {
static constexpr size_t NumUserDataRegs = 16;
static constexpr size_t MaxUboSize = 65536;
static constexpr size_t MaxUboDwords = MaxUboSize >> 2;
enum class TextureType : u32 {
Color1D,
@ -51,7 +53,7 @@ struct BufferResource {
bool is_formatted{};
[[nodiscard]] bool IsStorage(const AmdGpu::Buffer& buffer) const noexcept {
return buffer.GetSize() > MaxUboSize || is_written || is_gds_buffer;
return buffer.GetSize() > Vulkan::MaxUboSize || is_written || is_gds_buffer;
}
[[nodiscard]] constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept;

View File

@ -19,6 +19,8 @@
namespace Vulkan {
size_t MaxUboSize = 64_KB;
namespace {
std::vector<vk::PhysicalDevice> EnumeratePhysicalDevices(vk::UniqueInstance& instance) {
@ -180,6 +182,12 @@ Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index,
vk::to_string(format.flags & ~GetFormatFeatureFlags(format.vk_format)));
}
}
// When binding a UBO, we calculate its size considering the offset in the larger buffer cache
// underlying resource. In some cases, it may produce sizes exceeding the system maximum
// allowed UBO range, so we need to reduce the threshold to prevent issues.
MaxUboSize =
properties.limits.maxUniformBufferRange - properties.limits.minUniformBufferOffsetAlignment;
}
Instance::~Instance() {

View File

@ -554,7 +554,6 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
}
// Second pass to re-bind buffers that were updated after binding
auto& null_buffer = buffer_cache.GetBuffer(VideoCore::NULL_BUFFER_ID);
for (u32 i = 0; i < buffer_bindings.size(); i++) {
const auto& [buffer_id, vsharp] = buffer_bindings[i];
const auto& desc = stage.buffers[i];
@ -566,6 +565,7 @@ void Rasterizer::BindBuffers(const Shader::Info& stage, Shader::Backend::Binding
} else if (instance.IsNullDescriptorSupported()) {
buffer_infos.emplace_back(VK_NULL_HANDLE, 0, VK_WHOLE_SIZE);
} else {
auto& null_buffer = buffer_cache.GetBuffer(VideoCore::NULL_BUFFER_ID);
buffer_infos.emplace_back(null_buffer.Handle(), 0, VK_WHOLE_SIZE);
}
} else {