GPU: Material: Improve limit of UBO size

This moves the UBO size limit to be a capability.
This allows to check if size fits the requirements before
creating it and avoids hitting an assert.

Rel #146705

Pull Request: https://projects.blender.org/blender/blender/pulls/146728
This commit is contained in:
Clément Foucault
2025-09-25 09:44:12 +02:00
committed by Clément Foucault
parent 3cf7ce0fd1
commit e098441b5a
10 changed files with 23 additions and 9 deletions

View File

@@ -33,6 +33,7 @@ int GPU_max_varying_floats();
int GPU_max_shader_storage_buffer_bindings();
int GPU_max_compute_shader_storage_blocks();
int GPU_max_samplers();
size_t GPU_max_uniform_buffer_size();
size_t GPU_max_storage_buffer_size();
/* Used when binding subrange of SSBOs. In bytes.
* The start of the range must be aligned with this value. */

View File

@@ -191,6 +191,11 @@ int GPU_minimum_per_vertex_stride()
return GCaps.minimum_per_vertex_stride;
}
size_t GPU_max_uniform_buffer_size()
{
return GCaps.max_uniform_buffer_size;
}
size_t GPU_max_storage_buffer_size()
{
return GCaps.max_storage_buffer_size;

View File

@@ -39,6 +39,7 @@ struct GPUCapabilities {
int max_varying_floats = 0;
int max_shader_storage_buffer_bindings = 0;
int max_compute_shader_storage_blocks = 0;
size_t max_uniform_buffer_size = 0;
size_t max_storage_buffer_size = 0;
size_t storage_buffer_alignment = 256;
int extensions_len = 0;

View File

@@ -18,6 +18,7 @@
#include "gpu_backend.hh"
#include "gpu_node_graph.hh"
#include "GPU_capabilities.hh"
#include "GPU_context.hh"
#include "GPU_material.hh"
@@ -219,9 +220,12 @@ blender::gpu::UniformBuf *GPU_uniformbuf_create_from_list(ListBase *inputs, cons
void *data = MEM_mallocN(buffer_size, __func__);
buffer_fill_from_list(data, inputs);
UniformBuf *ubo = GPUBackend::get()->uniformbuf_alloc(buffer_size, name);
/* Defer data upload. */
ubo->attach_data(data);
UniformBuf *ubo = nullptr;
if (buffer_size <= GPU_max_uniform_buffer_size()) {
ubo = GPUBackend::get()->uniformbuf_alloc(buffer_size, name);
/* Defer data upload. */
ubo->attach_data(data);
}
return ubo;
}

View File

@@ -534,6 +534,7 @@ void MTLBackend::capabilities_init(MTLContext *ctx)
GCaps.max_shader_storage_buffer_bindings = 14;
GCaps.max_compute_shader_storage_blocks = 14;
GCaps.max_storage_buffer_size = size_t(ctx->device.maxBufferLength);
GCaps.max_uniform_buffer_size = size_t(ctx->device.maxBufferLength);
GCaps.storage_buffer_alignment = 256; /* TODO(fclem): But also unused. */
GCaps.max_work_group_count[0] = 65535;

View File

@@ -529,7 +529,6 @@ static void detect_workarounds()
GLint GLContext::max_cubemap_size = 0;
GLint GLContext::max_ubo_binds = 0;
GLint GLContext::max_ubo_size = 0;
GLint GLContext::max_ssbo_binds = 0;
/** Extensions. */
@@ -588,7 +587,9 @@ void GLBackend::capabilities_init()
glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_SIZE, 2, &GCaps.max_work_group_size[2]);
glGetIntegerv(GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &GCaps.max_shader_storage_buffer_bindings);
glGetIntegerv(GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS, &GCaps.max_compute_shader_storage_blocks);
int64_t max_ssbo_size;
int64_t max_ssbo_size, max_ubo_size;
glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &max_ubo_size);
GCaps.max_uniform_buffer_size = size_t(max_ubo_size);
glGetInteger64v(GL_MAX_SHADER_STORAGE_BLOCK_SIZE, &max_ssbo_size);
GCaps.max_storage_buffer_size = size_t(max_ssbo_size);
GLint ssbo_alignment;
@@ -601,7 +602,6 @@ void GLBackend::capabilities_init()
glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &GCaps.max_texture_3d_size);
glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &GLContext::max_cubemap_size);
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, &GLContext::max_ubo_binds);
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &GLContext::max_ubo_size);
GLint max_ssbo_binds;
GLContext::max_ssbo_binds = 999999;
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &max_ssbo_binds);

View File

@@ -42,7 +42,6 @@ class GLContext : public Context {
/** Capabilities. */
static GLint max_cubemap_size;
static GLint max_ubo_size;
static GLint max_ubo_binds;
static GLint max_ssbo_binds;

View File

@@ -27,7 +27,7 @@ GLStorageBuf::GLStorageBuf(size_t size, GPUUsageType usage, const char *name)
: StorageBuf(size, name)
{
usage_ = usage;
/* Do not create UBO GL buffer here to allow allocation from any thread. */
/* Do not create SSBO GL buffer here to allow allocation from any thread. */
BLI_assert(size <= GPU_max_storage_buffer_size());
}

View File

@@ -8,6 +8,8 @@
#include "BLI_string.h"
#include "GPU_capabilities.hh"
#include "gpu_context_private.hh"
#include "gl_debug.hh"
@@ -23,7 +25,7 @@ namespace blender::gpu {
GLUniformBuf::GLUniformBuf(size_t size, const char *name) : UniformBuf(size, name)
{
/* Do not create ubo GL buffer here to allow allocation from any thread. */
BLI_assert(size <= GLContext::max_ubo_size);
BLI_assert(size <= GPU_max_uniform_buffer_size());
}
GLUniformBuf::~GLUniformBuf()

View File

@@ -727,6 +727,7 @@ void VKBackend::capabilities_init(VKDevice &device)
GCaps.max_varying_floats = min_uu(limits.maxVertexOutputComponents, INT_MAX);
GCaps.max_shader_storage_buffer_bindings = GCaps.max_compute_shader_storage_blocks = min_uu(
limits.maxPerStageDescriptorStorageBuffers, INT_MAX);
GCaps.max_uniform_buffer_size = size_t(limits.maxUniformBufferRange);
GCaps.max_storage_buffer_size = size_t(limits.maxStorageBufferRange);
GCaps.storage_buffer_alignment = limits.minStorageBufferOffsetAlignment;