Browse Source

Merge pull request #65068 from BastiaanOlij/fix_dummy_mesh_allocation

Rémi Verschelde 3 years ago
parent
commit
c1b178be38

+ 55 - 2
servers/rendering/dummy/rasterizer_scene_dummy.h

@@ -31,12 +31,65 @@
 #ifndef RASTERIZER_SCENE_DUMMY_H
 #define RASTERIZER_SCENE_DUMMY_H
 
+#include "core/templates/paged_allocator.h"
 #include "servers/rendering/renderer_scene_render.h"
+#include "storage/utilities.h"
 
 class RasterizerSceneDummy : public RendererSceneRender {
 public:
-	RenderGeometryInstance *geometry_instance_create(RID p_base) override { return nullptr; }
-	void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override {}
+	class GeometryInstanceDummy : public RenderGeometryInstance {
+	public:
+		GeometryInstanceDummy() {}
+
+		virtual void _mark_dirty() override {}
+
+		virtual void set_skeleton(RID p_skeleton) override {}
+		virtual void set_material_override(RID p_override) override {}
+		virtual void set_material_overlay(RID p_overlay) override {}
+		virtual void set_surface_materials(const Vector<RID> &p_materials) override {}
+		virtual void set_mesh_instance(RID p_mesh_instance) override {}
+		virtual void set_transform(const Transform3D &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) override {}
+		virtual void set_lod_bias(float p_lod_bias) override {}
+		virtual void set_layer_mask(uint32_t p_layer_mask) override {}
+		virtual void set_fade_range(bool p_enable_near, float p_near_begin, float p_near_end, bool p_enable_far, float p_far_begin, float p_far_end) override {}
+		virtual void set_parent_fade_alpha(float p_alpha) override {}
+		virtual void set_transparency(float p_transparency) override {}
+		virtual void set_use_baked_light(bool p_enable) override {}
+		virtual void set_use_dynamic_gi(bool p_enable) override {}
+		virtual void set_use_lightmap(RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) override {}
+		virtual void set_lightmap_capture(const Color *p_sh9) override {}
+		virtual void set_instance_shader_uniforms_offset(int32_t p_offset) override {}
+		virtual void set_cast_double_sided_shadows(bool p_enable) override {}
+
+		virtual Transform3D get_transform() override { return Transform3D(); }
+		virtual AABB get_aabb() override { return AABB(); }
+
+		virtual void pair_light_instances(const RID *p_light_instances, uint32_t p_light_instance_count) override {}
+		virtual void pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) override {}
+		virtual void pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) override {}
+		virtual void pair_voxel_gi_instances(const RID *p_voxel_gi_instances, uint32_t p_voxel_gi_instance_count) override {}
+
+		virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override {}
+	};
+
+	PagedAllocator<GeometryInstanceDummy> geometry_instance_alloc;
+
+public:
+	RenderGeometryInstance *geometry_instance_create(RID p_base) override {
+		RS::InstanceType type = RendererDummy::Utilities::get_singleton()->get_base_type(p_base);
+		ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
+
+		GeometryInstanceDummy *ginstance = geometry_instance_alloc.alloc();
+
+		return ginstance;
+	}
+
+	void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) override {
+		GeometryInstanceDummy *ginstance = static_cast<GeometryInstanceDummy *>(p_geometry_instance);
+		ERR_FAIL_COND(!ginstance);
+
+		geometry_instance_alloc.free(ginstance);
+	}
 
 	uint32_t geometry_instance_get_pair_mask() override { return 0; }
 

+ 58 - 0
servers/rendering/dummy/storage/mesh_storage.cpp

@@ -0,0 +1,58 @@
+/*************************************************************************/
+/*  mesh_storage.cpp                                                     */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "mesh_storage.h"
+
+using namespace RendererDummy;
+
+MeshStorage *MeshStorage::singleton = nullptr;
+
+MeshStorage::MeshStorage() {
+	singleton = this;
+}
+
+MeshStorage::~MeshStorage() {
+	singleton = nullptr;
+}
+
+RID MeshStorage::mesh_allocate() {
+	return mesh_owner.allocate_rid();
+}
+
+void MeshStorage::mesh_initialize(RID p_rid) {
+	mesh_owner.initialize_rid(p_rid, DummyMesh());
+}
+
+void MeshStorage::mesh_free(RID p_rid) {
+	DummyMesh *mesh = mesh_owner.get_or_null(p_rid);
+	ERR_FAIL_COND(!mesh);
+
+	mesh_owner.free(p_rid);
+}

+ 16 - 9
servers/rendering/dummy/storage/mesh_storage.h

@@ -31,14 +31,17 @@
 #ifndef MESH_STORAGE_DUMMY_H
 #define MESH_STORAGE_DUMMY_H
 
+#include "core/templates/local_vector.h"
+#include "core/templates/rid_owner.h"
 #include "servers/rendering/storage/mesh_storage.h"
-#include "servers/rendering/storage/utilities.h"
 
 namespace RendererDummy {
 
 class MeshStorage : public RendererMeshStorage {
 private:
-	struct DummyMesh : public RID {
+	static MeshStorage *singleton;
+
+	struct DummyMesh {
 		Vector<RS::SurfaceData> surfaces;
 		int blend_shape_count;
 		RS::BlendShapeMode blend_shape_mode;
@@ -48,16 +51,20 @@ private:
 	mutable RID_Owner<DummyMesh> mesh_owner;
 
 public:
+	static MeshStorage *get_singleton() {
+		return singleton;
+	};
+
+	MeshStorage();
+	~MeshStorage();
+
 	/* MESH API */
 
-	virtual RID mesh_allocate() override {
-		return mesh_owner.allocate_rid();
-	}
+	bool owns_mesh(RID p_rid) { return mesh_owner.owns(p_rid); };
 
-	virtual void mesh_initialize(RID p_rid) override {
-		mesh_owner.initialize_rid(p_rid, DummyMesh());
-	}
-	virtual void mesh_free(RID p_rid) override {}
+	virtual RID mesh_allocate() override;
+	virtual void mesh_initialize(RID p_rid) override;
+	virtual void mesh_free(RID p_rid) override;
 
 	virtual void mesh_set_blend_shape_count(RID p_mesh, int p_blend_shape_count) override {}
 	virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override { return false; }

+ 0 - 1
servers/rendering/dummy/storage/texture_storage.h

@@ -69,7 +69,6 @@ public:
 
 	/* Texture API */
 
-	DummyTexture *get_texture(RID p_rid) { return texture_owner.get_or_null(p_rid); };
 	bool owns_texture(RID p_rid) { return texture_owner.owns(p_rid); };
 
 	virtual RID texture_allocate() override {

+ 43 - 0
servers/rendering/dummy/storage/utilities.cpp

@@ -0,0 +1,43 @@
+/*************************************************************************/
+/*  utilities.cpp                                                        */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "utilities.h"
+
+using namespace RendererDummy;
+
+Utilities *Utilities::singleton = nullptr;
+
+Utilities::Utilities() {
+	singleton = this;
+}
+
+Utilities::~Utilities() {
+	singleton = nullptr;
+}

+ 19 - 1
servers/rendering/dummy/storage/utilities.h

@@ -31,20 +31,38 @@
 #ifndef UTILITIES_DUMMY_H
 #define UTILITIES_DUMMY_H
 
+#include "mesh_storage.h"
 #include "servers/rendering/storage/utilities.h"
 #include "texture_storage.h"
 
 namespace RendererDummy {
 
 class Utilities : public RendererUtilities {
+private:
+	static Utilities *singleton;
+
 public:
+	static Utilities *get_singleton() { return singleton; }
+
+	Utilities();
+	~Utilities();
+
 	/* INSTANCES */
 
-	virtual RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; }
+	virtual RS::InstanceType get_base_type(RID p_rid) const override {
+		if (RendererDummy::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
+			return RS::INSTANCE_MESH;
+		}
+		return RS::INSTANCE_NONE;
+	}
+
 	virtual bool free(RID p_rid) override {
 		if (RendererDummy::TextureStorage::get_singleton()->owns_texture(p_rid)) {
 			RendererDummy::TextureStorage::get_singleton()->texture_free(p_rid);
 			return true;
+		} else if (RendererDummy::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
+			RendererDummy::MeshStorage::get_singleton()->mesh_free(p_rid);
+			return true;
 		}
 		return false;
 	}

+ 32 - 0
servers/rendering/renderer_scene_cull.cpp

@@ -637,6 +637,8 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
 				instance->base_data = geom;
 				geom->geometry_instance = scene_render->geometry_instance_create(p_base);
 
+				ERR_FAIL_NULL(geom->geometry_instance);
+
 				geom->geometry_instance->set_skeleton(instance->skeleton);
 				geom->geometry_instance->set_material_override(instance->material_override);
 				geom->geometry_instance->set_material_overlay(instance->material_overlay);
@@ -836,6 +838,7 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
 
 	if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
 		InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+		ERR_FAIL_NULL(geom->geometry_instance);
 		geom->geometry_instance->set_layer_mask(p_mask);
 	}
 }
@@ -848,6 +851,7 @@ void RendererSceneCull::instance_geometry_set_transparency(RID p_instance, float
 
 	if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
 		InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+		ERR_FAIL_NULL(geom->geometry_instance);
 		geom->geometry_instance->set_transparency(p_transparency);
 	}
 }
@@ -1009,6 +1013,7 @@ void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton)
 		_instance_update_mesh_instance(instance);
 
 		InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+		ERR_FAIL_NULL(geom->geometry_instance);
 		geom->geometry_instance->set_skeleton(p_skeleton);
 	}
 }
@@ -1129,6 +1134,7 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF
 
 			if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
 				InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+				ERR_FAIL_NULL(geom->geometry_instance);
 				geom->geometry_instance->set_use_baked_light(p_enabled);
 			}
 
@@ -1149,6 +1155,7 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF
 
 			if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
 				InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+				ERR_FAIL_NULL(geom->geometry_instance);
 				geom->geometry_instance->set_use_dynamic_gi(p_enabled);
 			}
 
@@ -1207,6 +1214,8 @@ void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instanc
 
 	if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
 		InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+		ERR_FAIL_NULL(geom->geometry_instance);
+
 		geom->geometry_instance->set_cast_double_sided_shadows(instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED);
 	}
 
@@ -1222,6 +1231,7 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance,
 
 	if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
 		InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+		ERR_FAIL_NULL(geom->geometry_instance);
 		geom->geometry_instance->set_material_override(p_material);
 	}
 }
@@ -1235,6 +1245,7 @@ void RendererSceneCull::instance_geometry_set_material_overlay(RID p_instance, R
 
 	if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
 		InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+		ERR_FAIL_NULL(geom->geometry_instance);
 		geom->geometry_instance->set_material_overlay(p_material);
 	}
 }
@@ -1407,6 +1418,7 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig
 
 	if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
 		InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+		ERR_FAIL_NULL(geom->geometry_instance);
 		geom->geometry_instance->set_use_lightmap(lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index);
 	}
 }
@@ -1419,6 +1431,7 @@ void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_l
 
 	if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
 		InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+		ERR_FAIL_NULL(geom->geometry_instance);
 		geom->geometry_instance->set_lod_bias(p_lod_bias);
 	}
 }
@@ -1587,10 +1600,12 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
 			if (!p_instance->lightmap_sh.is_empty()) {
 				p_instance->lightmap_sh.clear(); //don't need SH
 				p_instance->lightmap_target_sh.clear(); //don't need SH
+				ERR_FAIL_NULL(geom->geometry_instance);
 				geom->geometry_instance->set_lightmap_capture(nullptr);
 			}
 		}
 
+		ERR_FAIL_NULL(geom->geometry_instance);
 		geom->geometry_instance->set_transform(p_instance->transform, p_instance->aabb, p_instance->transformed_aabb);
 	}
 
@@ -1817,6 +1832,7 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) {
 	if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
 		// Clear these now because the InstanceData containing the dirty flags is gone
 		InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+		ERR_FAIL_NULL(geom->geometry_instance);
 
 		geom->geometry_instance->pair_light_instances(nullptr, 0);
 		geom->geometry_instance->pair_reflection_probe_instances(nullptr, 0);
@@ -1990,6 +2006,7 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance)
 		}
 	}
 
+	ERR_FAIL_NULL(geom->geometry_instance);
 	geom->geometry_instance->set_lightmap_capture(p_instance->lightmap_sh.ptr());
 }
 
@@ -2757,6 +2774,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
 							}
 						}
 
+						ERR_FAIL_NULL(geom->geometry_instance);
 						geom->geometry_instance->pair_light_instances(instance_pair_buffer, idx);
 						idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY);
 					}
@@ -2764,6 +2782,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
 					if (idata.flags & InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY) {
 						InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
 
+						ERR_FAIL_NULL(geom->geometry_instance);
 						geom->geometry_instance->set_softshadow_projector_pairing(geom->softshadow_count > 0, geom->projector_count > 0);
 						idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_PROJECTOR_SOFTSHADOW_DIRTY);
 					}
@@ -2781,6 +2800,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
 							}
 						}
 
+						ERR_FAIL_NULL(geom->geometry_instance);
 						geom->geometry_instance->pair_reflection_probe_instances(instance_pair_buffer, idx);
 						idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY);
 					}
@@ -2797,7 +2817,10 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
 								break;
 							}
 						}
+
+						ERR_FAIL_NULL(geom->geometry_instance);
 						geom->geometry_instance->pair_decal_instances(instance_pair_buffer, idx);
+
 						idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY);
 					}
 
@@ -2813,7 +2836,9 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
 							}
 						}
 
+						ERR_FAIL_NULL(geom->geometry_instance);
 						geom->geometry_instance->pair_voxel_gi_instances(instance_pair_buffer, idx);
+
 						idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY);
 					}
 
@@ -2824,6 +2849,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
 						for (uint32_t j = 0; j < 9; j++) {
 							sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed));
 						}
+						ERR_FAIL_NULL(geom->geometry_instance);
 						geom->geometry_instance->set_lightmap_capture(sh);
 						idata.instance->last_frame_pass = frame_number;
 					}
@@ -3588,11 +3614,13 @@ void RendererSceneCull::render_probes() {
 					}
 				}
 
+				ERR_FAIL_NULL(geom->geometry_instance);
 				geom->geometry_instance->pair_voxel_gi_instances(instance_pair_buffer, idx);
 
 				ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY);
 			}
 
+			ERR_FAIL_NULL(geom->geometry_instance);
 			scene_cull_result.geometry_instances.push_back(geom->geometry_instance);
 		}
 
@@ -3633,6 +3661,7 @@ void RendererSceneCull::render_particle_colliders() {
 					continue;
 				}
 				InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
+				ERR_FAIL_NULL(geom->geometry_instance);
 				scene_cull_result.geometry_instances.push_back(geom->geometry_instance);
 			}
 
@@ -3851,6 +3880,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
 				p_instance->instance_allocated_shader_uniforms = (p_instance->instance_shader_uniforms.size() > 0);
 				if (p_instance->instance_allocated_shader_uniforms) {
 					p_instance->instance_allocated_shader_uniforms_offset = RSG::material_storage->global_shader_uniforms_instance_allocate(p_instance->self);
+					ERR_FAIL_NULL(geom->geometry_instance);
 					geom->geometry_instance->set_instance_shader_uniforms_offset(p_instance->instance_allocated_shader_uniforms_offset);
 
 					for (const KeyValue<StringName, Instance::InstanceShaderParameter> &E : p_instance->instance_shader_uniforms) {
@@ -3861,6 +3891,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
 				} else {
 					RSG::material_storage->global_shader_uniforms_instance_free(p_instance->self);
 					p_instance->instance_allocated_shader_uniforms_offset = -1;
+					ERR_FAIL_NULL(geom->geometry_instance);
 					geom->geometry_instance->set_instance_shader_uniforms_offset(-1);
 				}
 			}
@@ -3874,6 +3905,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
 
 		if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
 			InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
+			ERR_FAIL_NULL(geom->geometry_instance);
 			geom->geometry_instance->set_surface_materials(p_instance->materials);
 		}
 	}