Răsfoiți Sursa

Fix LightmapGI causes crash when using --headless

Fixes #89119

Add dummy LightmapInstance and Lightmap resources for headless rendering

Prevents the RenderingServer from crashing when it accesses
lightmap_instance->base_data
Jamie Pate 11 luni în urmă
părinte
comite
f8c99efc3b

+ 86 - 0
servers/rendering/dummy/storage/light_storage.cpp

@@ -0,0 +1,86 @@
+/**************************************************************************/
+/*  light_storage.cpp                                                     */
+/**************************************************************************/
+/*                         This file is part of:                          */
+/*                             GODOT ENGINE                               */
+/*                        https://godotengine.org                         */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
+/*                                                                        */
+/* 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 "light_storage.h"
+
+using namespace RendererDummy;
+
+LightStorage *LightStorage::singleton = nullptr;
+
+LightStorage *LightStorage::get_singleton() {
+	return singleton;
+}
+
+LightStorage::LightStorage() {
+	singleton = this;
+}
+
+LightStorage::~LightStorage() {
+	singleton = nullptr;
+}
+
+bool LightStorage::free(RID p_rid) {
+	if (owns_lightmap(p_rid)) {
+		lightmap_free(p_rid);
+		return true;
+	} else if (owns_lightmap_instance(p_rid)) {
+		lightmap_instance_free(p_rid);
+		return true;
+	}
+
+	return false;
+}
+
+/* LIGHTMAP API */
+
+RID LightStorage::lightmap_allocate() {
+	return lightmap_owner.allocate_rid();
+}
+
+void LightStorage::lightmap_initialize(RID p_lightmap) {
+	lightmap_owner.initialize_rid(p_lightmap, Lightmap());
+}
+
+void LightStorage::lightmap_free(RID p_rid) {
+	lightmap_set_textures(p_rid, RID(), false);
+	lightmap_owner.free(p_rid);
+}
+
+/* LIGHTMAP INSTANCE */
+
+RID LightStorage::lightmap_instance_create(RID p_lightmap) {
+	LightmapInstance li;
+	li.lightmap = p_lightmap;
+	return lightmap_instance_owner.make_rid(li);
+}
+
+void LightStorage::lightmap_instance_free(RID p_lightmap) {
+	lightmap_instance_owner.free(p_lightmap);
+}

+ 31 - 5
servers/rendering/dummy/storage/light_storage.h

@@ -36,7 +36,29 @@
 namespace RendererDummy {
 namespace RendererDummy {
 
 
 class LightStorage : public RendererLightStorage {
 class LightStorage : public RendererLightStorage {
+private:
+	static LightStorage *singleton;
+	/* LIGHTMAP */
+	struct Lightmap {
+		// dummy lightmap, no data
+	};
+
+	mutable RID_Owner<Lightmap, true> lightmap_owner;
+	/* LIGHTMAP INSTANCE */
+
+	struct LightmapInstance {
+		RID lightmap;
+	};
+
+	mutable RID_Owner<LightmapInstance> lightmap_instance_owner;
+
 public:
 public:
+	static LightStorage *get_singleton();
+
+	LightStorage();
+	virtual ~LightStorage();
+
+	bool free(RID p_rid);
 	/* Light API */
 	/* Light API */
 
 
 	virtual RID directional_light_allocate() override { return RID(); }
 	virtual RID directional_light_allocate() override { return RID(); }
@@ -146,9 +168,11 @@ public:
 
 
 	/* LIGHTMAP CAPTURE */
 	/* LIGHTMAP CAPTURE */
 
 
-	virtual RID lightmap_allocate() override { return RID(); }
-	virtual void lightmap_initialize(RID p_rid) override {}
-	virtual void lightmap_free(RID p_rid) override {}
+	bool owns_lightmap(RID p_rid) { return lightmap_owner.owns(p_rid); }
+
+	virtual RID lightmap_allocate() override;
+	virtual void lightmap_initialize(RID p_rid) override;
+	virtual void lightmap_free(RID p_rid) override;
 
 
 	virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override {}
 	virtual void lightmap_set_textures(RID p_lightmap, RID p_light, bool p_uses_spherical_haromics) override {}
 	virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override {}
 	virtual void lightmap_set_probe_bounds(RID p_lightmap, const AABB &p_bounds) override {}
@@ -167,8 +191,10 @@ public:
 
 
 	/* LIGHTMAP INSTANCE */
 	/* LIGHTMAP INSTANCE */
 
 
-	RID lightmap_instance_create(RID p_lightmap) override { return RID(); }
-	void lightmap_instance_free(RID p_lightmap) override {}
+	bool owns_lightmap_instance(RID p_rid) { return lightmap_instance_owner.owns(p_rid); }
+
+	RID lightmap_instance_create(RID p_lightmap) override;
+	void lightmap_instance_free(RID p_lightmap) override;
 	void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override {}
 	void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override {}
 
 
 	/* SHADOW ATLAS API */
 	/* SHADOW ATLAS API */

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

@@ -31,6 +31,7 @@
 #ifndef UTILITIES_DUMMY_H
 #ifndef UTILITIES_DUMMY_H
 #define UTILITIES_DUMMY_H
 #define UTILITIES_DUMMY_H
 
 
+#include "light_storage.h"
 #include "material_storage.h"
 #include "material_storage.h"
 #include "mesh_storage.h"
 #include "mesh_storage.h"
 #include "servers/rendering/storage/utilities.h"
 #include "servers/rendering/storage/utilities.h"
@@ -55,12 +56,16 @@ public:
 			return RS::INSTANCE_MESH;
 			return RS::INSTANCE_MESH;
 		} else if (RendererDummy::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
 		} else if (RendererDummy::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
 			return RS::INSTANCE_MULTIMESH;
 			return RS::INSTANCE_MULTIMESH;
+		} else if (RendererDummy::LightStorage::get_singleton()->owns_lightmap(p_rid)) {
+			return RS::INSTANCE_LIGHTMAP;
 		}
 		}
 		return RS::INSTANCE_NONE;
 		return RS::INSTANCE_NONE;
 	}
 	}
 
 
 	virtual bool free(RID p_rid) override {
 	virtual bool free(RID p_rid) override {
-		if (RendererDummy::TextureStorage::get_singleton()->owns_texture(p_rid)) {
+		if (RendererDummy::LightStorage::get_singleton()->free(p_rid)) {
+			return true;
+		} else if (RendererDummy::TextureStorage::get_singleton()->owns_texture(p_rid)) {
 			RendererDummy::TextureStorage::get_singleton()->texture_free(p_rid);
 			RendererDummy::TextureStorage::get_singleton()->texture_free(p_rid);
 			return true;
 			return true;
 		} else if (RendererDummy::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
 		} else if (RendererDummy::MeshStorage::get_singleton()->owns_mesh(p_rid)) {