From ead36fdcc4c2f4115230d044a99113c0943c9efa Mon Sep 17 00:00:00 2001 From: clayjohn Date: Tue, 14 Nov 2023 16:27:10 +0100 Subject: [PATCH] Store ArrayMesh path in RenderingServer for use in error messages --- drivers/gles3/rasterizer_scene_gles3.cpp | 4 +++- drivers/gles3/storage/mesh_storage.cpp | 14 ++++++++++++++ drivers/gles3/storage/mesh_storage.h | 7 ++++++- scene/resources/mesh.cpp | 2 ++ servers/rendering/dummy/storage/mesh_storage.h | 5 ++++- .../forward_clustered/render_forward_clustered.cpp | 4 +++- .../forward_mobile/render_forward_mobile.cpp | 4 +++- .../renderer_rd/storage_rd/mesh_storage.cpp | 14 ++++++++++++++ .../renderer_rd/storage_rd/mesh_storage.h | 5 +++++ servers/rendering/rendering_server_default.h | 3 +++ servers/rendering/storage/mesh_storage.h | 4 +++- servers/rendering_server.h | 3 +++ 12 files changed, 63 insertions(+), 6 deletions(-) diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 205f9a552ef6..620012b31dc3 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -262,7 +262,9 @@ void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material(Geometry GLES3::Mesh::Surface *s = reinterpret_cast(sdcache->surface); if (p_material->shader_data->uses_tangent && !(s->format & RS::ARRAY_FORMAT_TANGENT)) { - WARN_PRINT_ED("Attempting to use a shader that requires tangents with a mesh that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool)."); + String shader_path = p_material->shader_data->path.is_empty() ? "" : "(" + p_material->shader_data->path + ")"; + String mesh_path = mesh_storage->mesh_get_path(p_mesh).is_empty() ? "" : "(" + mesh_storage->mesh_get_path(p_mesh) + ")"; + WARN_PRINT_ED(vformat("Attempting to use a shader %s that requires tangents with a mesh %s that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool).", shader_path, mesh_path)); } } diff --git a/drivers/gles3/storage/mesh_storage.cpp b/drivers/gles3/storage/mesh_storage.cpp index 88ee749ed661..5e9c931bb583 100644 --- a/drivers/gles3/storage/mesh_storage.cpp +++ b/drivers/gles3/storage/mesh_storage.cpp @@ -650,6 +650,20 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { return aabb; } +void MeshStorage::mesh_set_path(RID p_mesh, const String &p_path) { + Mesh *mesh = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL(mesh); + + mesh->path = p_path; +} + +String MeshStorage::mesh_get_path(RID p_mesh) const { + Mesh *mesh = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL_V(mesh, String()); + + return mesh->path; +} + void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) { Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); diff --git a/drivers/gles3/storage/mesh_storage.h b/drivers/gles3/storage/mesh_storage.h index 25b15ab6a68d..6f1171bffe7e 100644 --- a/drivers/gles3/storage/mesh_storage.h +++ b/drivers/gles3/storage/mesh_storage.h @@ -130,6 +130,8 @@ struct Mesh { RID shadow_mesh; HashSet shadow_owners; + String path; + Dependency dependency; }; @@ -292,8 +294,11 @@ class MeshStorage : public RendererMeshStorage { virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override; virtual AABB mesh_get_custom_aabb(RID p_mesh) const override; - virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override; + + virtual void mesh_set_path(RID p_mesh, const String &p_path) override; + virtual String mesh_get_path(RID p_mesh) const override; + virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override; virtual void mesh_clear(RID p_mesh) override; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 6f12539a6db3..0abf87865999 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -1558,6 +1558,7 @@ void ArrayMesh::_create_if_empty() const { mesh = RS::get_singleton()->mesh_create(); RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)blend_shape_mode); RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); + RS::get_singleton()->mesh_set_path(mesh, get_path()); } } @@ -1666,6 +1667,7 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { // we can create it with a single call, which is a lot more efficient and thread friendly mesh = RS::get_singleton()->mesh_create_from_surfaces(surface_data, blend_shapes.size()); RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)blend_shape_mode); + RS::get_singleton()->mesh_set_path(mesh, get_path()); } surfaces.clear(); diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h index 89cccec54b54..df5d45f7e09f 100644 --- a/servers/rendering/dummy/storage/mesh_storage.h +++ b/servers/rendering/dummy/storage/mesh_storage.h @@ -113,8 +113,11 @@ class MeshStorage : public RendererMeshStorage { virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) override {} virtual AABB mesh_get_custom_aabb(RID p_mesh) const override { return AABB(); } - virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override { return AABB(); } + + virtual void mesh_set_path(RID p_mesh, const String &p_path) override {} + virtual String mesh_get_path(RID p_mesh) const override { return String(); } + virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override {} virtual void mesh_clear(RID p_mesh) override; diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 2397249ca54d..9ced52912e3b 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -3722,7 +3722,9 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet uint64_t format = RendererRD::MeshStorage::get_singleton()->mesh_surface_get_format(sdcache->surface); if (p_material->shader_data->uses_tangent && !(format & RS::ARRAY_FORMAT_TANGENT)) { - WARN_PRINT_ED("Attempting to use a shader that requires tangents with a mesh that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool)."); + String shader_path = p_material->shader_data->path.is_empty() ? "" : "(" + p_material->shader_data->path + ")"; + String mesh_path = mesh_storage->mesh_get_path(p_mesh).is_empty() ? "" : "(" + mesh_storage->mesh_get_path(p_mesh) + ")"; + WARN_PRINT_ED(vformat("Attempting to use a shader %s that requires tangents with a mesh %s that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool).", shader_path, mesh_path)); } } diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 462fc4b524fa..737bf16c763b 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -2521,7 +2521,9 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI uint64_t format = RendererRD::MeshStorage::get_singleton()->mesh_surface_get_format(sdcache->surface); if (p_material->shader_data->uses_tangent && !(format & RS::ARRAY_FORMAT_TANGENT)) { - WARN_PRINT_ED("Attempting to use a shader that requires tangents with a mesh that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool)."); + String shader_path = p_material->shader_data->path.is_empty() ? "" : "(" + p_material->shader_data->path + ")"; + String mesh_path = mesh_storage->mesh_get_path(p_mesh).is_empty() ? "" : "(" + mesh_storage->mesh_get_path(p_mesh) + ")"; + WARN_PRINT_ED(vformat("Attempting to use a shader %s that requires tangents with a mesh %s that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool).", shader_path, mesh_path)); } } diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index da55b68109ae..8cd1c46864dd 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -753,6 +753,20 @@ AABB MeshStorage::mesh_get_aabb(RID p_mesh, RID p_skeleton) { return aabb; } +void MeshStorage::mesh_set_path(RID p_mesh, const String &p_path) { + Mesh *mesh = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL(mesh); + + mesh->path = p_path; +} + +String MeshStorage::mesh_get_path(RID p_mesh) const { + Mesh *mesh = mesh_owner.get_or_null(p_mesh); + ERR_FAIL_NULL_V(mesh, String()); + + return mesh->path; +} + void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) { Mesh *mesh = mesh_owner.get_or_null(p_mesh); ERR_FAIL_NULL(mesh); diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index db54816e0910..9b21d9ab675f 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -157,6 +157,8 @@ class MeshStorage : public RendererMeshStorage { RID shadow_mesh; HashSet shadow_owners; + String path; + Dependency dependency; }; @@ -373,6 +375,9 @@ class MeshStorage : public RendererMeshStorage { virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) override; virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) override; + virtual void mesh_set_path(RID p_mesh, const String &p_path) override; + virtual String mesh_get_path(RID p_mesh) const override; + virtual void mesh_clear(RID p_mesh) override; virtual bool mesh_needs_instance(RID p_mesh, bool p_has_skeleton) override; diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index cd5904f17579..9fcf7b2ea9fa 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -315,6 +315,9 @@ class RenderingServerDefault : public RenderingServer { FUNC2(mesh_set_custom_aabb, RID, const AABB &) FUNC1RC(AABB, mesh_get_custom_aabb, RID) + FUNC2(mesh_set_path, RID, const String &) + FUNC1RC(String, mesh_get_path, RID) + FUNC2(mesh_set_shadow_mesh, RID, RID) FUNC1(mesh_clear, RID) diff --git a/servers/rendering/storage/mesh_storage.h b/servers/rendering/storage/mesh_storage.h index 76e46a696a69..3c1b2b495d4b 100644 --- a/servers/rendering/storage/mesh_storage.h +++ b/servers/rendering/storage/mesh_storage.h @@ -67,9 +67,11 @@ class RendererMeshStorage { virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0; virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0; - virtual AABB mesh_get_aabb(RID p_mesh, RID p_skeleton = RID()) = 0; + virtual void mesh_set_path(RID p_mesh, const String &p_path) = 0; + virtual String mesh_get_path(RID p_mesh) const = 0; + virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) = 0; virtual void mesh_clear(RID p_mesh) = 0; diff --git a/servers/rendering_server.h b/servers/rendering_server.h index fbc67fc84dfc..6ae870a7f42f 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -381,6 +381,9 @@ class RenderingServer : public Object { virtual void mesh_set_custom_aabb(RID p_mesh, const AABB &p_aabb) = 0; virtual AABB mesh_get_custom_aabb(RID p_mesh) const = 0; + virtual void mesh_set_path(RID p_mesh, const String &p_path) = 0; + virtual String mesh_get_path(RID p_mesh) const = 0; + virtual void mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) = 0; virtual void mesh_clear(RID p_mesh) = 0;