diff options
Diffstat (limited to 'servers')
30 files changed, 366 insertions, 129 deletions
diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 39f14439f4..2d65cea432 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -344,7 +344,6 @@ DisplayServer::MouseMode DisplayServer::mouse_get_mode() const { } void DisplayServer::warp_mouse(const Point2i &p_position) { - WARN_PRINT("Mouse warping is not supported by this display server."); } Point2i DisplayServer::mouse_get_position() const { @@ -572,7 +571,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("global_menu_add_icon_check_item", "menu_root", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("global_menu_add_radio_check_item", "menu_root", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_radio_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("global_menu_add_icon_radio_check_item", "menu_root", "icon", "label", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_icon_radio_check_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); - ClassDB::bind_method(D_METHOD("global_menu_add_multistate_item", "menu_root", "labe", "max_states", "default_state", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_multistate_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("global_menu_add_multistate_item", "menu_root", "label", "max_states", "default_state", "callback", "key_callback", "tag", "accelerator", "index"), &DisplayServer::global_menu_add_multistate_item, DEFVAL(Callable()), DEFVAL(Callable()), DEFVAL(Variant()), DEFVAL(Key::NONE), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("global_menu_add_separator", "menu_root", "index"), &DisplayServer::global_menu_add_separator, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("global_menu_get_item_index_from_text", "menu_root", "text"), &DisplayServer::global_menu_get_item_index_from_text); diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index 943b2ae467..2e4087c1de 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -81,35 +81,12 @@ NavigationServer2D *NavigationServer2D::singleton = nullptr; return CONV_R(NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1))); \ } -#define FORWARD_4(FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, CONV_0, CONV_1, CONV_2, CONV_3) \ - NavigationServer2D::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) { \ - return NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3)); \ - } - -#define FORWARD_4_R_C(CONV_R, FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, CONV_0, CONV_1, CONV_2, CONV_3) \ - NavigationServer2D::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) \ - const { \ - return CONV_R(NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3))); \ - } - -#define FORWARD_4_C(FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, CONV_0, CONV_1, CONV_2, CONV_3) \ - NavigationServer2D::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3) \ - const { \ - return NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3)); \ - } - #define FORWARD_5_R_C(CONV_R, FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, T_4, D_4, CONV_0, CONV_1, CONV_2, CONV_3, CONV_4) \ NavigationServer2D::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3, T_4 D_4) \ const { \ return CONV_R(NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3), CONV_4(D_4))); \ } -#define FORWARD_5_C(FUNC_NAME, T_0, D_0, T_1, D_1, T_2, D_2, T_3, D_3, T_4, D_4, CONV_0, CONV_1, CONV_2, CONV_3, CONV_4) \ - NavigationServer2D::FUNC_NAME(T_0 D_0, T_1 D_1, T_2 D_2, T_3 D_3, T_4 D_4) \ - const { \ - return NavigationServer3D::get_singleton()->FUNC_NAME(CONV_0(D_0), CONV_1(D_1), CONV_2(D_2), CONV_3(D_3), CONV_4(D_4)); \ - } - static RID rid_to_rid(const RID d) { return d; } @@ -155,18 +132,14 @@ static Transform3D trf2_to_trf3(const Transform2D &d) { return Transform3D(b, o); } -static StringName sn_to_sn(const StringName &d) { - return d; -} - -static Variant var_to_var(const Variant &d) { - return d; -} - static ObjectID id_to_id(const ObjectID &id) { return id; } +static Callable callable_to_callable(const Callable &c) { + return c; +} + static Ref<NavigationMesh> poly_to_mesh(Ref<NavigationPolygon> d) { if (d.is_valid()) { return d->get_navigation_mesh(); @@ -285,10 +258,10 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("link_is_bidirectional", "link"), &NavigationServer2D::link_is_bidirectional); ClassDB::bind_method(D_METHOD("link_set_navigation_layers", "link", "navigation_layers"), &NavigationServer2D::link_set_navigation_layers); ClassDB::bind_method(D_METHOD("link_get_navigation_layers", "link"), &NavigationServer2D::link_get_navigation_layers); - ClassDB::bind_method(D_METHOD("link_set_start_location", "link", "location"), &NavigationServer2D::link_set_start_location); - ClassDB::bind_method(D_METHOD("link_get_start_location", "link"), &NavigationServer2D::link_get_start_location); - ClassDB::bind_method(D_METHOD("link_set_end_location", "link", "location"), &NavigationServer2D::link_set_end_location); - ClassDB::bind_method(D_METHOD("link_get_end_location", "link"), &NavigationServer2D::link_get_end_location); + ClassDB::bind_method(D_METHOD("link_set_start_position", "link", "position"), &NavigationServer2D::link_set_start_position); + ClassDB::bind_method(D_METHOD("link_get_start_position", "link"), &NavigationServer2D::link_get_start_position); + ClassDB::bind_method(D_METHOD("link_set_end_position", "link", "position"), &NavigationServer2D::link_set_end_position); + ClassDB::bind_method(D_METHOD("link_get_end_position", "link"), &NavigationServer2D::link_get_end_position); ClassDB::bind_method(D_METHOD("link_set_enter_cost", "link", "enter_cost"), &NavigationServer2D::link_set_enter_cost); ClassDB::bind_method(D_METHOD("link_get_enter_cost", "link"), &NavigationServer2D::link_get_enter_cost); ClassDB::bind_method(D_METHOD("link_set_travel_cost", "link", "travel_cost"), &NavigationServer2D::link_set_travel_cost); @@ -308,7 +281,7 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("agent_set_target_velocity", "agent", "target_velocity"), &NavigationServer2D::agent_set_target_velocity); ClassDB::bind_method(D_METHOD("agent_set_position", "agent", "position"), &NavigationServer2D::agent_set_position); ClassDB::bind_method(D_METHOD("agent_is_map_changed", "agent"), &NavigationServer2D::agent_is_map_changed); - ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "object_id", "method", "userdata"), &NavigationServer2D::agent_set_callback, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "callback"), &NavigationServer2D::agent_set_callback); ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer2D::free); @@ -392,10 +365,10 @@ void FORWARD_2(link_set_bidirectional, RID, p_link, bool, p_bidirectional, rid_t bool FORWARD_1_C(link_is_bidirectional, RID, p_link, rid_to_rid); void FORWARD_2(link_set_navigation_layers, RID, p_link, uint32_t, p_navigation_layers, rid_to_rid, uint32_to_uint32); uint32_t FORWARD_1_C(link_get_navigation_layers, RID, p_link, rid_to_rid); -void FORWARD_2(link_set_start_location, RID, p_link, Vector2, p_location, rid_to_rid, v2_to_v3); -Vector2 FORWARD_1_R_C(v3_to_v2, link_get_start_location, RID, p_link, rid_to_rid); -void FORWARD_2(link_set_end_location, RID, p_link, Vector2, p_location, rid_to_rid, v2_to_v3); -Vector2 FORWARD_1_R_C(v3_to_v2, link_get_end_location, RID, p_link, rid_to_rid); +void FORWARD_2(link_set_start_position, RID, p_link, Vector2, p_position, rid_to_rid, v2_to_v3); +Vector2 FORWARD_1_R_C(v3_to_v2, link_get_start_position, RID, p_link, rid_to_rid); +void FORWARD_2(link_set_end_position, RID, p_link, Vector2, p_position, rid_to_rid, v2_to_v3); +Vector2 FORWARD_1_R_C(v3_to_v2, link_get_end_position, RID, p_link, rid_to_rid); void FORWARD_2(link_set_enter_cost, RID, p_link, real_t, p_enter_cost, rid_to_rid, real_to_real); real_t FORWARD_1_C(link_get_enter_cost, RID, p_link, rid_to_rid); void FORWARD_2(link_set_travel_cost, RID, p_link, real_t, p_travel_cost, rid_to_rid, real_to_real); @@ -420,7 +393,7 @@ void FORWARD_2(agent_set_target_velocity, RID, p_agent, Vector2, p_velocity, rid void FORWARD_2(agent_set_position, RID, p_agent, Vector2, p_position, rid_to_rid, v2_to_v3); void FORWARD_2(agent_set_ignore_y, RID, p_agent, bool, p_ignore, rid_to_rid, bool_to_bool); bool FORWARD_1_C(agent_is_map_changed, RID, p_agent, rid_to_rid); -void FORWARD_4(agent_set_callback, RID, p_agent, ObjectID, p_object_id, StringName, p_method, Variant, p_udata, rid_to_rid, id_to_id, sn_to_sn, var_to_var); +void FORWARD_2(agent_set_callback, RID, p_agent, Callable, p_callback, rid_to_rid, callable_to_callable); void FORWARD_1(free, RID, p_object, rid_to_rid); diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index 0adf736b2a..cd18476182 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -130,7 +130,7 @@ public: virtual Vector2 region_get_connection_pathway_start(RID p_region, int p_connection_id) const; virtual Vector2 region_get_connection_pathway_end(RID p_region, int p_connection_id) const; - /// Creates a new link between locations in the nav map. + /// Creates a new link between positions in the nav map. virtual RID link_create(); /// Set the map of this link. @@ -145,13 +145,13 @@ public: virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers); virtual uint32_t link_get_navigation_layers(RID p_link) const; - /// Set the start location of the link. - virtual void link_set_start_location(RID p_link, Vector2 p_location); - virtual Vector2 link_get_start_location(RID p_link) const; + /// Set the start position of the link. + virtual void link_set_start_position(RID p_link, Vector2 p_position); + virtual Vector2 link_get_start_position(RID p_link) const; - /// Set the end location of the link. - virtual void link_set_end_location(RID p_link, Vector2 p_location); - virtual Vector2 link_get_end_location(RID p_link) const; + /// Set the end position of the link. + virtual void link_set_end_position(RID p_link, Vector2 p_position); + virtual Vector2 link_get_end_position(RID p_link) const; /// Set the enter cost of the link. virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost); @@ -223,7 +223,7 @@ public: virtual bool agent_is_map_changed(RID p_agent) const; /// Callback called at the end of the RVO process - virtual void agent_set_callback(RID p_agent, ObjectID p_object_id, StringName p_method, Variant p_udata = Variant()); + virtual void agent_set_callback(RID p_agent, Callable p_callback); virtual void query_path(const Ref<NavigationPathQueryParameters2D> &p_query_parameters, Ref<NavigationPathQueryResult2D> p_query_result) const; diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index 253b28a623..5b95317a38 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -90,10 +90,10 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("link_is_bidirectional", "link"), &NavigationServer3D::link_is_bidirectional); ClassDB::bind_method(D_METHOD("link_set_navigation_layers", "link", "navigation_layers"), &NavigationServer3D::link_set_navigation_layers); ClassDB::bind_method(D_METHOD("link_get_navigation_layers", "link"), &NavigationServer3D::link_get_navigation_layers); - ClassDB::bind_method(D_METHOD("link_set_start_location", "link", "location"), &NavigationServer3D::link_set_start_location); - ClassDB::bind_method(D_METHOD("link_get_start_location", "link"), &NavigationServer3D::link_get_start_location); - ClassDB::bind_method(D_METHOD("link_set_end_location", "link", "location"), &NavigationServer3D::link_set_end_location); - ClassDB::bind_method(D_METHOD("link_get_end_location", "link"), &NavigationServer3D::link_get_end_location); + ClassDB::bind_method(D_METHOD("link_set_start_position", "link", "position"), &NavigationServer3D::link_set_start_position); + ClassDB::bind_method(D_METHOD("link_get_start_position", "link"), &NavigationServer3D::link_get_start_position); + ClassDB::bind_method(D_METHOD("link_set_end_position", "link", "position"), &NavigationServer3D::link_set_end_position); + ClassDB::bind_method(D_METHOD("link_get_end_position", "link"), &NavigationServer3D::link_get_end_position); ClassDB::bind_method(D_METHOD("link_set_enter_cost", "link", "enter_cost"), &NavigationServer3D::link_set_enter_cost); ClassDB::bind_method(D_METHOD("link_get_enter_cost", "link"), &NavigationServer3D::link_get_enter_cost); ClassDB::bind_method(D_METHOD("link_set_travel_cost", "link", "travel_cost"), &NavigationServer3D::link_set_travel_cost); @@ -113,7 +113,7 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("agent_set_target_velocity", "agent", "target_velocity"), &NavigationServer3D::agent_set_target_velocity); ClassDB::bind_method(D_METHOD("agent_set_position", "agent", "position"), &NavigationServer3D::agent_set_position); ClassDB::bind_method(D_METHOD("agent_is_map_changed", "agent"), &NavigationServer3D::agent_is_map_changed); - ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "object_id", "method", "userdata"), &NavigationServer3D::agent_set_callback, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("agent_set_callback", "agent", "callback"), &NavigationServer3D::agent_set_callback); ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer3D::free); diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index 6c4bd2e151..9c468d1b10 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -145,7 +145,7 @@ public: virtual Vector3 region_get_connection_pathway_start(RID p_region, int p_connection_id) const = 0; virtual Vector3 region_get_connection_pathway_end(RID p_region, int p_connection_id) const = 0; - /// Creates a new link between locations in the nav map. + /// Creates a new link between positions in the nav map. virtual RID link_create() = 0; /// Set the map of this link. @@ -160,13 +160,13 @@ public: virtual void link_set_navigation_layers(RID p_link, uint32_t p_navigation_layers) = 0; virtual uint32_t link_get_navigation_layers(RID p_link) const = 0; - /// Set the start location of the link. - virtual void link_set_start_location(RID p_link, Vector3 p_location) = 0; - virtual Vector3 link_get_start_location(RID p_link) const = 0; + /// Set the start position of the link. + virtual void link_set_start_position(RID p_link, Vector3 p_position) = 0; + virtual Vector3 link_get_start_position(RID p_link) const = 0; - /// Set the end location of the link. - virtual void link_set_end_location(RID p_link, Vector3 p_location) = 0; - virtual Vector3 link_get_end_location(RID p_link) const = 0; + /// Set the end position of the link. + virtual void link_set_end_position(RID p_link, Vector3 p_position) = 0; + virtual Vector3 link_get_end_position(RID p_link) const = 0; /// Set the enter cost of the link. virtual void link_set_enter_cost(RID p_link, real_t p_enter_cost) = 0; @@ -238,7 +238,7 @@ public: virtual bool agent_is_map_changed(RID p_agent) const = 0; /// Callback called at the end of the RVO process - virtual void agent_set_callback(RID p_agent, ObjectID p_object_id, StringName p_method, Variant p_udata = Variant()) = 0; + virtual void agent_set_callback(RID p_agent, Callable p_callback) = 0; /// Destroy the `RID` virtual void free(RID p_object) = 0; diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h index 2d66c225e8..aba362c956 100644 --- a/servers/rendering/dummy/storage/mesh_storage.h +++ b/servers/rendering/dummy/storage/mesh_storage.h @@ -126,6 +126,7 @@ public: virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override {} virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override {} virtual void mesh_instance_check_for_update(RID p_mesh_instance) override {} + virtual void mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) override {} virtual void update_mesh_instances() override {} /* MULTIMESH API */ diff --git a/servers/rendering/renderer_rd/environment/sky.cpp b/servers/rendering/renderer_rd/environment/sky.cpp index 1dbad79477..814d145b66 100644 --- a/servers/rendering/renderer_rd/environment/sky.cpp +++ b/servers/rendering/renderer_rd/environment/sky.cpp @@ -1648,7 +1648,10 @@ void SkyRD::update_dirty_skys() { tf.mipmaps = MIN(mipmaps, layers); tf.width = w; tf.height = h; - tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT; + tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; + if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) { + tf.usage_bits |= RD::TEXTURE_USAGE_STORAGE_BIT; + } sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView()); 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 ad63d3fd4b..1bba95f511 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -3768,6 +3768,7 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::D case Dependency::DEPENDENCY_CHANGED_MULTIMESH: case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); + static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata)->data->dirty_dependencies = true; } break; case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata); @@ -3782,6 +3783,7 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::D } void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); + static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata)->data->dirty_dependencies = true; } RenderGeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) { diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 412406c0b4..2aaea4288b 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -717,6 +717,8 @@ void SceneShaderForwardClustered::init(const String p_defines) { actions.global_buffer_array_variable = "global_shader_uniforms.data"; actions.instance_uniform_index_variable = "instances.data[instance_index_interp].instance_uniforms_ofs"; + actions.check_multiview_samplers = true; // make sure we check sampling multiview textures + compiler.initialize(actions); } 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 25204f1abf..4065d253bb 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -2237,6 +2237,9 @@ RenderGeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base ginstance->data->base = p_base; ginstance->data->base_type = type; + ginstance->data->dependency_tracker.userdata = ginstance; + ginstance->data->dependency_tracker.changed_callback = _geometry_instance_dependency_changed; + ginstance->data->dependency_tracker.deleted_callback = _geometry_instance_dependency_deleted; ginstance->_mark_dirty(); @@ -2673,6 +2676,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::Depe case Dependency::DEPENDENCY_CHANGED_MULTIMESH: case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: { static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); + static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata)->data->dirty_dependencies = true; } break; case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: { GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata); @@ -2687,6 +2691,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::Depe } void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) { static_cast<RenderGeometryInstance *>(p_tracker->userdata)->_mark_dirty(); + static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata)->data->dirty_dependencies = true; } /* misc */ diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 3d1d78c63d..f9eecf4dc7 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -609,6 +609,7 @@ void SceneShaderForwardMobile::init(const String p_defines) { actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs"; actions.apply_luminance_multiplier = true; // apply luminance multiplier to screen texture + actions.check_multiview_samplers = true; // make sure we check sampling multiview textures compiler.initialize(actions); } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 638fe44266..0f4fa1b9c4 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1431,6 +1431,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p const Item::CommandMesh *cm = static_cast<const Item::CommandMesh *>(c); if (cm->mesh_instance.is_valid()) { mesh_storage->mesh_instance_check_for_update(cm->mesh_instance); + mesh_storage->mesh_instance_set_canvas_item_transform(cm->mesh_instance, canvas_transform_inverse * ci->final_transform); update_skeletons = true; } } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 2a87c4fa8d..33f6ac0276 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -253,6 +253,11 @@ void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderData Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers; ERR_FAIL_COND(rb.is_null()); + if (!rb->has_internal_texture()) { + // We're likely rendering reflection probes where we can't use our backbuffers. + return; + } + RD::get_singleton()->draw_command_begin_label("Copy screen texture"); rb->allocate_blur_textures(); @@ -292,6 +297,11 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers; ERR_FAIL_COND(rb.is_null()); + if (!rb->has_depth_texture()) { + // We're likely rendering reflection probes where we can't use our backbuffers. + return; + } + RD::get_singleton()->draw_command_begin_label("Copy depth texture"); // note, this only creates our back depth texture if we haven't already created it. diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index 91c2000c1a..c6a3c42e57 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -118,13 +118,13 @@ layout(location = 10) out flat uint instance_index_interp; // !BAS! This needs to become an input once we implement our fallback! #define ViewIndex 0 #endif // has_VK_KHR_multiview -vec3 normal_roughness_uv(vec2 uv) { +vec3 multiview_uv(vec2 uv) { return vec3(uv, ViewIndex); } #else // USE_MULTIVIEW // Set to zero, not supported in non stereo #define ViewIndex 0 -vec2 normal_roughness_uv(vec2 uv) { +vec2 multiview_uv(vec2 uv) { return uv; } #endif //USE_MULTIVIEW @@ -550,13 +550,13 @@ layout(location = 10) in flat uint instance_index_interp; // !BAS! This needs to become an input once we implement our fallback! #define ViewIndex 0 #endif // has_VK_KHR_multiview -vec3 normal_roughness_uv(vec2 uv) { +vec3 multiview_uv(vec2 uv) { return vec3(uv, ViewIndex); } #else // USE_MULTIVIEW // Set to zero, not supported in non stereo #define ViewIndex 0 -vec2 normal_roughness_uv(vec2 uv) { +vec2 multiview_uv(vec2 uv) { return uv; } #endif //USE_MULTIVIEW diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl index 1f524313f2..8ff7a784dc 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl @@ -271,15 +271,16 @@ layout(r32ui, set = 1, binding = 13) uniform restrict uimage3D geom_facing_grid; #define multiviewSampler sampler2D #else -layout(set = 1, binding = 10) uniform texture2D depth_buffer; -layout(set = 1, binding = 11) uniform texture2D color_buffer; - #ifdef USE_MULTIVIEW +layout(set = 1, binding = 10) uniform texture2DArray depth_buffer; +layout(set = 1, binding = 11) uniform texture2DArray color_buffer; layout(set = 1, binding = 12) uniform texture2DArray normal_roughness_buffer; layout(set = 1, binding = 14) uniform texture2DArray ambient_buffer; layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer; #define multiviewSampler sampler2DArray #else // USE_MULTIVIEW +layout(set = 1, binding = 10) uniform texture2D depth_buffer; +layout(set = 1, binding = 11) uniform texture2D color_buffer; layout(set = 1, binding = 12) uniform texture2D normal_roughness_buffer; layout(set = 1, binding = 14) uniform texture2D ambient_buffer; layout(set = 1, binding = 15) uniform texture2D reflection_buffer; diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 2966a2ff65..90e902ca33 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -112,9 +112,15 @@ layout(location = 9) out highp float dp_clip; // !BAS! This needs to become an input once we implement our fallback! #define ViewIndex 0 #endif +vec3 multiview_uv(vec2 uv) { + return vec3(uv, ViewIndex); +} #else // Set to zero, not supported in non stereo #define ViewIndex 0 +vec2 multiview_uv(vec2 uv) { + return uv; +} #endif //USE_MULTIVIEW invariant gl_Position; @@ -523,9 +529,15 @@ layout(location = 9) highp in float dp_clip; // !BAS! This needs to become an input once we implement our fallback! #define ViewIndex 0 #endif +vec3 multiview_uv(vec2 uv) { + return vec3(uv, ViewIndex); +} #else // Set to zero, not supported in non stereo #define ViewIndex 0 +vec2 multiview_uv(vec2 uv) { + return uv; +} #endif //USE_MULTIVIEW //defines to keep compatibility with vertex diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl index 631ff0575b..78b39a356d 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl @@ -154,8 +154,15 @@ layout(set = 1, binding = 5) uniform highp texture2D directional_shadow_atlas; // this needs to change to providing just the lightmap we're using.. layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; +#ifdef USE_MULTIVIEW +layout(set = 1, binding = 9) uniform highp texture2DArray depth_buffer; +layout(set = 1, binding = 10) uniform mediump texture2DArray color_buffer; +#define multiviewSampler sampler2DArray +#else layout(set = 1, binding = 9) uniform highp texture2D depth_buffer; layout(set = 1, binding = 10) uniform mediump texture2D color_buffer; +#define multiviewSampler sampler2D +#endif // USE_MULTIVIEW /* Set 2 Skeleton & Instancing (can change per item) */ diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl index f5b233cca0..59c161548c 100644 --- a/servers/rendering/renderer_rd/shaders/skeleton.glsl +++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl @@ -51,6 +51,15 @@ layout(push_constant, std430) uniform Params { bool normalized_blend_shapes; uint pad0; uint pad1; + + vec2 skeleton_transform_x; + vec2 skeleton_transform_y; + + vec2 skeleton_transform_offset; + vec2 inverse_transform_x; + + vec2 inverse_transform_y; + vec2 inverse_transform_offset; } params; @@ -158,8 +167,12 @@ void main() { m += mat4(bone_transforms.data[bones_23.x], bone_transforms.data[bones_23.x + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.x; m += mat4(bone_transforms.data[bones_23.y], bone_transforms.data[bones_23.y + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)) * weights_23.y; - //reverse order because its transposed - vertex = (vec4(vertex, 0.0, 1.0) * m).xy; + mat4 skeleton_matrix = mat4(vec4(params.skeleton_transform_x, 0.0, 0.0), vec4(params.skeleton_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(params.skeleton_transform_offset, 0.0, 1.0)); + mat4 inverse_matrix = mat4(vec4(params.inverse_transform_x, 0.0, 0.0), vec4(params.inverse_transform_y, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(params.inverse_transform_offset, 0.0, 1.0)); + + m = skeleton_matrix * transpose(m) * inverse_matrix; + + vertex = (m * vec4(vertex, 0.0, 1.0)).xy; } uint dst_offset = index * params.vertex_stride; diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp index 33e35a7a64..cdecb3828b 100644 --- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp @@ -1464,7 +1464,6 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_ fb.push_back(atlas->depth_buffer); atlas->depth_fb = RD::get_singleton()->framebuffer_create(fb); - atlas->render_buffers->cleanup(); atlas->render_buffers->configure_for_reflections(Size2i(atlas->size, atlas->size)); } diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index 46a0d85ba8..9124886764 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -842,7 +842,7 @@ void MeshStorage::mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int } void MeshStorage::_mesh_instance_clear(MeshInstance *mi) { - for (const RendererRD::MeshStorage::MeshInstance::Surface surface : mi->surfaces) { + for (const RendererRD::MeshStorage::MeshInstance::Surface &surface : mi->surfaces) { if (surface.versions) { for (uint32_t j = 0; j < surface.version_count; j++) { RD::get_singleton()->free(surface.versions[j].vertex_array); @@ -930,6 +930,11 @@ void MeshStorage::mesh_instance_check_for_update(RID p_mesh_instance) { } } +void MeshStorage::mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) { + MeshInstance *mi = mesh_instance_owner.get_or_null(p_mesh_instance); + mi->canvas_item_transform_2d = p_transform; +} + void MeshStorage::update_mesh_instances() { while (dirty_mesh_instance_weights.first()) { MeshInstance *mi = dirty_mesh_instance_weights.first()->self(); @@ -981,6 +986,22 @@ void MeshStorage::update_mesh_instances() { push_constant.skin_stride = (mi->mesh->surfaces[i]->skin_buffer_size / mi->mesh->surfaces[i]->vertex_count) / 4; push_constant.skin_weight_offset = (mi->mesh->surfaces[i]->format & RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS) ? 4 : 2; + Transform2D transform = mi->canvas_item_transform_2d.affine_inverse() * sk->base_transform_2d; + push_constant.skeleton_transform_x[0] = transform.columns[0][0]; + push_constant.skeleton_transform_x[1] = transform.columns[0][1]; + push_constant.skeleton_transform_y[0] = transform.columns[1][0]; + push_constant.skeleton_transform_y[1] = transform.columns[1][1]; + push_constant.skeleton_transform_offset[0] = transform.columns[2][0]; + push_constant.skeleton_transform_offset[1] = transform.columns[2][1]; + + Transform2D inverse_transform = transform.affine_inverse(); + push_constant.inverse_transform_x[0] = inverse_transform.columns[0][0]; + push_constant.inverse_transform_x[1] = inverse_transform.columns[0][1]; + push_constant.inverse_transform_y[0] = inverse_transform.columns[1][0]; + push_constant.inverse_transform_y[1] = inverse_transform.columns[1][1]; + push_constant.inverse_transform_offset[0] = inverse_transform.columns[2][0]; + push_constant.inverse_transform_offset[1] = inverse_transform.columns[2][1]; + push_constant.blend_shape_count = mi->mesh->blend_shape_count; push_constant.normalized_blend_shapes = mi->mesh->blend_shape_mode == RS::BLEND_SHAPE_MODE_NORMALIZED; push_constant.pad0 = 0; diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index b62da5fd7b..c921523941 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -178,6 +178,7 @@ private: bool weights_dirty = false; SelfList<MeshInstance> weight_update_list; SelfList<MeshInstance> array_update_list; + Transform2D canvas_item_transform_2d; MeshInstance() : weight_update_list(this), array_update_list(this) {} }; @@ -256,6 +257,14 @@ private: uint32_t normalized_blend_shapes; uint32_t pad0; uint32_t pad1; + float skeleton_transform_x[2]; + float skeleton_transform_y[2]; + + float skeleton_transform_offset[2]; + float inverse_transform_x[2]; + + float inverse_transform_y[2]; + float inverse_transform_offset[2]; }; enum { @@ -548,6 +557,7 @@ public: virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) override; virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) override; virtual void mesh_instance_check_for_update(RID p_mesh_instance) override; + virtual void mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) override; virtual void update_mesh_instances() override; /* MULTIMESH API */ diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp index 7771f75a65..255719183f 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.cpp @@ -490,6 +490,16 @@ Ref<RenderBufferCustomDataRD> RenderSceneBuffersRD::get_custom_data(const String // Depth texture +bool RenderSceneBuffersRD::has_depth_texture() { + RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); + RID depth = texture_storage->render_target_get_override_depth(render_target); + if (depth.is_valid()) { + return true; + } else { + return has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH); + } +} + RID RenderSceneBuffersRD::get_depth_texture() { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RID depth = texture_storage->render_target_get_override_depth(render_target); diff --git a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h index dc849fd56a..50fb06c0d9 100644 --- a/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h +++ b/servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h @@ -185,6 +185,9 @@ public: // For our internal textures we provide some easy access methods. + _FORCE_INLINE_ bool has_internal_texture() const { + return has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR); + } _FORCE_INLINE_ RID get_internal_texture() const { return get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR); } @@ -192,6 +195,7 @@ public: return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR, p_layer, 0); } + bool has_depth_texture(); RID get_depth_texture(); RID get_depth_texture(const uint32_t p_layer); diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index 68542f32af..2710724066 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -1173,9 +1173,10 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene code += "("; - // if normal roughness texture is used, we will add logic to automatically switch between + // if color backbuffer, depth backbuffer or normal roughness texture is used, + // we will add logic to automatically switch between // sampler2D and sampler2D array and vec2 UV and vec3 UV. - bool normal_roughness_texture_used = false; + bool multiview_uv_needed = false; for (int i = 1; i < onode->arguments.size(); i++) { if (i > 1) { @@ -1220,8 +1221,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - if (!RS::get_singleton()->is_low_end() && is_texture_func && i == 1) { - //need to map from texture to sampler in order to sample when using Vulkan GLSL + if (is_texture_func && i == 1) { + // If we're doing a texture lookup we need to check our texture argument StringName texture_uniform; bool correct_texture_uniform = false; @@ -1240,8 +1241,10 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene break; } - if (correct_texture_uniform) { + if (correct_texture_uniform && !RS::get_singleton()->is_low_end()) { + // Need to map from texture to sampler in order to sample when using Vulkan GLSL. String sampler_name; + bool is_depth_texture = false; bool is_normal_roughness_texture = false; if (actions.custom_samplers.has(texture_uniform)) { @@ -1251,6 +1254,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[texture_uniform]; if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE) { is_screen_texture = true; + } else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { + is_depth_texture = true; } else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) { is_normal_roughness_texture = true; } @@ -1281,24 +1286,40 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } String data_type_name = ""; - if (is_normal_roughness_texture) { + if (actions.check_multiview_samplers && (is_screen_texture || is_depth_texture || is_normal_roughness_texture)) { data_type_name = "multiviewSampler"; - normal_roughness_texture_used = true; + multiview_uv_needed = true; } else { data_type_name = ShaderLanguage::get_datatype_name(onode->arguments[i]->get_datatype()); } code += data_type_name + "(" + node_code + ", " + sampler_name + ")"; + } else if (actions.check_multiview_samplers && correct_texture_uniform && RS::get_singleton()->is_low_end()) { + // Texture function on low end hardware (i.e. OpenGL). + // We just need to know if the texture supports multiview. + + if (shader->uniforms.has(texture_uniform)) { + const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[texture_uniform]; + if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE) { + multiview_uv_needed = true; + } else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) { + multiview_uv_needed = true; + } else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) { + multiview_uv_needed = true; + } + } + + code += node_code; } else { code += node_code; } - } else { - if (normal_roughness_texture_used && i == 2) { - // UV coordinate after using normal roughness texture. - node_code = "normal_roughness_uv(" + node_code + ".xy)"; - } + } else if (multiview_uv_needed && i == 2) { + // UV coordinate after using color, depth or normal roughness texture. + node_code = "multiview_uv(" + node_code + ".xy)"; code += node_code; + } else { + code += node_code; } } code += ")"; diff --git a/servers/rendering/shader_compiler.h b/servers/rendering/shader_compiler.h index 43bea213da..3bb29a545b 100644 --- a/servers/rendering/shader_compiler.h +++ b/servers/rendering/shader_compiler.h @@ -101,6 +101,7 @@ public: String instance_uniform_index_variable; uint32_t base_varying_index = 0; bool apply_luminance_multiplier = false; + bool check_multiview_samplers = false; }; private: diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index ba7ffda00a..7a4ac709f4 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -90,8 +90,9 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "IDENTIFIER", "TRUE", "FALSE", - "REAL_CONSTANT", + "FLOAT_CONSTANT", "INT_CONSTANT", + "UINT_CONSTANT", "TYPE_VOID", "TYPE_BOOL", "TYPE_BVEC2", @@ -126,6 +127,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "INTERPOLATION_FLAT", "INTERPOLATION_SMOOTH", "CONST", + "STRUCT", "PRECISION_LOW", "PRECISION_MID", "PRECISION_HIGH", @@ -169,6 +171,7 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "CF_DO", "CF_SWITCH", "CF_CASE", + "CF_DEFAULT", "CF_BREAK", "CF_CONTINUE", "CF_RETURN", @@ -185,19 +188,26 @@ const char *ShaderLanguage::token_names[TK_MAX] = { "SEMICOLON", "PERIOD", "UNIFORM", + "UNIFORM_GROUP", "INSTANCE", "GLOBAL", "VARYING", - "IN", - "OUT", - "INOUT", + "ARG_IN", + "ARG_OUT", + "ARG_INOUT", "RENDER_MODE", - "SOURCE_COLOR", "HINT_DEFAULT_WHITE_TEXTURE", "HINT_DEFAULT_BLACK_TEXTURE", "HINT_DEFAULT_TRANSPARENT_TEXTURE", "HINT_NORMAL_TEXTURE", + "HINT_ROUGHNESS_NORMAL_TEXTURE", + "HINT_ROUGHNESS_R", + "HINT_ROUGHNESS_G", + "HINT_ROUGHNESS_B", + "HINT_ROUGHNESS_A", + "HINT_ROUGHNESS_GRAY", "HINT_ANISOTROPY_TEXTURE", + "HINT_SOURCE_COLOR", "HINT_RANGE", "HINT_INSTANCE_INDEX", "HINT_SCREEN_TEXTURE", @@ -612,7 +622,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() { char_idx += 2; include_positions.resize(include_positions.size() - 1); // Pop back. - tk_line = include_positions[include_positions.size() - 1].line; // Restore line. + tk_line = include_positions[include_positions.size() - 1].line - 1; // Restore line. } else { return _make_token(TK_ERROR, "Invalid include enter/exit hint token (@@> and @@<)"); @@ -2827,6 +2837,20 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "dFdx", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false }, { "dFdx", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false }, + // dFdxCoarse + + { "dFdxCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdxCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdxCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdxCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + + // dFdxFine + + { "dFdxFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdxFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdxFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdxFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + // dFdy { "dFdy", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false }, @@ -2834,6 +2858,20 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "dFdy", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false }, { "dFdy", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false }, + // dFdyCoarse + + { "dFdyCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdyCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdyCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdyCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + + // dFdyFine + + { "dFdyFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdyFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdyFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "dFdyFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + // fwidth { "fwidth", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, false }, @@ -2841,6 +2879,20 @@ const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { { "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, false }, { "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, false }, + // fwidthCoarse + + { "fwidthCoarse", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "fwidthCoarse", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "fwidthCoarse", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "fwidthCoarse", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + + // fwidthFine + + { "fwidthFine", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "fwidthFine", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "fwidthFine", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + { "fwidthFine", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, { "p" }, TAG_GLOBAL, true }, + // Sub-functions. // array @@ -8233,6 +8285,10 @@ Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_f _set_error(vformat(RTR("Uniform instances are not yet implemented for '%s' shaders."), shader_type_identifier)); return ERR_PARSE_ERROR; } + if (OS::get_singleton()->get_current_rendering_method() == "gl_compatibility") { + _set_error(RTR("Uniform instances are not supported in gl_compatibility shaders.")); + return ERR_PARSE_ERROR; + } if (uniform_scope == ShaderNode::Uniform::SCOPE_LOCAL) { tk = _get_token(); if (tk.type != TK_UNIFORM) { diff --git a/servers/rendering/shader_preprocessor.cpp b/servers/rendering/shader_preprocessor.cpp index 97efd2df94..b45a7c0db3 100644 --- a/servers/rendering/shader_preprocessor.cpp +++ b/servers/rendering/shader_preprocessor.cpp @@ -78,19 +78,46 @@ char32_t ShaderPreprocessor::Tokenizer::peek() { return 0; } +int ShaderPreprocessor::Tokenizer::consume_line_continuations(int p_offset) { + int skips = 0; + + for (int i = index + p_offset; i < size; i++) { + char32_t c = code[i]; + if (c == '\\') { + if (i + 1 < size && code[i + 1] == '\n') { + // This line ends with "\" and "\n" continuation. + add_generated(Token('\n', line)); + line++; + skips++; + + i = i + 2; + index = i; + } else { + break; + } + } else if (!is_whitespace(c)) { + break; + } + } + return skips; +} + LocalVector<ShaderPreprocessor::Token> ShaderPreprocessor::Tokenizer::advance(char32_t p_what) { LocalVector<ShaderPreprocessor::Token> tokens; while (index < size) { char32_t c = code[index++]; - - tokens.push_back(ShaderPreprocessor::Token(c, line)); + if (c == '\\' && consume_line_continuations(-1) > 0) { + continue; + } if (c == '\n') { add_generated(ShaderPreprocessor::Token('\n', line)); line++; } + tokens.push_back(ShaderPreprocessor::Token(c, line)); + if (c == p_what || c == 0) { return tokens; } @@ -104,6 +131,11 @@ void ShaderPreprocessor::Tokenizer::skip_whitespace() { } } +bool ShaderPreprocessor::Tokenizer::consume_empty_line() { + // Read until newline and return true if the content was all whitespace/empty. + return tokens_to_string(advance('\n')).strip_edges().size() == 0; +} + String ShaderPreprocessor::Tokenizer::get_identifier(bool *r_is_cursor, bool p_started) { if (r_is_cursor != nullptr) { *r_is_cursor = false; @@ -113,6 +145,10 @@ String ShaderPreprocessor::Tokenizer::get_identifier(bool *r_is_cursor, bool p_s while (true) { char32_t c = peek(); + if (c == '\\' && consume_line_continuations(0) > 0) { + continue; + } + if (is_char_end(c) || c == '(' || c == ')' || c == ',' || c == ';') { break; } @@ -146,8 +182,10 @@ String ShaderPreprocessor::Tokenizer::get_identifier(bool *r_is_cursor, bool p_s String ShaderPreprocessor::Tokenizer::peek_identifier() { const int original = index; + const int original_line = line; String id = get_identifier(); index = original; + line = original_line; return id; } @@ -485,7 +523,9 @@ void ShaderPreprocessor::process_else(Tokenizer *p_tokenizer) { state->previous_region->to_line = line - 1; } - p_tokenizer->advance('\n'); + if (!p_tokenizer->consume_empty_line()) { + set_error(RTR("Invalid else."), p_tokenizer->get_line()); + } bool skip = false; for (int i = 0; i < state->current_branch->conditions.size(); i++) { @@ -508,17 +548,21 @@ void ShaderPreprocessor::process_else(Tokenizer *p_tokenizer) { } void ShaderPreprocessor::process_endif(Tokenizer *p_tokenizer) { + const int line = p_tokenizer->get_line(); + state->condition_depth--; if (state->condition_depth < 0) { - set_error(RTR("Unmatched endif."), p_tokenizer->get_line()); + set_error(RTR("Unmatched endif."), line); return; } if (state->previous_region != nullptr) { - state->previous_region->to_line = p_tokenizer->get_line() - 1; + state->previous_region->to_line = line - 1; state->previous_region = state->previous_region->parent; } - p_tokenizer->advance('\n'); + if (!p_tokenizer->consume_empty_line()) { + set_error(RTR("Invalid endif."), line); + } state->current_branch = state->current_branch->parent; state->branches.pop_back(); @@ -574,12 +618,10 @@ void ShaderPreprocessor::process_ifdef(Tokenizer *p_tokenizer) { return; } - p_tokenizer->skip_whitespace(); - if (!is_char_end(p_tokenizer->peek())) { + if (!p_tokenizer->consume_empty_line()) { set_error(RTR("Invalid ifdef."), line); return; } - p_tokenizer->advance('\n'); bool success = state->defines.has(label); start_branch_condition(p_tokenizer, success); @@ -598,12 +640,10 @@ void ShaderPreprocessor::process_ifndef(Tokenizer *p_tokenizer) { return; } - p_tokenizer->skip_whitespace(); - if (!is_char_end(p_tokenizer->peek())) { + if (!p_tokenizer->consume_empty_line()) { set_error(RTR("Invalid ifndef."), line); return; } - p_tokenizer->advance('\n'); bool success = !state->defines.has(label); start_branch_condition(p_tokenizer, success); @@ -628,13 +668,17 @@ void ShaderPreprocessor::process_include(Tokenizer *p_tokenizer) { } } path = path.substr(0, path.length() - 1); - p_tokenizer->skip_whitespace(); - if (path.is_empty() || !is_char_end(p_tokenizer->peek())) { + if (path.is_empty() || !p_tokenizer->consume_empty_line()) { set_error(RTR("Invalid path."), line); return; } + path = path.simplify_path(); + if (path.is_relative_path()) { + path = state->current_filename.get_base_dir().path_join(path); + } + Ref<Resource> res = ResourceLoader::load(path); if (res.is_null()) { set_error(RTR("Shader include load failed. Does the shader include exist? Is there a cyclic dependency?"), line); @@ -728,25 +772,24 @@ void ShaderPreprocessor::process_pragma(Tokenizer *p_tokenizer) { return; } - p_tokenizer->advance('\n'); + if (!p_tokenizer->consume_empty_line()) { + set_error(RTR("Invalid pragma directive."), line); + return; + } } void ShaderPreprocessor::process_undef(Tokenizer *p_tokenizer) { const int line = p_tokenizer->get_line(); const String label = p_tokenizer->get_identifier(); - if (label.is_empty() || !state->defines.has(label)) { - set_error(RTR("Invalid name."), line); - return; - } - - p_tokenizer->skip_whitespace(); - if (!is_char_end(p_tokenizer->peek())) { + if (label.is_empty() || !p_tokenizer->consume_empty_line()) { set_error(RTR("Invalid undef."), line); return; } - memdelete(state->defines[label]); - state->defines.erase(label); + if (state->defines.has(label)) { + memdelete(state->defines[label]); + state->defines.erase(label); + } } void ShaderPreprocessor::add_region(int p_line, bool p_enabled, Region *p_parent_region) { @@ -957,15 +1000,57 @@ bool ShaderPreprocessor::expand_macros_once(const String &p_line, int p_line_num String body = define->body; if (define->arguments.size() > 0) { // Complex macro with arguments. - int args_start = index + key.length(); - int args_end = p_line.find(")", args_start); - if (args_start == -1 || args_end == -1) { - set_error(RTR("Missing macro argument parenthesis."), p_line_number); - return false; + + int args_start = -1; + int args_end = -1; + int brackets_open = 0; + Vector<String> args; + for (int i = index_start - 1; i < p_line.length(); i++) { + bool add_argument = false; + bool reached_end = false; + char32_t c = p_line[i]; + + if (c == '(') { + brackets_open++; + if (brackets_open == 1) { + args_start = i + 1; + args_end = -1; + } + } else if (c == ')') { + brackets_open--; + if (brackets_open == 0) { + args_end = i; + add_argument = true; + reached_end = true; + } + } else if (c == ',') { + if (brackets_open == 1) { + args_end = i; + add_argument = true; + } + } + + if (add_argument) { + if (args_start == -1 || args_end == -1) { + set_error(RTR("Invalid macro argument list."), p_line_number); + return false; + } + + String arg = p_line.substr(args_start, args_end - args_start).strip_edges(); + if (arg.is_empty()) { + set_error(RTR("Invalid macro argument."), p_line_number); + return false; + } + args.append(arg); + + args_start = args_end + 1; + } + + if (reached_end) { + break; + } } - String values = result.substr(args_start + 1, args_end - (args_start + 1)); - Vector<String> args = values.split(","); if (args.size() != define->arguments.size()) { set_error(RTR("Invalid macro argument count."), p_line_number); return false; @@ -987,9 +1072,6 @@ bool ShaderPreprocessor::expand_macros_once(const String &p_line, int p_line_num result = result.substr(0, index) + " " + body + " " + result.substr(args_end + 1, result.length()); } else { result = result.substr(0, index) + body + result.substr(index + key.length(), result.length() - (index + key.length())); - // Manually reset index_start to where the body value of the define finishes. - // This ensures we don't skip another instance of this macro in the string. - index_start = index + body.length() + 1; } r_expanded = result; diff --git a/servers/rendering/shader_preprocessor.h b/servers/rendering/shader_preprocessor.h index 6e5533c575..2b7d2c274e 100644 --- a/servers/rendering/shader_preprocessor.h +++ b/servers/rendering/shader_preprocessor.h @@ -93,11 +93,13 @@ private: int get_line() const; int get_index() const; char32_t peek(); + int consume_line_continuations(int p_offset); void get_and_clear_generated(Vector<Token> *r_out); void backtrack(char32_t p_what); LocalVector<Token> advance(char32_t p_what); void skip_whitespace(); + bool consume_empty_line(); String get_identifier(bool *r_is_cursor = nullptr, bool p_started = false); String peek_identifier(); Token get_token(); diff --git a/servers/rendering/storage/mesh_storage.h b/servers/rendering/storage/mesh_storage.h index 704c2e015c..76e46a696a 100644 --- a/servers/rendering/storage/mesh_storage.h +++ b/servers/rendering/storage/mesh_storage.h @@ -83,6 +83,7 @@ public: virtual void mesh_instance_set_skeleton(RID p_mesh_instance, RID p_skeleton) = 0; virtual void mesh_instance_set_blend_shape_weight(RID p_mesh_instance, int p_shape, float p_weight) = 0; virtual void mesh_instance_check_for_update(RID p_mesh_instance) = 0; + virtual void mesh_instance_set_canvas_item_transform(RID p_mesh_instance, const Transform2D &p_transform) = 0; virtual void update_mesh_instances() = 0; /* MULTIMESH API */ diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 4ef562adcb..97907bed48 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2875,7 +2875,7 @@ void RenderingServer::init() { GLOBAL_DEF("rendering/2d/shadow_atlas/size", 2048); // Number of commands that can be drawn per frame. - GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/gl_compatibility/item_buffer_size", PROPERTY_HINT_RANGE, "1024,1048576,1"), 16384); + GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/gl_compatibility/item_buffer_size", PROPERTY_HINT_RANGE, "128,1048576,1"), 16384); GLOBAL_DEF("rendering/shader_compiler/shader_cache/enabled", true); GLOBAL_DEF("rendering/shader_compiler/shader_cache/compress", true); |