Browse Source

Metal: Fix crash when uniform set is empty for slot binding mode

Co-authored-by: Hugo Locurcio <[email protected]>
Stuart Carnie 8 months ago
parent
commit
b643599749

+ 6 - 1
drivers/metal/metal_objects.mm

@@ -56,6 +56,10 @@
 
 #import <os/signpost.h>
 
+// 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];
 

+ 4 - 2
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.
 	}
 }