From b64359974919b2611aaec7d3c9206cc36576dc13 Mon Sep 17 00:00:00 2001 From: Stuart Carnie Date: Mon, 23 Dec 2024 08:25:32 -0700 Subject: [PATCH] Metal: Fix crash when uniform set is empty for slot binding mode Co-authored-by: Hugo Locurcio --- drivers/metal/metal_objects.mm | 7 ++++++- .../rendering/renderer_rd/storage_rd/particles_storage.cpp | 6 ++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/metal/metal_objects.mm b/drivers/metal/metal_objects.mm index b44c496e4f6..04900a0e516 100644 --- a/drivers/metal/metal_objects.mm +++ b/drivers/metal/metal_objects.mm @@ -56,6 +56,10 @@ #import +// We have to undefine these macros because they are defined in NSObjCRuntime.h. +#undef MIN +#undef MAX + void MDCommandBuffer::begin() { DEV_ASSERT(commandBuffer == nil); commandBuffer = queue.commandBufferWithUnretainedReferences; @@ -764,6 +768,7 @@ void MDCommandBuffer::render_bind_vertex_buffers(uint32_t p_binding_count, const [render.encoder setVertexBuffers:render.vertex_buffers.ptr() offsets:render.vertex_offsets.ptr() withRange:NSMakeRange(first, p_binding_count)]; + render.dirty.clear_flag(RenderState::DIRTY_VERTEX); } else { render.dirty.set_flag(RenderState::DIRTY_VERTEX); } @@ -1082,7 +1087,7 @@ void MDUniformSet::bind_uniforms_direct(MDShader *p_shader, MDCommandBuffer::Ren UniformSet const &set = p_shader->sets[index]; - for (uint32_t i = 0; i < uniforms.size(); i++) { + for (uint32_t i = 0; i < MIN(uniforms.size(), set.uniforms.size()); i++) { RDD::BoundUniform const &uniform = uniforms[i]; UniformInfo ui = set.uniforms[i]; diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 7bd2d75c74a..2ed4efd1572 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -541,13 +541,15 @@ void ParticlesStorage::_particles_allocate_emission_buffer(Particles *particles) void ParticlesStorage::_particles_ensure_unused_emission_buffer(Particles *particles) { if (particles->unused_emission_storage_buffer.is_null()) { - particles->unused_emission_storage_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4); + // For rendering devices that do not support empty arrays (like C++), + // we need to size the buffer with at least 1 element. + particles->unused_emission_storage_buffer = RD::get_singleton()->storage_buffer_create(sizeof(ParticleEmissionBuffer)); } } void ParticlesStorage::_particles_ensure_unused_trail_buffer(Particles *particles) { if (particles->unused_trail_storage_buffer.is_null()) { - particles->unused_trail_storage_buffer = RD::get_singleton()->storage_buffer_create(sizeof(uint32_t) * 4); + particles->unused_trail_storage_buffer = RD::get_singleton()->storage_buffer_create(16 * sizeof(float)); // Size of mat4. } }