diff options
Diffstat (limited to 'servers')
109 files changed, 2612 insertions, 1919 deletions
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h index 9800707849..bf200e7ecf 100644 --- a/servers/audio/audio_stream.h +++ b/servers/audio/audio_stream.h @@ -125,7 +125,7 @@ class AudioStreamMicrophone : public AudioStream { GDCLASS(AudioStreamMicrophone, AudioStream); friend class AudioStreamPlaybackMicrophone; - Set<AudioStreamPlaybackMicrophone *> playbacks; + HashSet<AudioStreamPlaybackMicrophone *> playbacks; protected: static void _bind_methods(); @@ -192,7 +192,7 @@ private: float weight; }; - Set<AudioStreamPlaybackRandomizer *> playbacks; + HashSet<AudioStreamPlaybackRandomizer *> playbacks; Vector<PoolEntry> audio_stream_pool; float random_pitch_scale = 1.1f; float random_volume_offset_db = 5.0f; diff --git a/servers/audio/effects/audio_effect_amplify.cpp b/servers/audio/effects/audio_effect_amplify.cpp index b01160ea5c..87d46f8bbe 100644 --- a/servers/audio/effects/audio_effect_amplify.cpp +++ b/servers/audio/effects/audio_effect_amplify.cpp @@ -64,7 +64,7 @@ void AudioEffectAmplify::_bind_methods() { ClassDB::bind_method(D_METHOD("set_volume_db", "volume"), &AudioEffectAmplify::set_volume_db); ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioEffectAmplify::get_volume_db); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01"), "set_volume_db", "get_volume_db"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volume_db", PROPERTY_HINT_RANGE, "-80,24,0.01,suffix:dB"), "set_volume_db", "get_volume_db"); } AudioEffectAmplify::AudioEffectAmplify() { diff --git a/servers/audio/effects/audio_effect_eq.cpp b/servers/audio/effects/audio_effect_eq.cpp index cc317031d4..b7c373479a 100644 --- a/servers/audio/effects/audio_effect_eq.cpp +++ b/servers/audio/effects/audio_effect_eq.cpp @@ -90,9 +90,9 @@ int AudioEffectEQ::get_band_count() const { } bool AudioEffectEQ::_set(const StringName &p_name, const Variant &p_value) { - const Map<StringName, int>::Element *E = prop_band_map.find(p_name); + HashMap<StringName, int>::ConstIterator E = prop_band_map.find(p_name); if (E) { - set_band_gain_db(E->get(), p_value); + set_band_gain_db(E->value, p_value); return true; } @@ -100,9 +100,9 @@ bool AudioEffectEQ::_set(const StringName &p_name, const Variant &p_value) { } bool AudioEffectEQ::_get(const StringName &p_name, Variant &r_ret) const { - const Map<StringName, int>::Element *E = prop_band_map.find(p_name); + HashMap<StringName, int>::ConstIterator E = prop_band_map.find(p_name); if (E) { - r_ret = get_band_gain_db(E->get()); + r_ret = get_band_gain_db(E->value); return true; } diff --git a/servers/audio/effects/audio_effect_eq.h b/servers/audio/effects/audio_effect_eq.h index 252f931e6c..9b0560223f 100644 --- a/servers/audio/effects/audio_effect_eq.h +++ b/servers/audio/effects/audio_effect_eq.h @@ -55,7 +55,7 @@ class AudioEffectEQ : public AudioEffect { EQ eq; Vector<float> gain; - Map<StringName, int> prop_band_map; + HashMap<StringName, int> prop_band_map; Vector<String> band_names; protected: diff --git a/servers/audio_server.cpp b/servers/audio_server.cpp index c8f48207e4..8ec3e469d3 100644 --- a/servers/audio_server.cpp +++ b/servers/audio_server.cpp @@ -1106,13 +1106,13 @@ float AudioServer::get_playback_speed_scale() const { void AudioServer::start_playback_stream(Ref<AudioStreamPlayback> p_playback, StringName p_bus, Vector<AudioFrame> p_volume_db_vector, float p_start_time, float p_pitch_scale) { ERR_FAIL_COND(p_playback.is_null()); - Map<StringName, Vector<AudioFrame>> map; + HashMap<StringName, Vector<AudioFrame>> map; map[p_bus] = p_volume_db_vector; start_playback_stream(p_playback, map, p_start_time, p_pitch_scale); } -void AudioServer::start_playback_stream(Ref<AudioStreamPlayback> p_playback, Map<StringName, Vector<AudioFrame>> p_bus_volumes, float p_start_time, float p_pitch_scale, float p_highshelf_gain, float p_attenuation_cutoff_hz) { +void AudioServer::start_playback_stream(Ref<AudioStreamPlayback> p_playback, HashMap<StringName, Vector<AudioFrame>> p_bus_volumes, float p_start_time, float p_pitch_scale, float p_highshelf_gain, float p_attenuation_cutoff_hz) { ERR_FAIL_COND(p_playback.is_null()); AudioStreamPlaybackListNode *playback_node = new AudioStreamPlaybackListNode(); @@ -1173,13 +1173,13 @@ void AudioServer::stop_playback_stream(Ref<AudioStreamPlayback> p_playback) { void AudioServer::set_playback_bus_exclusive(Ref<AudioStreamPlayback> p_playback, StringName p_bus, Vector<AudioFrame> p_volumes) { ERR_FAIL_COND(p_volumes.size() != MAX_CHANNELS_PER_BUS); - Map<StringName, Vector<AudioFrame>> map; + HashMap<StringName, Vector<AudioFrame>> map; map[p_bus] = p_volumes; set_playback_bus_volumes_linear(p_playback, map); } -void AudioServer::set_playback_bus_volumes_linear(Ref<AudioStreamPlayback> p_playback, Map<StringName, Vector<AudioFrame>> p_bus_volumes) { +void AudioServer::set_playback_bus_volumes_linear(Ref<AudioStreamPlayback> p_playback, HashMap<StringName, Vector<AudioFrame>> p_bus_volumes) { ERR_FAIL_COND(p_bus_volumes.size() > MAX_BUSES_PER_PLAYBACK); AudioStreamPlaybackListNode *playback_node = _find_playback_list_node(p_playback); @@ -1215,7 +1215,7 @@ void AudioServer::set_playback_all_bus_volumes_linear(Ref<AudioStreamPlayback> p ERR_FAIL_COND(p_playback.is_null()); ERR_FAIL_COND(p_volumes.size() != MAX_CHANNELS_PER_BUS); - Map<StringName, Vector<AudioFrame>> map; + HashMap<StringName, Vector<AudioFrame>> map; AudioStreamPlaybackListNode *playback_node = _find_playback_list_node(p_playback); if (!playback_node) { diff --git a/servers/audio_server.h b/servers/audio_server.h index 3d8755071a..18e173ff0b 100644 --- a/servers/audio_server.h +++ b/servers/audio_server.h @@ -263,7 +263,7 @@ private: Vector<Vector<AudioFrame>> temp_buffer; //temp_buffer for each level Vector<AudioFrame> mix_buffer; Vector<Bus *> buses; - Map<StringName, Bus *> bus_map; + HashMap<StringName, Bus *> bus_map; void _update_bus_effects(int p_bus); @@ -365,11 +365,11 @@ public: // Convenience method. void start_playback_stream(Ref<AudioStreamPlayback> p_playback, StringName p_bus, Vector<AudioFrame> p_volume_db_vector, float p_start_time = 0, float p_pitch_scale = 1); // Expose all parameters. - void start_playback_stream(Ref<AudioStreamPlayback> p_playback, Map<StringName, Vector<AudioFrame>> p_bus_volumes, float p_start_time = 0, float p_pitch_scale = 1, float p_highshelf_gain = 0, float p_attenuation_cutoff_hz = 0); + void start_playback_stream(Ref<AudioStreamPlayback> p_playback, HashMap<StringName, Vector<AudioFrame>> p_bus_volumes, float p_start_time = 0, float p_pitch_scale = 1, float p_highshelf_gain = 0, float p_attenuation_cutoff_hz = 0); void stop_playback_stream(Ref<AudioStreamPlayback> p_playback); void set_playback_bus_exclusive(Ref<AudioStreamPlayback> p_playback, StringName p_bus, Vector<AudioFrame> p_volumes); - void set_playback_bus_volumes_linear(Ref<AudioStreamPlayback> p_playback, Map<StringName, Vector<AudioFrame>> p_bus_volumes); + void set_playback_bus_volumes_linear(Ref<AudioStreamPlayback> p_playback, HashMap<StringName, Vector<AudioFrame>> p_bus_volumes); void set_playback_all_bus_volumes_linear(Ref<AudioStreamPlayback> p_playback, Vector<AudioFrame> p_volumes); void set_playback_pitch_scale(Ref<AudioStreamPlayback> p_playback, float p_pitch_scale); void set_playback_paused(Ref<AudioStreamPlayback> p_playback, bool p_paused); diff --git a/servers/debugger/servers_debugger.cpp b/servers/debugger/servers_debugger.cpp index 02703cacbf..222b475be8 100644 --- a/servers/debugger/servers_debugger.cpp +++ b/servers/debugger/servers_debugger.cpp @@ -199,7 +199,7 @@ class ServersDebugger::ScriptsProfiler : public EngineProfiler { }; Vector<ScriptLanguage::ProfilingInfo> info; Vector<ScriptLanguage::ProfilingInfo *> ptrs; - Map<StringName, int> sig_map; + HashMap<StringName, int> sig_map; int max_frame_functions = 16; public: @@ -277,7 +277,7 @@ class ServersDebugger::ServersProfiler : public EngineProfiler { typedef ServersDebugger::ServerInfo ServerInfo; typedef ServersDebugger::ServerFunctionInfo ServerFunctionInfo; - Map<StringName, ServerInfo> server_data; + HashMap<StringName, ServerInfo> server_data; ScriptsProfiler scripts_profiler; double frame_time = 0; @@ -292,13 +292,13 @@ class ServersDebugger::ServersProfiler : public EngineProfiler { frame.process_time = process_time; frame.physics_time = physics_time; frame.physics_frame_time = physics_frame_time; - Map<StringName, ServerInfo>::Element *E = server_data.front(); + HashMap<StringName, ServerInfo>::Iterator E = server_data.begin(); while (E) { if (!p_final) { - frame.servers.push_back(E->get()); + frame.servers.push_back(E->value); } - E->get().functions.clear(); - E = E->next(); + E->value.functions.clear(); + ++E; } uint64_t time = 0; scripts_profiler.write_frame_data(frame.script_functions, time, p_final); @@ -357,7 +357,7 @@ class ServersDebugger::VisualProfiler : public EngineProfiler { typedef ServersDebugger::ServerInfo ServerInfo; typedef ServersDebugger::ServerFunctionInfo ServerFunctionInfo; - Map<StringName, ServerInfo> server_data; + HashMap<StringName, ServerInfo> server_data; public: void toggle(bool p_enable, const Array &p_opts) { diff --git a/servers/extensions/physics_server_3d_extension.cpp b/servers/extensions/physics_server_3d_extension.cpp index b2a9273538..3694dcdb9a 100644 --- a/servers/extensions/physics_server_3d_extension.cpp +++ b/servers/extensions/physics_server_3d_extension.cpp @@ -34,7 +34,7 @@ bool PhysicsDirectSpaceState3DExtension::is_body_excluded_from_query(const RID & return exclude && exclude->has(p_body); } -thread_local const Set<RID> *PhysicsDirectSpaceState3DExtension::exclude = nullptr; +thread_local const HashSet<RID> *PhysicsDirectSpaceState3DExtension::exclude = nullptr; void PhysicsDirectSpaceState3DExtension::_bind_methods() { GDVIRTUAL_BIND(_intersect_ray, "from", "to", "collision_mask", "collide_with_bodies", "collide_with_areas", "hit_from_inside", "hit_back_faces", "result"); @@ -113,8 +113,8 @@ void PhysicsDirectBodyState3DExtension::_bind_methods() { PhysicsDirectBodyState3DExtension::PhysicsDirectBodyState3DExtension() { } -thread_local const Set<RID> *PhysicsServer3DExtension::exclude_bodies = nullptr; -thread_local const Set<ObjectID> *PhysicsServer3DExtension::exclude_objects = nullptr; +thread_local const HashSet<RID> *PhysicsServer3DExtension::exclude_bodies = nullptr; +thread_local const HashSet<ObjectID> *PhysicsServer3DExtension::exclude_objects = nullptr; bool PhysicsServer3DExtension::body_test_motion_is_excluding_body(RID p_body) const { return exclude_bodies && exclude_bodies->has(p_body); diff --git a/servers/extensions/physics_server_3d_extension.h b/servers/extensions/physics_server_3d_extension.h index ce6bed41c9..663af1ae6c 100644 --- a/servers/extensions/physics_server_3d_extension.h +++ b/servers/extensions/physics_server_3d_extension.h @@ -122,7 +122,7 @@ GDVIRTUAL_NATIVE_PTR(PhysicsServer3DExtensionShapeRestInfo) class PhysicsDirectSpaceState3DExtension : public PhysicsDirectSpaceState3D { GDCLASS(PhysicsDirectSpaceState3DExtension, PhysicsDirectSpaceState3D); - thread_local static const Set<RID> *exclude; + thread_local static const HashSet<RID> *exclude; protected: static void _bind_methods(); @@ -388,8 +388,8 @@ public: GDVIRTUAL7RC(bool, _body_test_motion, RID, const Transform3D &, const Vector3 &, real_t, int, bool, GDNativePtr<PhysicsServer3DExtensionMotionResult>) - thread_local static const Set<RID> *exclude_bodies; - thread_local static const Set<ObjectID> *exclude_objects; + thread_local static const HashSet<RID> *exclude_bodies; + thread_local static const HashSet<ObjectID> *exclude_objects; bool body_test_motion_is_excluding_body(RID p_body) const; bool body_test_motion_is_excluding_object(ObjectID p_object) const; diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp index a92fe8c79a..901d335017 100644 --- a/servers/navigation_server_2d.cpp +++ b/servers/navigation_server_2d.cpp @@ -170,8 +170,12 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("map_get_closest_point", "map", "to_point"), &NavigationServer2D::map_get_closest_point); ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer2D::map_get_closest_point_owner); + ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer2D::map_get_regions); + ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer2D::map_get_agents); + ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer2D::region_create); ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer2D::region_set_map); + ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer2D::region_get_map); ClassDB::bind_method(D_METHOD("region_set_layers", "region", "layers"), &NavigationServer2D::region_set_layers); ClassDB::bind_method(D_METHOD("region_get_layers", "region"), &NavigationServer2D::region_get_layers); ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer2D::region_set_transform); @@ -182,6 +186,7 @@ void NavigationServer2D::_bind_methods() { ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer2D::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer2D::agent_set_map); + ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer2D::agent_get_map); ClassDB::bind_method(D_METHOD("agent_set_neighbor_dist", "agent", "dist"), &NavigationServer2D::agent_set_neighbor_dist); ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &NavigationServer2D::agent_set_max_neighbors); ClassDB::bind_method(D_METHOD("agent_set_time_horizon", "agent", "time"), &NavigationServer2D::agent_set_time_horizon); @@ -208,6 +213,14 @@ NavigationServer2D::~NavigationServer2D() { singleton = nullptr; } +Array FORWARD_1_C(map_get_regions, RID, p_map, rid_to_rid); + +Array FORWARD_1_C(map_get_agents, RID, p_map, rid_to_rid); + +RID FORWARD_1_C(region_get_map, RID, p_region, rid_to_rid); + +RID FORWARD_1_C(agent_get_map, RID, p_agent, rid_to_rid); + RID FORWARD_0_C(map_create); void FORWARD_2_C(map_set_active, RID, p_map, bool, p_active, rid_to_rid, bool_to_bool); diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h index 7350eeb5b1..dfdcf5fca8 100644 --- a/servers/navigation_server_2d.h +++ b/servers/navigation_server_2d.h @@ -80,11 +80,15 @@ public: virtual Vector2 map_get_closest_point(RID p_map, const Vector2 &p_point) const; virtual RID map_get_closest_point_owner(RID p_map, const Vector2 &p_point) const; + virtual Array map_get_regions(RID p_map) const; + virtual Array map_get_agents(RID p_map) const; + /// Creates a new region. virtual RID region_create() const; /// Set the map of this region. virtual void region_set_map(RID p_region, RID p_map) const; + virtual RID region_get_map(RID p_region) const; /// Set the region's layers virtual void region_set_layers(RID p_region, uint32_t p_layers) const; @@ -106,6 +110,7 @@ public: /// Put the agent in the map. virtual void agent_set_map(RID p_agent, RID p_map) const; + virtual RID agent_get_map(RID p_agent) const; /// The maximum distance (center point to /// center point) to other agents this agent diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp index 46192772f6..0ce869ad1a 100644 --- a/servers/navigation_server_3d.cpp +++ b/servers/navigation_server_3d.cpp @@ -48,8 +48,12 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("map_get_closest_point_normal", "map", "to_point"), &NavigationServer3D::map_get_closest_point_normal); ClassDB::bind_method(D_METHOD("map_get_closest_point_owner", "map", "to_point"), &NavigationServer3D::map_get_closest_point_owner); + ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer3D::map_get_regions); + ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer3D::map_get_agents); + ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer3D::region_create); ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer3D::region_set_map); + ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer3D::region_get_map); ClassDB::bind_method(D_METHOD("region_set_layers", "region", "layers"), &NavigationServer3D::region_set_layers); ClassDB::bind_method(D_METHOD("region_get_layers", "region"), &NavigationServer3D::region_get_layers); ClassDB::bind_method(D_METHOD("region_set_transform", "region", "transform"), &NavigationServer3D::region_set_transform); @@ -61,6 +65,7 @@ void NavigationServer3D::_bind_methods() { ClassDB::bind_method(D_METHOD("agent_create"), &NavigationServer3D::agent_create); ClassDB::bind_method(D_METHOD("agent_set_map", "agent", "map"), &NavigationServer3D::agent_set_map); + ClassDB::bind_method(D_METHOD("agent_get_map", "agent"), &NavigationServer3D::agent_get_map); ClassDB::bind_method(D_METHOD("agent_set_neighbor_dist", "agent", "dist"), &NavigationServer3D::agent_set_neighbor_dist); ClassDB::bind_method(D_METHOD("agent_set_max_neighbors", "agent", "count"), &NavigationServer3D::agent_set_max_neighbors); ClassDB::bind_method(D_METHOD("agent_set_time_horizon", "agent", "time"), &NavigationServer3D::agent_set_time_horizon); diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h index 0a75b07931..c3d3a589a9 100644 --- a/servers/navigation_server_3d.h +++ b/servers/navigation_server_3d.h @@ -91,11 +91,15 @@ public: virtual Vector3 map_get_closest_point_normal(RID p_map, const Vector3 &p_point) const = 0; virtual RID map_get_closest_point_owner(RID p_map, const Vector3 &p_point) const = 0; + virtual Array map_get_regions(RID p_map) const = 0; + virtual Array map_get_agents(RID p_map) const = 0; + /// Creates a new region. virtual RID region_create() const = 0; /// Set the map of this region. virtual void region_set_map(RID p_region, RID p_map) const = 0; + virtual RID region_get_map(RID p_region) const = 0; /// Set the region's layers virtual void region_set_layers(RID p_region, uint32_t p_layers) const = 0; @@ -120,6 +124,7 @@ public: /// Put the agent in the map. virtual void agent_set_map(RID p_agent, RID p_map) const = 0; + virtual RID agent_get_map(RID p_agent) const = 0; /// The maximum distance (center point to /// center point) to other agents this agent diff --git a/servers/physics_2d/godot_area_2d.cpp b/servers/physics_2d/godot_area_2d.cpp index 9937178550..11208f2d5b 100644 --- a/servers/physics_2d/godot_area_2d.cpp +++ b/servers/physics_2d/godot_area_2d.cpp @@ -225,22 +225,24 @@ void GodotArea2D::call_queries() { resptr[i] = &res[i]; } - for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) { - if (E->get().state == 0) { // Nothing happened - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_bodies.erase(E); + for (HashMap<BodyKey, BodyState, BodyKey>::Iterator E = monitored_bodies.begin(); E;) { + if (E->value.state == 0) { // Nothing happened + HashMap<BodyKey, BodyState, BodyKey>::Iterator next = E; + ++next; + monitored_bodies.remove(E); E = next; continue; } - res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED; - res[1] = E->key().rid; - res[2] = E->key().instance_id; - res[3] = E->key().body_shape; - res[4] = E->key().area_shape; + res[0] = E->value.state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED; + res[1] = E->key.rid; + res[2] = E->key.instance_id; + res[3] = E->key.body_shape; + res[4] = E->key.area_shape; - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_bodies.erase(E); + HashMap<BodyKey, BodyState, BodyKey>::Iterator next = E; + ++next; + monitored_bodies.remove(E); E = next; Callable::CallError ce; @@ -261,22 +263,24 @@ void GodotArea2D::call_queries() { resptr[i] = &res[i]; } - for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) { - if (E->get().state == 0) { // Nothing happened - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_areas.erase(E); + for (HashMap<BodyKey, BodyState, BodyKey>::Iterator E = monitored_areas.begin(); E;) { + if (E->value.state == 0) { // Nothing happened + HashMap<BodyKey, BodyState, BodyKey>::Iterator next = E; + ++next; + monitored_areas.remove(E); E = next; continue; } - res[0] = E->get().state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED; - res[1] = E->key().rid; - res[2] = E->key().instance_id; - res[3] = E->key().body_shape; - res[4] = E->key().area_shape; + res[0] = E->value.state > 0 ? PhysicsServer2D::AREA_BODY_ADDED : PhysicsServer2D::AREA_BODY_REMOVED; + res[1] = E->key.rid; + res[2] = E->key.instance_id; + res[3] = E->key.body_shape; + res[4] = E->key.area_shape; - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_areas.erase(E); + HashMap<BodyKey, BodyState, BodyKey>::Iterator next = E; + ++next; + monitored_areas.remove(E); E = next; Callable::CallError ce; diff --git a/servers/physics_2d/godot_area_2d.h b/servers/physics_2d/godot_area_2d.h index dadd9747b1..35dad9d2c3 100644 --- a/servers/physics_2d/godot_area_2d.h +++ b/servers/physics_2d/godot_area_2d.h @@ -68,16 +68,15 @@ class GodotArea2D : public GodotCollisionObject2D { uint32_t body_shape = 0; uint32_t area_shape = 0; - _FORCE_INLINE_ bool operator<(const BodyKey &p_key) const { - if (rid == p_key.rid) { - if (body_shape == p_key.body_shape) { - return area_shape < p_key.area_shape; - } else { - return body_shape < p_key.body_shape; - } - } else { - return rid < p_key.rid; - } + static uint32_t hash(const BodyKey &p_key) { + uint32_t h = hash_one_uint64(p_key.rid.get_id()); + h = hash_djb2_one_64(p_key.instance_id, h); + h = hash_djb2_one_32(p_key.area_shape, h); + return hash_djb2_one_32(p_key.body_shape, h); + } + + _FORCE_INLINE_ bool operator==(const BodyKey &p_key) const { + return rid == p_key.rid && instance_id == p_key.instance_id && body_shape == p_key.body_shape && area_shape == p_key.area_shape; } _FORCE_INLINE_ BodyKey() {} @@ -91,10 +90,10 @@ class GodotArea2D : public GodotCollisionObject2D { _FORCE_INLINE_ void dec() { state--; } }; - Map<BodyKey, BodyState> monitored_bodies; - Map<BodyKey, BodyState> monitored_areas; + HashMap<BodyKey, BodyState, BodyKey> monitored_bodies; + HashMap<BodyKey, BodyState, BodyKey> monitored_areas; - Set<GodotConstraint2D *> constraints; + HashSet<GodotConstraint2D *> constraints; virtual void _shapes_changed() override; void _queue_monitor_update(); @@ -143,7 +142,7 @@ public: _FORCE_INLINE_ void add_constraint(GodotConstraint2D *p_constraint) { constraints.insert(p_constraint); } _FORCE_INLINE_ void remove_constraint(GodotConstraint2D *p_constraint) { constraints.erase(p_constraint); } - _FORCE_INLINE_ const Set<GodotConstraint2D *> &get_constraints() const { return constraints; } + _FORCE_INLINE_ const HashSet<GodotConstraint2D *> &get_constraints() const { return constraints; } _FORCE_INLINE_ void clear_constraints() { constraints.clear(); } void set_monitorable(bool p_monitorable); diff --git a/servers/physics_2d/godot_physics_server_2d.cpp b/servers/physics_2d/godot_physics_server_2d.cpp index 650a95c914..99e68de07c 100644 --- a/servers/physics_2d/godot_physics_server_2d.cpp +++ b/servers/physics_2d/godot_physics_server_2d.cpp @@ -1179,7 +1179,7 @@ void GodotPhysicsServer2D::free(RID p_rid) { GodotShape2D *shape = shape_owner.get_or_null(p_rid); while (shape->get_owners().size()) { - GodotShapeOwner2D *so = shape->get_owners().front()->key(); + GodotShapeOwner2D *so = shape->get_owners().begin()->key; so->remove_shape(shape); } @@ -1212,7 +1212,7 @@ void GodotPhysicsServer2D::free(RID p_rid) { GodotSpace2D *space = space_owner.get_or_null(p_rid); while (space->get_objects().size()) { - GodotCollisionObject2D *co = static_cast<GodotCollisionObject2D *>(space->get_objects().front()->get()); + GodotCollisionObject2D *co = static_cast<GodotCollisionObject2D *>(*space->get_objects().begin()); co->set_space(nullptr); } @@ -1250,11 +1250,11 @@ void GodotPhysicsServer2D::step(real_t p_step) { island_count = 0; active_objects = 0; collision_pairs = 0; - for (Set<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) { - stepper->step(const_cast<GodotSpace2D *>(E->get()), p_step); - island_count += E->get()->get_island_count(); - active_objects += E->get()->get_active_objects(); - collision_pairs += E->get()->get_collision_pairs(); + for (const GodotSpace2D *E : active_spaces) { + stepper->step(const_cast<GodotSpace2D *>(E), p_step); + island_count += E->get_island_count(); + active_objects += E->get_active_objects(); + collision_pairs += E->get_collision_pairs(); } } @@ -1271,8 +1271,8 @@ void GodotPhysicsServer2D::flush_queries() { uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); - for (Set<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) { - GodotSpace2D *space = const_cast<GodotSpace2D *>(E->get()); + for (const GodotSpace2D *E : active_spaces) { + GodotSpace2D *space = const_cast<GodotSpace2D *>(E); space->call_queries(); } @@ -1292,9 +1292,9 @@ void GodotPhysicsServer2D::flush_queries() { total_time[i] = 0; } - for (Set<const GodotSpace2D *>::Element *E = active_spaces.front(); E; E = E->next()) { + for (const GodotSpace2D *E : active_spaces) { for (int i = 0; i < GodotSpace2D::ELAPSED_TIME_MAX; i++) { - total_time[i] += E->get()->get_elapsed_time(GodotSpace2D::ElapsedTime(i)); + total_time[i] += E->get_elapsed_time(GodotSpace2D::ElapsedTime(i)); } } diff --git a/servers/physics_2d/godot_physics_server_2d.h b/servers/physics_2d/godot_physics_server_2d.h index 0a84caadc5..2af6e5c97c 100644 --- a/servers/physics_2d/godot_physics_server_2d.h +++ b/servers/physics_2d/godot_physics_server_2d.h @@ -56,7 +56,7 @@ class GodotPhysicsServer2D : public PhysicsServer2D { bool flushing_queries = false; GodotStep2D *stepper = nullptr; - Set<const GodotSpace2D *> active_spaces; + HashSet<const GodotSpace2D *> active_spaces; mutable RID_PtrOwner<GodotShape2D, true> shape_owner; mutable RID_PtrOwner<GodotSpace2D, true> space_owner; diff --git a/servers/physics_2d/godot_shape_2d.cpp b/servers/physics_2d/godot_shape_2d.cpp index 6c020f9e72..72ade3757b 100644 --- a/servers/physics_2d/godot_shape_2d.cpp +++ b/servers/physics_2d/godot_shape_2d.cpp @@ -50,20 +50,20 @@ Vector2 GodotShape2D::get_support(const Vector2 &p_normal) const { } void GodotShape2D::add_owner(GodotShapeOwner2D *p_owner) { - Map<GodotShapeOwner2D *, int>::Element *E = owners.find(p_owner); + HashMap<GodotShapeOwner2D *, int>::Iterator E = owners.find(p_owner); if (E) { - E->get()++; + E->value++; } else { owners[p_owner] = 1; } } void GodotShape2D::remove_owner(GodotShapeOwner2D *p_owner) { - Map<GodotShapeOwner2D *, int>::Element *E = owners.find(p_owner); + HashMap<GodotShapeOwner2D *, int>::Iterator E = owners.find(p_owner); ERR_FAIL_COND(!E); - E->get()--; - if (E->get() == 0) { - owners.erase(E); + E->value--; + if (E->value == 0) { + owners.remove(E); } } @@ -71,7 +71,7 @@ bool GodotShape2D::is_owner(GodotShapeOwner2D *p_owner) const { return owners.has(p_owner); } -const Map<GodotShapeOwner2D *, int> &GodotShape2D::get_owners() const { +const HashMap<GodotShapeOwner2D *, int> &GodotShape2D::get_owners() const { return owners; } @@ -841,7 +841,7 @@ void GodotConcavePolygonShape2D::set_data(const Variant &p_data) { const Vector2 *arr = p2arr.ptr(); - Map<Point2, int> pointmap; + HashMap<Point2, int> pointmap; for (int i = 0; i < len; i += 2) { Point2 p1 = arr[i]; Point2 p2 = arr[i + 1]; @@ -868,7 +868,7 @@ void GodotConcavePolygonShape2D::set_data(const Variant &p_data) { } points.resize(pointmap.size()); - aabb.position = pointmap.front()->key(); + aabb.position = pointmap.begin()->key; for (const KeyValue<Point2, int> &E : pointmap) { aabb.expand_to(E.key); points.write[E.value] = E.key; diff --git a/servers/physics_2d/godot_shape_2d.h b/servers/physics_2d/godot_shape_2d.h index 9b3477cea8..cede01e18d 100644 --- a/servers/physics_2d/godot_shape_2d.h +++ b/servers/physics_2d/godot_shape_2d.h @@ -50,7 +50,7 @@ class GodotShape2D { bool configured = false; real_t custom_bias = 0.0; - Map<GodotShapeOwner2D *, int> owners; + HashMap<GodotShapeOwner2D *, int> owners; protected: void configure(const Rect2 &p_aabb); @@ -86,7 +86,7 @@ public: void add_owner(GodotShapeOwner2D *p_owner); void remove_owner(GodotShapeOwner2D *p_owner); bool is_owner(GodotShapeOwner2D *p_owner) const; - const Map<GodotShapeOwner2D *, int> &get_owners() const; + const HashMap<GodotShapeOwner2D *, int> &get_owners() const; _FORCE_INLINE_ void get_supports_transformed_cast(const Vector2 &p_cast, const Vector2 &p_normal, const Transform2D &p_xform, Vector2 *r_supports, int &r_amount) const { get_supports(p_xform.basis_xform_inv(p_normal).normalized(), r_supports, r_amount); diff --git a/servers/physics_2d/godot_space_2d.cpp b/servers/physics_2d/godot_space_2d.cpp index 3ff7ab86bb..166ec3049e 100644 --- a/servers/physics_2d/godot_space_2d.cpp +++ b/servers/physics_2d/godot_space_2d.cpp @@ -874,7 +874,7 @@ bool GodotSpace2D::test_body_motion(GodotBody2D *p_body, const PhysicsServer2D:: bool collided = false; - if (recovered || (safe < 1)) { + if ((p_parameters.recovery_as_collision && recovered) || (safe < 1)) { if (safe >= 1) { best_shape = -1; //no best shape with cast, reset to -1 } @@ -1073,7 +1073,7 @@ void GodotSpace2D::remove_object(GodotCollisionObject2D *p_object) { objects.erase(p_object); } -const Set<GodotCollisionObject2D *> &GodotSpace2D::get_objects() const { +const HashSet<GodotCollisionObject2D *> &GodotSpace2D::get_objects() const { return objects; } diff --git a/servers/physics_2d/godot_space_2d.h b/servers/physics_2d/godot_space_2d.h index 5d97721176..b6fc48bd70 100644 --- a/servers/physics_2d/godot_space_2d.h +++ b/servers/physics_2d/godot_space_2d.h @@ -92,7 +92,7 @@ private: static void *_broadphase_pair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_self); static void _broadphase_unpair(GodotCollisionObject2D *A, int p_subindex_A, GodotCollisionObject2D *B, int p_subindex_B, void *p_data, void *p_self); - Set<GodotCollisionObject2D *> objects; + HashSet<GodotCollisionObject2D *> objects; GodotArea2D *area = nullptr; @@ -156,7 +156,7 @@ public: void add_object(GodotCollisionObject2D *p_object); void remove_object(GodotCollisionObject2D *p_object); - const Set<GodotCollisionObject2D *> &get_objects() const; + const HashSet<GodotCollisionObject2D *> &get_objects() const; _FORCE_INLINE_ int get_solver_iterations() const { return solver_iterations; } _FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; } diff --git a/servers/physics_2d/godot_step_2d.cpp b/servers/physics_2d/godot_step_2d.cpp index fd72038be3..551fd9329f 100644 --- a/servers/physics_2d/godot_step_2d.cpp +++ b/servers/physics_2d/godot_step_2d.cpp @@ -168,8 +168,8 @@ void GodotStep2D::step(GodotSpace2D *p_space, real_t p_delta) { const SelfList<GodotArea2D>::List &aml = p_space->get_moved_area_list(); while (aml.first()) { - for (const Set<GodotConstraint2D *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) { - GodotConstraint2D *constraint = E->get(); + for (GodotConstraint2D *E : aml.first()->self()->get_constraints()) { + GodotConstraint2D *constraint = E; if (constraint->get_island_step() == _step) { continue; } diff --git a/servers/physics_3d/godot_area_3d.cpp b/servers/physics_3d/godot_area_3d.cpp index e7df23d0d8..e2ad765d62 100644 --- a/servers/physics_3d/godot_area_3d.cpp +++ b/servers/physics_3d/godot_area_3d.cpp @@ -254,22 +254,24 @@ void GodotArea3D::call_queries() { resptr[i] = &res[i]; } - for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) { - if (E->get().state == 0) { // Nothing happened - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_bodies.erase(E); + for (HashMap<BodyKey, BodyState, BodyKey>::Iterator E = monitored_bodies.begin(); E;) { + if (E->value.state == 0) { // Nothing happened + HashMap<BodyKey, BodyState, BodyKey>::Iterator next = E; + ++next; + monitored_bodies.remove(E); E = next; continue; } - res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED; - res[1] = E->key().rid; - res[2] = E->key().instance_id; - res[3] = E->key().body_shape; - res[4] = E->key().area_shape; + res[0] = E->value.state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED; + res[1] = E->key.rid; + res[2] = E->key.instance_id; + res[3] = E->key.body_shape; + res[4] = E->key.area_shape; - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_bodies.erase(E); + HashMap<BodyKey, BodyState, BodyKey>::Iterator next = E; + ++next; + monitored_bodies.remove(E); E = next; Callable::CallError ce; @@ -290,22 +292,24 @@ void GodotArea3D::call_queries() { resptr[i] = &res[i]; } - for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) { - if (E->get().state == 0) { // Nothing happened - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_areas.erase(E); + for (HashMap<BodyKey, BodyState, BodyKey>::Iterator E = monitored_areas.begin(); E;) { + if (E->value.state == 0) { // Nothing happened + HashMap<BodyKey, BodyState, BodyKey>::Iterator next = E; + ++next; + monitored_areas.remove(E); E = next; continue; } - res[0] = E->get().state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED; - res[1] = E->key().rid; - res[2] = E->key().instance_id; - res[3] = E->key().body_shape; - res[4] = E->key().area_shape; + res[0] = E->value.state > 0 ? PhysicsServer3D::AREA_BODY_ADDED : PhysicsServer3D::AREA_BODY_REMOVED; + res[1] = E->key.rid; + res[2] = E->key.instance_id; + res[3] = E->key.body_shape; + res[4] = E->key.area_shape; - Map<BodyKey, BodyState>::Element *next = E->next(); - monitored_areas.erase(E); + HashMap<BodyKey, BodyState, BodyKey>::Iterator next = E; + ++next; + monitored_areas.remove(E); E = next; Callable::CallError ce; diff --git a/servers/physics_3d/godot_area_3d.h b/servers/physics_3d/godot_area_3d.h index d15f8ec0a6..a00451f602 100644 --- a/servers/physics_3d/godot_area_3d.h +++ b/servers/physics_3d/godot_area_3d.h @@ -72,16 +72,15 @@ class GodotArea3D : public GodotCollisionObject3D { uint32_t body_shape = 0; uint32_t area_shape = 0; - _FORCE_INLINE_ bool operator<(const BodyKey &p_key) const { - if (rid == p_key.rid) { - if (body_shape == p_key.body_shape) { - return area_shape < p_key.area_shape; - } else { - return body_shape < p_key.body_shape; - } - } else { - return rid < p_key.rid; - } + static uint32_t hash(const BodyKey &p_key) { + uint32_t h = hash_one_uint64(p_key.rid.get_id()); + h = hash_djb2_one_64(p_key.instance_id, h); + h = hash_djb2_one_32(p_key.area_shape, h); + return hash_djb2_one_32(p_key.body_shape, h); + } + + _FORCE_INLINE_ bool operator==(const BodyKey &p_key) const { + return rid == p_key.rid && instance_id == p_key.instance_id && body_shape == p_key.body_shape && area_shape == p_key.area_shape; } _FORCE_INLINE_ BodyKey() {} @@ -96,11 +95,11 @@ class GodotArea3D : public GodotCollisionObject3D { _FORCE_INLINE_ void dec() { state--; } }; - Map<BodyKey, BodyState> monitored_soft_bodies; - Map<BodyKey, BodyState> monitored_bodies; - Map<BodyKey, BodyState> monitored_areas; + HashMap<BodyKey, BodyState, BodyKey> monitored_soft_bodies; + HashMap<BodyKey, BodyState, BodyKey> monitored_bodies; + HashMap<BodyKey, BodyState, BodyKey> monitored_areas; - Set<GodotConstraint3D *> constraints; + HashSet<GodotConstraint3D *> constraints; virtual void _shapes_changed() override; void _queue_monitor_update(); @@ -164,7 +163,7 @@ public: _FORCE_INLINE_ void add_constraint(GodotConstraint3D *p_constraint) { constraints.insert(p_constraint); } _FORCE_INLINE_ void remove_constraint(GodotConstraint3D *p_constraint) { constraints.erase(p_constraint); } - _FORCE_INLINE_ const Set<GodotConstraint3D *> &get_constraints() const { return constraints; } + _FORCE_INLINE_ const HashSet<GodotConstraint3D *> &get_constraints() const { return constraints; } _FORCE_INLINE_ void clear_constraints() { constraints.clear(); } void set_monitorable(bool p_monitorable); diff --git a/servers/physics_3d/godot_body_3d.h b/servers/physics_3d/godot_body_3d.h index c0c847d920..93bd5a0071 100644 --- a/servers/physics_3d/godot_body_3d.h +++ b/servers/physics_3d/godot_body_3d.h @@ -112,7 +112,7 @@ class GodotBody3D : public GodotCollisionObject3D { virtual void _shapes_changed() override; Transform3D new_transform; - Map<GodotConstraint3D *, int> constraint_map; + HashMap<GodotConstraint3D *, int> constraint_map; Vector<AreaCMP> areas; @@ -196,7 +196,7 @@ public: _FORCE_INLINE_ void add_constraint(GodotConstraint3D *p_constraint, int p_pos) { constraint_map[p_constraint] = p_pos; } _FORCE_INLINE_ void remove_constraint(GodotConstraint3D *p_constraint) { constraint_map.erase(p_constraint); } - const Map<GodotConstraint3D *, int> &get_constraint_map() const { return constraint_map; } + const HashMap<GodotConstraint3D *, int> &get_constraint_map() const { return constraint_map; } _FORCE_INLINE_ void clear_constraint_map() { constraint_map.clear(); } _FORCE_INLINE_ void set_omit_force_integration(bool p_omit_force_integration) { omit_force_integration = p_omit_force_integration; } diff --git a/servers/physics_3d/godot_physics_server_3d.cpp b/servers/physics_3d/godot_physics_server_3d.cpp index e5107be74b..bed9b02da1 100644 --- a/servers/physics_3d/godot_physics_server_3d.cpp +++ b/servers/physics_3d/godot_physics_server_3d.cpp @@ -1531,7 +1531,7 @@ void GodotPhysicsServer3D::free(RID p_rid) { GodotShape3D *shape = shape_owner.get_or_null(p_rid); while (shape->get_owners().size()) { - GodotShapeOwner3D *so = shape->get_owners().front()->key(); + GodotShapeOwner3D *so = shape->get_owners().begin()->key; so->remove_shape(shape); } @@ -1570,7 +1570,7 @@ void GodotPhysicsServer3D::free(RID p_rid) { GodotSpace3D *space = space_owner.get_or_null(p_rid); while (space->get_objects().size()) { - GodotCollisionObject3D *co = static_cast<GodotCollisionObject3D *>(space->get_objects().front()->get()); + GodotCollisionObject3D *co = static_cast<GodotCollisionObject3D *>(*space->get_objects().begin()); co->set_space(nullptr); } @@ -1611,11 +1611,11 @@ void GodotPhysicsServer3D::step(real_t p_step) { island_count = 0; active_objects = 0; collision_pairs = 0; - for (Set<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) { - stepper->step(const_cast<GodotSpace3D *>(E->get()), p_step); - island_count += E->get()->get_island_count(); - active_objects += E->get()->get_active_objects(); - collision_pairs += E->get()->get_collision_pairs(); + for (const GodotSpace3D *E : active_spaces) { + stepper->step(const_cast<GodotSpace3D *>(E), p_step); + island_count += E->get_island_count(); + active_objects += E->get_active_objects(); + collision_pairs += E->get_collision_pairs(); } #endif } @@ -1635,8 +1635,8 @@ void GodotPhysicsServer3D::flush_queries() { uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); - for (Set<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) { - GodotSpace3D *space = const_cast<GodotSpace3D *>(E->get()); + for (const GodotSpace3D *E : active_spaces) { + GodotSpace3D *space = const_cast<GodotSpace3D *>(E); space->call_queries(); } @@ -1656,9 +1656,9 @@ void GodotPhysicsServer3D::flush_queries() { total_time[i] = 0; } - for (Set<const GodotSpace3D *>::Element *E = active_spaces.front(); E; E = E->next()) { + for (const GodotSpace3D *E : active_spaces) { for (int i = 0; i < GodotSpace3D::ELAPSED_TIME_MAX; i++) { - total_time[i] += E->get()->get_elapsed_time(GodotSpace3D::ElapsedTime(i)); + total_time[i] += E->get_elapsed_time(GodotSpace3D::ElapsedTime(i)); } } diff --git a/servers/physics_3d/godot_physics_server_3d.h b/servers/physics_3d/godot_physics_server_3d.h index d2078a912c..1d57451925 100644 --- a/servers/physics_3d/godot_physics_server_3d.h +++ b/servers/physics_3d/godot_physics_server_3d.h @@ -54,7 +54,7 @@ class GodotPhysicsServer3D : public PhysicsServer3D { bool flushing_queries = false; GodotStep3D *stepper = nullptr; - Set<const GodotSpace3D *> active_spaces; + HashSet<const GodotSpace3D *> active_spaces; mutable RID_PtrOwner<GodotShape3D, true> shape_owner; mutable RID_PtrOwner<GodotSpace3D, true> space_owner; diff --git a/servers/physics_3d/godot_shape_3d.cpp b/servers/physics_3d/godot_shape_3d.cpp index 2efc11a4c0..5e310670a5 100644 --- a/servers/physics_3d/godot_shape_3d.cpp +++ b/servers/physics_3d/godot_shape_3d.cpp @@ -76,20 +76,20 @@ Vector3 GodotShape3D::get_support(const Vector3 &p_normal) const { } void GodotShape3D::add_owner(GodotShapeOwner3D *p_owner) { - Map<GodotShapeOwner3D *, int>::Element *E = owners.find(p_owner); + HashMap<GodotShapeOwner3D *, int>::Iterator E = owners.find(p_owner); if (E) { - E->get()++; + E->value++; } else { owners[p_owner] = 1; } } void GodotShape3D::remove_owner(GodotShapeOwner3D *p_owner) { - Map<GodotShapeOwner3D *, int>::Element *E = owners.find(p_owner); + HashMap<GodotShapeOwner3D *, int>::Iterator E = owners.find(p_owner); ERR_FAIL_COND(!E); - E->get()--; - if (E->get() == 0) { - owners.erase(E); + E->value--; + if (E->value == 0) { + owners.remove(E); } } @@ -97,7 +97,7 @@ bool GodotShape3D::is_owner(GodotShapeOwner3D *p_owner) const { return owners.has(p_owner); } -const Map<GodotShapeOwner3D *, int> &GodotShape3D::get_owners() const { +const HashMap<GodotShapeOwner3D *, int> &GodotShape3D::get_owners() const { return owners; } diff --git a/servers/physics_3d/godot_shape_3d.h b/servers/physics_3d/godot_shape_3d.h index 9d171c3928..1fc8f7c711 100644 --- a/servers/physics_3d/godot_shape_3d.h +++ b/servers/physics_3d/godot_shape_3d.h @@ -51,7 +51,7 @@ class GodotShape3D { bool configured = false; real_t custom_bias = 0.0; - Map<GodotShapeOwner3D *, int> owners; + HashMap<GodotShapeOwner3D *, int> owners; protected: void configure(const AABB &p_aabb); @@ -93,7 +93,7 @@ public: void add_owner(GodotShapeOwner3D *p_owner); void remove_owner(GodotShapeOwner3D *p_owner); bool is_owner(GodotShapeOwner3D *p_owner) const; - const Map<GodotShapeOwner3D *, int> &get_owners() const; + const HashMap<GodotShapeOwner3D *, int> &get_owners() const; GodotShape3D() {} virtual ~GodotShape3D(); diff --git a/servers/physics_3d/godot_soft_body_3d.cpp b/servers/physics_3d/godot_soft_body_3d.cpp index be4b41292d..9cc7912a5a 100644 --- a/servers/physics_3d/godot_soft_body_3d.cpp +++ b/servers/physics_3d/godot_soft_body_3d.cpp @@ -33,7 +33,7 @@ #include "godot_space_3d.h" #include "core/math/geometry_3d.h" -#include "core/templates/map.h" +#include "core/templates/rb_map.h" #include "servers/rendering_server.h" // Based on Bullet soft body. @@ -494,7 +494,7 @@ bool GodotSoftBody3D::create_from_trimesh(const Vector<int> &p_indices, const Ve // Process vertices. { uint32_t vertex_count = 0; - Map<Vector3, uint32_t> unique_vertices; + HashMap<Vector3, uint32_t> unique_vertices; vertices.resize(visual_vertex_count); map_visual_to_physics.resize(visual_vertex_count); @@ -502,11 +502,11 @@ bool GodotSoftBody3D::create_from_trimesh(const Vector<int> &p_indices, const Ve for (int visual_vertex_index = 0; visual_vertex_index < visual_vertex_count; ++visual_vertex_index) { const Vector3 &vertex = p_vertices[visual_vertex_index]; - Map<Vector3, uint32_t>::Element *e = unique_vertices.find(vertex); + HashMap<Vector3, uint32_t>::Iterator e = unique_vertices.find(vertex); uint32_t vertex_id; if (e) { // Already existing. - vertex_id = e->value(); + vertex_id = e->value; } else { // Create new one. vertex_id = vertex_count++; diff --git a/servers/physics_3d/godot_soft_body_3d.h b/servers/physics_3d/godot_soft_body_3d.h index 96f63e5819..86f73c366b 100644 --- a/servers/physics_3d/godot_soft_body_3d.h +++ b/servers/physics_3d/godot_soft_body_3d.h @@ -37,8 +37,8 @@ #include "core/math/aabb.h" #include "core/math/dynamic_bvh.h" #include "core/math/vector3.h" +#include "core/templates/hash_set.h" #include "core/templates/local_vector.h" -#include "core/templates/set.h" #include "core/templates/vset.h" class GodotConstraint3D; @@ -103,7 +103,7 @@ class GodotSoftBody3D : public GodotCollisionObject3D { SelfList<GodotSoftBody3D> active_list; - Set<GodotConstraint3D *> constraints; + HashSet<GodotConstraint3D *> constraints; Vector<AreaCMP> areas; @@ -123,7 +123,7 @@ public: _FORCE_INLINE_ void add_constraint(GodotConstraint3D *p_constraint) { constraints.insert(p_constraint); } _FORCE_INLINE_ void remove_constraint(GodotConstraint3D *p_constraint) { constraints.erase(p_constraint); } - _FORCE_INLINE_ const Set<GodotConstraint3D *> &get_constraints() const { return constraints; } + _FORCE_INLINE_ const HashSet<GodotConstraint3D *> &get_constraints() const { return constraints; } _FORCE_INLINE_ void clear_constraints() { constraints.clear(); } _FORCE_INLINE_ void add_exception(const RID &p_exception) { exceptions.insert(p_exception); } diff --git a/servers/physics_3d/godot_space_3d.cpp b/servers/physics_3d/godot_space_3d.cpp index 0b84520c39..533d7605ce 100644 --- a/servers/physics_3d/godot_space_3d.cpp +++ b/servers/physics_3d/godot_space_3d.cpp @@ -906,7 +906,7 @@ bool GodotSpace3D::test_body_motion(GodotBody3D *p_body, const PhysicsServer3D:: } bool collided = false; - if (recovered || (safe < 1)) { + if ((p_parameters.recovery_as_collision && recovered) || (safe < 1)) { if (safe >= 1) { best_shape = -1; //no best shape with cast, reset to -1 } @@ -1096,7 +1096,7 @@ void GodotSpace3D::remove_object(GodotCollisionObject3D *p_object) { objects.erase(p_object); } -const Set<GodotCollisionObject3D *> &GodotSpace3D::get_objects() const { +const HashSet<GodotCollisionObject3D *> &GodotSpace3D::get_objects() const { return objects; } diff --git a/servers/physics_3d/godot_space_3d.h b/servers/physics_3d/godot_space_3d.h index 6308ede9a9..df7315e96d 100644 --- a/servers/physics_3d/godot_space_3d.h +++ b/servers/physics_3d/godot_space_3d.h @@ -89,7 +89,7 @@ private: static void *_broadphase_pair(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_self); static void _broadphase_unpair(GodotCollisionObject3D *A, int p_subindex_A, GodotCollisionObject3D *B, int p_subindex_B, void *p_data, void *p_self); - Set<GodotCollisionObject3D *> objects; + HashSet<GodotCollisionObject3D *> objects; GodotArea3D *area = nullptr; @@ -158,7 +158,7 @@ public: void add_object(GodotCollisionObject3D *p_object); void remove_object(GodotCollisionObject3D *p_object); - const Set<GodotCollisionObject3D *> &get_objects() const; + const HashSet<GodotCollisionObject3D *> &get_objects() const; _FORCE_INLINE_ int get_solver_iterations() const { return solver_iterations; } _FORCE_INLINE_ real_t get_contact_recycle_radius() const { return contact_recycle_radius; } diff --git a/servers/physics_3d/godot_step_3d.cpp b/servers/physics_3d/godot_step_3d.cpp index 204adae450..99656d01a0 100644 --- a/servers/physics_3d/godot_step_3d.cpp +++ b/servers/physics_3d/godot_step_3d.cpp @@ -87,8 +87,8 @@ void GodotStep3D::_populate_island(GodotBody3D *p_body, LocalVector<GodotBody3D void GodotStep3D::_populate_island_soft_body(GodotSoftBody3D *p_soft_body, LocalVector<GodotBody3D *> &p_body_island, LocalVector<GodotConstraint3D *> &p_constraint_island) { p_soft_body->set_island_step(_step); - for (Set<GodotConstraint3D *>::Element *E = p_soft_body->get_constraints().front(); E; E = E->next()) { - GodotConstraint3D *constraint = const_cast<GodotConstraint3D *>(E->get()); + for (const GodotConstraint3D *E : p_soft_body->get_constraints()) { + GodotConstraint3D *constraint = const_cast<GodotConstraint3D *>(E); if (constraint->get_island_step() == _step) { continue; // Already processed. } @@ -236,8 +236,8 @@ void GodotStep3D::step(GodotSpace3D *p_space, real_t p_delta) { const SelfList<GodotArea3D>::List &aml = p_space->get_moved_area_list(); while (aml.first()) { - for (const Set<GodotConstraint3D *>::Element *E = aml.first()->self()->get_constraints().front(); E; E = E->next()) { - GodotConstraint3D *constraint = E->get(); + for (GodotConstraint3D *E : aml.first()->self()->get_constraints()) { + GodotConstraint3D *constraint = E; if (constraint->get_island_step() == _step) { continue; } diff --git a/servers/physics_server_2d.cpp b/servers/physics_server_2d.cpp index d6d23f8310..41aae36785 100644 --- a/servers/physics_server_2d.cpp +++ b/servers/physics_server_2d.cpp @@ -158,8 +158,8 @@ Vector<RID> PhysicsRayQueryParameters2D::get_exclude() const { Vector<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; - for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) { - ret.write[idx++] = E->get(); + for (const RID &E : parameters.exclude) { + ret.write[idx++] = E; } return ret; } @@ -208,8 +208,8 @@ Vector<RID> PhysicsPointQueryParameters2D::get_exclude() const { Vector<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; - for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) { - ret.write[idx++] = E->get(); + for (const RID &E : parameters.exclude) { + ret.write[idx++] = E; } return ret; } @@ -267,8 +267,8 @@ Vector<RID> PhysicsShapeQueryParameters2D::get_exclude() const { Vector<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; - for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) { - ret.write[idx++] = E->get(); + for (const RID &E : parameters.exclude) { + ret.write[idx++] = E; } return ret; } @@ -505,12 +505,16 @@ void PhysicsTestMotionParameters2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_exclude_objects"), &PhysicsTestMotionParameters2D::get_exclude_objects); ClassDB::bind_method(D_METHOD("set_exclude_objects", "exclude_list"), &PhysicsTestMotionParameters2D::set_exclude_objects); + ClassDB::bind_method(D_METHOD("is_recovery_as_collision_enabled"), &PhysicsTestMotionParameters2D::is_recovery_as_collision_enabled); + ClassDB::bind_method(D_METHOD("set_recovery_as_collision_enabled", "enabled"), &PhysicsTestMotionParameters2D::set_recovery_as_collision_enabled); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM2D, "from"), "set_from", "get_from"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "motion"), "set_motion", "get_motion"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_separation_ray"), "set_collide_separation_ray_enabled", "is_collide_separation_ray_enabled"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_bodies", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_exclude_bodies", "get_exclude_bodies"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_objects"), "set_exclude_objects", "get_exclude_objects"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "recovery_as_collision"), "set_recovery_as_collision_enabled", "is_recovery_as_collision_enabled"); } /////////////////////////////// @@ -857,7 +861,7 @@ PhysicsServer2D::~PhysicsServer2D() { Vector<PhysicsServer2DManager::ClassInfo> PhysicsServer2DManager::physics_2d_servers; int PhysicsServer2DManager::default_server_id = -1; int PhysicsServer2DManager::default_server_priority = -1; -const String PhysicsServer2DManager::setting_property_name("physics/2d/physics_engine"); +const String PhysicsServer2DManager::setting_property_name(PNAME("physics/2d/physics_engine")); void PhysicsServer2DManager::on_servers_changed() { String physics_servers("DEFAULT"); diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h index 2f70b88e30..7a821c64e6 100644 --- a/servers/physics_server_2d.h +++ b/servers/physics_server_2d.h @@ -127,7 +127,7 @@ public: struct RayParameters { Vector2 from; Vector2 to; - Set<RID> exclude; + HashSet<RID> exclude; uint32_t collision_mask = UINT32_MAX; bool collide_with_bodies = true; @@ -157,7 +157,7 @@ public: struct PointParameters { Vector2 position; ObjectID canvas_instance_id; - Set<RID> exclude; + HashSet<RID> exclude; uint32_t collision_mask = UINT32_MAX; bool collide_with_bodies = true; @@ -173,7 +173,7 @@ public: Transform2D transform; Vector2 motion; real_t margin = 0.0; - Set<RID> exclude; + HashSet<RID> exclude; uint32_t collision_mask = UINT32_MAX; bool collide_with_bodies = true; @@ -483,8 +483,9 @@ public: Vector2 motion; real_t margin = 0.08; bool collide_separation_ray = false; - Set<RID> exclude_bodies; - Set<ObjectID> exclude_objects; + HashSet<RID> exclude_bodies; + HashSet<ObjectID> exclude_objects; + bool recovery_as_collision = false; MotionParameters() {} @@ -727,6 +728,9 @@ public: Array get_exclude_objects() const; void set_exclude_objects(const Array &p_exclude); + + bool is_recovery_as_collision_enabled() const { return parameters.recovery_as_collision; } + void set_recovery_as_collision_enabled(bool p_enabled) { parameters.recovery_as_collision = p_enabled; } }; class PhysicsTestMotionResult2D : public RefCounted { diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp index bfe93f0dfb..a606d055f7 100644 --- a/servers/physics_server_3d.cpp +++ b/servers/physics_server_3d.cpp @@ -177,8 +177,8 @@ Vector<RID> PhysicsRayQueryParameters3D::get_exclude() const { Vector<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; - for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) { - ret.write[idx++] = E->get(); + for (const RID &E : parameters.exclude) { + ret.write[idx++] = E; } return ret; } @@ -231,8 +231,8 @@ Vector<RID> PhysicsPointQueryParameters3D::get_exclude() const { Vector<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; - for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) { - ret.write[idx++] = E->get(); + for (const RID &E : parameters.exclude) { + ret.write[idx++] = E; } return ret; } @@ -286,8 +286,8 @@ Vector<RID> PhysicsShapeQueryParameters3D::get_exclude() const { Vector<RID> ret; ret.resize(parameters.exclude.size()); int idx = 0; - for (Set<RID>::Element *E = parameters.exclude.front(); E; E = E->next()) { - ret.write[idx++] = E->get(); + for (const RID &E : parameters.exclude) { + ret.write[idx++] = E; } return ret; } @@ -527,6 +527,9 @@ void PhysicsTestMotionParameters3D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_exclude_objects"), &PhysicsTestMotionParameters3D::get_exclude_objects); ClassDB::bind_method(D_METHOD("set_exclude_objects", "exclude_list"), &PhysicsTestMotionParameters3D::set_exclude_objects); + ClassDB::bind_method(D_METHOD("is_recovery_as_collision_enabled"), &PhysicsTestMotionParameters3D::is_recovery_as_collision_enabled); + ClassDB::bind_method(D_METHOD("set_recovery_as_collision_enabled", "enabled"), &PhysicsTestMotionParameters3D::set_recovery_as_collision_enabled); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM3D, "from"), "set_from", "get_from"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "motion"), "set_motion", "get_motion"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "margin"), "set_margin", "get_margin"); @@ -534,6 +537,7 @@ void PhysicsTestMotionParameters3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_separation_ray"), "set_collide_separation_ray_enabled", "is_collide_separation_ray_enabled"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_bodies", PROPERTY_HINT_ARRAY_TYPE, "RID"), "set_exclude_bodies", "get_exclude_bodies"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "exclude_objects"), "set_exclude_objects", "get_exclude_objects"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "recovery_as_collision"), "set_recovery_as_collision_enabled", "is_recovery_as_collision_enabled"); } /////////////////////////////// @@ -1029,7 +1033,7 @@ PhysicsServer3D::~PhysicsServer3D() { Vector<PhysicsServer3DManager::ClassInfo> PhysicsServer3DManager::physics_servers; int PhysicsServer3DManager::default_server_id = -1; int PhysicsServer3DManager::default_server_priority = -1; -const String PhysicsServer3DManager::setting_property_name("physics/3d/physics_engine"); +const String PhysicsServer3DManager::setting_property_name(PNAME("physics/3d/physics_engine")); void PhysicsServer3DManager::on_servers_changed() { String physics_servers2("DEFAULT"); diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h index 47f3fc2027..86a41d96ef 100644 --- a/servers/physics_server_3d.h +++ b/servers/physics_server_3d.h @@ -133,7 +133,7 @@ public: struct RayParameters { Vector3 from; Vector3 to; - Set<RID> exclude; + HashSet<RID> exclude; uint32_t collision_mask = UINT32_MAX; bool collide_with_bodies = true; @@ -165,7 +165,7 @@ public: struct PointParameters { Vector3 position; - Set<RID> exclude; + HashSet<RID> exclude; uint32_t collision_mask = UINT32_MAX; bool collide_with_bodies = true; @@ -179,7 +179,7 @@ public: Transform3D transform; Vector3 motion; real_t margin = 0.0; - Set<RID> exclude; + HashSet<RID> exclude; uint32_t collision_mask = UINT32_MAX; bool collide_with_bodies = true; @@ -520,8 +520,9 @@ public: real_t margin = 0.001; int max_collisions = 1; bool collide_separation_ray = false; - Set<RID> exclude_bodies; - Set<ObjectID> exclude_objects; + HashSet<RID> exclude_bodies; + HashSet<ObjectID> exclude_objects; + bool recovery_as_collision = false; MotionParameters() {} @@ -941,6 +942,9 @@ public: Array get_exclude_objects() const; void set_exclude_objects(const Array &p_exclude); + + bool is_recovery_as_collision_enabled() const { return parameters.recovery_as_collision; } + void set_recovery_as_collision_enabled(bool p_enabled) { parameters.recovery_as_collision = p_enabled; } }; class PhysicsTestMotionResult3D : public RefCounted { diff --git a/servers/rendering/dummy/rasterizer_dummy.h b/servers/rendering/dummy/rasterizer_dummy.h index 6cad45ea6d..5c6fcc8386 100644 --- a/servers/rendering/dummy/rasterizer_dummy.h +++ b/servers/rendering/dummy/rasterizer_dummy.h @@ -95,9 +95,9 @@ public: static void make_current() { _create_func = _create_current; + low_end = true; } - bool is_low_end() const override { return true; } uint64_t get_frame_number() const override { return frame; } double get_frame_delta_time() const override { return delta; } diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp index 84ab19880c..bc1e8eb348 100644 --- a/servers/rendering/renderer_canvas_cull.cpp +++ b/servers/rendering/renderer_canvas_cull.cpp @@ -1831,8 +1831,8 @@ void RendererCanvasCull::canvas_occluder_polygon_set_shape(RID p_occluder_polygo RSG::canvas_render->occluder_polygon_set_shape(occluder_poly->occluder, p_shape, p_closed); - for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) { - E->get()->aabb_cache = occluder_poly->aabb; + for (RendererCanvasRender::LightOccluderInstance *E : occluder_poly->owners) { + E->aabb_cache = occluder_poly->aabb; } } @@ -1841,8 +1841,8 @@ void RendererCanvasCull::canvas_occluder_polygon_set_cull_mode(RID p_occluder_po ERR_FAIL_COND(!occluder_poly); occluder_poly->cull_mode = p_mode; RSG::canvas_render->occluder_polygon_set_cull_mode(occluder_poly->occluder, p_mode); - for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *E = occluder_poly->owners.front(); E; E = E->next()) { - E->get()->cull_cache = p_mode; + for (RendererCanvasRender::LightOccluderInstance *E : occluder_poly->owners) { + E->cull_cache = p_mode; } } @@ -1928,26 +1928,26 @@ bool RendererCanvasCull::free(RID p_rid) { ERR_FAIL_COND_V(!canvas, false); while (canvas->viewports.size()) { - RendererViewport::Viewport *vp = RSG::viewport->viewport_owner.get_or_null(canvas->viewports.front()->get()); + RendererViewport::Viewport *vp = RSG::viewport->viewport_owner.get_or_null(*canvas->viewports.begin()); ERR_FAIL_COND_V(!vp, true); - Map<RID, RendererViewport::Viewport::CanvasData>::Element *E = vp->canvas_map.find(p_rid); + HashMap<RID, RendererViewport::Viewport::CanvasData>::Iterator E = vp->canvas_map.find(p_rid); ERR_FAIL_COND_V(!E, true); vp->canvas_map.erase(p_rid); - canvas->viewports.erase(canvas->viewports.front()); + canvas->viewports.erase(*canvas->viewports.begin()); } for (int i = 0; i < canvas->child_items.size(); i++) { canvas->child_items[i].item->parent = RID(); } - for (Set<RendererCanvasRender::Light *>::Element *E = canvas->lights.front(); E; E = E->next()) { - E->get()->canvas = RID(); + for (RendererCanvasRender::Light *E : canvas->lights) { + E->canvas = RID(); } - for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *E = canvas->occluders.front(); E; E = E->next()) { - E->get()->canvas = RID(); + for (RendererCanvasRender::LightOccluderInstance *E : canvas->occluders) { + E->canvas = RID(); } canvas_owner.free(p_rid); @@ -2030,8 +2030,8 @@ bool RendererCanvasCull::free(RID p_rid) { RSG::canvas_render->free(occluder_poly->occluder); while (occluder_poly->owners.size()) { - occluder_poly->owners.front()->get()->polygon = RID(); - occluder_poly->owners.erase(occluder_poly->owners.front()); + (*occluder_poly->owners.begin())->polygon = RID(); + occluder_poly->owners.remove(occluder_poly->owners.begin()); } canvas_light_occluder_polygon_owner.free(p_rid); diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h index 637245502d..963cca7630 100644 --- a/servers/rendering/renderer_canvas_cull.h +++ b/servers/rendering/renderer_canvas_cull.h @@ -108,7 +108,7 @@ public: Rect2 aabb; RS::CanvasOccluderPolygonCullMode cull_mode; RID occluder; - Set<RendererCanvasRender::LightOccluderInstance *> owners; + HashSet<RendererCanvasRender::LightOccluderInstance *> owners; LightOccluderPolygon() { active = false; @@ -121,7 +121,7 @@ public: RID_Owner<RendererCanvasRender::LightOccluderInstance, true> canvas_light_occluder_owner; struct Canvas : public RendererViewport::CanvasBase { - Set<RID> viewports; + HashSet<RID> viewports; struct ChildItem { Point2 mirror; Item *item = nullptr; @@ -130,10 +130,10 @@ public: } }; - Set<RendererCanvasRender::Light *> lights; - Set<RendererCanvasRender::Light *> directional_lights; + HashSet<RendererCanvasRender::Light *> lights; + HashSet<RendererCanvasRender::Light *> directional_lights; - Set<RendererCanvasRender::LightOccluderInstance *> occluders; + HashSet<RendererCanvasRender::LightOccluderInstance *> occluders; bool children_order_dirty; Vector<ChildItem> child_items; diff --git a/servers/rendering/renderer_compositor.cpp b/servers/rendering/renderer_compositor.cpp index fa4d9c8b31..b331ec2c1d 100644 --- a/servers/rendering/renderer_compositor.cpp +++ b/servers/rendering/renderer_compositor.cpp @@ -35,6 +35,7 @@ #include "core/string/print_string.h" RendererCompositor *(*RendererCompositor::_create_func)() = nullptr; +bool RendererCompositor::low_end = false; RendererCompositor *RendererCompositor::create() { return _create_func(); diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h index 9466148a31..df3df1077a 100644 --- a/servers/rendering/renderer_compositor.h +++ b/servers/rendering/renderer_compositor.h @@ -71,6 +71,7 @@ private: protected: static RendererCompositor *(*_create_func)(); bool back_end = false; + static bool low_end; public: static RendererCompositor *create(); @@ -97,7 +98,7 @@ public: virtual uint64_t get_frame_number() const = 0; virtual double get_frame_delta_time() const = 0; - _FORCE_INLINE_ virtual bool is_low_end() const { return back_end; }; + static bool is_low_end() { return low_end; }; virtual bool is_xr_enabled() const; RendererCompositor(); diff --git a/servers/rendering/renderer_rd/effects/bokeh_dof.cpp b/servers/rendering/renderer_rd/effects/bokeh_dof.cpp new file mode 100644 index 0000000000..cc7441776d --- /dev/null +++ b/servers/rendering/renderer_rd/effects/bokeh_dof.cpp @@ -0,0 +1,475 @@ +/*************************************************************************/ +/* bokeh_dof.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 "bokeh_dof.h" +#include "copy_effects.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/storage_rd/material_storage.h" +#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" + +using namespace RendererRD; + +BokehDOF::BokehDOF(bool p_prefer_raster_effects) { + prefer_raster_effects = p_prefer_raster_effects; + + // Initialize bokeh + Vector<String> bokeh_modes; + bokeh_modes.push_back("\n#define MODE_GEN_BLUR_SIZE\n"); + bokeh_modes.push_back("\n#define MODE_BOKEH_BOX\n#define OUTPUT_WEIGHT\n"); + bokeh_modes.push_back("\n#define MODE_BOKEH_BOX\n"); + bokeh_modes.push_back("\n#define MODE_BOKEH_HEXAGONAL\n#define OUTPUT_WEIGHT\n"); + bokeh_modes.push_back("\n#define MODE_BOKEH_HEXAGONAL\n"); + bokeh_modes.push_back("\n#define MODE_BOKEH_CIRCULAR\n#define OUTPUT_WEIGHT\n"); + bokeh_modes.push_back("\n#define MODE_COMPOSITE_BOKEH\n"); + if (prefer_raster_effects) { + bokeh.raster_shader.initialize(bokeh_modes); + + bokeh.shader_version = bokeh.raster_shader.version_create(); + + const int att_count[BOKEH_MAX] = { 1, 2, 1, 2, 1, 2, 1 }; + for (int i = 0; i < BOKEH_MAX; i++) { + RD::PipelineColorBlendState blend_state = (i == BOKEH_COMPOSITE) ? RD::PipelineColorBlendState::create_blend(att_count[i]) : RD::PipelineColorBlendState::create_disabled(att_count[i]); + bokeh.raster_pipelines[i].setup(bokeh.raster_shader.version_get_shader(bokeh.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0); + } + } else { + bokeh.compute_shader.initialize(bokeh_modes); + bokeh.compute_shader.set_variant_enabled(BOKEH_GEN_BOKEH_BOX_NOWEIGHT, false); + bokeh.compute_shader.set_variant_enabled(BOKEH_GEN_BOKEH_HEXAGONAL_NOWEIGHT, false); + bokeh.shader_version = bokeh.compute_shader.version_create(); + + for (int i = 0; i < BOKEH_MAX; i++) { + if (bokeh.compute_shader.is_variant_enabled(i)) { + bokeh.compute_pipelines[i] = RD::get_singleton()->compute_pipeline_create(bokeh.compute_shader.version_get_shader(bokeh.shader_version, i)); + } + } + + for (int i = 0; i < BOKEH_MAX; i++) { + bokeh.raster_pipelines[i].clear(); + } + } +} + +BokehDOF::~BokehDOF() { + if (prefer_raster_effects) { + bokeh.raster_shader.version_free(bokeh.shader_version); + } else { + bokeh.compute_shader.version_free(bokeh.shader_version); + } +} + +void BokehDOF::bokeh_dof_compute(const BokehBuffers &p_buffers, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute version of bokeh depth of field with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + // setup our push constant + memset(&bokeh.push_constant, 0, sizeof(BokehPushConstant)); + bokeh.push_constant.blur_far_active = p_dof_far; + bokeh.push_constant.blur_far_begin = p_dof_far_begin; + bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size; + + bokeh.push_constant.blur_near_active = p_dof_near; + bokeh.push_constant.blur_near_begin = p_dof_near_begin; + bokeh.push_constant.blur_near_end = MAX(0, p_dof_near_begin - p_dof_near_size); + bokeh.push_constant.use_jitter = p_use_jitter; + bokeh.push_constant.jitter_seed = Math::randf() * 1000.0; + + bokeh.push_constant.z_near = p_cam_znear; + bokeh.push_constant.z_far = p_cam_zfar; + bokeh.push_constant.orthogonal = p_cam_orthogonal; + bokeh.push_constant.blur_size = p_bokeh_size; + + bokeh.push_constant.second_pass = false; + bokeh.push_constant.half_size = false; + + bokeh.push_constant.blur_scale = 0.5; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_base_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.base_texture })); + RD::Uniform u_depth_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.depth_texture })); + RD::Uniform u_secondary_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.secondary_texture })); + RD::Uniform u_half_texture0(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.half_texture[0] })); + RD::Uniform u_half_texture1(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.half_texture[1] })); + + RD::Uniform u_base_image(RD::UNIFORM_TYPE_IMAGE, 0, p_buffers.base_texture); + RD::Uniform u_secondary_image(RD::UNIFORM_TYPE_IMAGE, 0, p_buffers.secondary_texture); + RD::Uniform u_half_image0(RD::UNIFORM_TYPE_IMAGE, 0, p_buffers.half_texture[0]); + RD::Uniform u_half_image1(RD::UNIFORM_TYPE_IMAGE, 0, p_buffers.half_texture[1]); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + + /* FIRST PASS */ + // The alpha channel of the source color texture is filled with the expected circle size + // If used for DOF far, the size is positive, if used for near, its negative. + + RID shader = bokeh.compute_shader.version_get_shader(bokeh.shader_version, BOKEH_GEN_BLUR_SIZE); + ERR_FAIL_COND(shader.is_null()); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.compute_pipelines[BOKEH_GEN_BLUR_SIZE]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_base_image), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_depth_texture), 1); + + bokeh.push_constant.size[0] = p_buffers.base_texture_size.x; + bokeh.push_constant.size[1] = p_buffers.base_texture_size.y; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_buffers.base_texture_size.x, p_buffers.base_texture_size.y, 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + if (p_bokeh_shape == RS::DOF_BOKEH_BOX || p_bokeh_shape == RS::DOF_BOKEH_HEXAGON) { + //second pass + BokehMode mode = p_bokeh_shape == RS::DOF_BOKEH_BOX ? BOKEH_GEN_BOKEH_BOX : BOKEH_GEN_BOKEH_HEXAGONAL; + shader = bokeh.compute_shader.version_get_shader(bokeh.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.compute_pipelines[mode]); + + static const int quality_samples[4] = { 6, 12, 12, 24 }; + + bokeh.push_constant.steps = quality_samples[p_quality]; + + if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { + //box and hexagon are more or less the same, and they can work in either half (very low and low quality) or full (medium and high quality_ sizes) + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_half_image0), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_base_texture), 1); + + bokeh.push_constant.size[0] = p_buffers.base_texture_size.x >> 1; + bokeh.push_constant.size[1] = p_buffers.base_texture_size.y >> 1; + bokeh.push_constant.half_size = true; + bokeh.push_constant.blur_size *= 0.5; + + } else { + //medium and high quality use full size + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_secondary_image), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_base_texture), 1); + } + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + //third pass + bokeh.push_constant.second_pass = true; + + if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_half_image1), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_half_texture0), 1); + } else { + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_base_image), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_secondary_texture), 1); + } + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { + //forth pass, upscale for low quality + + shader = bokeh.compute_shader.version_get_shader(bokeh.shader_version, BOKEH_COMPOSITE); + ERR_FAIL_COND(shader.is_null()); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.compute_pipelines[BOKEH_COMPOSITE]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_base_image), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_half_texture1), 1); + + bokeh.push_constant.size[0] = p_buffers.base_texture_size.x; + bokeh.push_constant.size[1] = p_buffers.base_texture_size.y; + bokeh.push_constant.half_size = false; + bokeh.push_constant.second_pass = false; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_buffers.base_texture_size.x, p_buffers.base_texture_size.y, 1); + } + } else { + //circle + + shader = bokeh.compute_shader.version_get_shader(bokeh.shader_version, BOKEH_GEN_BOKEH_CIRCULAR); + ERR_FAIL_COND(shader.is_null()); + + //second pass + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.compute_pipelines[BOKEH_GEN_BOKEH_CIRCULAR]); + + static const float quality_scale[4] = { 8.0, 4.0, 1.0, 0.5 }; + + bokeh.push_constant.steps = 0; + bokeh.push_constant.blur_scale = quality_scale[p_quality]; + + //circle always runs in half size, otherwise too expensive + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_half_image0), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_base_texture), 1); + + bokeh.push_constant.size[0] = p_buffers.base_texture_size.x >> 1; + bokeh.push_constant.size[1] = p_buffers.base_texture_size.y >> 1; + bokeh.push_constant.half_size = true; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); + RD::get_singleton()->compute_list_add_barrier(compute_list); + + //circle is just one pass, then upscale + + // upscale + + shader = bokeh.compute_shader.version_get_shader(bokeh.shader_version, BOKEH_COMPOSITE); + ERR_FAIL_COND(shader.is_null()); + + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.compute_pipelines[BOKEH_COMPOSITE]); + + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_base_image), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_half_texture0), 1); + + bokeh.push_constant.size[0] = p_buffers.base_texture_size.x; + bokeh.push_constant.size[1] = p_buffers.base_texture_size.y; + bokeh.push_constant.half_size = false; + bokeh.push_constant.second_pass = false; + + RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_buffers.base_texture_size.x, p_buffers.base_texture_size.y, 1); + } + + RD::get_singleton()->compute_list_end(); +} + +void BokehDOF::bokeh_dof_raster(const BokehBuffers &p_buffers, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_dof_blur_amount, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't blur-based depth of field with the clustered renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + // setup our base push constant + memset(&bokeh.push_constant, 0, sizeof(BokehPushConstant)); + + bokeh.push_constant.orthogonal = p_cam_orthogonal; + bokeh.push_constant.size[0] = p_buffers.base_texture_size.width; + bokeh.push_constant.size[1] = p_buffers.base_texture_size.height; + bokeh.push_constant.z_far = p_cam_zfar; + bokeh.push_constant.z_near = p_cam_znear; + + bokeh.push_constant.second_pass = false; + bokeh.push_constant.half_size = false; + bokeh.push_constant.blur_size = p_dof_blur_amount; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_base_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.base_texture })); + RD::Uniform u_depth_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.depth_texture })); + RD::Uniform u_secondary_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.secondary_texture })); + RD::Uniform u_half_texture0(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.half_texture[0] })); + RD::Uniform u_half_texture1(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.half_texture[1] })); + RD::Uniform u_weight_texture0(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.weight_texture[0] })); + RD::Uniform u_weight_texture1(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.weight_texture[1] })); + RD::Uniform u_weight_texture2(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.weight_texture[2] })); + RD::Uniform u_weight_texture3(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_buffers.weight_texture[3] })); + + if (p_dof_far || p_dof_near) { + if (p_dof_far) { + bokeh.push_constant.blur_far_active = true; + bokeh.push_constant.blur_far_begin = p_dof_far_begin; + bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size; + } + + if (p_dof_near) { + bokeh.push_constant.blur_near_active = true; + bokeh.push_constant.blur_near_begin = p_dof_near_begin; + bokeh.push_constant.blur_near_end = p_dof_near_begin - p_dof_near_size; + } + + { + // generate our depth data + RID shader = bokeh.raster_shader.version_get_shader(bokeh.shader_version, BOKEH_GEN_BLUR_SIZE); + ERR_FAIL_COND(shader.is_null()); + + RID framebuffer = p_buffers.base_weight_fb; + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[BOKEH_GEN_BLUR_SIZE].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_depth_texture), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + } + + if (p_bokeh_shape == RS::DOF_BOKEH_BOX || p_bokeh_shape == RS::DOF_BOKEH_HEXAGON) { + // double pass approach + BokehMode mode = p_bokeh_shape == RS::DOF_BOKEH_BOX ? BOKEH_GEN_BOKEH_BOX : BOKEH_GEN_BOKEH_HEXAGONAL; + + RID shader = bokeh.raster_shader.version_get_shader(bokeh.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { + //box and hexagon are more or less the same, and they can work in either half (very low and low quality) or full (medium and high quality_ sizes) + bokeh.push_constant.size[0] = p_buffers.base_texture_size.x >> 1; + bokeh.push_constant.size[1] = p_buffers.base_texture_size.y >> 1; + bokeh.push_constant.half_size = true; + bokeh.push_constant.blur_size *= 0.5; + } + + static const int quality_samples[4] = { 6, 12, 12, 24 }; + bokeh.push_constant.blur_scale = 0.5; + bokeh.push_constant.steps = quality_samples[p_quality]; + + RID framebuffer = bokeh.push_constant.half_size ? p_buffers.half_fb[0] : p_buffers.secondary_fb; + + // Pass 1 + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_base_texture), 0); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_weight_texture0), 1); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + + // Pass 2 + if (!bokeh.push_constant.half_size) { + // do not output weight, we're writing back into our base buffer + mode = p_bokeh_shape == RS::DOF_BOKEH_BOX ? BOKEH_GEN_BOKEH_BOX_NOWEIGHT : BOKEH_GEN_BOKEH_HEXAGONAL_NOWEIGHT; + + shader = bokeh.raster_shader.version_get_shader(bokeh.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + } + bokeh.push_constant.second_pass = true; + + framebuffer = bokeh.push_constant.half_size ? p_buffers.half_fb[1] : p_buffers.base_fb; + RD::Uniform texture = bokeh.push_constant.half_size ? u_half_texture0 : u_secondary_texture; + RD::Uniform weight = bokeh.push_constant.half_size ? u_weight_texture2 : u_weight_texture1; + + draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, texture), 0); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, weight), 1); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + + if (bokeh.push_constant.half_size) { + // Compose pass + mode = BOKEH_COMPOSITE; + shader = bokeh.raster_shader.version_get_shader(bokeh.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + framebuffer = p_buffers.base_fb; + + draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_half_texture1), 0); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_weight_texture3), 1); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 2, u_weight_texture0), 2); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + } + + } else { + // circular is a single pass approach + BokehMode mode = BOKEH_GEN_BOKEH_CIRCULAR; + + RID shader = bokeh.raster_shader.version_get_shader(bokeh.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + { + // circle always runs in half size, otherwise too expensive (though the code below does support making this optional) + bokeh.push_constant.size[0] = p_buffers.base_texture_size.x >> 1; + bokeh.push_constant.size[1] = p_buffers.base_texture_size.y >> 1; + bokeh.push_constant.half_size = true; + // bokeh.push_constant.blur_size *= 0.5; + } + + static const float quality_scale[4] = { 8.0, 4.0, 1.0, 0.5 }; + bokeh.push_constant.blur_scale = quality_scale[p_quality]; + bokeh.push_constant.steps = 0.0; + + RID framebuffer = bokeh.push_constant.half_size ? p_buffers.half_fb[0] : p_buffers.secondary_fb; + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_base_texture), 0); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_weight_texture0), 1); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + + if (bokeh.push_constant.half_size) { + // Compose + mode = BOKEH_COMPOSITE; + shader = bokeh.raster_shader.version_get_shader(bokeh.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + framebuffer = p_buffers.base_fb; + + draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_half_texture0), 0); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_weight_texture2), 1); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 2, u_weight_texture0), 2); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + } else { + CopyEffects::get_singleton()->copy_raster(p_buffers.secondary_texture, p_buffers.base_fb); + } + } + } +} diff --git a/servers/rendering/renderer_rd/effects/bokeh_dof.h b/servers/rendering/renderer_rd/effects/bokeh_dof.h new file mode 100644 index 0000000000..d7b736119c --- /dev/null +++ b/servers/rendering/renderer_rd/effects/bokeh_dof.h @@ -0,0 +1,120 @@ +/*************************************************************************/ +/* bokeh_dof.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ + +#ifndef BOKEH_DOF_RD_H +#define BOKEH_DOF_RD_H + +#include "servers/rendering/renderer_rd/pipeline_cache_rd.h" +#include "servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl.gen.h" +#include "servers/rendering/renderer_scene_render.h" + +#include "servers/rendering_server.h" + +namespace RendererRD { + +class BokehDOF { +private: + bool prefer_raster_effects; + + struct BokehPushConstant { + uint32_t size[2]; + float z_far; + float z_near; + + uint32_t orthogonal; + float blur_size; + float blur_scale; + uint32_t steps; + + uint32_t blur_near_active; + float blur_near_begin; + float blur_near_end; + uint32_t blur_far_active; + + float blur_far_begin; + float blur_far_end; + uint32_t second_pass; + uint32_t half_size; + + uint32_t use_jitter; + float jitter_seed; + uint32_t pad[2]; + }; + + enum BokehMode { + BOKEH_GEN_BLUR_SIZE, + BOKEH_GEN_BOKEH_BOX, + BOKEH_GEN_BOKEH_BOX_NOWEIGHT, + BOKEH_GEN_BOKEH_HEXAGONAL, + BOKEH_GEN_BOKEH_HEXAGONAL_NOWEIGHT, + BOKEH_GEN_BOKEH_CIRCULAR, + BOKEH_COMPOSITE, + BOKEH_MAX + }; + + struct Bokeh { + BokehPushConstant push_constant; + BokehDofShaderRD compute_shader; + BokehDofRasterShaderRD raster_shader; + RID shader_version; + RID compute_pipelines[BOKEH_MAX]; + PipelineCacheRD raster_pipelines[BOKEH_MAX]; + } bokeh; + +public: + struct BokehBuffers { + // bokeh buffers + + // textures + Size2i base_texture_size; + RID base_texture; + RID depth_texture; + RID secondary_texture; + RID half_texture[2]; + + // raster only + RID base_fb; + RID secondary_fb; // with weights + RID half_fb[2]; // with weights + RID base_weight_fb; + RID weight_texture[4]; + }; + + BokehDOF(bool p_prefer_raster_effects); + ~BokehDOF(); + + void bokeh_dof_compute(const BokehBuffers &p_buffers, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); + void bokeh_dof_raster(const BokehBuffers &p_buffers, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_dof_blur_amount, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); +}; + +} // namespace RendererRD + +#endif // !BOKEH_DOF_RD_H diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp new file mode 100644 index 0000000000..6b786fdf16 --- /dev/null +++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp @@ -0,0 +1,683 @@ +/*************************************************************************/ +/* copy_effects.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 "copy_effects.h" +#include "servers/rendering/renderer_rd/renderer_compositor_rd.h" +#include "servers/rendering/renderer_rd/storage_rd/material_storage.h" +#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h" + +using namespace RendererRD; + +CopyEffects *CopyEffects::singleton = nullptr; + +CopyEffects *CopyEffects::get_singleton() { + return singleton; +} + +CopyEffects::CopyEffects(bool p_prefer_raster_effects) { + singleton = this; + prefer_raster_effects = p_prefer_raster_effects; + + if (prefer_raster_effects) { + // init blur shader (on compute use copy shader) + + Vector<String> blur_modes; + blur_modes.push_back("\n#define MODE_MIPMAP\n"); // BLUR_MIPMAP + blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); // BLUR_MODE_GAUSSIAN_BLUR + blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n"); // BLUR_MODE_GAUSSIAN_GLOW + blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); // BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE + blur_modes.push_back("\n#define MODE_COPY\n"); // BLUR_MODE_COPY + + blur_raster.shader.initialize(blur_modes); + memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); + blur_raster.shader_version = blur_raster.shader.version_create(); + + for (int i = 0; i < BLUR_MODE_MAX; i++) { + blur_raster.pipelines[i].setup(blur_raster.shader.version_get_shader(blur_raster.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + } + + } else { + // not used in clustered + for (int i = 0; i < BLUR_MODE_MAX; i++) { + blur_raster.pipelines[i].clear(); + } + + Vector<String> copy_modes; + copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); + copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define DST_IMAGE_8BIT\n"); + copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n"); + copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); + copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n"); + copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n#define DST_IMAGE_8BIT\n"); + copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n"); + copy_modes.push_back("\n#define MODE_SET_COLOR\n"); + copy_modes.push_back("\n#define MODE_SET_COLOR\n#define DST_IMAGE_8BIT\n"); + copy_modes.push_back("\n#define MODE_MIPMAP\n"); + copy_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n"); + copy_modes.push_back("\n#define MODE_CUBEMAP_TO_PANORAMA\n"); + copy_modes.push_back("\n#define MODE_CUBEMAP_ARRAY_TO_PANORAMA\n"); + + copy.shader.initialize(copy_modes); + memset(©.push_constant, 0, sizeof(CopyPushConstant)); + + copy.shader_version = copy.shader.version_create(); + + for (int i = 0; i < COPY_MODE_MAX; i++) { + if (copy.shader.is_variant_enabled(i)) { + copy.pipelines[i] = RD::get_singleton()->compute_pipeline_create(copy.shader.version_get_shader(copy.shader_version, i)); + } + } + } + + { + Vector<String> copy_modes; + copy_modes.push_back("\n"); + copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n"); + copy_modes.push_back("\n#define MODE_TWO_SOURCES\n"); + copy_modes.push_back("\n#define MULTIVIEW\n"); + copy_modes.push_back("\n#define MULTIVIEW\n#define MODE_TWO_SOURCES\n"); + + copy_to_fb.shader.initialize(copy_modes); + + if (!RendererCompositorRD::singleton->is_xr_enabled()) { + copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW, false); + copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW_WITH_DEPTH, false); + } + + copy_to_fb.shader_version = copy_to_fb.shader.version_create(); + + //use additive + + for (int i = 0; i < COPY_TO_FB_MAX; i++) { + if (copy_to_fb.shader.is_variant_enabled(i)) { + copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); + } else { + copy_to_fb.pipelines[i].clear(); + } + } + } +} + +CopyEffects::~CopyEffects() { + if (prefer_raster_effects) { + blur_raster.shader.version_free(blur_raster.shader_version); + } else { + copy.shader.version_free(copy.shader_version); + } + + copy_to_fb.shader.version_free(copy_to_fb.shader_version); + + singleton = nullptr; +} + +void CopyEffects::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the copy_to_rect shader with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(©.push_constant, 0, sizeof(CopyPushConstant)); + if (p_flip_y) { + copy.push_constant.flags |= COPY_FLAG_FLIP_Y; + } + + if (p_force_luminance) { + copy.push_constant.flags |= COPY_FLAG_FORCE_LUMINANCE; + } + + if (p_all_source) { + copy.push_constant.flags |= COPY_FLAG_ALL_SOURCE; + } + + if (p_alpha_to_one) { + copy.push_constant.flags |= COPY_FLAG_ALPHA_TO_ONE; + } + + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_rect.size.width; + copy.push_constant.section[3] = p_rect.size.height; + copy.push_constant.target[0] = p_rect.position.x; + copy.push_constant.target[1] = p_rect.position.y; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture); + + CopyMode mode = p_8_bit_dst ? COPY_MODE_SIMPLY_COPY_8BIT : COPY_MODE_SIMPLY_COPY; + RID shader = copy.shader.version_get_shader(copy.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); + RD::get_singleton()->compute_list_end(); +} + +void CopyEffects::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the copy_cubemap_to_panorama shader with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(©.push_constant, 0, sizeof(CopyPushConstant)); + + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_panorama_size.width; + copy.push_constant.section[3] = p_panorama_size.height; + copy.push_constant.target[0] = 0; + copy.push_constant.target[1] = 0; + copy.push_constant.camera_z_far = p_lod; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_cube(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_cube })); + RD::Uniform u_dest_panorama(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_panorama); + + CopyMode mode = p_is_array ? COPY_MODE_CUBE_ARRAY_TO_PANORAMA : COPY_MODE_CUBE_TO_PANORAMA; + RID shader = copy.shader.version_get_shader(copy.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_cube), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_panorama), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_panorama_size.width, p_panorama_size.height, 1); + RD::get_singleton()->compute_list_end(); +} + +void CopyEffects::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the copy_depth_to_rect shader with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(©.push_constant, 0, sizeof(CopyPushConstant)); + if (p_flip_y) { + copy.push_constant.flags |= COPY_FLAG_FLIP_Y; + } + + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_rect.size.width; + copy.push_constant.section[3] = p_rect.size.height; + copy.push_constant.target[0] = p_rect.position.x; + copy.push_constant.target[1] = p_rect.position.y; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture); + + CopyMode mode = COPY_MODE_SIMPLY_COPY_DEPTH; + RID shader = copy.shader.version_get_shader(copy.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); + RD::get_singleton()->compute_list_end(); +} + +void CopyEffects::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the copy_depth_to_rect_and_linearize shader with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(©.push_constant, 0, sizeof(CopyPushConstant)); + if (p_flip_y) { + copy.push_constant.flags |= COPY_FLAG_FLIP_Y; + } + + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_rect.size.width; + copy.push_constant.section[3] = p_rect.size.height; + copy.push_constant.target[0] = p_rect.position.x; + copy.push_constant.target[1] = p_rect.position.y; + copy.push_constant.camera_z_far = p_z_far; + copy.push_constant.camera_z_near = p_z_near; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture); + + CopyMode mode = COPY_MODE_LINEARIZE_DEPTH; + RID shader = copy.shader.version_get_shader(copy.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); + RD::get_singleton()->compute_list_end(); +} + +void CopyEffects::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); + + copy_to_fb.push_constant.use_section = true; + copy_to_fb.push_constant.section[0] = p_uv_rect.position.x; + copy_to_fb.push_constant.section[1] = p_uv_rect.position.y; + copy_to_fb.push_constant.section[2] = p_uv_rect.size.x; + copy_to_fb.push_constant.section[3] = p_uv_rect.size.y; + + if (p_flip_y) { + copy_to_fb.push_constant.flip_y = true; + } + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + + CopyToFBMode mode = p_panorama ? COPY_TO_FB_COPY_PANORAMA_TO_DP : COPY_TO_FB_COPY; + RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::DrawListID draw_list = p_draw_list; + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); + RD::get_singleton()->draw_list_draw(draw_list, true); +} + +void CopyEffects::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview) { + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); + + if (p_flip_y) { + copy_to_fb.push_constant.flip_y = true; + } + if (p_force_luminance) { + copy_to_fb.push_constant.force_luminance = true; + } + if (p_alpha_to_zero) { + copy_to_fb.push_constant.alpha_to_zero = true; + } + if (p_srgb) { + copy_to_fb.push_constant.srgb = true; + } + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + + CopyToFBMode mode; + if (p_multiview) { + mode = p_secondary.is_valid() ? COPY_TO_FB_MULTIVIEW_WITH_DEPTH : COPY_TO_FB_MULTIVIEW; + } else { + mode = p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY; + } + + RID shader = copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + if (p_secondary.is_valid()) { + // TODO may need to do this differently when reading from depth buffer for multiview + RD::Uniform u_secondary(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_secondary })); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_secondary), 1); + } + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + +void CopyEffects::copy_raster(RID p_source_texture, RID p_dest_framebuffer) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of the copy with the clustered renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_texture })); + + RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, BLUR_MODE_COPY); + ERR_FAIL_COND(shader.is_null()); + + // Just copy it back (we use our blur raster shader here).. + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[BLUR_MODE_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_texture), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + +void CopyEffects::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian blur with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(©.push_constant, 0, sizeof(CopyPushConstant)); + + copy.push_constant.section[0] = p_region.position.x; + copy.push_constant.section[1] = p_region.position.y; + copy.push_constant.section[2] = p_region.size.width; + copy.push_constant.section[3] = p_region.size.height; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + RD::Uniform u_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_texture); + + CopyMode mode = p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY; + RID shader = copy.shader.version_get_shader(copy.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + //HORIZONTAL + RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_texture), 3); + + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); + + RD::get_singleton()->compute_list_end(); +} + +void CopyEffects::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian glow with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(©.push_constant, 0, sizeof(CopyPushConstant)); + + CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; + uint32_t base_flags = 0; + + copy.push_constant.section[2] = p_size.x; + copy.push_constant.section[3] = p_size.y; + + copy.push_constant.glow_strength = p_strength; + copy.push_constant.glow_bloom = p_bloom; + copy.push_constant.glow_hdr_threshold = p_hdr_bleed_threshold; + copy.push_constant.glow_hdr_scale = p_hdr_bleed_scale; + copy.push_constant.glow_exposure = p_exposure; + copy.push_constant.glow_white = 0; //actually unused + copy.push_constant.glow_luminance_cap = p_luminance_cap; + + copy.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + RD::Uniform u_back_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_back_texture); + + RID shader = copy.shader.version_get_shader(copy.shader_version, copy_mode); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_back_texture), 3); + if (p_auto_exposure.is_valid() && p_first_pass) { + RD::Uniform u_auto_exposure(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_auto_exposure })); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_auto_exposure), 1); + } + + copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); + RD::get_singleton()->compute_list_end(); +} + +void CopyEffects::gaussian_glow_raster(RID p_source_rd_texture, float p_luminance_multiplier, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of the gaussian glow with the clustered renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); + + BlurRasterMode blur_mode = p_first_pass && p_auto_exposure.is_valid() ? BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : BLUR_MODE_GAUSSIAN_GLOW; + uint32_t base_flags = 0; + + blur_raster.push_constant.pixel_size[0] = 1.0 / float(p_size.x); + blur_raster.push_constant.pixel_size[1] = 1.0 / float(p_size.y); + + blur_raster.push_constant.glow_strength = p_strength; + blur_raster.push_constant.glow_bloom = p_bloom; + blur_raster.push_constant.glow_hdr_threshold = p_hdr_bleed_threshold; + blur_raster.push_constant.glow_hdr_scale = p_hdr_bleed_scale; + blur_raster.push_constant.glow_exposure = p_exposure; + blur_raster.push_constant.glow_white = 0; //actually unused + blur_raster.push_constant.glow_luminance_cap = p_luminance_cap; + + blur_raster.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also + + blur_raster.push_constant.luminance_multiplier = p_luminance_multiplier; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + RD::Uniform u_rd_texture_half(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_rd_texture_half })); + + RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode); + ERR_FAIL_COND(shader.is_null()); + + //HORIZONTAL + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer_half, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer_half))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + if (p_auto_exposure.is_valid() && p_first_pass) { + RD::Uniform u_auto_exposure(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_auto_exposure })); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_auto_exposure), 1); + } + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + blur_raster.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL | (p_first_pass ? BLUR_FLAG_GLOW_FIRST_PASS : 0); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); + + blur_mode = BLUR_MODE_GAUSSIAN_GLOW; + + shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, blur_mode); + ERR_FAIL_COND(shader.is_null()); + + //VERTICAL + draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_rd_texture_half), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + + blur_raster.push_constant.flags = base_flags; + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + +void CopyEffects::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the make_mipmap shader with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(©.push_constant, 0, sizeof(CopyPushConstant)); + + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_size.width; + copy.push_constant.section[3] = p_size.height; + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture); + + CopyMode mode = COPY_MODE_MIPMAP; + RID shader = copy.shader.version_get_shader(copy.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); + RD::get_singleton()->compute_list_end(); +} + +void CopyEffects::make_mipmap_raster(RID p_source_rd_texture, RID p_dest_framebuffer, const Size2i &p_size) { + ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of mipmap with the clustered renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + MaterialStorage *material_storage = MaterialStorage::get_singleton(); + ERR_FAIL_NULL(material_storage); + + memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); + + BlurRasterMode mode = BLUR_MIPMAP; + + blur_raster.push_constant.pixel_size[0] = 1.0 / float(p_size.x); + blur_raster.push_constant.pixel_size[1] = 1.0 / float(p_size.y); + + // setup our uniforms + RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); + + RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_rd_texture })); + + RID shader = blur_raster.shader.version_get_shader(blur_raster.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); + RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); + RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); + RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); + + RD::get_singleton()->draw_list_draw(draw_list, true); + RD::get_singleton()->draw_list_end(); +} + +void CopyEffects::set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst) { + ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the set_color shader with the mobile renderer."); + + UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); + ERR_FAIL_NULL(uniform_set_cache); + + memset(©.push_constant, 0, sizeof(CopyPushConstant)); + + copy.push_constant.section[0] = 0; + copy.push_constant.section[1] = 0; + copy.push_constant.section[2] = p_region.size.width; + copy.push_constant.section[3] = p_region.size.height; + copy.push_constant.target[0] = p_region.position.x; + copy.push_constant.target[1] = p_region.position.y; + copy.push_constant.set_color[0] = p_color.r; + copy.push_constant.set_color[1] = p_color.g; + copy.push_constant.set_color[2] = p_color.b; + copy.push_constant.set_color[3] = p_color.a; + + // setup our uniforms + RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_texture); + + CopyMode mode = p_8bit_dst ? COPY_MODE_SET_COLOR_8BIT : COPY_MODE_SET_COLOR; + RID shader = copy.shader.version_get_shader(copy.shader_version, mode); + ERR_FAIL_COND(shader.is_null()); + + RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); + RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[mode]); + RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_texture), 3); + RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); + RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); + RD::get_singleton()->compute_list_end(); +} diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h new file mode 100644 index 0000000000..e522408d20 --- /dev/null +++ b/servers/rendering/renderer_rd/effects/copy_effects.h @@ -0,0 +1,220 @@ +/*************************************************************************/ +/* copy_effects.h */ +/*************************************************************************/ +/* 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. */ +/*************************************************************************/ + +#ifndef COPY_RD_H +#define COPY_RD_H + +#include "servers/rendering/renderer_rd/pipeline_cache_rd.h" +#include "servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/copy.glsl.gen.h" +#include "servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl.gen.h" +#include "servers/rendering/renderer_scene_render.h" + +#include "servers/rendering_server.h" + +namespace RendererRD { + +class CopyEffects { +private: + bool prefer_raster_effects; + + // Blur raster shader + + enum BlurRasterMode { + BLUR_MIPMAP, + + BLUR_MODE_GAUSSIAN_BLUR, + BLUR_MODE_GAUSSIAN_GLOW, + BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE, + BLUR_MODE_COPY, + + BLUR_MODE_MAX + }; + + enum { + BLUR_FLAG_HORIZONTAL = (1 << 0), + BLUR_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 1), + BLUR_FLAG_GLOW_FIRST_PASS = (1 << 2), + }; + + struct BlurRasterPushConstant { + float pixel_size[2]; + uint32_t flags; + uint32_t pad; + + //glow + float glow_strength; + float glow_bloom; + float glow_hdr_threshold; + float glow_hdr_scale; + + float glow_exposure; + float glow_white; + float glow_luminance_cap; + float glow_auto_exposure_grey; + + float luminance_multiplier; + float res1; + float res2; + float res3; + }; + + struct BlurRaster { + BlurRasterPushConstant push_constant; + BlurRasterShaderRD shader; + RID shader_version; + PipelineCacheRD pipelines[BLUR_MODE_MAX]; + } blur_raster; + + // Copy shader + + enum CopyMode { + COPY_MODE_GAUSSIAN_COPY, + COPY_MODE_GAUSSIAN_COPY_8BIT, + COPY_MODE_GAUSSIAN_GLOW, + COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE, + COPY_MODE_SIMPLY_COPY, + COPY_MODE_SIMPLY_COPY_8BIT, + COPY_MODE_SIMPLY_COPY_DEPTH, + COPY_MODE_SET_COLOR, + COPY_MODE_SET_COLOR_8BIT, + COPY_MODE_MIPMAP, + COPY_MODE_LINEARIZE_DEPTH, + COPY_MODE_CUBE_TO_PANORAMA, + COPY_MODE_CUBE_ARRAY_TO_PANORAMA, + COPY_MODE_MAX, + + }; + + enum { + COPY_FLAG_HORIZONTAL = (1 << 0), + COPY_FLAG_USE_COPY_SECTION = (1 << 1), + COPY_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 2), + COPY_FLAG_DOF_NEAR_FIRST_TAP = (1 << 3), + COPY_FLAG_GLOW_FIRST_PASS = (1 << 4), + COPY_FLAG_FLIP_Y = (1 << 5), + COPY_FLAG_FORCE_LUMINANCE = (1 << 6), + COPY_FLAG_ALL_SOURCE = (1 << 7), + COPY_FLAG_HIGH_QUALITY_GLOW = (1 << 8), + COPY_FLAG_ALPHA_TO_ONE = (1 << 9), + }; + + struct CopyPushConstant { + int32_t section[4]; + int32_t target[2]; + uint32_t flags; + uint32_t pad; + // Glow. + float glow_strength; + float glow_bloom; + float glow_hdr_threshold; + float glow_hdr_scale; + + float glow_exposure; + float glow_white; + float glow_luminance_cap; + float glow_auto_exposure_grey; + // DOF. + float camera_z_far; + float camera_z_near; + uint32_t pad2[2]; + //SET color + float set_color[4]; + }; + + struct Copy { + CopyPushConstant push_constant; + CopyShaderRD shader; + RID shader_version; + RID pipelines[COPY_MODE_MAX]; + + } copy; + + // Copy to FB shader + + enum CopyToFBMode { + COPY_TO_FB_COPY, + COPY_TO_FB_COPY_PANORAMA_TO_DP, + COPY_TO_FB_COPY2, + + COPY_TO_FB_MULTIVIEW, + COPY_TO_FB_MULTIVIEW_WITH_DEPTH, + COPY_TO_FB_MAX, + }; + + struct CopyToFbPushConstant { + float section[4]; + float pixel_size[2]; + uint32_t flip_y; + uint32_t use_section; + + uint32_t force_luminance; + uint32_t alpha_to_zero; + uint32_t srgb; + uint32_t pad; + }; + + struct CopyToFb { + CopyToFbPushConstant push_constant; + CopyToFbShaderRD shader; + RID shader_version; + PipelineCacheRD pipelines[COPY_TO_FB_MAX]; + + } copy_to_fb; + + static CopyEffects *singleton; + +public: + static CopyEffects *get_singleton(); + + CopyEffects(bool p_prefer_raster_effects); + ~CopyEffects(); + + void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false, bool p_alpha_to_one = false); + void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array); + void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); + void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far); + void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false); + void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false); + void copy_raster(RID p_source_texture, RID p_dest_framebuffer); + + void gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst = false); + void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); + void gaussian_glow_raster(RID p_source_rd_texture, float p_luminance_multiplier, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); + + void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size); + void make_mipmap_raster(RID p_source_rd_texture, RID p_dest_framebuffer, const Size2i &p_size); + + void set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst = false); +}; + +} // namespace RendererRD + +#endif // !COPY_RD_H diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.cpp b/servers/rendering/renderer_rd/effects/tone_mapper.cpp index e5642116bb..38a4a37b8a 100644 --- a/servers/rendering/renderer_rd/effects/tone_mapper.cpp +++ b/servers/rendering/renderer_rd/effects/tone_mapper.cpp @@ -75,28 +75,9 @@ ToneMapper::ToneMapper() { } } } - - // TODO maybe centralise this in mesh_storage? - { //create index array for copy shaders - Vector<uint8_t> pv; - pv.resize(6 * 4); - { - uint8_t *w = pv.ptrw(); - int *p32 = (int *)w; - p32[0] = 0; - p32[1] = 1; - p32[2] = 2; - p32[3] = 0; - p32[4] = 2; - p32[5] = 3; - } - index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv); - index_array = RD::get_singleton()->index_array_create(index_buffer, 0, 6); - } } ToneMapper::~ToneMapper() { - RD::get_singleton()->free(index_buffer); //array gets freed as dependency tonemap.shader.version_free(tonemap.shader_version); } @@ -154,11 +135,7 @@ void ToneMapper::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Ton RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED); - RD::Uniform u_source_color; - u_source_color.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; - u_source_color.binding = 0; - u_source_color.append_id(default_sampler); - u_source_color.append_id(p_source_color); + RD::Uniform u_source_color(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_color })); RD::Uniform u_exposure_texture; u_exposure_texture.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE; @@ -193,7 +170,7 @@ void ToneMapper::tonemapper(RID p_source_color, RID p_dst_framebuffer, const Ton RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 1, u_exposure_texture), 1); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 2, u_glow_texture, u_glow_map), 2); RD::get_singleton()->draw_list_bind_uniform_set(draw_list, uniform_set_cache->get_cache(shader, 3, u_color_correction_texture), 3); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); + RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array()); RD::get_singleton()->draw_list_set_push_constant(draw_list, &tonemap.push_constant, sizeof(TonemapPushConstant)); RD::get_singleton()->draw_list_draw(draw_list, true); @@ -273,7 +250,7 @@ void ToneMapper::tonemapper(RD::DrawListID p_subpass_draw_list, RID p_source_col RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, uniform_set_cache->get_cache(shader, 1, u_exposure_texture), 1); // should be set to a default texture, it's ignored RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, uniform_set_cache->get_cache(shader, 2, u_glow_texture, u_glow_map), 2); // should be set to a default texture, it's ignored RD::get_singleton()->draw_list_bind_uniform_set(p_subpass_draw_list, uniform_set_cache->get_cache(shader, 3, u_color_correction_texture), 3); - RD::get_singleton()->draw_list_bind_index_array(p_subpass_draw_list, index_array); + RD::get_singleton()->draw_list_bind_index_array(p_subpass_draw_list, material_storage->get_quad_index_array()); RD::get_singleton()->draw_list_set_push_constant(p_subpass_draw_list, &tonemap.push_constant, sizeof(TonemapPushConstant)); RD::get_singleton()->draw_list_draw(p_subpass_draw_list, true); diff --git a/servers/rendering/renderer_rd/effects/tone_mapper.h b/servers/rendering/renderer_rd/effects/tone_mapper.h index 357e814845..a90849dbeb 100644 --- a/servers/rendering/renderer_rd/effects/tone_mapper.h +++ b/servers/rendering/renderer_rd/effects/tone_mapper.h @@ -96,9 +96,6 @@ private: PipelineCacheRD pipelines[TONEMAP_MODE_MAX]; } tonemap; - RID index_buffer; - RID index_array; - public: ToneMapper(); ~ToneMapper(); diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index f05027d569..774745abdc 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -86,7 +86,7 @@ RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) u.append_id(p_texture); uniforms.push_back(u); // anything with the same configuration (one texture in binding 0 for set 0), is good - RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, 0), 0); + RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0), 0); texture_to_uniform_set_cache[p_texture] = uniform_set; @@ -252,295 +252,6 @@ void EffectsRD::fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RI RD::get_singleton()->compute_list_end(compute_list); } -void EffectsRD::copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y, bool p_panorama) { - memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); - - copy_to_fb.push_constant.use_section = true; - copy_to_fb.push_constant.section[0] = p_uv_rect.position.x; - copy_to_fb.push_constant.section[1] = p_uv_rect.position.y; - copy_to_fb.push_constant.section[2] = p_uv_rect.size.x; - copy_to_fb.push_constant.section[3] = p_uv_rect.size.y; - - if (p_flip_y) { - copy_to_fb.push_constant.flip_y = true; - } - - RD::DrawListID draw_list = p_draw_list; - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[p_panorama ? COPY_TO_FB_COPY_PANORAMA_TO_DP : COPY_TO_FB_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, true); -} - -void EffectsRD::copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_alpha_to_zero, bool p_srgb, RID p_secondary, bool p_multiview) { - memset(©_to_fb.push_constant, 0, sizeof(CopyToFbPushConstant)); - - if (p_flip_y) { - copy_to_fb.push_constant.flip_y = true; - } - if (p_force_luminance) { - copy_to_fb.push_constant.force_luminance = true; - } - if (p_alpha_to_zero) { - copy_to_fb.push_constant.alpha_to_zero = true; - } - if (p_srgb) { - copy_to_fb.push_constant.srgb = true; - } - - CopyToFBMode mode; - if (p_multiview) { - mode = p_secondary.is_valid() ? COPY_TO_FB_MULTIVIEW_WITH_DEPTH : COPY_TO_FB_MULTIVIEW; - } else { - mode = p_secondary.is_valid() ? COPY_TO_FB_COPY2 : COPY_TO_FB_COPY; - } - - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, p_rect); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, copy_to_fb.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); - if (p_secondary.is_valid()) { - // TODO may need to do this differently when reading from depth buffer for multiview - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_secondary), 1); - } - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - RD::get_singleton()->draw_list_set_push_constant(draw_list, ©_to_fb.push_constant, sizeof(CopyToFbPushConstant)); - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); -} - -void EffectsRD::copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, bool p_force_luminance, bool p_all_source, bool p_8_bit_dst, bool p_alpha_to_one) { - memset(©.push_constant, 0, sizeof(CopyPushConstant)); - if (p_flip_y) { - copy.push_constant.flags |= COPY_FLAG_FLIP_Y; - } - - if (p_force_luminance) { - copy.push_constant.flags |= COPY_FLAG_FORCE_LUMINANCE; - } - - if (p_all_source) { - copy.push_constant.flags |= COPY_FLAG_ALL_SOURCE; - } - - if (p_alpha_to_one) { - copy.push_constant.flags |= COPY_FLAG_ALPHA_TO_ONE; - } - - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_rect.size.width; - copy.push_constant.section[3] = p_rect.size.height; - copy.push_constant.target[0] = p_rect.position.x; - copy.push_constant.target[1] = p_rect.position.y; - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8_bit_dst ? COPY_MODE_SIMPLY_COPY_8BIT : COPY_MODE_SIMPLY_COPY]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array) { - memset(©.push_constant, 0, sizeof(CopyPushConstant)); - - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_panorama_size.width; - copy.push_constant.section[3] = p_panorama_size.height; - copy.push_constant.target[0] = 0; - copy.push_constant.target[1] = 0; - copy.push_constant.camera_z_far = p_lod; - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_is_array ? COPY_MODE_CUBE_ARRAY_TO_PANORAMA : COPY_MODE_CUBE_TO_PANORAMA]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cube), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_panorama), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_panorama_size.width, p_panorama_size.height, 1); - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far) { - memset(©.push_constant, 0, sizeof(CopyPushConstant)); - if (p_flip_y) { - copy.push_constant.flags |= COPY_FLAG_FLIP_Y; - } - - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_rect.size.width; - copy.push_constant.section[3] = p_rect.size.height; - copy.push_constant.target[0] = p_rect.position.x; - copy.push_constant.target[1] = p_rect.position.y; - copy.push_constant.camera_z_far = p_z_far; - copy.push_constant.camera_z_near = p_z_near; - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_LINEARIZE_DEPTH]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y) { - memset(©.push_constant, 0, sizeof(CopyPushConstant)); - if (p_flip_y) { - copy.push_constant.flags |= COPY_FLAG_FLIP_Y; - } - - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_rect.size.width; - copy.push_constant.section[3] = p_rect.size.height; - copy.push_constant.target[0] = p_rect.position.x; - copy.push_constant.target[1] = p_rect.position.y; - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_SIMPLY_COPY_DEPTH]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_rect.size.width, p_rect.size.height, 1); - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst) { - memset(©.push_constant, 0, sizeof(CopyPushConstant)); - - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_region.size.width; - copy.push_constant.section[3] = p_region.size.height; - copy.push_constant.target[0] = p_region.position.x; - copy.push_constant.target[1] = p_region.position.y; - copy.push_constant.set_color[0] = p_color.r; - copy.push_constant.set_color[1] = p_color.g; - copy.push_constant.set_color[2] = p_color.b; - copy.push_constant.set_color[3] = p_color.a; - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_SET_COLOR_8BIT : COPY_MODE_SET_COLOR]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst) { - ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian blur with the mobile renderer."); - - memset(©.push_constant, 0, sizeof(CopyPushConstant)); - - copy.push_constant.section[0] = p_region.position.x; - copy.push_constant.section[1] = p_region.position.y; - copy.push_constant.section[2] = p_region.size.width; - copy.push_constant.section[3] = p_region.size.height; - - //HORIZONTAL - RD::DrawListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[p_8bit_dst ? COPY_MODE_GAUSSIAN_COPY_8BIT : COPY_MODE_GAUSSIAN_COPY]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_texture), 3); - - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1); - - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { - ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute version of the gaussian glow with the mobile renderer."); - - memset(©.push_constant, 0, sizeof(CopyPushConstant)); - - CopyMode copy_mode = p_first_pass && p_auto_exposure.is_valid() ? COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : COPY_MODE_GAUSSIAN_GLOW; - uint32_t base_flags = 0; - - copy.push_constant.section[2] = p_size.x; - copy.push_constant.section[3] = p_size.y; - - copy.push_constant.glow_strength = p_strength; - copy.push_constant.glow_bloom = p_bloom; - copy.push_constant.glow_hdr_threshold = p_hdr_bleed_threshold; - copy.push_constant.glow_hdr_scale = p_hdr_bleed_scale; - copy.push_constant.glow_exposure = p_exposure; - copy.push_constant.glow_white = 0; //actually unused - copy.push_constant.glow_luminance_cap = p_luminance_cap; - - copy.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[copy_mode]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_back_texture), 3); - if (p_auto_exposure.is_valid() && p_first_pass) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_auto_exposure), 1); - } - - copy.push_constant.flags = base_flags | (p_first_pass ? COPY_FLAG_GLOW_FIRST_PASS : 0) | (p_high_quality ? COPY_FLAG_HIGH_QUALITY_GLOW : 0); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::gaussian_glow_raster(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength, bool p_high_quality, bool p_first_pass, float p_luminance_cap, float p_exposure, float p_bloom, float p_hdr_bleed_threshold, float p_hdr_bleed_scale, RID p_auto_exposure, float p_auto_exposure_grey) { - ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of the gaussian glow with the clustered renderer."); - - memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); - - BlurRasterMode blur_mode = p_first_pass && p_auto_exposure.is_valid() ? BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE : BLUR_MODE_GAUSSIAN_GLOW; - uint32_t base_flags = 0; - - blur_raster.push_constant.pixel_size[0] = p_pixel_size.x; - blur_raster.push_constant.pixel_size[1] = p_pixel_size.y; - - blur_raster.push_constant.glow_strength = p_strength; - blur_raster.push_constant.glow_bloom = p_bloom; - blur_raster.push_constant.glow_hdr_threshold = p_hdr_bleed_threshold; - blur_raster.push_constant.glow_hdr_scale = p_hdr_bleed_scale; - blur_raster.push_constant.glow_exposure = p_exposure; - blur_raster.push_constant.glow_white = 0; //actually unused - blur_raster.push_constant.glow_luminance_cap = p_luminance_cap; - - blur_raster.push_constant.glow_auto_exposure_grey = p_auto_exposure_grey; //unused also - - //HORIZONTAL - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer_half, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer_half))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); - if (p_auto_exposure.is_valid() && p_first_pass) { - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_auto_exposure), 1); - } - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - blur_raster.push_constant.flags = base_flags | BLUR_FLAG_HORIZONTAL | (p_first_pass ? BLUR_FLAG_GLOW_FIRST_PASS : 0); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); - - blur_mode = BLUR_MODE_GAUSSIAN_GLOW; - - //VERTICAL - draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[blur_mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_rd_texture_half), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - blur_raster.push_constant.flags = base_flags; - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); -} - void EffectsRD::screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); @@ -733,43 +444,6 @@ void EffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_bas RD::get_singleton()->draw_list_end(); } -void EffectsRD::make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size) { - memset(©.push_constant, 0, sizeof(CopyPushConstant)); - - copy.push_constant.section[0] = 0; - copy.push_constant.section[1] = 0; - copy.push_constant.section[2] = p_size.width; - copy.push_constant.section[3] = p_size.height; - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, copy.pipelines[COPY_MODE_MIPMAP]); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 3); - RD::get_singleton()->compute_list_set_push_constant(compute_list, ©.push_constant, sizeof(CopyPushConstant)); - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.width, p_size.height, 1); - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::make_mipmap_raster(RID p_source_rd_texture, RID p_dest_framebuffer, const Size2i &p_size) { - ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use the raster version of mipmap with the clustered renderer."); - - memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); - - BlurRasterMode mode = BLUR_MIPMAP; - - blur_raster.push_constant.pixel_size[0] = 1.0 / float(p_size.x); - blur_raster.push_constant.pixel_size[1] = 1.0 / float(p_size.y); - - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dest_framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); -} - void EffectsRD::copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip) { CopyToDPPushConstant push_constant; push_constant.screen_rect[0] = p_rect.position.x; @@ -865,332 +539,6 @@ void EffectsRD::luminance_reduction_raster(RID p_source_texture, const Size2i p_ } } -void EffectsRD::bokeh_dof(const BokehBuffers &p_buffers, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { - ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute version of BOKEH DOF with the mobile renderer."); - - bokeh.push_constant.blur_far_active = p_dof_far; - bokeh.push_constant.blur_far_begin = p_dof_far_begin; - bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size; - - bokeh.push_constant.blur_near_active = p_dof_near; - bokeh.push_constant.blur_near_begin = p_dof_near_begin; - bokeh.push_constant.blur_near_end = MAX(0, p_dof_near_begin - p_dof_near_size); - bokeh.push_constant.use_jitter = p_use_jitter; - bokeh.push_constant.jitter_seed = Math::randf() * 1000.0; - - bokeh.push_constant.z_near = p_cam_znear; - bokeh.push_constant.z_far = p_cam_zfar; - bokeh.push_constant.orthogonal = p_cam_orthogonal; - bokeh.push_constant.blur_size = p_bokeh_size; - - bokeh.push_constant.second_pass = false; - bokeh.push_constant.half_size = false; - - bokeh.push_constant.blur_scale = 0.5; - - RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); - - /* FIRST PASS */ - // The alpha channel of the source color texture is filled with the expected circle size - // If used for DOF far, the size is positive, if used for near, its negative. - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.compute_pipelines[BOKEH_GEN_BLUR_SIZE]); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_buffers.base_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_buffers.depth_texture), 1); - - bokeh.push_constant.size[0] = p_buffers.base_texture_size.x; - bokeh.push_constant.size[1] = p_buffers.base_texture_size.y; - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_buffers.base_texture_size.x, p_buffers.base_texture_size.y, 1); - RD::get_singleton()->compute_list_add_barrier(compute_list); - - if (p_bokeh_shape == RS::DOF_BOKEH_BOX || p_bokeh_shape == RS::DOF_BOKEH_HEXAGON) { - //second pass - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.compute_pipelines[p_bokeh_shape == RS::DOF_BOKEH_BOX ? BOKEH_GEN_BOKEH_BOX : BOKEH_GEN_BOKEH_HEXAGONAL]); - - static const int quality_samples[4] = { 6, 12, 12, 24 }; - - bokeh.push_constant.steps = quality_samples[p_quality]; - - if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { - //box and hexagon are more or less the same, and they can work in either half (very low and low quality) or full (medium and high quality_ sizes) - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_buffers.half_texture[0]), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_buffers.base_texture), 1); - - bokeh.push_constant.size[0] = p_buffers.base_texture_size.x >> 1; - bokeh.push_constant.size[1] = p_buffers.base_texture_size.y >> 1; - bokeh.push_constant.half_size = true; - bokeh.push_constant.blur_size *= 0.5; - - } else { - //medium and high quality use full size - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_buffers.secondary_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_buffers.base_texture), 1); - } - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); - RD::get_singleton()->compute_list_add_barrier(compute_list); - - //third pass - bokeh.push_constant.second_pass = true; - - if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_buffers.half_texture[1]), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_buffers.half_texture[0]), 1); - } else { - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_buffers.base_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_buffers.secondary_texture), 1); - } - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); - RD::get_singleton()->compute_list_add_barrier(compute_list); - - if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { - //forth pass, upscale for low quality - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.compute_pipelines[BOKEH_COMPOSITE]); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_buffers.base_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_buffers.half_texture[1]), 1); - - bokeh.push_constant.size[0] = p_buffers.base_texture_size.x; - bokeh.push_constant.size[1] = p_buffers.base_texture_size.y; - bokeh.push_constant.half_size = false; - bokeh.push_constant.second_pass = false; - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_buffers.base_texture_size.x, p_buffers.base_texture_size.y, 1); - } - } else { - //circle - - //second pass - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.compute_pipelines[BOKEH_GEN_BOKEH_CIRCULAR]); - - static const float quality_scale[4] = { 8.0, 4.0, 1.0, 0.5 }; - - bokeh.push_constant.steps = 0; - bokeh.push_constant.blur_scale = quality_scale[p_quality]; - - //circle always runs in half size, otherwise too expensive - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_buffers.half_texture[0]), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_buffers.base_texture), 1); - - bokeh.push_constant.size[0] = p_buffers.base_texture_size.x >> 1; - bokeh.push_constant.size[1] = p_buffers.base_texture_size.y >> 1; - bokeh.push_constant.half_size = true; - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, bokeh.push_constant.size[0], bokeh.push_constant.size[1], 1); - RD::get_singleton()->compute_list_add_barrier(compute_list); - - //circle is just one pass, then upscale - - // upscale - - RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, bokeh.compute_pipelines[BOKEH_COMPOSITE]); - - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_buffers.base_texture), 0); - RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_buffers.half_texture[0]), 1); - - bokeh.push_constant.size[0] = p_buffers.base_texture_size.x; - bokeh.push_constant.size[1] = p_buffers.base_texture_size.y; - bokeh.push_constant.half_size = false; - bokeh.push_constant.second_pass = false; - - RD::get_singleton()->compute_list_set_push_constant(compute_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_buffers.base_texture_size.x, p_buffers.base_texture_size.y, 1); - } - - RD::get_singleton()->compute_list_end(); -} - -void EffectsRD::bokeh_dof_raster(const BokehBuffers &p_buffers, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_dof_blur_amount, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal) { - ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use blur DOF with the clustered renderer."); - - memset(&bokeh.push_constant, 0, sizeof(BokehPushConstant)); - - bokeh.push_constant.orthogonal = p_cam_orthogonal; - bokeh.push_constant.size[0] = p_buffers.base_texture_size.width; - bokeh.push_constant.size[1] = p_buffers.base_texture_size.height; - bokeh.push_constant.z_far = p_cam_zfar; - bokeh.push_constant.z_near = p_cam_znear; - - bokeh.push_constant.second_pass = false; - bokeh.push_constant.half_size = false; - bokeh.push_constant.blur_size = p_dof_blur_amount; - - if (p_dof_far || p_dof_near) { - if (p_dof_far) { - bokeh.push_constant.blur_far_active = true; - bokeh.push_constant.blur_far_begin = p_dof_far_begin; - bokeh.push_constant.blur_far_end = p_dof_far_begin + p_dof_far_size; - } - - if (p_dof_near) { - bokeh.push_constant.blur_near_active = true; - bokeh.push_constant.blur_near_begin = p_dof_near_begin; - bokeh.push_constant.blur_near_end = p_dof_near_begin - p_dof_near_size; - } - - { - // generate our depth data - RID framebuffer = p_buffers.base_weight_fb; - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[BOKEH_GEN_BLUR_SIZE].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.depth_texture), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); - } - - if (p_bokeh_shape == RS::DOF_BOKEH_BOX || p_bokeh_shape == RS::DOF_BOKEH_HEXAGON) { - // double pass approach - BokehMode mode = p_bokeh_shape == RS::DOF_BOKEH_BOX ? BOKEH_GEN_BOKEH_BOX : BOKEH_GEN_BOKEH_HEXAGONAL; - - if (p_quality == RS::DOF_BLUR_QUALITY_VERY_LOW || p_quality == RS::DOF_BLUR_QUALITY_LOW) { - //box and hexagon are more or less the same, and they can work in either half (very low and low quality) or full (medium and high quality_ sizes) - bokeh.push_constant.size[0] = p_buffers.base_texture_size.x >> 1; - bokeh.push_constant.size[1] = p_buffers.base_texture_size.y >> 1; - bokeh.push_constant.half_size = true; - bokeh.push_constant.blur_size *= 0.5; - } - - static const int quality_samples[4] = { 6, 12, 12, 24 }; - bokeh.push_constant.blur_scale = 0.5; - bokeh.push_constant.steps = quality_samples[p_quality]; - - RID framebuffer = bokeh.push_constant.half_size ? p_buffers.half_fb[0] : p_buffers.secondary_fb; - - // Pass 1 - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.base_texture), 0); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.weight_texture[0]), 1); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); - - // Pass 2 - if (!bokeh.push_constant.half_size) { - // do not output weight, we're writing back into our base buffer - mode = p_bokeh_shape == RS::DOF_BOKEH_BOX ? BOKEH_GEN_BOKEH_BOX_NOWEIGHT : BOKEH_GEN_BOKEH_HEXAGONAL_NOWEIGHT; - } - bokeh.push_constant.second_pass = true; - - framebuffer = bokeh.push_constant.half_size ? p_buffers.half_fb[1] : p_buffers.base_fb; - RID texture = bokeh.push_constant.half_size ? p_buffers.half_texture[0] : p_buffers.secondary_texture; - RID weight = bokeh.push_constant.half_size ? p_buffers.weight_texture[2] : p_buffers.weight_texture[1]; - - draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(texture), 0); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(weight), 1); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); - - if (bokeh.push_constant.half_size) { - // Compose pass - mode = BOKEH_COMPOSITE; - framebuffer = p_buffers.base_fb; - - draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.half_texture[1]), 0); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.weight_texture[3]), 1); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.weight_texture[0]), 2); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); - } - - } else { - // circular is a single pass approach - BokehMode mode = BOKEH_GEN_BOKEH_CIRCULAR; - - { - // circle always runs in half size, otherwise too expensive (though the code below does support making this optional) - bokeh.push_constant.size[0] = p_buffers.base_texture_size.x >> 1; - bokeh.push_constant.size[1] = p_buffers.base_texture_size.y >> 1; - bokeh.push_constant.half_size = true; - // bokeh.push_constant.blur_size *= 0.5; - } - - static const float quality_scale[4] = { 8.0, 4.0, 1.0, 0.5 }; - bokeh.push_constant.blur_scale = quality_scale[p_quality]; - bokeh.push_constant.steps = 0.0; - - RID framebuffer = bokeh.push_constant.half_size ? p_buffers.half_fb[0] : p_buffers.secondary_fb; - - RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.base_texture), 0); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.weight_texture[0]), 1); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); - - if (bokeh.push_constant.half_size) { - // Compose - mode = BOKEH_COMPOSITE; - framebuffer = p_buffers.base_fb; - - draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, bokeh.raster_pipelines[mode].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(framebuffer))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.half_texture[0]), 0); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.weight_texture[2]), 1); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.weight_texture[0]), 2); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - RD::get_singleton()->draw_list_set_push_constant(draw_list, &bokeh.push_constant, sizeof(BokehPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); - } else { - // Just copy it back (we use our blur raster shader here).. - draw_list = RD::get_singleton()->draw_list_begin(p_buffers.base_fb, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD); - RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, blur_raster.pipelines[BLUR_MODE_COPY].get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_buffers.base_fb))); - RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_buffers.secondary_texture), 0); - RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array); - - memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); - RD::get_singleton()->draw_list_set_push_constant(draw_list, &blur_raster.push_constant, sizeof(BlurRasterPushConstant)); - - RD::get_singleton()->draw_list_draw(draw_list, true); - RD::get_singleton()->draw_list_end(); - } - } - } -} - void EffectsRD::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection) { // Downsample and deinterleave the depth buffer for SSAO and SSIL RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); @@ -2152,94 +1500,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { prefer_raster_effects = p_prefer_raster_effects; - if (prefer_raster_effects) { - // init blur shader (on compute use copy shader) - - Vector<String> blur_modes; - blur_modes.push_back("\n#define MODE_MIPMAP\n"); // BLUR_MIPMAP - blur_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); // BLUR_MODE_GAUSSIAN_BLUR - blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n"); // BLUR_MODE_GAUSSIAN_GLOW - blur_modes.push_back("\n#define MODE_GAUSSIAN_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); // BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE - blur_modes.push_back("\n#define MODE_COPY\n"); // BLUR_MODE_COPY - - blur_raster.shader.initialize(blur_modes); - memset(&blur_raster.push_constant, 0, sizeof(BlurRasterPushConstant)); - blur_raster.shader_version = blur_raster.shader.version_create(); - - for (int i = 0; i < BLUR_MODE_MAX; i++) { - blur_raster.pipelines[i].setup(blur_raster.shader.version_get_shader(blur_raster.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); - } - - } else { - // not used in clustered - for (int i = 0; i < BLUR_MODE_MAX; i++) { - blur_raster.pipelines[i].clear(); - } - } - - if (!prefer_raster_effects) { // Initialize copy - Vector<String> copy_modes; - copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n"); - copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define DST_IMAGE_8BIT\n"); - copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n"); - copy_modes.push_back("\n#define MODE_GAUSSIAN_BLUR\n#define MODE_GLOW\n#define GLOW_USE_AUTO_EXPOSURE\n"); - copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n"); - copy_modes.push_back("\n#define MODE_SIMPLE_COPY\n#define DST_IMAGE_8BIT\n"); - copy_modes.push_back("\n#define MODE_SIMPLE_COPY_DEPTH\n"); - copy_modes.push_back("\n#define MODE_SET_COLOR\n"); - copy_modes.push_back("\n#define MODE_SET_COLOR\n#define DST_IMAGE_8BIT\n"); - copy_modes.push_back("\n#define MODE_MIPMAP\n"); - copy_modes.push_back("\n#define MODE_LINEARIZE_DEPTH_COPY\n"); - copy_modes.push_back("\n#define MODE_CUBEMAP_TO_PANORAMA\n"); - copy_modes.push_back("\n#define MODE_CUBEMAP_ARRAY_TO_PANORAMA\n"); - - copy.shader.initialize(copy_modes); - memset(©.push_constant, 0, sizeof(CopyPushConstant)); - - if (prefer_raster_effects) { - // disable shaders we can't use - copy.shader.set_variant_enabled(COPY_MODE_GAUSSIAN_COPY, false); - copy.shader.set_variant_enabled(COPY_MODE_GAUSSIAN_COPY_8BIT, false); - copy.shader.set_variant_enabled(COPY_MODE_GAUSSIAN_GLOW, false); - copy.shader.set_variant_enabled(COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE, false); - } - - copy.shader_version = copy.shader.version_create(); - - for (int i = 0; i < COPY_MODE_MAX; i++) { - if (copy.shader.is_variant_enabled(i)) { - copy.pipelines[i] = RD::get_singleton()->compute_pipeline_create(copy.shader.version_get_shader(copy.shader_version, i)); - } - } - } - { - Vector<String> copy_modes; - copy_modes.push_back("\n"); - copy_modes.push_back("\n#define MODE_PANORAMA_TO_DP\n"); - copy_modes.push_back("\n#define MODE_TWO_SOURCES\n"); - copy_modes.push_back("\n#define MULTIVIEW\n"); - copy_modes.push_back("\n#define MULTIVIEW\n#define MODE_TWO_SOURCES\n"); - - copy_to_fb.shader.initialize(copy_modes); - - if (!RendererCompositorRD::singleton->is_xr_enabled()) { - copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW, false); - copy_to_fb.shader.set_variant_enabled(COPY_TO_FB_MULTIVIEW_WITH_DEPTH, false); - } - - copy_to_fb.shader_version = copy_to_fb.shader.version_create(); - - //use additive - - for (int i = 0; i < COPY_TO_FB_MAX; i++) { - if (copy_to_fb.shader.is_variant_enabled(i)) { - copy_to_fb.pipelines[i].setup(copy_to_fb.shader.version_get_shader(copy_to_fb.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0); - } else { - copy_to_fb.pipelines[i].clear(); - } - } - } - { // Initialize roughness Vector<String> cubemap_roughness_modes; @@ -2311,42 +1571,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) { cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0); } - // Initialize bokeh - Vector<String> bokeh_modes; - bokeh_modes.push_back("\n#define MODE_GEN_BLUR_SIZE\n"); - bokeh_modes.push_back("\n#define MODE_BOKEH_BOX\n#define OUTPUT_WEIGHT\n"); - bokeh_modes.push_back("\n#define MODE_BOKEH_BOX\n"); - bokeh_modes.push_back("\n#define MODE_BOKEH_HEXAGONAL\n#define OUTPUT_WEIGHT\n"); - bokeh_modes.push_back("\n#define MODE_BOKEH_HEXAGONAL\n"); - bokeh_modes.push_back("\n#define MODE_BOKEH_CIRCULAR\n#define OUTPUT_WEIGHT\n"); - bokeh_modes.push_back("\n#define MODE_COMPOSITE_BOKEH\n"); - if (prefer_raster_effects) { - bokeh.raster_shader.initialize(bokeh_modes); - - bokeh.shader_version = bokeh.raster_shader.version_create(); - - const int att_count[BOKEH_MAX] = { 1, 2, 1, 2, 1, 2, 1 }; - for (int i = 0; i < BOKEH_MAX; i++) { - RD::PipelineColorBlendState blend_state = (i == BOKEH_COMPOSITE) ? RD::PipelineColorBlendState::create_blend(att_count[i]) : RD::PipelineColorBlendState::create_disabled(att_count[i]); - bokeh.raster_pipelines[i].setup(bokeh.raster_shader.version_get_shader(bokeh.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), blend_state, 0); - } - } else { - bokeh.compute_shader.initialize(bokeh_modes); - bokeh.compute_shader.set_variant_enabled(BOKEH_GEN_BOKEH_BOX_NOWEIGHT, false); - bokeh.compute_shader.set_variant_enabled(BOKEH_GEN_BOKEH_HEXAGONAL_NOWEIGHT, false); - bokeh.shader_version = bokeh.compute_shader.version_create(); - - for (int i = 0; i < BOKEH_MAX; i++) { - if (bokeh.compute_shader.is_variant_enabled(i)) { - bokeh.compute_pipelines[i] = RD::get_singleton()->compute_pipeline_create(bokeh.compute_shader.version_get_shader(bokeh.shader_version, i)); - } - } - - for (int i = 0; i < BOKEH_MAX; i++) { - bokeh.raster_pipelines[i].clear(); - } - } - if (!prefer_raster_effects) { { // Initialize depth buffer for screen space effects @@ -2837,21 +2061,17 @@ EffectsRD::~EffectsRD() { FSR_upscale.shader.version_free(FSR_upscale.shader_version); if (prefer_raster_effects) { - blur_raster.shader.version_free(blur_raster.shader_version); - bokeh.raster_shader.version_free(blur_raster.shader_version); luminance_reduce_raster.shader.version_free(luminance_reduce_raster.shader_version); roughness.raster_shader.version_free(roughness.shader_version); cubemap_downsampler.raster_shader.version_free(cubemap_downsampler.shader_version); filter.raster_shader.version_free(filter.shader_version); } else { - bokeh.compute_shader.version_free(bokeh.shader_version); luminance_reduce.shader.version_free(luminance_reduce.shader_version); roughness.compute_shader.version_free(roughness.shader_version); cubemap_downsampler.compute_shader.version_free(cubemap_downsampler.shader_version); filter.compute_shader.version_free(filter.shader_version); } if (!prefer_raster_effects) { - copy.shader.version_free(copy.shader_version); resolve.shader.version_free(resolve.shader_version); specular_merge.shader.version_free(specular_merge.shader_version); ss_effects.downsample_shader.version_free(ss_effects.downsample_shader_version); @@ -2875,7 +2095,6 @@ EffectsRD::~EffectsRD() { RD::get_singleton()->free(ssil.importance_map_load_counter); RD::get_singleton()->free(ssil.projection_uniform_buffer); } - copy_to_fb.shader.version_free(copy_to_fb.shader_version); cube_to_dp.shader.version_free(cube_to_dp.shader_version); sort.shader.version_free(sort.shader_version); } diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index 8174e30238..1963935236 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -33,11 +33,6 @@ #include "core/math/camera_matrix.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" -#include "servers/rendering/renderer_rd/shaders/blur_raster.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/bokeh_dof.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/copy.glsl.gen.h" -#include "servers/rendering/renderer_rd/shaders/copy_to_fb.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/cube_to_dp.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/cubemap_downsampler_raster.glsl.gen.h" @@ -95,140 +90,6 @@ private: RID pipeline; } FSR_upscale; - enum BlurRasterMode { - BLUR_MIPMAP, - - BLUR_MODE_GAUSSIAN_BLUR, - BLUR_MODE_GAUSSIAN_GLOW, - BLUR_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE, - BLUR_MODE_COPY, - - BLUR_MODE_MAX - }; - - enum { - BLUR_FLAG_HORIZONTAL = (1 << 0), - BLUR_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 1), - BLUR_FLAG_GLOW_FIRST_PASS = (1 << 2), - }; - - struct BlurRasterPushConstant { - float pixel_size[2]; - uint32_t flags; - uint32_t pad; - - //glow - float glow_strength; - float glow_bloom; - float glow_hdr_threshold; - float glow_hdr_scale; - - float glow_exposure; - float glow_white; - float glow_luminance_cap; - float glow_auto_exposure_grey; - }; - - struct BlurRaster { - BlurRasterPushConstant push_constant; - BlurRasterShaderRD shader; - RID shader_version; - PipelineCacheRD pipelines[BLUR_MODE_MAX]; - } blur_raster; - - enum CopyMode { - COPY_MODE_GAUSSIAN_COPY, - COPY_MODE_GAUSSIAN_COPY_8BIT, - COPY_MODE_GAUSSIAN_GLOW, - COPY_MODE_GAUSSIAN_GLOW_AUTO_EXPOSURE, - COPY_MODE_SIMPLY_COPY, - COPY_MODE_SIMPLY_COPY_8BIT, - COPY_MODE_SIMPLY_COPY_DEPTH, - COPY_MODE_SET_COLOR, - COPY_MODE_SET_COLOR_8BIT, - COPY_MODE_MIPMAP, - COPY_MODE_LINEARIZE_DEPTH, - COPY_MODE_CUBE_TO_PANORAMA, - COPY_MODE_CUBE_ARRAY_TO_PANORAMA, - COPY_MODE_MAX, - - }; - - enum { - COPY_FLAG_HORIZONTAL = (1 << 0), - COPY_FLAG_USE_COPY_SECTION = (1 << 1), - COPY_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 2), - COPY_FLAG_DOF_NEAR_FIRST_TAP = (1 << 3), - COPY_FLAG_GLOW_FIRST_PASS = (1 << 4), - COPY_FLAG_FLIP_Y = (1 << 5), - COPY_FLAG_FORCE_LUMINANCE = (1 << 6), - COPY_FLAG_ALL_SOURCE = (1 << 7), - COPY_FLAG_HIGH_QUALITY_GLOW = (1 << 8), - COPY_FLAG_ALPHA_TO_ONE = (1 << 9), - }; - - struct CopyPushConstant { - int32_t section[4]; - int32_t target[2]; - uint32_t flags; - uint32_t pad; - // Glow. - float glow_strength; - float glow_bloom; - float glow_hdr_threshold; - float glow_hdr_scale; - - float glow_exposure; - float glow_white; - float glow_luminance_cap; - float glow_auto_exposure_grey; - // DOF. - float camera_z_far; - float camera_z_near; - uint32_t pad2[2]; - //SET color - float set_color[4]; - }; - - struct Copy { - CopyPushConstant push_constant; - CopyShaderRD shader; - RID shader_version; - RID pipelines[COPY_MODE_MAX]; - - } copy; - - enum CopyToFBMode { - COPY_TO_FB_COPY, - COPY_TO_FB_COPY_PANORAMA_TO_DP, - COPY_TO_FB_COPY2, - - COPY_TO_FB_MULTIVIEW, - COPY_TO_FB_MULTIVIEW_WITH_DEPTH, - COPY_TO_FB_MAX, - - }; - - struct CopyToFbPushConstant { - float section[4]; - float pixel_size[2]; - uint32_t flip_y; - uint32_t use_section; - - uint32_t force_luminance; - uint32_t alpha_to_zero; - uint32_t srgb; - uint32_t pad; - }; - - struct CopyToFb { - CopyToFbPushConstant push_constant; - CopyToFbShaderRD shader; - RID shader_version; - PipelineCacheRD pipelines[COPY_TO_FB_MAX]; - - } copy_to_fb; - struct CubemapRoughnessPushConstant { uint32_t face_id; uint32_t sample_count; @@ -305,51 +166,6 @@ private: PipelineCacheRD pipeline; } cube_to_dp; - struct BokehPushConstant { - uint32_t size[2]; - float z_far; - float z_near; - - uint32_t orthogonal; - float blur_size; - float blur_scale; - uint32_t steps; - - uint32_t blur_near_active; - float blur_near_begin; - float blur_near_end; - uint32_t blur_far_active; - - float blur_far_begin; - float blur_far_end; - uint32_t second_pass; - uint32_t half_size; - - uint32_t use_jitter; - float jitter_seed; - uint32_t pad[2]; - }; - - enum BokehMode { - BOKEH_GEN_BLUR_SIZE, - BOKEH_GEN_BOKEH_BOX, - BOKEH_GEN_BOKEH_BOX_NOWEIGHT, - BOKEH_GEN_BOKEH_HEXAGONAL, - BOKEH_GEN_BOKEH_HEXAGONAL_NOWEIGHT, - BOKEH_GEN_BOKEH_CIRCULAR, - BOKEH_COMPOSITE, - BOKEH_MAX - }; - - struct Bokeh { - BokehPushConstant push_constant; - BokehDofShaderRD compute_shader; - BokehDofRasterShaderRD raster_shader; - RID shader_version; - RID compute_pipelines[BOKEH_MAX]; - PipelineCacheRD raster_pipelines[BOKEH_MAX]; - } bokeh; - struct SSEffectsDownsamplePushConstant { float pixel_size[2]; float z_far; @@ -792,10 +608,10 @@ private: RID index_buffer; RID index_array; - Map<RID, RID> texture_to_uniform_set_cache; - Map<RID, RID> input_to_uniform_set_cache; + HashMap<RID, RID> texture_to_uniform_set_cache; + HashMap<RID, RID> input_to_uniform_set_cache; - Map<RID, RID> image_to_uniform_set_cache; + HashMap<RID, RID> image_to_uniform_set_cache; struct TexturePair { RID texture1; @@ -821,11 +637,11 @@ private: } }; - Map<TexturePair, RID> texture_pair_to_uniform_set_cache; - Map<RID, RID> texture_to_compute_uniform_set_cache; - Map<TexturePair, RID> texture_pair_to_compute_uniform_set_cache; - Map<TexturePair, RID> image_pair_to_compute_uniform_set_cache; - Map<TextureSamplerPair, RID> texture_sampler_to_compute_uniform_set_cache; + RBMap<TexturePair, RID> texture_pair_to_uniform_set_cache; + RBMap<RID, RID> texture_to_compute_uniform_set_cache; + RBMap<TexturePair, RID> texture_pair_to_compute_uniform_set_cache; + RBMap<TexturePair, RID> image_pair_to_compute_uniform_set_cache; + RBMap<TextureSamplerPair, RID> texture_sampler_to_compute_uniform_set_cache; RID _get_uniform_set_from_image(RID p_texture); RID _get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false); @@ -838,46 +654,13 @@ public: bool get_prefer_raster_effects(); void fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RID p_destination_texture, const Size2i &p_internal_size, const Size2i &p_size, float p_fsr_upscale_sharpness); - void copy_to_fb_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_alpha_to_zero = false, bool p_srgb = false, RID p_secondary = RID(), bool p_multiview = false); - void copy_to_rect(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y = false, bool p_force_luminance = false, bool p_all_source = false, bool p_8_bit_dst = false, bool p_alpha_to_one = false); - void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array); - void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false); - void copy_depth_to_rect_and_linearize(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_rect, bool p_flip_y, float p_z_near, float p_z_far); - void copy_to_atlas_fb(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2 &p_uv_rect, RD::DrawListID p_draw_list, bool p_flip_y = false, bool p_panorama = false); - void gaussian_blur(RID p_source_rd_texture, RID p_texture, const Rect2i &p_region, bool p_8bit_dst = false); - void set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst = false); - void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); - void gaussian_glow_raster(RID p_source_rd_texture, RID p_framebuffer_half, RID p_rd_texture_half, RID p_dest_framebuffer, const Vector2 &p_pixel_size, float p_strength = 1.0, bool p_high_quality = false, bool p_first_pass = false, float p_luminance_cap = 16.0, float p_exposure = 1.0, float p_bloom = 0.0, float p_hdr_bleed_threshold = 1.0, float p_hdr_bleed_scale = 1.0, RID p_auto_exposure = RID(), float p_auto_exposure_grey = 1.0); void cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); void cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size); - void make_mipmap(RID p_source_rd_texture, RID p_dest_texture, const Size2i &p_size); - void make_mipmap_raster(RID p_source_rd_texture, RID p_dest_framebuffer, const Size2i &p_size); void copy_cubemap_to_dp(RID p_source_rd_texture, RID p_dst_framebuffer, const Rect2 &p_rect, const Vector2 &p_dst_size, float p_z_near, float p_z_far, bool p_dp_flip); void luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); void luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false); - struct BokehBuffers { - // bokeh buffers - - // textures - Size2i base_texture_size; - RID base_texture; - RID depth_texture; - RID secondary_texture; - RID half_texture[2]; - - // raster only - RID base_fb; - RID secondary_fb; // with weights - RID half_fb[2]; // with weights - RID base_weight_fb; - RID weight_texture[4]; - }; - - void bokeh_dof(const BokehBuffers &p_buffers, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_bokeh_size, RS::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, bool p_use_jitter, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); - void bokeh_dof_raster(const BokehBuffers &p_buffers, bool p_dof_far, float p_dof_far_begin, float p_dof_far_size, bool p_dof_near, float p_dof_near_begin, float p_dof_near_size, float p_dof_blur_amount, RenderingServer::DOFBokehShape p_bokeh_shape, RS::DOFBlurQuality p_quality, float p_cam_znear, float p_cam_zfar, bool p_cam_orthogonal); - struct SSAOSettings { float radius = 1.0; float intensity = 2.0; 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 4bfaad9fe6..7b92e92f8c 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -1523,7 +1523,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co Vector<Color> c; { Color cc = clear_color.srgb_to_linear(); - if (using_separate_specular) { + if (using_separate_specular || render_buffer) { cc.a = 0; //subsurf scatter must be 0 } c.push_back(cc); @@ -2006,14 +2006,14 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i RID rp_uniform_set = _setup_sdfgi_render_pass_uniform_set(p_albedo_texture, p_emission_texture, p_emission_aniso_texture, p_geom_facing_texture); - Map<Size2i, RID>::Element *E = sdfgi_framebuffer_size_cache.find(fb_size); + HashMap<Size2i, RID>::Iterator E = sdfgi_framebuffer_size_cache.find(fb_size); if (!E) { RID fb = RD::get_singleton()->framebuffer_create_empty(fb_size); E = sdfgi_framebuffer_size_cache.insert(fb_size, fb); } RenderListParameters render_list_params(render_list[RENDER_LIST_SECONDARY].elements.ptr(), render_list[RENDER_LIST_SECONDARY].element_info.ptr(), render_list[RENDER_LIST_SECONDARY].elements.size(), true, pass_mode, 0, true, false, rp_uniform_set, false); - _render_list_with_threads(&render_list_params, E->get(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs); + _render_list_with_threads(&render_list_params, E->value, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, Vector<Color>(), 1.0, 0, Rect2(), sbs); } RD::get_singleton()->draw_command_end_label(); @@ -3276,8 +3276,8 @@ RenderForwardClustered::~RenderForwardClustered() { memdelete_arr(scene_state.lightmap_captures); } - while (sdfgi_framebuffer_size_cache.front()) { - RD::get_singleton()->free(sdfgi_framebuffer_size_cache.front()->get()); - sdfgi_framebuffer_size_cache.erase(sdfgi_framebuffer_size_cache.front()); + while (sdfgi_framebuffer_size_cache.begin()) { + RD::get_singleton()->free(sdfgi_framebuffer_size_cache.begin()->value); + sdfgi_framebuffer_size_cache.remove(sdfgi_framebuffer_size_cache.begin()); } } diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 0e588aecb4..bec10f7f0e 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -106,7 +106,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { RID color_only_fb; RID specular_only_fb; int width, height; - Map<uint32_t, RID> color_framebuffers; + HashMap<uint32_t, RID> color_framebuffers; uint32_t view_count; RID render_sdfgi_uniform_set; @@ -396,7 +396,7 @@ class RenderForwardClustered : public RendererSceneRenderRD { void _fill_instance_data(RenderListType p_render_list, int *p_render_info = nullptr, uint32_t p_offset = 0, int32_t p_max_elements = -1, bool p_update_buffer = true); void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_using_sdfgi = false, bool p_using_opaque_gi = false, bool p_append = false); - Map<Size2i, RID> sdfgi_framebuffer_size_cache; + HashMap<Size2i, RID> sdfgi_framebuffer_size_cache; struct GeometryInstanceData; struct GeometryInstanceForwardClustered; 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 036ad0f18a..bd39dd9c70 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 @@ -154,7 +154,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { print_line(gen_code.defines[i]); } - Map<String, String>::Element *el = gen_code.code.front(); + RBMap<String, String>::Element *el = gen_code.code.front(); while (el) { print_line("\n**code " + el->key() + ":\n" + el->value()); @@ -376,14 +376,14 @@ void SceneShaderForwardClustered::ShaderData::set_default_texture_param(const St } } else { if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = Map<int, RID>(); + default_texture_params[p_name] = HashMap<int, RID>(); } default_texture_params[p_name][p_index] = p_texture; } } void SceneShaderForwardClustered::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - Map<int, StringName> order; + HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { @@ -477,7 +477,7 @@ void SceneShaderForwardClustered::MaterialData::set_next_pass(RID p_pass) { next_pass = p_pass; } -bool SceneShaderForwardClustered::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +bool SceneShaderForwardClustered::MaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton; return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET, RD::BARRIER_MASK_RASTER); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 0b2df983ff..a4eb0656b7 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -138,14 +138,14 @@ public: String path; - Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; String code; - Map<StringName, Map<int, RID>> default_texture_params; + HashMap<StringName, HashMap<int, RID>> default_texture_params; DepthDraw depth_draw; DepthTest depth_test; @@ -208,7 +208,7 @@ public: uint8_t priority; virtual void set_render_priority(int p_priority); virtual void set_next_pass(RID p_pass); - virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); + virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); virtual ~MaterialData(); }; @@ -239,7 +239,7 @@ public: ShaderData *overdraw_material_shader_ptr = nullptr; Vector<RD::PipelineSpecializationConstant> default_specialization_constants; - Set<uint32_t> valid_color_pass_pipelines; + HashSet<uint32_t> valid_color_pass_pipelines; SceneShaderForwardClustered(); ~SceneShaderForwardClustered(); 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 cdddc35579..a3cabb0693 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 @@ -154,7 +154,7 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { print_line(gen_code.defines[i]); } - Map<String, String>::Element * el = gen_code.code.front(); + RBMap<String, String>::Element * el = gen_code.code.front(); while (el) { print_line("\n**code " + el->key() + ":\n" + el->value()); @@ -339,14 +339,14 @@ void SceneShaderForwardMobile::ShaderData::set_default_texture_param(const Strin } } else { if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = Map<int, RID>(); + default_texture_params[p_name] = HashMap<int, RID>(); } default_texture_params[p_name][p_index] = p_texture; } } void SceneShaderForwardMobile::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - Map<int, StringName> order; + HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { @@ -440,7 +440,7 @@ void SceneShaderForwardMobile::MaterialData::set_next_pass(RID p_pass) { next_pass = p_pass; } -bool SceneShaderForwardMobile::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +bool SceneShaderForwardMobile::MaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { SceneShaderForwardMobile *shader_singleton = (SceneShaderForwardMobile *)SceneShaderForwardMobile::singleton; return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardMobile::MATERIAL_UNIFORM_SET, RD::BARRIER_MASK_RASTER); diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index 50b5fb26ec..f325d5c0a5 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -104,14 +104,14 @@ public: String path; - Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; String code; - Map<StringName, Map<int, RID>> default_texture_params; + HashMap<StringName, HashMap<int, RID>> default_texture_params; DepthDraw depth_draw; DepthTest depth_test; @@ -171,7 +171,7 @@ public: uint8_t priority; virtual void set_render_priority(int p_priority); virtual void set_next_pass(RID p_pass); - virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); + virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); virtual ~MaterialData(); }; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 386bc18fcd..3c2f3f8a42 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -2160,14 +2160,14 @@ void RendererCanvasRenderRD::CanvasShaderData::set_default_texture_param(const S } } else { if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = Map<int, RID>(); + default_texture_params[p_name] = HashMap<int, RID>(); } default_texture_params[p_name][p_index] = p_texture; } } void RendererCanvasRenderRD::CanvasShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - Map<int, StringName> order; + HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) { @@ -2246,7 +2246,7 @@ RendererRD::ShaderData *RendererCanvasRenderRD::_create_shader_func() { return shader_data; } -bool RendererCanvasRenderRD::CanvasMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +bool RendererCanvasRenderRD::CanvasMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { RendererCanvasRenderRD *canvas_singleton = static_cast<RendererCanvasRenderRD *>(RendererCanvasRender::singleton); return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, canvas_singleton->shader.canvas_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET); diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h index 06970acca6..04881ce7e6 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h @@ -166,14 +166,14 @@ class RendererCanvasRenderRD : public RendererCanvasRender { PipelineVariants pipeline_variants; String path; - Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; uint32_t ubo_size = 0; String code; - Map<StringName, Map<int, RID>> default_texture_params; + HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_screen_texture = false; bool uses_sdf = false; @@ -205,7 +205,7 @@ class RendererCanvasRenderRD : public RendererCanvasRender { virtual void set_render_priority(int p_priority) {} virtual void set_next_pass(RID p_pass) {} - virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); + virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); virtual ~CanvasMaterialData(); }; diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h index 26bd28286b..aefc189f68 100644 --- a/servers/rendering/renderer_rd/renderer_compositor_rd.h +++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h @@ -90,7 +90,7 @@ protected: RID sampler; } blit; - Map<RID, RID> render_target_descriptors; + HashMap<RID, RID> render_target_descriptors; double time = 0.0; double delta = 0.0; @@ -131,6 +131,7 @@ public: static void make_current() { _create_func = _create_current; + low_end = false; } static RendererCompositorRD *singleton; diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp index 5cbacb0ef3..7aede6bb48 100644 --- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp @@ -1115,6 +1115,7 @@ void RendererSceneGIRD::SDFGI::update_cascades() { void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); + RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); if (!debug_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set)) { Vector<RD::Uniform> uniforms; @@ -1251,7 +1252,7 @@ void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, cons RD::get_singleton()->compute_list_end(); Size2 rtsize = texture_storage->render_target_get_size(p_render_target); - storage->get_effects()->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true); + copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true); } void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index bf65dca56a..9e798e8b6d 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1556,8 +1556,6 @@ void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) { uint32_t mipmaps_required = Image::get_image_required_mipmaps(rb->width, rb->height, Image::FORMAT_RGBAH); - // TODO make sure texture_create_shared_from_slice works for multiview - RD::TextureFormat tf; tf.format = _render_buffers_get_color_format(); // RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.width = rb->internal_width; @@ -1583,55 +1581,63 @@ void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) { tf.mipmaps--; rb->blur[1].texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); - int base_width = rb->internal_width; - int base_height = rb->internal_height; + for (uint32_t l = 0; l < rb->view_count; l++) { + RenderBuffers::Blur::Layer ll[2]; + int base_width = rb->internal_width; + int base_height = rb->internal_height; - for (uint32_t i = 0; i < mipmaps_required; i++) { - RenderBuffers::Blur::Mipmap mm; - mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[0].texture, 0, i); + for (uint32_t i = 0; i < mipmaps_required; i++) { + RenderBuffers::Blur::Mipmap mm; + mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[0].texture, l, i); - mm.width = base_width; - mm.height = base_height; + mm.width = base_width; + mm.height = base_height; - if (!_render_buffers_can_be_storage()) { - Vector<RID> fb; - fb.push_back(mm.texture); - - mm.fb = RD::get_singleton()->framebuffer_create(fb); - } + if (!_render_buffers_can_be_storage()) { + Vector<RID> fb; + fb.push_back(mm.texture); - if (!_render_buffers_can_be_storage()) { - // and half texture, this is an intermediate result so just allocate a texture, is this good enough? - tf.width = MAX(1, base_width >> 1); - tf.height = base_height; - tf.mipmaps = 1; // 1 or 0? + mm.fb = RD::get_singleton()->framebuffer_create(fb); + } - mm.half_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); + if (!_render_buffers_can_be_storage()) { + // and half texture, this is an intermediate result so just allocate a texture, is this good enough? + tf.width = MAX(1, base_width >> 1); + tf.height = base_height; + tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = 1; + tf.mipmaps = 1; + + mm.half_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); + + Vector<RID> half_fb; + half_fb.push_back(mm.half_texture); + mm.half_fb = RD::get_singleton()->framebuffer_create(half_fb); + } - Vector<RID> half_fb; - half_fb.push_back(mm.half_texture); - mm.half_fb = RD::get_singleton()->framebuffer_create(half_fb); - } + ll[0].mipmaps.push_back(mm); - rb->blur[0].mipmaps.push_back(mm); + if (i > 0) { + mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[1].texture, l, i - 1); - if (i > 0) { - mm.texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->blur[1].texture, 0, i - 1); + if (!_render_buffers_can_be_storage()) { + Vector<RID> fb; + fb.push_back(mm.texture); - if (!_render_buffers_can_be_storage()) { - Vector<RID> fb; - fb.push_back(mm.texture); + mm.fb = RD::get_singleton()->framebuffer_create(fb); - mm.fb = RD::get_singleton()->framebuffer_create(fb); + // We can re-use the half texture here as it is an intermediate result + } - // We can re-use the half texture here as it is an intermediate result + ll[1].mipmaps.push_back(mm); } - rb->blur[1].mipmaps.push_back(mm); + base_width = MAX(1, base_width >> 1); + base_height = MAX(1, base_height >> 1); } - base_width = MAX(1, base_width >> 1); - base_height = MAX(1, base_height >> 1); + rb->blur[0].layers.push_back(ll[0]); + rb->blur[1].layers.push_back(ll[1]); } if (!_render_buffers_can_be_storage()) { @@ -1640,21 +1646,19 @@ void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) { tf.format = RD::DATA_FORMAT_R16_SFLOAT; // We could probably use DATA_FORMAT_R8_SNORM if we don't pre-multiply by blur_size but that depends on whether we can remove DEPTH_GAP tf.width = rb->internal_width; tf.height = rb->internal_height; - tf.texture_type = rb->view_count > 1 ? RD::TEXTURE_TYPE_2D_ARRAY : RD::TEXTURE_TYPE_2D; - tf.array_layers = rb->view_count; + tf.texture_type = RD::TEXTURE_TYPE_2D; + tf.array_layers = 1; // Our DOF effect handles one eye per turn tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT; tf.mipmaps = 1; for (uint32_t i = 0; i < 4; i++) { // associated blur texture RID texture; - if (i == 0) { - texture = rb->texture; - } else if (i == 1) { - texture = rb->blur[0].mipmaps[0].texture; + if (i == 1) { + texture = rb->blur[0].layers[0].mipmaps[0].texture; } else if (i == 2) { - texture = rb->blur[1].mipmaps[0].texture; + texture = rb->blur[1].layers[0].mipmaps[0].texture; } else if (i == 3) { - texture = rb->blur[0].mipmaps[1].texture; + texture = rb->blur[0].layers[0].mipmaps[1].texture; } // create weight texture @@ -1662,7 +1666,9 @@ void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) { // create frame buffer Vector<RID> fb; - fb.push_back(texture); + if (i != 0) { + fb.push_back(texture); + } fb.push_back(rb->weight_buffers[i].weight); rb->weight_buffers[i].fb = RD::get_singleton()->framebuffer_create(fb); @@ -1672,13 +1678,6 @@ void RendererSceneRenderRD::_allocate_blur_textures(RenderBuffers *rb) { tf.height = MAX(1u, tf.height >> 1); } } - - { - // and finally an FB for just our base weights - Vector<RID> fb; - fb.push_back(rb->weight_buffers[0].weight); - rb->base_weight_fb = RD::get_singleton()->framebuffer_create(fb); - } } } @@ -1765,6 +1764,21 @@ void RendererSceneRenderRD::_allocate_luminance_textures(RenderBuffers *rb) { } void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { + if (rb->views.size() > 1) { // if 1 these are copies ofs rb->internal_texture, rb->depth_texture and rb->texture_fb + for (int i = 0; i < rb->views.size(); i++) { + if (rb->views[i].view_fb.is_valid()) { + RD::get_singleton()->free(rb->views[i].view_fb); + } + if (rb->views[i].view_texture.is_valid()) { + RD::get_singleton()->free(rb->views[i].view_texture); + } + if (rb->views[i].view_depth.is_valid()) { + RD::get_singleton()->free(rb->views[i].view_depth); + } + } + } + rb->views.clear(); + if (rb->texture_fb.is_valid()) { RD::get_singleton()->free(rb->texture_fb); rb->texture_fb = RID(); @@ -1813,24 +1827,26 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { } for (int i = 0; i < 2; i++) { - for (int m = 0; m < rb->blur[i].mipmaps.size(); m++) { - // do we free the texture slice here? or is it enough to free the main texture? + for (int l = 0; l < rb->blur[i].layers.size(); l++) { + for (int m = 0; m < rb->blur[i].layers[l].mipmaps.size(); m++) { + // do we free the texture slice here? or is it enough to free the main texture? - // do free the mobile extra stuff - if (rb->blur[i].mipmaps[m].fb.is_valid()) { - RD::get_singleton()->free(rb->blur[i].mipmaps[m].fb); - } - // texture and framebuffer in both blur mipmaps are shared, so only free from the first one - if (i == 0) { - if (rb->blur[i].mipmaps[m].half_fb.is_valid()) { - RD::get_singleton()->free(rb->blur[i].mipmaps[m].half_fb); + // do free the mobile extra stuff + if (rb->blur[i].layers[l].mipmaps[m].fb.is_valid()) { + RD::get_singleton()->free(rb->blur[i].layers[l].mipmaps[m].fb); } - if (rb->blur[i].mipmaps[m].half_texture.is_valid()) { - RD::get_singleton()->free(rb->blur[i].mipmaps[m].half_texture); + // texture and framebuffer in both blur mipmaps are shared, so only free from the first one + if (i == 0) { + if (rb->blur[i].layers[l].mipmaps[m].half_fb.is_valid()) { + RD::get_singleton()->free(rb->blur[i].layers[l].mipmaps[m].half_fb); + } + if (rb->blur[i].layers[l].mipmaps[m].half_texture.is_valid()) { + RD::get_singleton()->free(rb->blur[i].layers[l].mipmaps[m].half_texture); + } } } } - rb->blur[i].mipmaps.clear(); + rb->blur[i].layers.clear(); if (rb->blur[i].texture.is_valid()) { RD::get_singleton()->free(rb->blur[i].texture); @@ -1998,8 +2014,8 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb _allocate_blur_textures(rb); } - storage->get_effects()->screen_space_reflection(rb->internal_texture, p_normal_buffer, ssr_roughness_quality, rb->ssr.blur_radius[0], rb->ssr.blur_radius[1], p_metallic, p_metallic_mask, rb->depth_texture, rb->ssr.depth_scaled, rb->ssr.normal_scaled, rb->blur[0].mipmaps[1].texture, rb->blur[1].mipmaps[0].texture, Size2i(rb->internal_width / 2, rb->internal_height / 2), env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, p_projection); - storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->blur[0].mipmaps[1].texture); + storage->get_effects()->screen_space_reflection(rb->internal_texture, p_normal_buffer, ssr_roughness_quality, rb->ssr.blur_radius[0], rb->ssr.blur_radius[1], p_metallic, p_metallic_mask, rb->depth_texture, rb->ssr.depth_scaled, rb->ssr.normal_scaled, rb->blur[0].layers[0].mipmaps[1].texture, rb->blur[1].layers[0].mipmaps[0].texture, Size2i(rb->internal_width / 2, rb->internal_height / 2), env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, p_projection); + storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->blur[0].layers[0].mipmaps[1].texture); } void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { @@ -2295,14 +2311,14 @@ void RendererSceneRenderRD::_copy_framebuffer_to_ssil(RID p_render_buffers) { ERR_FAIL_COND(!rb); if (rb->ss_effects.last_frame.is_valid()) { - storage->get_effects()->copy_to_rect(rb->texture, rb->ss_effects.last_frame, Rect2i(0, 0, rb->width, rb->height)); + copy_effects->copy_to_rect(rb->texture, rb->ss_effects.last_frame, Rect2i(0, 0, rb->width, rb->height)); int width = rb->width; int height = rb->height; for (int i = 0; i < rb->ss_effects.last_frame_slices.size() - 1; i++) { width = MAX(1, width >> 1); height = MAX(1, height >> 1); - storage->get_effects()->make_mipmap(rb->ss_effects.last_frame_slices[i], rb->ss_effects.last_frame_slices[i + 1], Size2i(width, height)); + copy_effects->make_mipmap(rb->ss_effects.last_frame_slices[i], rb->ss_effects.last_frame_slices[i + 1], Size2i(width, height)); } } } @@ -2317,19 +2333,19 @@ void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderData _allocate_blur_textures(rb); } - // @TODO IMPLEMENT MULTIVIEW, all effects need to support stereo buffers or effects are only applied to the left eye - bool can_use_storage = _render_buffers_can_be_storage(); - if (can_use_storage) { - storage->get_effects()->copy_to_rect(rb->texture, rb->blur[0].mipmaps[0].texture, Rect2i(0, 0, rb->width, rb->height)); - for (int i = 1; i < rb->blur[0].mipmaps.size(); i++) { - storage->get_effects()->make_mipmap(rb->blur[0].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i].texture, Size2i(rb->blur[0].mipmaps[i].width, rb->blur[0].mipmaps[i].height)); - } - } else { - storage->get_effects()->copy_to_fb_rect(rb->texture, rb->blur[0].mipmaps[0].fb, Rect2i(0, 0, rb->width, rb->height)); - for (int i = 1; i < rb->blur[0].mipmaps.size(); i++) { - storage->get_effects()->make_mipmap_raster(rb->blur[0].mipmaps[i - 1].texture, rb->blur[0].mipmaps[i].fb, Size2i(rb->blur[0].mipmaps[i].width, rb->blur[0].mipmaps[i].height)); + for (uint32_t v = 0; v < rb->view_count; v++) { + if (can_use_storage) { + copy_effects->copy_to_rect(rb->views[v].view_texture, rb->blur[0].layers[v].mipmaps[0].texture, Rect2i(0, 0, rb->width, rb->height)); + for (int i = 1; i < rb->blur[0].layers[v].mipmaps.size(); i++) { + copy_effects->make_mipmap(rb->blur[0].layers[v].mipmaps[i - 1].texture, rb->blur[0].layers[v].mipmaps[i].texture, Size2i(rb->blur[0].layers[v].mipmaps[i].width, rb->blur[0].layers[v].mipmaps[i].height)); + } + } else { + copy_effects->copy_to_fb_rect(rb->views[v].view_texture, rb->blur[0].layers[v].mipmaps[0].fb, Rect2i(0, 0, rb->width, rb->height)); + for (int i = 1; i < rb->blur[0].layers[v].mipmaps.size(); i++) { + copy_effects->make_mipmap_raster(rb->blur[0].layers[v].mipmaps[i - 1].texture, rb->blur[0].layers[v].mipmaps[i].fb, Size2i(rb->blur[0].layers[v].mipmaps[i].width, rb->blur[0].layers[v].mipmaps[i].height)); + } } } @@ -2351,9 +2367,9 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR bool can_use_storage = _render_buffers_can_be_storage(); if (can_use_storage) { - storage->get_effects()->copy_to_rect(rb->depth_texture, rb->depth_back_texture, Rect2i(0, 0, rb->width, rb->height)); + copy_effects->copy_to_rect(rb->depth_texture, rb->depth_back_texture, Rect2i(0, 0, rb->width, rb->height)); } else { - storage->get_effects()->copy_to_fb_rect(rb->depth_texture, rb->depth_back_fb, Rect2i(0, 0, rb->width, rb->height)); + copy_effects->copy_to_fb_rect(rb->depth_texture, rb->depth_back_fb, Rect2i(0, 0, rb->width, rb->height)); } RD::get_singleton()->draw_command_end_label(); @@ -2371,30 +2387,34 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende bool can_use_effects = rb->width >= 8 && rb->height >= 8; bool can_use_storage = _render_buffers_can_be_storage(); - // @TODO IMPLEMENT MULTIVIEW, all effects need to support stereo buffers or effects are only applied to the left eye - if (can_use_effects && camfx && (camfx->dof_blur_near_enabled || camfx->dof_blur_far_enabled) && camfx->dof_blur_amount > 0.0) { + RENDER_TIMESTAMP("Depth of Field"); RD::get_singleton()->draw_command_begin_label("DOF"); if (rb->blur[0].texture.is_null()) { _allocate_blur_textures(rb); } - EffectsRD::BokehBuffers buffers; + RendererRD::BokehDOF::BokehBuffers buffers; // Textures we use buffers.base_texture_size = Size2i(rb->internal_width, rb->internal_height); - buffers.base_texture = rb->internal_texture; - buffers.depth_texture = rb->depth_texture; - buffers.secondary_texture = rb->blur[0].mipmaps[0].texture; - buffers.half_texture[0] = rb->blur[1].mipmaps[0].texture; - buffers.half_texture[1] = rb->blur[0].mipmaps[1].texture; + buffers.secondary_texture = rb->blur[0].layers[0].mipmaps[0].texture; + buffers.half_texture[0] = rb->blur[1].layers[0].mipmaps[0].texture; + buffers.half_texture[1] = rb->blur[0].layers[0].mipmaps[1].texture; float bokeh_size = camfx->dof_blur_amount * 64.0; if (can_use_storage) { - storage->get_effects()->bokeh_dof(buffers, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_orthogonal); + for (uint32_t i = 0; i < rb->view_count; i++) { + buffers.base_texture = rb->views[i].view_texture; + buffers.depth_texture = rb->views[i].view_depth; + + // In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum + float z_near = p_render_data->view_projection[i].get_z_near(); + float z_far = p_render_data->view_projection[i].get_z_far(); + bokeh_dof->bokeh_dof_compute(buffers, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, dof_blur_use_jitter, z_near, z_far, p_render_data->cam_orthogonal); + }; } else { // Set framebuffers. - buffers.base_fb = rb->texture_fb; buffers.secondary_fb = rb->weight_buffers[1].fb; buffers.half_fb[0] = rb->weight_buffers[2].fb; buffers.half_fb[1] = rb->weight_buffers[3].fb; @@ -2404,14 +2424,24 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende buffers.weight_texture[3] = rb->weight_buffers[3].weight; // Set weight buffers. - buffers.base_weight_fb = rb->base_weight_fb; + buffers.base_weight_fb = rb->weight_buffers[0].fb; + + for (uint32_t i = 0; i < rb->view_count; i++) { + buffers.base_texture = rb->views[i].view_texture; + buffers.depth_texture = rb->views[i].view_depth; + buffers.base_fb = rb->views[i].view_fb; - storage->get_effects()->bokeh_dof_raster(buffers, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, p_render_data->z_near, p_render_data->z_far, p_render_data->cam_orthogonal); + // In stereo p_render_data->z_near and p_render_data->z_far can be offset for our combined frustrum + float z_near = p_render_data->view_projection[i].get_z_near(); + float z_far = p_render_data->view_projection[i].get_z_far(); + bokeh_dof->bokeh_dof_raster(buffers, camfx->dof_blur_far_enabled, camfx->dof_blur_far_distance, camfx->dof_blur_far_transition, camfx->dof_blur_near_enabled, camfx->dof_blur_near_distance, camfx->dof_blur_near_transition, bokeh_size, dof_blur_bokeh_shape, dof_blur_quality, z_near, z_far, p_render_data->cam_orthogonal); + } } RD::get_singleton()->draw_command_end_label(); } if (can_use_effects && env && env->auto_exposure) { + RENDER_TIMESTAMP("Auto exposure"); RD::get_singleton()->draw_command_begin_label("Auto exposure"); if (rb->luminance.current.is_null()) { _allocate_luminance_textures(rb); @@ -2439,6 +2469,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende int max_glow_level = -1; if (can_use_effects && env && env->glow_enabled) { + RENDER_TIMESTAMP("Glow"); RD::get_singleton()->draw_command_begin_label("Gaussian Glow"); /* see that blur textures are allocated */ @@ -2449,33 +2480,36 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { if (env->glow_levels[i] > 0.0) { - if (i >= rb->blur[1].mipmaps.size()) { - max_glow_level = rb->blur[1].mipmaps.size() - 1; + if (i >= rb->blur[1].layers[0].mipmaps.size()) { + max_glow_level = rb->blur[1].layers[0].mipmaps.size() - 1; } else { max_glow_level = i; } } } - for (int i = 0; i < (max_glow_level + 1); i++) { - int vp_w = rb->blur[1].mipmaps[i].width; - int vp_h = rb->blur[1].mipmaps[i].height; + float luminance_multiplier = _render_buffers_get_luminance_multiplier(); + for (uint32_t l = 0; l < rb->view_count; l++) { + for (int i = 0; i < (max_glow_level + 1); i++) { + int vp_w = rb->blur[1].layers[l].mipmaps[i].width; + int vp_h = rb->blur[1].layers[l].mipmaps[i].height; - if (i == 0) { - RID luminance_texture; - if (env->auto_exposure && rb->luminance.current.is_valid()) { - luminance_texture = rb->luminance.current; - } - if (can_use_storage) { - storage->get_effects()->gaussian_glow(rb->internal_texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); - } else { - storage->get_effects()->gaussian_glow_raster(rb->internal_texture, rb->blur[1].mipmaps[i].half_fb, rb->blur[1].mipmaps[i].half_texture, rb->blur[1].mipmaps[i].fb, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); - } - } else { - if (can_use_storage) { - storage->get_effects()->gaussian_glow(rb->blur[1].mipmaps[i - 1].texture, rb->blur[1].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); + if (i == 0) { + RID luminance_texture; + if (env->auto_exposure && rb->luminance.current.is_valid()) { + luminance_texture = rb->luminance.current; + } + if (can_use_storage) { + copy_effects->gaussian_glow(rb->views[l].view_texture, rb->blur[1].layers[l].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + } else { + copy_effects->gaussian_glow_raster(rb->views[l].view_texture, luminance_multiplier, rb->blur[1].layers[l].mipmaps[i].half_fb, rb->blur[1].layers[l].mipmaps[i].half_texture, rb->blur[1].layers[l].mipmaps[i].fb, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality, true, env->glow_hdr_luminance_cap, env->exposure, env->glow_bloom, env->glow_hdr_bleed_threshold, env->glow_hdr_bleed_scale, luminance_texture, env->auto_exp_scale); + } } else { - storage->get_effects()->gaussian_glow_raster(rb->blur[1].mipmaps[i - 1].texture, rb->blur[1].mipmaps[i].half_fb, rb->blur[1].mipmaps[i].half_texture, rb->blur[1].mipmaps[i].fb, Vector2(1.0 / vp_w, 1.0 / vp_h), env->glow_strength, glow_high_quality); + if (can_use_storage) { + copy_effects->gaussian_glow(rb->blur[1].layers[l].mipmaps[i - 1].texture, rb->blur[1].layers[l].mipmaps[i].texture, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); + } else { + copy_effects->gaussian_glow_raster(rb->blur[1].layers[l].mipmaps[i - 1].texture, luminance_multiplier, rb->blur[1].layers[l].mipmaps[i].half_fb, rb->blur[1].layers[l].mipmaps[i].half_texture, rb->blur[1].layers[l].mipmaps[i].fb, Size2i(vp_w, vp_h), env->glow_strength, glow_high_quality); + } } } } @@ -2484,6 +2518,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende } { + RENDER_TIMESTAMP("Tonemap"); RD::get_singleton()->draw_command_begin_label("Tonemap"); RendererRD::ToneMapper::TonemapSettings tonemap; @@ -2503,8 +2538,8 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende for (int i = 0; i < RS::MAX_GLOW_LEVELS; i++) { tonemap.glow_levels[i] = env->glow_levels[i]; } - tonemap.glow_texture_size.x = rb->blur[1].mipmaps[0].width; - tonemap.glow_texture_size.y = rb->blur[1].mipmaps[0].height; + tonemap.glow_texture_size.x = rb->blur[1].layers[0].mipmaps[0].width; + tonemap.glow_texture_size.y = rb->blur[1].layers[0].mipmaps[0].height; tonemap.glow_use_bicubic_upscale = glow_bicubic_upscale; tonemap.glow_texture = rb->blur[1].texture; if (env->glow_map.is_valid()) { @@ -2562,7 +2597,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende } if (can_use_effects && can_use_storage && (rb->internal_width != rb->width || rb->internal_height != rb->height)) { - RD::get_singleton()->draw_command_begin_label("FSR Upscale"); + RD::get_singleton()->draw_command_begin_label("FSR 1.0 Upscale"); storage->get_effects()->fsr_upscale(rb->internal_texture, rb->upscale_texture, rb->texture, Size2i(rb->internal_width, rb->internal_height), Size2i(rb->width, rb->height), rb->fsr_sharpness); @@ -2652,7 +2687,6 @@ void RendererSceneRenderRD::_disable_clear_request(const RenderDataRD *p_render_ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); - EffectsRD *effects = storage->get_effects(); RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); @@ -2666,7 +2700,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID } Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); - effects->copy_to_fb_rect(shadow_atlas_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true); + copy_effects->copy_to_fb_rect(shadow_atlas_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true); } } @@ -2675,7 +2709,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID RID shadow_atlas_texture = directional_shadow_get_texture(); Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); - effects->copy_to_fb_rect(shadow_atlas_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true); + copy_effects->copy_to_fb_rect(shadow_atlas_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, true); } } @@ -2685,7 +2719,7 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID if (decal_atlas.is_valid()) { Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); - effects->copy_to_fb_rect(decal_atlas, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, false, true); + copy_effects->copy_to_fb_rect(decal_atlas, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize / 2), false, false, true); } } @@ -2693,36 +2727,36 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID if (rb->luminance.current.is_valid()) { Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); - effects->copy_to_fb_rect(rb->luminance.current, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true); + copy_effects->copy_to_fb_rect(rb->luminance.current, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize / 8), false, true); } } if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSAO && rb->ss_effects.ssao.ao_final.is_valid()) { Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); - effects->copy_to_fb_rect(rb->ss_effects.ssao.ao_final, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true); + copy_effects->copy_to_fb_rect(rb->ss_effects.ssao.ao_final, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, true); } if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SSIL && rb->ss_effects.ssil.ssil_final.is_valid()) { Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); - effects->copy_to_fb_rect(rb->ss_effects.ssil.ssil_final, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false); + copy_effects->copy_to_fb_rect(rb->ss_effects.ssil.ssil_final, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false); } if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_NORMAL_BUFFER && _render_buffers_get_normal_texture(p_render_buffers).is_valid()) { Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); - effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false); + copy_effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false); } if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->ambient_buffer.is_valid()) { Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); RID ambient_texture = rb->ambient_buffer; RID reflection_texture = rb->reflection_buffer; - effects->copy_to_fb_rect(ambient_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture); + copy_effects->copy_to_fb_rect(ambient_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture); } if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_OCCLUDERS) { if (p_occlusion_buffer.is_valid()) { Size2 rtsize = texture_storage->render_target_get_size(rb->render_target); - effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_occlusion_buffer), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize), true, false); + copy_effects->copy_to_fb_rect(texture_storage->texture_get_rd_texture(p_occlusion_buffer), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2i(Vector2(), rtsize), true, false); } } } @@ -3035,12 +3069,38 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p rb->depth_texture = RD::get_singleton()->texture_create(tf, RD::TextureView()); } - if (!_render_buffers_can_be_storage()) { - // ONLY USED ON MOBILE RENDERER, ONLY USED FOR POST EFFECTS! - Vector<RID> fb; - fb.push_back(rb->internal_texture); + { + if (!_render_buffers_can_be_storage()) { + // ONLY USED ON MOBILE RENDERER, ONLY USED FOR POST EFFECTS! + Vector<RID> fb; + fb.push_back(rb->internal_texture); + + rb->texture_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, rb->view_count); + } - rb->texture_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, rb->view_count); + rb->views.clear(); // JIC + if (rb->view_count == 1) { + // copy as a convenience + RenderBuffers::View view; + view.view_texture = rb->internal_texture; + view.view_depth = rb->depth_texture; + view.view_fb = rb->texture_fb; + rb->views.push_back(view); + } else { + for (uint32_t i = 0; i < rb->view_count; i++) { + RenderBuffers::View view; + view.view_texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->internal_texture, i, 0); + view.view_depth = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->depth_texture, i, 0); + + if (!_render_buffers_can_be_storage()) { + Vector<RID> fb; + fb.push_back(view.view_texture); + view.view_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, 1); + } + + rb->views.push_back(view); + } + } } RID target_texture = texture_storage->render_target_get_rd_texture(rb->render_target); @@ -3903,45 +3963,45 @@ void RendererSceneRenderRD::FogShaderData::set_default_texture_param(const Strin } } else { if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = Map<int, RID>(); + default_texture_params[p_name] = HashMap<int, RID>(); } default_texture_params[p_name][p_index] = p_texture; } } void RendererSceneRenderRD::FogShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - Map<int, StringName> order; + RBMap<int, StringName> order; - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E->get().scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } - if (E->get().texture_order >= 0) { - order[E->get().texture_order + 100000] = E->key(); + if (E.value.texture_order >= 0) { + order[E.value.texture_order + 100000] = E.key; } else { - order[E->get().order] = E->key(); + order[E.value.order] = E.key; } } - for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) { - PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]); - pi.name = E->get(); + for (const KeyValue<int, StringName> &E : order) { + PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E.value]); + pi.name = E.value; p_param_list->push_back(pi); } } void RendererSceneRenderRD::FogShaderData::get_instance_param_list(List<RendererMaterialStorage::InstanceShaderParam> *p_param_list) const { - for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { - if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { + for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { + if (E.value.scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { continue; } RendererMaterialStorage::InstanceShaderParam p; - p.info = ShaderLanguage::uniform_to_property_info(E->get()); - p.info.name = E->key(); //supply name - p.index = E->get().instance_index; - p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().array_size, E->get().hint); + p.info = ShaderLanguage::uniform_to_property_info(E.value); + p.info.name = E.key; //supply name + p.index = E.value.instance_index; + p.default_value = ShaderLanguage::constant_value_to_variant(E.value.default_value, E.value.type, E.value.array_size, E.value.hint); p_param_list->push_back(p); } } @@ -3989,7 +4049,7 @@ RendererSceneRenderRD::FogShaderData::~FogShaderData() { //////////////////////////////////////////////////////////////////////////////// // Fog material -bool RendererSceneRenderRD::FogMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +bool RendererSceneRenderRD::FogMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); uniform_set_updated = true; @@ -5114,7 +5174,6 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData if (p_render_buffers.is_valid()) { /* _debug_draw_cluster(p_render_buffers); - RENDER_TIMESTAMP("Tonemap"); _render_buffers_post_process_and_tonemap(&render_data); */ @@ -5408,8 +5467,8 @@ bool RendererSceneRenderRD::free(RID p_rid) { LightInstance *light_instance = light_instance_owner.get_or_null(p_rid); //remove from shadow atlases.. - for (Set<RID>::Element *E = light_instance->shadow_atlases.front(); E; E = E->next()) { - ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(E->get()); + for (const RID &E : light_instance->shadow_atlases) { + ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(E); ERR_CONTINUE(!shadow_atlas->shadow_owners.has(p_rid)); uint32_t key = shadow_atlas->shadow_owners[p_rid]; uint32_t q = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3; @@ -5836,12 +5895,21 @@ void fog() { cull_argument.set_page_pool(&cull_argument_pool); + bool can_use_storage = _render_buffers_can_be_storage(); + bokeh_dof = memnew(RendererRD::BokehDOF(!can_use_storage)); + copy_effects = memnew(RendererRD::CopyEffects(!can_use_storage)); tone_mapper = memnew(RendererRD::ToneMapper); } RendererSceneRenderRD::~RendererSceneRenderRD() { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); + if (bokeh_dof) { + memdelete(bokeh_dof); + } + if (copy_effects) { + memdelete(copy_effects); + } if (tone_mapper) { memdelete(tone_mapper); } diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 6bf3a95dd0..a384f216cd 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -35,6 +35,8 @@ #include "core/templates/rid_owner.h" #include "servers/rendering/renderer_compositor.h" #include "servers/rendering/renderer_rd/cluster_builder_rd.h" +#include "servers/rendering/renderer_rd/effects/bokeh_dof.h" +#include "servers/rendering/renderer_rd/effects/copy_effects.h" #include "servers/rendering/renderer_rd/effects/tone_mapper.h" #include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h" #include "servers/rendering/renderer_rd/renderer_scene_gi_rd.h" @@ -94,6 +96,8 @@ class RendererSceneRenderRD : public RendererSceneRender { protected: RendererStorageRD *storage = nullptr; + RendererRD::BokehDOF *bokeh_dof = nullptr; + RendererRD::CopyEffects *copy_effects = nullptr; RendererRD::ToneMapper *tone_mapper = nullptr; double time = 0.0; double time_step = 0.0; @@ -293,7 +297,7 @@ private: RID depth; RID fb; //for copying - Map<RID, uint32_t> shadow_owners; + HashMap<RID, uint32_t> shadow_owners; }; RID_Owner<ShadowAtlas> shadow_atlas_owner; @@ -341,7 +345,7 @@ private: RID side_fb[6]; }; - Map<int, ShadowCubemap> shadow_cubemaps; + HashMap<int, ShadowCubemap> shadow_cubemaps; ShadowCubemap *_get_shadow_cubemap(int p_size); void _create_shadow_cubemaps(); @@ -383,7 +387,7 @@ private: Rect2 directional_rect; - Set<RID> shadow_atlases; //shadow atlases where this light is registered + HashSet<RID> shadow_atlases; //shadow atlases where this light is registered ForwardID forward_id = -1; @@ -482,6 +486,14 @@ private: RID texture_fb; // framebuffer for the main texture, ONLY USED FOR MOBILE RENDERER POST EFFECTS, DO NOT USE FOR RENDERING 3D!!! RID upscale_texture; //used when upscaling internal_texture (This uses the same resource as internal_texture if there is no upscaling) + // Access to the layers for each of our views (specifically needed for applying post effects on stereoscopic images) + struct View { + RID view_texture; // texture slice for this view/layer + RID view_depth; // depth slice for this view/layer + RID view_fb; // framebuffer for this view/layer, ONLY USED FOR MOBILE RENDERER POST EFFECTS, DO NOT USE FOR RENDERING 3D!!! + }; + Vector<View> views; + RendererSceneGIRD::SDFGI *sdfgi = nullptr; VolumetricFog *volumetric_fog = nullptr; RendererSceneGIRD::RenderBuffersGI gi; @@ -503,19 +515,22 @@ private: RID half_fb; }; - Vector<Mipmap> mipmaps; + struct Layer { + Vector<Mipmap> mipmaps; + }; + + Vector<Layer> layers; }; Blur blur[2]; //the second one starts from the first mipmap struct WeightBuffers { RID weight; - RID fb; // FB with both texture and weight + RID fb; // FB with both texture and weight writing into one level lower }; // 2 full size, 2 half size WeightBuffers weight_buffers[4]; // Only used in raster - RID base_weight_fb; // base buffer for weight RID depth_back_texture; RID depth_back_fb; // only used on mobile @@ -906,7 +921,7 @@ private: RID version; RID pipeline; - Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; @@ -914,7 +929,7 @@ private: String path; String code; - Map<StringName, Map<int, RID>> default_texture_params; + HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_time = false; @@ -939,7 +954,7 @@ private: virtual void set_render_priority(int p_priority) {} virtual void set_next_pass(RID p_pass) {} - virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); + virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); virtual ~FogMaterialData(); }; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 51cf0e952b..14a5f02eee 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -32,6 +32,7 @@ #include "core/config/project_settings.h" #include "core/math/math_defs.h" #include "renderer_scene_render_rd.h" +#include "servers/rendering/renderer_rd/effects/copy_effects.h" #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #include "servers/rendering/renderer_rd/storage_rd/material_storage.h" #include "servers/rendering/renderer_rd/storage_rd/texture_storage.h" @@ -150,14 +151,14 @@ void RendererSceneSkyRD::SkyShaderData::set_default_texture_param(const StringNa } } else { if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = Map<int, RID>(); + default_texture_params[p_name] = HashMap<int, RID>(); } default_texture_params[p_name][p_index] = p_texture; } } void RendererSceneSkyRD::SkyShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - Map<int, StringName> order; + HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { @@ -236,7 +237,7 @@ RendererSceneSkyRD::SkyShaderData::~SkyShaderData() { //////////////////////////////////////////////////////////////////////////////// // Sky material -bool RendererSceneSkyRD::SkyMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +bool RendererSceneSkyRD::SkyMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { RendererSceneRenderRD *scene_singleton = static_cast<RendererSceneRenderRD *>(RendererSceneRenderRD::singleton); uniform_set_updated = true; @@ -730,8 +731,10 @@ bool RendererSceneSkyRD::Sky::set_material(RID p_material) { return true; } -Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(RendererStorageRD *p_storage, float p_energy, int p_roughness_layers, const Size2i &p_size) { +Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size) { if (radiance.is_valid()) { + RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); + RD::TextureFormat tf; tf.format = RD::DATA_FORMAT_R32G32B32A32_SFLOAT; tf.width = p_size.width; @@ -739,7 +742,7 @@ Ref<Image> RendererSceneSkyRD::Sky::bake_panorama(RendererStorageRD *p_storage, tf.usage_bits = RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT; RID rad_tex = RD::get_singleton()->texture_create(tf, RD::TextureView()); - p_storage->get_effects()->copy_cubemap_to_panorama(radiance, rad_tex, p_size, p_roughness_layers, reflection.layers.size() > 1); + copy_effects->copy_cubemap_to_panorama(radiance, rad_tex, p_size, p_roughness_layers, reflection.layers.size() > 1); Vector<uint8_t> data = RD::get_singleton()->texture_get_data(rad_tex, 0); RD::get_singleton()->free(rad_tex); @@ -1905,7 +1908,7 @@ Ref<Image> RendererSceneSkyRD::sky_bake_panorama(RID p_sky, float p_energy, bool update_dirty_skys(); - return sky->bake_panorama(storage, p_energy, p_bake_irradiance ? roughness_layers : 0, p_size); + return sky->bake_panorama(p_energy, p_bake_irradiance ? roughness_layers : 0, p_size); } RID RendererSceneSkyRD::sky_get_radiance_texture_rd(RID p_sky) const { diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h index 497d27ec26..83a8fe6e77 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h @@ -110,7 +110,7 @@ private: RID version; PipelineCacheRD pipelines[SKY_VERSION_MAX]; - Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; @@ -118,7 +118,7 @@ private: String path; String code; - Map<StringName, Map<int, RID>> default_texture_params; + HashMap<StringName, HashMap<int, RID>> default_texture_params; bool uses_time = false; bool uses_position = false; @@ -235,7 +235,7 @@ public: virtual void set_render_priority(int p_priority) {} virtual void set_next_pass(RID p_pass) {} - virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); + virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); virtual ~SkyMaterialData(); }; @@ -273,7 +273,7 @@ public: bool set_radiance_size(int p_radiance_size); bool set_mode(RS::SkyMode p_mode); bool set_material(RID p_material); - Ref<Image> bake_panorama(RendererStorageRD *p_storage, float p_energy, int p_roughness_layers, const Size2i &p_size); + Ref<Image> bake_panorama(float p_energy, int p_roughness_layers, const Size2i &p_size); }; uint32_t sky_ggx_samples_quality; diff --git a/servers/rendering/renderer_rd/shader_rd.cpp b/servers/rendering/renderer_rd/shader_rd.cpp index fdfecf2d2c..04e05380f1 100644 --- a/servers/rendering/renderer_rd/shader_rd.cpp +++ b/servers/rendering/renderer_rd/shader_rd.cpp @@ -522,7 +522,7 @@ void ShaderRD::_compile_version(Version *p_version) { p_version->valid = true; } -void ShaderRD::version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines) { +void ShaderRD::version_set_code(RID p_version, const HashMap<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines) { ERR_FAIL_COND(is_compute); Version *version = version_owner.get_or_null(p_version); @@ -547,7 +547,7 @@ void ShaderRD::version_set_code(RID p_version, const Map<String, String> &p_code } } -void ShaderRD::version_set_compute_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_compute_globals, const Vector<String> &p_custom_defines) { +void ShaderRD::version_set_compute_code(RID p_version, const HashMap<String, String> &p_code, const String &p_uniforms, const String &p_compute_globals, const Vector<String> &p_custom_defines) { ERR_FAIL_COND(!is_compute); Version *version = version_owner.get_or_null(p_version); diff --git a/servers/rendering/renderer_rd/shader_rd.h b/servers/rendering/renderer_rd/shader_rd.h index 8e57f0d9af..40b10808c2 100644 --- a/servers/rendering/renderer_rd/shader_rd.h +++ b/servers/rendering/renderer_rd/shader_rd.h @@ -35,7 +35,7 @@ #include "core/string/string_builder.h" #include "core/templates/hash_map.h" #include "core/templates/local_vector.h" -#include "core/templates/map.h" +#include "core/templates/rb_map.h" #include "core/templates/rid_owner.h" #include "core/variant/variant.h" #include "servers/rendering_server.h" @@ -51,7 +51,7 @@ class ShaderRD { CharString vertex_globals; CharString compute_globals; CharString fragment_globals; - Map<StringName, CharString> code_sections; + HashMap<StringName, CharString> code_sections; Vector<CharString> custom_defines; Vector<uint8_t> *variant_data = nullptr; @@ -129,8 +129,8 @@ protected: public: RID version_create(); - void version_set_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines); - void version_set_compute_code(RID p_version, const Map<String, String> &p_code, const String &p_uniforms, const String &p_compute_globals, const Vector<String> &p_custom_defines); + void version_set_code(RID p_version, const HashMap<String, String> &p_code, const String &p_uniforms, const String &p_vertex_globals, const String &p_fragment_globals, const Vector<String> &p_custom_defines); + void version_set_compute_code(RID p_version, const HashMap<String, String> &p_code, const String &p_uniforms, const String &p_compute_globals, const Vector<String> &p_custom_defines); _FORCE_INLINE_ RID version_get_shader(RID p_version, int p_variant) { ERR_FAIL_INDEX_V(p_variant, variant_defines.size(), RID()); diff --git a/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl deleted file mode 100644 index e7a2e18323..0000000000 --- a/servers/rendering/renderer_rd/shaders/blur_raster_inc.glsl +++ /dev/null @@ -1,21 +0,0 @@ -#define FLAG_HORIZONTAL (1 << 0) -#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 1) -#define FLAG_GLOW_FIRST_PASS (1 << 2) - -layout(push_constant, std430) uniform Blur { - vec2 pixel_size; - uint flags; - uint pad; - - // Glow. - float glow_strength; - float glow_bloom; - float glow_hdr_threshold; - float glow_hdr_scale; - - float glow_exposure; - float glow_white; - float glow_luminance_cap; - float glow_auto_exposure_grey; -} -blur; diff --git a/servers/rendering/renderer_rd/shaders/blur_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl index f8b4e3f610..96f5c3e9f2 100644 --- a/servers/rendering/renderer_rd/shaders/blur_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl @@ -53,7 +53,9 @@ void main() { #ifdef MODE_GAUSSIAN_BLUR - //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect + // Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect + + // note, for blur blur.luminance_multiplier is irrelavant, we would be multiplying and then dividing by this amount. if (bool(blur.flags & FLAG_HORIZONTAL)) { vec2 pix_size = blur.pixel_size; @@ -94,6 +96,7 @@ void main() { if (bool(blur.flags & FLAG_HORIZONTAL)) { vec2 pix_size = blur.pixel_size; pix_size *= 0.5; //reading from larger buffer, so use more samples + vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.174938; GLOW_ADD(vec2(1.0, 0.0), 0.165569); GLOW_ADD(vec2(2.0, 0.0), 0.140367); @@ -101,7 +104,10 @@ void main() { GLOW_ADD(vec2(-1.0, 0.0), 0.165569); GLOW_ADD(vec2(-2.0, 0.0), 0.140367); GLOW_ADD(vec2(-3.0, 0.0), 0.106595); + + // only do this in the horizontal pass, if we also do this in the vertical pass we're doubling up. color *= blur.glow_strength; + frag_color = color; } else { vec2 pix_size = blur.pixel_size; @@ -110,13 +116,17 @@ void main() { GLOW_ADD(vec2(0.0, 2.0), 0.122581); GLOW_ADD(vec2(0.0, -1.0), 0.233062); GLOW_ADD(vec2(0.0, -2.0), 0.122581); - color *= blur.glow_strength; + frag_color = color; } #undef GLOW_ADD if (bool(blur.flags & FLAG_GLOW_FIRST_PASS)) { + // In the first pass bring back to correct color range else we're applying the wrong threshold + // in subsequent passes we can use it as is as we'd just be undoing it right after. + frag_color *= blur.luminance_multiplier; + #ifdef GLOW_USE_AUTO_EXPOSURE frag_color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / blur.glow_auto_exposure_grey; @@ -126,10 +136,10 @@ void main() { float luminance = max(frag_color.r, max(frag_color.g, frag_color.b)); float feedback = max(smoothstep(blur.glow_hdr_threshold, blur.glow_hdr_threshold + blur.glow_hdr_scale, luminance), blur.glow_bloom); - frag_color = min(frag_color * feedback, vec4(blur.glow_luminance_cap)); + frag_color = min(frag_color * feedback, vec4(blur.glow_luminance_cap)) / blur.luminance_multiplier; } -#endif +#endif // MODE_GAUSSIAN_GLOW #ifdef MODE_COPY vec4 color = textureLod(source_color, uv_interp, 0.0); diff --git a/servers/rendering/renderer_rd/shaders/effects/blur_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/blur_raster_inc.glsl new file mode 100644 index 0000000000..730504571a --- /dev/null +++ b/servers/rendering/renderer_rd/shaders/effects/blur_raster_inc.glsl @@ -0,0 +1,26 @@ +#define FLAG_HORIZONTAL (1 << 0) +#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 1) +#define FLAG_GLOW_FIRST_PASS (1 << 2) + +layout(push_constant, std430) uniform Blur { + vec2 pixel_size; // 08 - 08 + uint flags; // 04 - 12 + uint pad; // 04 - 16 + + // Glow. + float glow_strength; // 04 - 20 + float glow_bloom; // 04 - 24 + float glow_hdr_threshold; // 04 - 28 + float glow_hdr_scale; // 04 - 32 + + float glow_exposure; // 04 - 36 + float glow_white; // 04 - 40 + float glow_luminance_cap; // 04 - 44 + float glow_auto_exposure_grey; // 04 - 48 + + float luminance_multiplier; // 04 - 52 + float res1; // 04 - 56 + float res2; // 04 - 60 + float res3; // 04 - 64 +} +blur; diff --git a/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl index 0438671dd2..0438671dd2 100644 --- a/servers/rendering/renderer_rd/shaders/bokeh_dof.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof.glsl diff --git a/servers/rendering/renderer_rd/shaders/bokeh_dof_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_inc.glsl index b90a527554..b90a527554 100644 --- a/servers/rendering/renderer_rd/shaders/bokeh_dof_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_inc.glsl diff --git a/servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl index a3b3938ee9..a3b3938ee9 100644 --- a/servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/bokeh_dof_raster.glsl diff --git a/servers/rendering/renderer_rd/shaders/copy.glsl b/servers/rendering/renderer_rd/shaders/effects/copy.glsl index 4563ac7af9..3a4ef86ef0 100644 --- a/servers/rendering/renderer_rd/shaders/copy.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy.glsl @@ -189,7 +189,7 @@ void main() { #endif color *= params.glow_exposure; - float luminance = dot(color.rgb, vec3(0.299, 0.587, 0.114)); + float luminance = max(color.r, max(color.g, color.b)); float feedback = max(smoothstep(params.glow_hdr_threshold, params.glow_hdr_threshold + params.glow_hdr_scale, luminance), params.glow_bloom); color = min(color * feedback, vec4(params.glow_luminance_cap)); diff --git a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl index 9787c9879d..9787c9879d 100644 --- a/servers/rendering/renderer_rd/shaders/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl diff --git a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl index 19a9350137..a8ccdea60b 100644 --- a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl @@ -44,7 +44,11 @@ layout(set = 0, binding = 0) uniform sampler2D source_color; #endif layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure; +#ifdef MULTIVIEW +layout(set = 2, binding = 0) uniform sampler2DArray source_glow; +#else layout(set = 2, binding = 0) uniform sampler2D source_glow; +#endif layout(set = 2, binding = 1) uniform sampler2D glow_map; #ifdef USE_1D_LUT @@ -118,6 +122,36 @@ float h1(float a) { return 1.0f + w3(a) / (w2(a) + w3(a)); } +#ifdef MULTIVIEW +vec4 texture2D_bicubic(sampler2DArray tex, vec2 uv, int p_lod) { + float lod = float(p_lod); + vec2 tex_size = vec2(params.glow_texture_size >> p_lod); + vec2 pixel_size = vec2(1.0f) / tex_size; + + uv = uv * tex_size + vec2(0.5f); + + vec2 iuv = floor(uv); + vec2 fuv = fract(uv); + + float g0x = g0(fuv.x); + float g1x = g1(fuv.x); + float h0x = h0(fuv.x); + float h1x = h1(fuv.x); + float h0y = h0(fuv.y); + float h1y = h1(fuv.y); + + vec3 p0 = vec3((vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5f)) * pixel_size, ViewIndex); + vec3 p1 = vec3((vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5f)) * pixel_size, ViewIndex); + vec3 p2 = vec3((vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5f)) * pixel_size, ViewIndex); + vec3 p3 = vec3((vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5f)) * pixel_size, ViewIndex); + + return (g0(fuv.y) * (g0x * textureLod(tex, p0, lod) + g1x * textureLod(tex, p1, lod))) + + (g1(fuv.y) * (g0x * textureLod(tex, p2, lod) + g1x * textureLod(tex, p3, lod))); +} + +#define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2D_bicubic(m_tex, m_uv, m_lod) +#else // MULTIVIEW + vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) { float lod = float(p_lod); vec2 tex_size = vec2(params.glow_texture_size >> p_lod); @@ -145,12 +179,17 @@ vec4 texture2D_bicubic(sampler2D tex, vec2 uv, int p_lod) { } #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) texture2D_bicubic(m_tex, m_uv, m_lod) +#endif // !MULTIVIEW -#else +#else // USE_GLOW_FILTER_BICUBIC +#ifdef MULTIVIEW +#define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) textureLod(m_tex, vec3(m_uv, ViewIndex), float(m_lod)) +#else // MULTIVIEW #define GLOW_TEXTURE_SAMPLE(m_tex, m_uv, m_lod) textureLod(m_tex, m_uv, float(m_lod)) +#endif // !MULTIVIEW -#endif +#endif // !USE_GLOW_FILTER_BICUBIC vec3 tonemap_filmic(vec3 color, float white) { // exposure bias: input scale (color *= bias, white *= bias) to make the brightness consistent with other tonemappers @@ -231,7 +270,11 @@ vec3 apply_tonemapping(vec3 color, float white) { // inputs are LINEAR, always o } } +#ifdef MULTIVIEW +vec3 gather_glow(sampler2DArray tex, vec2 uv) { // sample all selected glow levels, view is added to uv later +#else vec3 gather_glow(sampler2D tex, vec2 uv) { // sample all selected glow levels +#endif // defined(MULTIVIEW) vec3 glow = vec3(0.0f); if (params.glow_levels[0] > 0.0001) { @@ -383,12 +426,13 @@ vec3 screen_space_dither(vec2 frag_coord) { void main() { #ifdef SUBPASS // SUBPASS and MULTIVIEW can be combined but in that case we're already reading from the correct layer - vec3 color = subpassLoad(input_color).rgb * params.luminance_multiplier; + vec4 color = subpassLoad(input_color); #elif defined(MULTIVIEW) - vec3 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f).rgb * params.luminance_multiplier; + vec4 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f); #else - vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb * params.luminance_multiplier; + vec4 color = textureLod(source_color, uv_interp, 0.0f); #endif + color.rgb *= params.luminance_multiplier; // Exposure @@ -400,7 +444,7 @@ void main() { } #endif - color *= exposure; + color.rgb *= exposure; // Early Tonemap & SRGB Conversion #ifndef SUBPASS @@ -413,19 +457,19 @@ void main() { } if (params.use_fxaa) { - color = do_fxaa(color, exposure, uv_interp); + color.rgb = do_fxaa(color.rgb, exposure, uv_interp); } #endif if (params.use_debanding) { // For best results, debanding should be done before tonemapping. // Otherwise, we're adding noise to an already-quantized image. - color += screen_space_dither(gl_FragCoord.xy); + color.rgb += screen_space_dither(gl_FragCoord.xy); } - color = apply_tonemapping(color, params.white); + color.rgb = apply_tonemapping(color.rgb, params.white); - color = linear_to_srgb(color); // regular linear -> SRGB conversion + color.rgb = linear_to_srgb(color.rgb); // regular linear -> SRGB conversion #ifndef SUBPASS // Glow @@ -439,19 +483,19 @@ void main() { glow = apply_tonemapping(glow, params.white); glow = linear_to_srgb(glow); - color = apply_glow(color, glow); + color.rgb = apply_glow(color.rgb, glow); } #endif // Additional effects if (params.use_bcs) { - color = apply_bcs(color, params.bcs); + color.rgb = apply_bcs(color.rgb, params.bcs); } if (params.use_color_correction) { - color = apply_color_correction(color); + color.rgb = apply_color_correction(color.rgb); } - frag_color = vec4(color, 1.0f); + frag_color = color; } diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index 1b1051ecfa..acb62b812e 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -228,6 +228,14 @@ bool emit_subparticle(mat4 p_xform, vec3 p_velocity, vec4 p_color, vec4 p_custom return true; } +vec3 safe_normalize(vec3 direction) { + const float EPSILON = 0.001; + if (length(direction) < EPSILON) { + return vec3(0.0); + } + return normalize(direction); +} + #GLOBALS void main() { @@ -431,7 +439,7 @@ void main() { switch (FRAME.attractors[i].type) { case ATTRACTOR_TYPE_SPHERE: { - dir = normalize(rel_vec); + dir = safe_normalize(rel_vec); float d = length(local_pos) / FRAME.attractors[i].extents.x; if (d > 1.0) { continue; @@ -439,7 +447,7 @@ void main() { amount = max(0.0, 1.0 - d); } break; case ATTRACTOR_TYPE_BOX: { - dir = normalize(rel_vec); + dir = safe_normalize(rel_vec); vec3 abs_pos = abs(local_pos / FRAME.attractors[i].extents); float d = max(abs_pos.x, max(abs_pos.y, abs_pos.z)); @@ -455,13 +463,13 @@ void main() { continue; } vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz; - dir = mat3(FRAME.attractors[i].transform) * normalize(s); //revert direction + dir = mat3(FRAME.attractors[i].transform) * safe_normalize(s); //revert direction amount = length(s); } break; } amount = pow(amount, FRAME.attractors[i].attenuation); - dir = normalize(mix(dir, FRAME.attractors[i].transform[2].xyz, FRAME.attractors[i].directionality)); + dir = safe_normalize(mix(dir, FRAME.attractors[i].transform[2].xyz, FRAME.attractors[i].directionality)); attractor_force -= amount * dir * FRAME.attractors[i].strength; } diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl index 58b4ded9f4..4f49c186a6 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl @@ -679,7 +679,7 @@ void main() { float normal_map_depth = 1.0; - vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size + scene_data.screen_pixel_size * 0.5; //account for center + vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size; float sss_strength = 0.0; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl index b6ba244665..fd0fefc5fd 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl @@ -650,7 +650,7 @@ void main() { float normal_map_depth = 1.0; - vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size + scene_data.screen_pixel_size * 0.5; //account for center + vec2 screen_uv = gl_FragCoord.xy * scene_data.screen_pixel_size; float sss_strength = 0.0; @@ -924,7 +924,7 @@ void main() { #endif // !USE_LIGHTMAP #if defined(CUSTOM_IRRADIANCE_USED) - ambient_light = mix(specular_light, custom_irradiance.rgb, custom_irradiance.a); + ambient_light = mix(ambient_light, custom_irradiance.rgb, custom_irradiance.a); #endif // CUSTOM_IRRADIANCE_USED #ifdef LIGHT_CLEARCOAT_USED diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl index 4ef6a26443..a893a66c94 100644 --- a/servers/rendering/renderer_rd/shaders/skeleton.glsl +++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl @@ -160,7 +160,7 @@ void main() { } if (params.has_tangent) { - blend_tangent += decode_abgr_2_10_10_10(src_blend_shapes.data[base_offset]).rgb; + blend_tangent += decode_abgr_2_10_10_10(src_blend_shapes.data[base_offset]).rgb * w; } blend_total += w; @@ -174,8 +174,8 @@ void main() { } vertex += blend_vertex; - normal += normalize(normal + blend_normal); - tangent.rgb += normalize(tangent.rgb + blend_tangent); + normal = normalize(normal + blend_normal); + tangent.rgb = normalize(tangent.rgb + blend_tangent); } if (params.has_skeleton) { diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index b4122e3337..8e2e9b14cb 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -896,7 +896,7 @@ _FORCE_INLINE_ static void _fill_std140_ubo_empty(ShaderLanguage::DataType type, /////////////////////////////////////////////////////////////////////////// // MaterialData -void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { +void MaterialData::update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color) { MaterialStorage *material_storage = MaterialStorage::get_singleton(); bool uses_global_buffer = false; @@ -943,11 +943,11 @@ void MaterialData::update_uniform_buffer(const Map<StringName, ShaderLanguage::S ERR_CONTINUE(offset + size > p_buffer_size); #endif uint8_t *data = &p_buffer[offset]; - const Map<StringName, Variant>::Element *V = p_parameters.find(E.key); + HashMap<StringName, Variant>::ConstIterator V = p_parameters.find(E.key); if (V) { //user provided - _fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->get(), data, p_use_linear_color); + _fill_std140_variant_ubo_value(E.value.type, E.value.array_size, V->value, data, p_use_linear_color); } else if (E.value.default_value.size()) { //default value @@ -1001,7 +1001,7 @@ MaterialData::~MaterialData() { } } -void MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { +void MaterialData::update_textures(const HashMap<StringName, Variant> &p_parameters, const HashMap<StringName, HashMap<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color) { TextureStorage *texture_storage = TextureStorage::get_singleton(); MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -1029,12 +1029,12 @@ void MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it changed type and is no longer a texture!."); } else { - Map<StringName, uint64_t>::Element *E = used_global_textures.find(uniform_name); + HashMap<StringName, uint64_t>::Iterator E = used_global_textures.find(uniform_name); if (!E) { E = used_global_textures.insert(uniform_name, global_textures_pass); v->texture_materials.insert(self); } else { - E->get() = global_textures_pass; + E->value = global_textures_pass; } textures.push_back(v->override.get_type() != Variant::NIL ? v->override : v->value); @@ -1044,10 +1044,10 @@ void MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, WARN_PRINT("Shader uses global uniform texture '" + String(uniform_name) + "', but it was removed at some point. Material will not display correctly."); } } else { - const Map<StringName, Variant>::Element *V = p_parameters.find(uniform_name); + HashMap<StringName, Variant>::ConstIterator V = p_parameters.find(uniform_name); if (V) { - if (V->get().is_array()) { - Array array = (Array)V->get(); + if (V->value.is_array()) { + Array array = (Array)V->value; if (uniform_array_size > 0) { for (int j = 0; j < array.size(); j++) { textures.push_back(array[j]); @@ -1058,25 +1058,25 @@ void MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, } } } else { - textures.push_back(V->get()); + textures.push_back(V->value); } } if (uniform_array_size > 0) { if (textures.size() < uniform_array_size) { - const Map<StringName, Map<int, RID>>::Element *W = p_default_textures.find(uniform_name); + HashMap<StringName, HashMap<int, RID>>::ConstIterator W = p_default_textures.find(uniform_name); for (int j = textures.size(); j < uniform_array_size; j++) { - if (W && W->get().has(j)) { - textures.push_back(W->get()[j]); + if (W && W->value.has(j)) { + textures.push_back(W->value[j]); } else { textures.push_back(RID()); } } } } else if (textures.is_empty()) { - const Map<StringName, Map<int, RID>>::Element *W = p_default_textures.find(uniform_name); - if (W && W->get().has(0)) { - textures.push_back(W->get()[0]); + HashMap<StringName, HashMap<int, RID>>::ConstIterator W = p_default_textures.find(uniform_name); + if (W && W->value.has(0)) { + textures.push_back(W->value[0]); } } } @@ -1188,12 +1188,12 @@ void MaterialData::update_textures(const Map<StringName, Variant> &p_parameters, } { //for textures no longer used, unregister them - List<Map<StringName, uint64_t>::Element *> to_delete; - for (Map<StringName, uint64_t>::Element *E = used_global_textures.front(); E; E = E->next()) { - if (E->get() != global_textures_pass) { - to_delete.push_back(E); + List<StringName> to_delete; + for (KeyValue<StringName, uint64_t> &E : used_global_textures) { + if (E.value != global_textures_pass) { + to_delete.push_back(E.key); - GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E->key()); + GlobalVariables::Variable *v = material_storage->global_variables.variables.getptr(E.key); if (v) { v->texture_materials.erase(self); } @@ -1223,7 +1223,7 @@ void MaterialData::free_parameters_uniform_set(RID p_uniform_set) { } } -bool MaterialData::update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) { +bool MaterialData::update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier) { if ((uint32_t)ubo_data.size() != p_ubo_size) { p_uniform_dirty = true; if (uniform_buffer.is_valid()) { @@ -1418,6 +1418,25 @@ MaterialStorage::MaterialStorage() { //custom sampler sampler_rd_configure_custom(0.0f); + // buffers + { //create index array for copy shaders + Vector<uint8_t> pv; + pv.resize(6 * 4); + { + uint8_t *w = pv.ptrw(); + int *p32 = (int *)w; + p32[0] = 0; + p32[1] = 1; + p32[2] = 2; + p32[3] = 0; + p32[4] = 2; + p32[5] = 3; + } + quad_index_buffer = RD::get_singleton()->index_buffer_create(6, RenderingDevice::INDEX_BUFFER_FORMAT_UINT32, pv); + quad_index_array = RD::get_singleton()->index_array_create(quad_index_buffer, 0, 6); + } + + // Shaders for (int i = 0; i < SHADER_TYPE_MAX; i++) { shader_data_request_func[i] = nullptr; } @@ -1439,6 +1458,10 @@ MaterialStorage::~MaterialStorage() { memdelete_arr(global_variables.buffer_dirty_regions); RD::get_singleton()->free(global_variables.buffer); + // buffers + + RD::get_singleton()->free(quad_index_buffer); //array gets freed as dependency + //def samplers for (int i = 1; i < RS::CANVAS_ITEM_TEXTURE_FILTER_MAX; i++) { for (int j = 1; j < RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX; j++) { @@ -1934,10 +1957,9 @@ Vector<StringName> MaterialStorage::global_variable_get_list() const { ERR_FAIL_V_MSG(Vector<StringName>(), "This function should never be used outside the editor, it can severely damage performance."); } - const StringName *K = nullptr; Vector<StringName> names; - while ((K = global_variables.variables.next(K))) { - names.push_back(*K); + for (const KeyValue<StringName, GlobalVariables::Variable> &E : global_variables.variables) { + names.push_back(E.key); } names.sort_custom<StringName::AlphCompare>(); return names; @@ -1955,8 +1977,8 @@ void MaterialStorage::global_variable_set(const StringName &p_name, const Varian } else { //texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); - for (Set<RID>::Element *E = gv.texture_materials.front(); E; E = E->next()) { - Material *material = material_storage->get_material(E->get()); + for (const RID &E : gv.texture_materials) { + Material *material = material_storage->get_material(E); ERR_CONTINUE(!material); material_storage->_material_queue_update(material, false, true); } @@ -1987,8 +2009,8 @@ void MaterialStorage::global_variable_set_override(const StringName &p_name, con } else { //texture MaterialStorage *material_storage = MaterialStorage::get_singleton(); - for (Set<RID>::Element *E = gv.texture_materials.front(); E; E = E->next()) { - Material *material = material_storage->get_material(E->get()); + for (const RID &E : gv.texture_materials) { + Material *material = material_storage->get_material(E); ERR_CONTINUE(!material); material_storage->_material_queue_update(material, false, true); } @@ -2243,7 +2265,7 @@ void MaterialStorage::shader_free(RID p_rid) { //make material unreference this while (shader->owners.size()) { - material_set_shader(shader->owners.front()->get()->self, RID()); + material_set_shader((*shader->owners.begin())->self, RID()); } //clear data if exists @@ -2281,8 +2303,8 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { shader->data = nullptr; } - for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) { - Material *material = E->get(); + for (Material *E : shader->owners) { + Material *material = E; material->shader_type = new_type; if (material->data) { memdelete(material->data); @@ -2298,8 +2320,8 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { shader->type = SHADER_TYPE_MAX; //invalid } - for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) { - Material *material = E->get(); + for (Material *E : shader->owners) { + Material *material = E; if (shader->data) { material->data = material_get_data_request_function(new_type)(shader->data); material->data->self = material->self; @@ -2310,7 +2332,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { } if (shader->data) { - for (const KeyValue<StringName, Map<int, RID>> &E : shader->default_texture_parameter) { + for (const KeyValue<StringName, HashMap<int, RID>> &E : shader->default_texture_parameter) { for (const KeyValue<int, RID> &E2 : E.value) { shader->data->set_default_texture_param(E.key, E2.value, E2.key); } @@ -2322,8 +2344,8 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) { shader->data->set_code(p_code); } - for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) { - Material *material = E->get(); + for (Material *E : shader->owners) { + Material *material = E; material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL); _material_queue_update(material, true, true); } @@ -2349,7 +2371,7 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin if (p_texture.is_valid() && TextureStorage::get_singleton()->owns_texture(p_texture)) { if (!shader->default_texture_parameter.has(p_name)) { - shader->default_texture_parameter[p_name] = Map<int, RID>(); + shader->default_texture_parameter[p_name] = HashMap<int, RID>(); } shader->default_texture_parameter[p_name][p_index] = p_texture; } else { @@ -2364,8 +2386,8 @@ void MaterialStorage::shader_set_default_texture_param(RID p_shader, const Strin if (shader->data) { shader->data->set_default_texture_param(p_name, p_texture, p_index); } - for (Set<Material *>::Element *E = shader->owners.front(); E; E = E->next()) { - Material *material = E->get(); + for (Material *E : shader->owners) { + Material *material = E; _material_queue_update(material, false, true); } } diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h index c8cc418c3a..f83df05355 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h @@ -76,23 +76,23 @@ struct Shader { ShaderData *data = nullptr; String code; ShaderType type; - Map<StringName, Map<int, RID>> default_texture_parameter; - Set<Material *> owners; + HashMap<StringName, HashMap<int, RID>> default_texture_parameter; + HashSet<Material *> owners; }; /* Material structs */ struct MaterialData { - void update_uniform_buffer(const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Map<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color); - void update_textures(const Map<StringName, Variant> &p_parameters, const Map<StringName, Map<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color); + void update_uniform_buffer(const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const HashMap<StringName, Variant> &p_parameters, uint8_t *p_buffer, uint32_t p_buffer_size, bool p_use_linear_color); + void update_textures(const HashMap<StringName, Variant> &p_parameters, const HashMap<StringName, HashMap<int, RID>> &p_default_textures, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, RID *p_textures, bool p_use_linear_color); virtual void set_render_priority(int p_priority) = 0; virtual void set_next_pass(RID p_pass) = 0; - virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0; + virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) = 0; virtual ~MaterialData(); //to be used internally by update_parameters, in the most common configuration of material parameters - bool update_parameters_uniform_set(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const Map<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const Map<StringName, Map<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL); + bool update_parameters_uniform_set(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty, const HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> &p_uniforms, const uint32_t *p_uniform_offsets, const Vector<ShaderCompiler::GeneratedCode::Texture> &p_texture_uniforms, const HashMap<StringName, HashMap<int, RID>> &p_default_texture_params, uint32_t p_ubo_size, RID &uniform_set, RID p_shader, uint32_t p_shader_uniform_set, uint32_t p_barrier = RD::BARRIER_MASK_ALL); void free_parameters_uniform_set(RID p_uniform_set); private: @@ -101,7 +101,7 @@ private: List<RID>::Element *global_buffer_E = nullptr; List<RID>::Element *global_texture_E = nullptr; uint64_t global_textures_pass = 0; - Map<StringName, uint64_t> used_global_textures; + HashMap<StringName, uint64_t> used_global_textures; //internally by update_parameters_uniform_set Vector<uint8_t> ubo_data; @@ -120,7 +120,7 @@ struct Material { uint32_t shader_id = 0; bool uniform_dirty = false; bool texture_dirty = false; - Map<StringName, Variant> params; + HashMap<StringName, Variant> params; int32_t priority = 0; RID next_pass; SelfList<Material> update_element; @@ -137,7 +137,7 @@ struct GlobalVariables { BUFFER_DIRTY_REGION_SIZE = 1024 }; struct Variable { - Set<RID> texture_materials; // materials using this + HashSet<RID> texture_materials; // materials using this RS::GlobalVariableType type; Variant value; @@ -200,6 +200,11 @@ private: RID default_rd_samplers[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX]; RID custom_rd_samplers[RS::CANVAS_ITEM_TEXTURE_FILTER_MAX][RS::CANVAS_ITEM_TEXTURE_REPEAT_MAX]; + /* Buffers */ + + RID quad_index_buffer; + RID quad_index_array; + /* GLOBAL VARIABLE API */ GlobalVariables global_variables; @@ -240,6 +245,10 @@ public: // void sampler_rd_set_default(float p_mipmap_bias); + /* Buffers */ + + RID get_quad_index_array() { return quad_index_array; } + /* GLOBAL VARIABLE API */ void _update_global_variables(); diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp index 9b7b0d2c25..1e0d67f269 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp @@ -215,8 +215,8 @@ void MeshStorage::mesh_free(RID p_rid) { ERR_PRINT("deleting mesh with active instances"); } if (mesh->shadow_owners.size()) { - for (Set<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) { - Mesh *shadow_owner = E->get(); + for (Mesh *E : mesh->shadow_owners) { + Mesh *shadow_owner = E; shadow_owner->shadow_mesh = RID(); shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); } @@ -431,8 +431,8 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface) mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); - for (Set<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) { - Mesh *shadow_owner = E->get(); + for (Mesh *E : mesh->shadow_owners) { + Mesh *shadow_owner = E; shadow_owner->shadow_mesh = RID(); shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); } @@ -742,8 +742,8 @@ void MeshStorage::mesh_clear(RID p_mesh) { mesh->has_bone_weights = false; mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); - for (Set<Mesh *>::Element *E = mesh->shadow_owners.front(); E; E = E->next()) { - Mesh *shadow_owner = E->get(); + for (Mesh *E : mesh->shadow_owners) { + Mesh *shadow_owner = E; shadow_owner->shadow_mesh = RID(); shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH); } diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h index 7d3f603afd..7ce019cf98 100644 --- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h @@ -141,7 +141,7 @@ struct Mesh { List<MeshInstance *> instances; RID shadow_mesh; - Set<Mesh *> shadow_owners; + HashSet<Mesh *> shadow_owners; RendererStorage::Dependency dependency; }; diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp index 094120f908..e15d3e13a9 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp @@ -838,8 +838,8 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta } uint32_t collision_3d_textures_used = 0; - for (const Set<RID>::Element *E = p_particles->collisions.front(); E; E = E->next()) { - ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(E->get()); + for (const RID &E : p_particles->collisions) { + ParticlesCollisionInstance *pci = particles_collision_instance_owner.get_or_null(E); if (!pci || !pci->active) { continue; } @@ -1592,14 +1592,14 @@ void ParticlesStorage::ParticlesShaderData::set_default_texture_param(const Stri } } else { if (!default_texture_params.has(p_name)) { - default_texture_params[p_name] = Map<int, RID>(); + default_texture_params[p_name] = HashMap<int, RID>(); } default_texture_params[p_name][p_index] = p_texture; } } void ParticlesStorage::ParticlesShaderData::get_param_list(List<PropertyInfo> *p_param_list) const { - Map<int, StringName> order; + HashMap<int, StringName> order; for (const KeyValue<StringName, ShaderLanguage::ShaderNode::Uniform> &E : uniforms) { if (E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_GLOBAL || E.value.scope == ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) { @@ -1676,7 +1676,7 @@ ShaderData *ParticlesStorage::_create_particles_shader_func() { return shader_data; } -bool ParticlesStorage::ParticlesMaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { +bool ParticlesStorage::ParticlesMaterialData::update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) { return update_parameters_uniform_set(p_parameters, p_uniform_dirty, p_textures_dirty, shader_data->uniforms, shader_data->ubo_offsets.ptr(), shader_data->texture_uniforms, shader_data->default_texture_params, shader_data->ubo_size, uniform_set, ParticlesStorage::get_singleton()->particles_shader.shader.version_get_shader(shader_data->version, 0), 3); } diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h index c6480794c1..115633d17a 100644 --- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h @@ -224,7 +224,7 @@ struct Particles { ParticleEmissionBuffer *emission_buffer = nullptr; RID emission_storage_buffer; - Set<RID> collisions; + HashSet<RID> collisions; RendererStorage::Dependency dependency; @@ -345,7 +345,7 @@ private: RID version; bool uses_collision = false; - Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms; Vector<ShaderCompiler::GeneratedCode::Texture> texture_uniforms; Vector<uint32_t> ubo_offsets; @@ -353,7 +353,7 @@ private: String path; String code; - Map<StringName, Map<int, RID>> default_texture_params; + HashMap<StringName, HashMap<int, RID>> default_texture_params; RID pipeline; @@ -387,7 +387,7 @@ private: virtual void set_render_priority(int p_priority) {} virtual void set_next_pass(RID p_pass) {} - virtual bool update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); + virtual bool update_parameters(const HashMap<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty); virtual ~ParticlesMaterialData(); }; diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp index 3b52a187f6..7d4808f936 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "texture_storage.h" - -#include "../renderer_storage_rd.h" +#include "../effects/copy_effects.h" +#include "material_storage.h" using namespace RendererRD; @@ -1808,8 +1808,8 @@ AABB TextureStorage::decal_get_aabb(RID p_decal) const { } void TextureStorage::update_decal_atlas() { - EffectsRD *effects = RendererStorageRD::base_singleton->get_effects(); - ERR_FAIL_NULL(effects); + RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); + ERR_FAIL_NULL(copy_effects); if (!decal_atlas.dirty) { return; //nothing to do @@ -1831,13 +1831,13 @@ void TextureStorage::update_decal_atlas() { Vector<DecalAtlas::SortItem> itemsv; itemsv.resize(decal_atlas.textures.size()); int base_size = 8; - const RID *K = nullptr; int idx = 0; - while ((K = decal_atlas.textures.next(K))) { + + for (const KeyValue<RID, DecalAtlas::Texture> &E : decal_atlas.textures) { DecalAtlas::SortItem &si = itemsv.write[idx]; - Texture *src_tex = get_texture(*K); + Texture *src_tex = get_texture(E.key); si.size.width = (src_tex->width / border) + 1; si.size.height = (src_tex->height / border) + 1; @@ -1847,7 +1847,7 @@ void TextureStorage::update_decal_atlas() { base_size = nearest_power_of_2_templated(si.size.width); } - si.texture = *K; + si.texture = E.key; idx++; } @@ -1983,18 +1983,17 @@ void TextureStorage::update_decal_atlas() { RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(mm.fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, cc); - const RID *K = nullptr; - while ((K = decal_atlas.textures.next(K))) { - DecalAtlas::Texture *t = decal_atlas.textures.getptr(*K); - Texture *src_tex = get_texture(*K); - effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0); + for (const KeyValue<RID, DecalAtlas::Texture> &E : decal_atlas.textures) { + DecalAtlas::Texture *t = decal_atlas.textures.getptr(E.key); + Texture *src_tex = get_texture(E.key); + copy_effects->copy_to_atlas_fb(src_tex->rd_texture, mm.fb, t->uv_rect, draw_list, false, t->panorama_to_dp_users > 0); } RD::get_singleton()->draw_list_end(); prev_texture = mm.texture; } else { - effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size)); + copy_effects->copy_to_fb_rect(prev_texture, mm.fb, Rect2i(Point2i(), mm.size)); prev_texture = mm.texture; } } else { @@ -2623,8 +2622,8 @@ void TextureStorage::render_target_sdf_process(RID p_render_target) { } void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, const Rect2i &p_region, bool p_gen_mipmaps) { - EffectsRD *effects = RendererStorageRD::base_singleton->get_effects(); - ERR_FAIL_NULL(effects); + CopyEffects *copy_effects = CopyEffects::get_singleton(); + ERR_FAIL_NULL(copy_effects); RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); @@ -2642,9 +2641,11 @@ void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, cons } } + // TODO figure out stereo support here + //single texture copy for backbuffer //RD::get_singleton()->texture_copy(rt->color, rt->backbuffer_mipmap0, Vector3(region.position.x, region.position.y, 0), Vector3(region.position.x, region.position.y, 0), Vector3(region.size.x, region.size.y, 1), 0, 0, 0, 0, true); - effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true); + copy_effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true); if (!p_gen_mipmaps) { return; @@ -2660,7 +2661,7 @@ void TextureStorage::render_target_copy_to_back_buffer(RID p_render_target, cons region.size.y = MAX(1, region.size.y >> 1); RID mipmap = rt->backbuffer_mipmaps[i]; - effects->gaussian_blur(prev_texture, mipmap, region, true); + copy_effects->gaussian_blur(prev_texture, mipmap, region, true); prev_texture = mipmap; } RD::get_singleton()->draw_command_end_label(); @@ -2670,8 +2671,8 @@ void TextureStorage::render_target_clear_back_buffer(RID p_render_target, const RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); - EffectsRD *effects = RendererStorageRD::base_singleton->get_effects(); - ERR_FAIL_NULL(effects); + CopyEffects *copy_effects = CopyEffects::get_singleton(); + ERR_FAIL_NULL(copy_effects); if (!rt->backbuffer.is_valid()) { _create_render_target_backbuffer(rt); @@ -2688,15 +2689,15 @@ void TextureStorage::render_target_clear_back_buffer(RID p_render_target, const } //single texture copy for backbuffer - effects->set_color(rt->backbuffer_mipmap0, p_color, region, true); + copy_effects->set_color(rt->backbuffer_mipmap0, p_color, region, true); } void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, const Rect2i &p_region) { RenderTarget *rt = render_target_owner.get_or_null(p_render_target); ERR_FAIL_COND(!rt); - EffectsRD *effects = RendererStorageRD::base_singleton->get_effects(); - ERR_FAIL_NULL(effects); + CopyEffects *copy_effects = CopyEffects::get_singleton(); + ERR_FAIL_NULL(copy_effects); if (!rt->backbuffer.is_valid()) { _create_render_target_backbuffer(rt); @@ -2722,7 +2723,7 @@ void TextureStorage::render_target_gen_back_buffer_mipmaps(RID p_render_target, region.size.y = MAX(1, region.size.y >> 1); RID mipmap = rt->backbuffer_mipmaps[i]; - effects->gaussian_blur(prev_texture, mipmap, region, true); + copy_effects->gaussian_blur(prev_texture, mipmap, region, true); prev_texture = mipmap; } RD::get_singleton()->draw_command_end_label(); diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h index a6f50803e4..418eb82808 100644 --- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h @@ -124,7 +124,7 @@ public: RID proxy_to; Vector<RID> proxies; - Set<RID> lightmap_users; + HashSet<RID> lightmap_users; RS::TextureDetectCallback detect_3d_callback = nullptr; void *detect_3d_callback_ud = nullptr; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index 6e1fa59a7a..2cb4e16583 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -562,8 +562,8 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { case RS::INSTANCE_LIGHTMAP: { InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(instance->base_data); //erase dependencies, since no longer a lightmap - while (lightmap_data->users.front()) { - instance_geometry_set_lightmap(lightmap_data->users.front()->get()->self, RID(), Rect2(), 0); + while (lightmap_data->users.begin()) { + instance_geometry_set_lightmap((*lightmap_data->users.begin())->self, RID(), Rect2(), 0); } scene_render->free(lightmap_data->instance); } break; @@ -609,13 +609,16 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { if (p_base.is_valid()) { instance->base_type = RSG::storage->get_base_type(p_base); + // fix up a specific malfunctioning case before the switch, so it can be handled if (instance->base_type == RS::INSTANCE_NONE && RendererSceneOcclusionCull::get_singleton()->is_occluder(p_base)) { instance->base_type = RS::INSTANCE_OCCLUDER; } - ERR_FAIL_COND(instance->base_type == RS::INSTANCE_NONE); - switch (instance->base_type) { + case RS::INSTANCE_NONE: { + ERR_PRINT_ONCE("unimplemented base type encountered in renderer scene cull"); + return; + } case RS::INSTANCE_LIGHT: { InstanceLightData *light = memnew(InstanceLightData); @@ -650,8 +653,8 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) { scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, instance->lightmap_sh.ptr()); } - for (Set<Instance *>::Element *E = instance->visibility_dependencies.front(); E; E = E->next()) { - Instance *dep_instance = E->get(); + for (Instance *E : instance->visibility_dependencies) { + Instance *dep_instance = E; ERR_CONTINUE(dep_instance->array_index == -1); ERR_CONTINUE(dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index != -1); dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = instance->array_index; @@ -1289,15 +1292,15 @@ void RendererSceneCull::instance_set_visibility_parent(RID p_instance, RID p_par bool RendererSceneCull::_update_instance_visibility_depth(Instance *p_instance) { bool cycle_detected = false; - Set<Instance *> traversed_nodes; + HashSet<Instance *> traversed_nodes; { Instance *instance = p_instance; while (instance) { if (!instance->visibility_dependencies.is_empty()) { uint32_t depth = 0; - for (Set<Instance *>::Element *E = instance->visibility_dependencies.front(); E; E = E->next()) { - depth = MAX(depth, E->get()->visibility_dependencies_depth); + for (const Instance *E : instance->visibility_dependencies) { + depth = MAX(depth, E->visibility_dependencies_depth); } instance->visibility_dependencies_depth = depth + 1; } else { @@ -1426,7 +1429,7 @@ void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, c ERR_FAIL_COND(p_value.get_type() == Variant::OBJECT); - Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter); + HashMap<StringName, Instance::InstanceShaderParameter>::Iterator E = instance->instance_shader_parameters.find(p_parameter); if (!E) { Instance::InstanceShaderParameter isp; @@ -1435,10 +1438,10 @@ void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, c isp.value = p_value; instance->instance_shader_parameters[p_parameter] = isp; } else { - E->get().value = p_value; - if (E->get().index >= 0 && instance->instance_allocated_shader_parameters) { + E->value.value = p_value; + if (E->value.index >= 0 && instance->instance_allocated_shader_parameters) { //update directly - RSG::material_storage->global_variables_instance_update(p_instance, E->get().index, p_value); + RSG::material_storage->global_variables_instance_update(p_instance, E->value.index, p_value); } } } @@ -1556,8 +1559,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data); //erase dependencies, since no longer a lightmap - for (Set<Instance *>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) { - Instance *geom = E->get(); + for (Instance *E : lightmap_data->geometries) { + Instance *geom = E; _instance_queue_update(geom, true, false); } } @@ -1571,8 +1574,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { //make sure lights are updated if it casts shadow if (geom->can_cast_shadows) { - for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) { - InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); + for (const Instance *E : geom->lights) { + InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data); light->shadow_dirty = true; } } @@ -1629,8 +1632,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) { idata.parent_array_index = p_instance->visibility_parent ? p_instance->visibility_parent->array_index : -1; idata.visibility_index = p_instance->visibility_index; - for (Set<Instance *>::Element *E = p_instance->visibility_dependencies.front(); E; E = E->next()) { - Instance *dep_instance = E->get(); + for (Instance *E : p_instance->visibility_dependencies) { + Instance *dep_instance = E; if (dep_instance->array_index != -1) { dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = p_instance->array_index; } @@ -1797,8 +1800,8 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) { swapped_instance->scenario->instance_visibility[swapped_instance->visibility_index].array_index = swapped_instance->array_index; } - for (Set<Instance *>::Element *E = swapped_instance->visibility_dependencies.front(); E; E = E->next()) { - Instance *dep_instance = E->get(); + for (Instance *E : swapped_instance->visibility_dependencies) { + Instance *dep_instance = E; if (dep_instance != p_instance && dep_instance->array_index != -1) { dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = swapped_instance->array_index; } @@ -1821,8 +1824,8 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) { scene_render->geometry_instance_pair_voxel_gi_instances(geom->geometry_instance, nullptr, 0); } - for (Set<Instance *>::Element *E = p_instance->visibility_dependencies.front(); E; E = E->next()) { - Instance *dep_instance = E->get(); + for (Instance *E : p_instance->visibility_dependencies) { + Instance *dep_instance = E; if (dep_instance->array_index != -1) { dep_instance->scenario->instance_data[dep_instance->array_index].parent_array_index = -1; if ((1 << dep_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) { @@ -1920,8 +1923,8 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) float accum_blend = 0.0; InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data); - for (Set<Instance *>::Element *E = geom->lightmap_captures.front(); E; E = E->next()) { - Instance *lightmap = E->get(); + for (Instance *E : geom->lightmap_captures) { + Instance *lightmap = E; bool interior = RSG::light_storage->lightmap_is_interior(lightmap->base); @@ -2741,8 +2744,8 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); uint32_t idx = 0; - for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) { - InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); + for (const Instance *E : geom->lights) { + InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data); instance_pair_buffer[idx++] = light->instance; if (idx == MAX_INSTANCE_PAIRS) { break; @@ -2764,8 +2767,8 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); uint32_t idx = 0; - for (Set<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) { - InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data); + for (const Instance *E : geom->reflection_probes) { + InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->base_data); instance_pair_buffer[idx++] = reflection_probe->instance; if (idx == MAX_INSTANCE_PAIRS) { @@ -2781,8 +2784,8 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); uint32_t idx = 0; - for (Set<Instance *>::Element *E = geom->decals.front(); E; E = E->next()) { - InstanceDecalData *decal = static_cast<InstanceDecalData *>(E->get()->base_data); + for (const Instance *E : geom->decals) { + InstanceDecalData *decal = static_cast<InstanceDecalData *>(E->base_data); instance_pair_buffer[idx++] = decal->instance; if (idx == MAX_INSTANCE_PAIRS) { @@ -2796,8 +2799,8 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul if (idata.flags & InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY) { InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data); uint32_t idx = 0; - for (Set<Instance *>::Element *E = geom->voxel_gi_instances.front(); E; E = E->next()) { - InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(E->get()->base_data); + for (const Instance *E : geom->voxel_gi_instances) { + InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(E->base_data); instance_pair_buffer[idx++] = voxel_gi->probe_instance; if (idx == MAX_INSTANCE_PAIRS) { @@ -3417,8 +3420,8 @@ void RendererSceneCull::render_probes() { const RID *instance_caches = probe->light_instances.ptr(); int idx = 0; //must count visible lights - for (Set<Instance *>::Element *E = probe->lights.front(); E; E = E->next()) { - Instance *instance = E->get(); + for (Instance *E : probe->lights) { + Instance *instance = E; InstanceLightData *instance_light = (InstanceLightData *)instance->base_data; if (!instance->visible) { continue; @@ -3499,8 +3502,8 @@ void RendererSceneCull::render_probes() { RID *instance_caches = probe->light_instances.ptrw(); int idx = 0; //must count visible lights - for (Set<Instance *>::Element *E = probe->lights.front(); E; E = E->next()) { - Instance *instance = E->get(); + for (Instance *E : probe->lights) { + Instance *instance = E; InstanceLightData *instance_light = (InstanceLightData *)instance->base_data; if (!instance->visible) { continue; @@ -3554,8 +3557,8 @@ void RendererSceneCull::render_probes() { RID instance_pair_buffer[MAX_INSTANCE_PAIRS]; - for (Set<Instance *>::Element *E = probe->dynamic_geometries.front(); E; E = E->next()) { - Instance *ins = E->get(); + for (Instance *E : probe->dynamic_geometries) { + Instance *ins = E; if (!ins->visible) { continue; } @@ -3563,8 +3566,8 @@ void RendererSceneCull::render_probes() { if (ins->scenario && ins->array_index >= 0 && (ins->scenario->instance_data[ins->array_index].flags & InstanceData::FLAG_GEOM_VOXEL_GI_DIRTY)) { uint32_t idx = 0; - for (Set<Instance *>::Element *F = geom->voxel_gi_instances.front(); F; F = F->next()) { - InstanceVoxelGIData *voxel_gi2 = static_cast<InstanceVoxelGIData *>(F->get()->base_data); + for (const Instance *F : geom->voxel_gi_instances) { + InstanceVoxelGIData *voxel_gi2 = static_cast<InstanceVoxelGIData *>(F->base_data); instance_pair_buffer[idx++] = voxel_gi2->probe_instance; if (idx == MAX_INSTANCE_PAIRS) { @@ -3589,8 +3592,8 @@ void RendererSceneCull::render_probes() { } void RendererSceneCull::render_particle_colliders() { - while (heightfield_particle_colliders_update_list.front()) { - Instance *hfpc = heightfield_particle_colliders_update_list.front()->get(); + while (heightfield_particle_colliders_update_list.begin()) { + Instance *hfpc = *heightfield_particle_colliders_update_list.begin(); if (hfpc->scenario && hfpc->base_type == RS::INSTANCE_PARTICLES_COLLISION && RSG::particles_storage->particles_collision_is_heightfield(hfpc->base)) { //update heightfield @@ -3622,11 +3625,11 @@ void RendererSceneCull::render_particle_colliders() { scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, scene_cull_result.geometry_instances); } - heightfield_particle_colliders_update_list.erase(heightfield_particle_colliders_update_list.front()); + heightfield_particle_colliders_update_list.remove(heightfield_particle_colliders_update_list.begin()); } } -void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) { +void RendererSceneCull::_update_instance_shader_parameters_from_material(HashMap<StringName, Instance::InstanceShaderParameter> &isparams, const HashMap<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) { List<RendererMaterialStorage::InstanceShaderParam> plist; RSG::material_storage->material_get_instance_shader_parameters(p_material, &plist); for (const RendererMaterialStorage::InstanceShaderParam &E : plist) { @@ -3697,7 +3700,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { bool can_cast_shadows = true; bool is_animated = false; - Map<StringName, Instance::InstanceShaderParameter> isparams; + HashMap<StringName, Instance::InstanceShaderParameter> isparams; if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) { can_cast_shadows = false; @@ -3820,8 +3823,8 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) { if (can_cast_shadows != geom->can_cast_shadows) { //ability to cast shadows change, let lights now - for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) { - InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data); + for (const Instance *E : geom->lights) { + InstanceLightData *light = static_cast<InstanceLightData *>(E->base_data); light->shadow_dirty = true; } diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index b5e8cf702f..60983f9944 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -324,7 +324,7 @@ public: RID reflection_probe_shadow_atlas; RID reflection_atlas; uint64_t used_viewport_visibility_bits; - Map<RID, uint64_t> viewport_visibility_masks; + HashMap<RID, uint64_t> viewport_visibility_masks; SelfList<Instance>::List instances; @@ -426,7 +426,7 @@ public: PropertyInfo info; }; - Map<StringName, InstanceShaderParameter> instance_shader_parameters; + HashMap<StringName, InstanceShaderParameter> instance_shader_parameters; bool instance_allocated_shader_parameters = false; int32_t instance_allocated_shader_parameters_offset = -1; @@ -443,7 +443,7 @@ public: float visibility_range_end_margin = 0.0f; RS::VisibilityRangeFadeMode visibility_range_fade_mode = RS::VISIBILITY_RANGE_FADE_DISABLED; Instance *visibility_parent = nullptr; - Set<Instance *> visibility_dependencies; + HashSet<Instance *> visibility_dependencies; uint32_t visibility_dependencies_depth = 0; float transparency = 0.0f; Scenario *scenario = nullptr; @@ -579,16 +579,16 @@ public: struct InstanceGeometryData : public InstanceBaseData { RendererSceneRender::GeometryInstance *geometry_instance = nullptr; - Set<Instance *> lights; + HashSet<Instance *> lights; bool can_cast_shadows; bool material_is_animated; uint32_t projector_count = 0; uint32_t softshadow_count = 0; - Set<Instance *> decals; - Set<Instance *> reflection_probes; - Set<Instance *> voxel_gi_instances; - Set<Instance *> lightmap_captures; + HashSet<Instance *> decals; + HashSet<Instance *> reflection_probes; + HashSet<Instance *> voxel_gi_instances; + HashSet<Instance *> lightmap_captures; InstanceGeometryData() { can_cast_shadows = true; @@ -599,7 +599,7 @@ public: struct InstanceReflectionProbeData : public InstanceBaseData { Instance *owner = nullptr; - Set<Instance *> geometries; + HashSet<Instance *> geometries; RID instance; SelfList<InstanceReflectionProbeData> update_list; @@ -616,7 +616,7 @@ public: Instance *owner = nullptr; RID instance; - Set<Instance *> geometries; + HashSet<Instance *> geometries; InstanceDecalData() { } @@ -654,7 +654,7 @@ public: bool uses_projector = false; bool uses_softshadow = false; - Set<Instance *> geometries; + HashSet<Instance *> geometries; Instance *baked_light = nullptr; @@ -673,10 +673,10 @@ public: struct InstanceVoxelGIData : public InstanceBaseData { Instance *owner = nullptr; - Set<Instance *> geometries; - Set<Instance *> dynamic_geometries; + HashSet<Instance *> geometries; + HashSet<Instance *> dynamic_geometries; - Set<Instance *> lights; + HashSet<Instance *> lights; struct LightCache { RS::LightType type; @@ -713,8 +713,8 @@ public: struct InstanceLightmapData : public InstanceBaseData { RID instance; - Set<Instance *> geometries; - Set<Instance *> users; + HashSet<Instance *> geometries; + HashSet<Instance *> users; InstanceLightmapData() { } @@ -779,7 +779,7 @@ public: } }; - Set<Instance *> heightfield_particle_colliders_update_list; + HashSet<Instance *> heightfield_particle_colliders_update_list; PagedArrayPool<Instance *> instance_cull_page_pool; PagedArrayPool<RendererSceneRender::GeometryInstance *> geometry_instance_cull_page_pool; @@ -964,7 +964,7 @@ public: virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index); virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias); - void _update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material); + void _update_instance_shader_parameters_from_material(HashMap<StringName, Instance::InstanceShaderParameter> &isparams, const HashMap<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material); virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value); virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const; diff --git a/servers/rendering/renderer_scene_occlusion_cull.h b/servers/rendering/renderer_scene_occlusion_cull.h index 48412dab68..7198379ade 100644 --- a/servers/rendering/renderer_scene_occlusion_cull.h +++ b/servers/rendering/renderer_scene_occlusion_cull.h @@ -161,31 +161,31 @@ public: static RendererSceneOcclusionCull *get_singleton() { return singleton; } - void _print_warining() { - WARN_PRINT_ONCE("Occlusion culling is disabled at build time."); + void _print_warning() { + WARN_PRINT_ONCE("Occlusion culling is disabled at build-time."); } virtual bool is_occluder(RID p_rid) { return false; } virtual RID occluder_allocate() { return RID(); } virtual void occluder_initialize(RID p_occluder) {} - virtual void free_occluder(RID p_occluder) { _print_warining(); } - virtual void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) { _print_warining(); } + virtual void free_occluder(RID p_occluder) { _print_warning(); } + virtual void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) { _print_warning(); } virtual void add_scenario(RID p_scenario) {} virtual void remove_scenario(RID p_scenario) {} - virtual void scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform3D &p_xform, bool p_enabled) { _print_warining(); } - virtual void scenario_remove_instance(RID p_scenario, RID p_instance) { _print_warining(); } + virtual void scenario_set_instance(RID p_scenario, RID p_instance, RID p_occluder, const Transform3D &p_xform, bool p_enabled) { _print_warning(); } + virtual void scenario_remove_instance(RID p_scenario, RID p_instance) { _print_warning(); } - virtual void add_buffer(RID p_buffer) { _print_warining(); } - virtual void remove_buffer(RID p_buffer) { _print_warining(); } + virtual void add_buffer(RID p_buffer) { _print_warning(); } + virtual void remove_buffer(RID p_buffer) { _print_warning(); } virtual HZBuffer *buffer_get_ptr(RID p_buffer) { return nullptr; } - virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) { _print_warining(); } - virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) { _print_warining(); } + virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) { _print_warning(); } + virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) { _print_warning(); } virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) {} virtual RID buffer_get_debug_texture(RID p_buffer) { - _print_warining(); + _print_warning(); return RID(); } diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h index 7cf4fd0aff..bb4acab582 100644 --- a/servers/rendering/renderer_storage.h +++ b/servers/rendering/renderer_storage.h @@ -62,7 +62,7 @@ public: private: friend struct DependencyTracker; - Map<DependencyTracker *, uint32_t> instances; + HashMap<DependencyTracker *, uint32_t> instances; }; struct DependencyTracker { @@ -83,15 +83,16 @@ public: } void update_end() { //call after updating dependencies - List<Pair<Dependency *, Map<DependencyTracker *, uint32_t>::Element *>> to_clean_up; - for (Set<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) { - Dependency *dep = E->get(); - Map<DependencyTracker *, uint32_t>::Element *F = dep->instances.find(this); + List<Pair<Dependency *, DependencyTracker *>> to_clean_up; + + for (Dependency *E : dependencies) { + Dependency *dep = E; + HashMap<DependencyTracker *, uint32_t>::Iterator F = dep->instances.find(this); ERR_CONTINUE(!F); - if (F->get() != instance_version) { - Pair<Dependency *, Map<DependencyTracker *, uint32_t>::Element *> p; + if (F->value != instance_version) { + Pair<Dependency *, DependencyTracker *> p; p.first = dep; - p.second = F; + p.second = F->key; to_clean_up.push_back(p); } } @@ -104,8 +105,8 @@ public: } void clear() { // clear all dependencies - for (Set<Dependency *>::Element *E = dependencies.front(); E; E = E->next()) { - Dependency *dep = E->get(); + for (Dependency *E : dependencies) { + Dependency *dep = E; dep->instances.erase(this); } dependencies.clear(); @@ -116,7 +117,7 @@ public: private: friend struct Dependency; uint32_t instance_version = 0; - Set<Dependency *> dependencies; + HashSet<Dependency *> dependencies; }; virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0; diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp index 7e18eac6ae..7c2d7a1e1d 100644 --- a/servers/rendering/renderer_viewport.cpp +++ b/servers/rendering/renderer_viewport.cpp @@ -226,9 +226,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { } if (!p_viewport->disable_2d) { - int i = 0; - - Map<Viewport::CanvasKey, Viewport::CanvasData *> canvas_map; + RBMap<Viewport::CanvasKey, Viewport::CanvasData *> canvas_map; Rect2 clip_rect(0, 0, p_viewport->size.x, p_viewport->size.y); RendererCanvasRender::Light *lights = nullptr; @@ -238,26 +236,26 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RendererCanvasRender::Light *directional_lights_with_shadow = nullptr; if (p_viewport->sdf_active) { - //process SDF + // Process SDF. Rect2 sdf_rect = RSG::texture_storage->render_target_get_sdf_rect(p_viewport->render_target); RendererCanvasRender::LightOccluderInstance *occluders = nullptr; - //make list of occluders + // Make list of occluders. for (KeyValue<RID, Viewport::CanvasData> &E : p_viewport->canvas_map) { RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size); - for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { - if (!F->get()->enabled) { + for (RendererCanvasRender::LightOccluderInstance *F : canvas->occluders) { + if (!F->enabled) { continue; } - F->get()->xform_cache = xf * F->get()->xform; + F->xform_cache = xf * F->xform; - if (sdf_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) { - F->get()->next = occluders; - occluders = F->get(); + if (sdf_rect.intersects_transformed(F->xform_cache, F->aabb_cache)) { + F->next = occluders; + occluders = F; } } } @@ -265,14 +263,13 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RSG::canvas_render->render_sdf(p_viewport->render_target, occluders); RSG::texture_storage->render_target_mark_sdf_enabled(p_viewport->render_target, true); - p_viewport->sdf_active = false; // if used, gets set active again + p_viewport->sdf_active = false; // If used, gets set active again. } else { RSG::texture_storage->render_target_mark_sdf_enabled(p_viewport->render_target, false); } Rect2 shadow_rect; - int light_count = 0; int shadow_count = 0; int directional_light_count = 0; @@ -282,10 +279,10 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size); - //find lights in canvas + // Find lights in canvas. - for (Set<RendererCanvasRender::Light *>::Element *F = canvas->lights.front(); F; F = F->next()) { - RendererCanvasRender::Light *cl = F->get(); + for (RendererCanvasRender::Light *F : canvas->lights) { + RendererCanvasRender::Light *cl = F; if (cl->enabled && cl->texture.is_valid()) { //not super efficient.. Size2 tsize = RSG::texture_storage->texture_size_with_proxy(cl->texture); @@ -298,12 +295,10 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { if (clip_rect.intersects_transformed(cl->xform_cache, cl->rect_cache)) { cl->filter_next_ptr = lights; lights = cl; - // cl->texture_cache = nullptr; Transform2D scale; scale.scale(cl->rect_cache.size); scale.columns[2] = cl->rect_cache.position; cl->light_shader_xform = cl->xform * scale; - //cl->light_shader_pos = cl->xform_cache[2]; if (cl->use_shadow) { cl->shadows_next_ptr = lights_with_shadow; if (lights_with_shadow == nullptr) { @@ -314,16 +309,12 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { lights_with_shadow = cl; cl->radius_cache = cl->rect_cache.size.length(); } - - light_count++; } - - //guess this is not needed, but keeping because it may be } } - for (Set<RendererCanvasRender::Light *>::Element *F = canvas->directional_lights.front(); F; F = F->next()) { - RendererCanvasRender::Light *cl = F->get(); + for (RendererCanvasRender::Light *F : canvas->directional_lights) { + RendererCanvasRender::Light *cl = F; if (cl->enabled) { cl->filter_next_ptr = directional_lights; directional_lights = cl; @@ -358,14 +349,14 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size); - for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { - if (!F->get()->enabled) { + for (RendererCanvasRender::LightOccluderInstance *F : canvas->occluders) { + if (!F->enabled) { continue; } - F->get()->xform_cache = xf * F->get()->xform; - if (shadow_rect.intersects_transformed(F->get()->xform_cache, F->get()->aabb_cache)) { - F->get()->next = occluders; - occluders = F->get(); + F->xform_cache = xf * F->xform; + if (shadow_rect.intersects_transformed(F->xform_cache, F->aabb_cache)) { + F->next = occluders; + occluders = F; } } } @@ -433,26 +424,24 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RENDER_TIMESTAMP("> Render DirectionalLight2D Shadows"); - //make list of occluders - int occ_cullded = 0; + // Make list of occluders. for (KeyValue<RID, Viewport::CanvasData> &E : p_viewport->canvas_map) { RendererCanvasCull::Canvas *canvas = static_cast<RendererCanvasCull::Canvas *>(E.value.canvas); Transform2D xf = _canvas_get_transform(p_viewport, canvas, &E.value, clip_rect.size); - for (Set<RendererCanvasRender::LightOccluderInstance *>::Element *F = canvas->occluders.front(); F; F = F->next()) { - if (!F->get()->enabled) { + for (RendererCanvasRender::LightOccluderInstance *F : canvas->occluders) { + if (!F->enabled) { continue; } - F->get()->xform_cache = xf * F->get()->xform; - Transform2D localizer = F->get()->xform_cache.affine_inverse(); + F->xform_cache = xf * F->xform; + Transform2D localizer = F->xform_cache.affine_inverse(); for (int j = 0; j < point_count; j++) { xf_points[j] = localizer.xform(points[j]); } - if (F->get()->aabb_cache.intersects_filled_polygon(xf_points, point_count)) { - F->get()->next = occluders; - occluders = F->get(); - occ_cullded++; + if (F->aabb_cache.intersects_filled_polygon(xf_points, point_count)) { + F->next = occluders; + occluders = F; } } } @@ -465,7 +454,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { RENDER_TIMESTAMP("< Render DirectionalLight2D Shadows"); } - if (scenario_draw_canvas_bg && canvas_map.front() && canvas_map.front()->key().get_layer() > scenario_canvas_max_layer) { + if (scenario_draw_canvas_bg && canvas_map.begin() && canvas_map.begin()->key.get_layer() > scenario_canvas_max_layer) { if (!can_draw_3d) { RSG::scene->render_empty_scene(p_viewport->render_buffers, p_viewport->scenario, p_viewport->shadow_atlas); } else { @@ -504,7 +493,6 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) { if (RSG::canvas->was_sdf_used()) { p_viewport->sdf_active = true; } - i++; if (scenario_draw_canvas_bg && E.key.get_layer() >= scenario_canvas_max_layer) { if (!can_draw_3d) { @@ -559,7 +547,7 @@ void RendererViewport::draw_viewports() { //sort viewports active_viewports.sort_custom<ViewportSort>(); - Map<DisplayServer::WindowID, Vector<BlitToScreen>> blit_to_screen_list; + HashMap<DisplayServer::WindowID, Vector<BlitToScreen>> blit_to_screen_list; //draw viewports RENDER_TIMESTAMP("> Render Viewports"); @@ -1188,8 +1176,8 @@ bool RendererViewport::free(RID p_rid) { RSG::scene->free(viewport->render_buffers); } - while (viewport->canvas_map.front()) { - viewport_remove_canvas(p_rid, viewport->canvas_map.front()->key()); + while (viewport->canvas_map.begin()) { + viewport_remove_canvas(p_rid, viewport->canvas_map.begin()->key); } viewport_set_scenario(p_rid, RID()); diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h index b6e44e8436..da8cf5396c 100644 --- a/servers/rendering/renderer_viewport.h +++ b/servers/rendering/renderer_viewport.h @@ -137,7 +137,7 @@ public: Transform2D global_transform; - Map<RID, CanvasData> canvas_map; + HashMap<RID, CanvasData> canvas_map; RendererScene::RenderInfo render_info; diff --git a/servers/rendering/rendering_device_binds.cpp b/servers/rendering/rendering_device_binds.cpp index e50ac42027..d03c4e0427 100644 --- a/servers/rendering/rendering_device_binds.cpp +++ b/servers/rendering/rendering_device_binds.cpp @@ -45,7 +45,7 @@ Error RDShaderFile::parse_versions_from_text(const String &p_text, const String }; String stage_code[RD::SHADER_STAGE_MAX]; int stages_found = 0; - Map<StringName, String> version_texts; + HashMap<StringName, String> version_texts; versions.clear(); base_error = ""; diff --git a/servers/rendering/rendering_device_binds.h b/servers/rendering/rendering_device_binds.h index ee5bf8b891..8bdd3deea1 100644 --- a/servers/rendering/rendering_device_binds.h +++ b/servers/rendering/rendering_device_binds.h @@ -329,7 +329,7 @@ protected: class RDShaderFile : public Resource { GDCLASS(RDShaderFile, Resource) - Map<StringName, Ref<RDShaderSPIRV>> versions; + HashMap<StringName, Ref<RDShaderSPIRV>> versions; String base_error; public: diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp index 000b253e8a..c4538e0776 100644 --- a/servers/rendering/rendering_server_default.cpp +++ b/servers/rendering/rendering_server_default.cpp @@ -179,10 +179,10 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) { print_line("GPU PROFILE (total " + rtos(total_time) + "ms): "); float print_threshold = 0.01; - for (OrderedHashMap<String, float>::Element E = print_gpu_profile_task_time.front(); E; E = E.next()) { - double time = E.value() / double(print_frame_profile_frame_count); + for (const KeyValue<String, float> &E : print_gpu_profile_task_time) { + double time = E.value / double(print_frame_profile_frame_count); if (time > print_threshold) { - print_line("\t-" + E.key() + ": " + rtos(time) + "ms"); + print_line("\t-" + E.key + ": " + rtos(time) + "ms"); } } print_gpu_profile_task_time.clear(); @@ -321,11 +321,7 @@ void RenderingServerDefault::set_debug_generate_wireframes(bool p_generate) { } bool RenderingServerDefault::is_low_end() const { - // FIXME: Commented out when rebasing vulkan branch on master, - // causes a crash, it seems rasterizer is not initialized yet the - // first time it's called. - //return RSG::rasterizer->is_low_end(); - return false; + return RendererCompositor::is_low_end(); } void RenderingServerDefault::_thread_exit() { diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h index de4f8d9194..9d4059b9df 100644 --- a/servers/rendering/rendering_server_default.h +++ b/servers/rendering/rendering_server_default.h @@ -33,7 +33,7 @@ #include "core/math/octree.h" #include "core/templates/command_queue_mt.h" -#include "core/templates/ordered_hash_map.h" +#include "core/templates/hash_map.h" #include "renderer_canvas_cull.h" #include "renderer_scene_cull.h" #include "renderer_viewport.h" @@ -69,7 +69,7 @@ class RenderingServerDefault : public RenderingServer { //for printing bool print_gpu_profile = false; - OrderedHashMap<String, float> print_gpu_profile_task_time; + HashMap<String, float> print_gpu_profile_task_time; uint64_t print_frame_profile_ticks_from = 0; uint32_t print_frame_profile_frame_count = 0; @@ -113,7 +113,9 @@ public: _changes_changed(); #else - _FORCE_INLINE_ static void redraw_request() { changes++; } + _FORCE_INLINE_ static void redraw_request() { + changes++; + } #endif #define WRITE_ACTION redraw_request(); diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index 812d636a0b..81cd83aebb 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -48,8 +48,8 @@ static String _mktab(int p_level) { static String _typestr(SL::DataType p_type) { String type = ShaderLanguage::get_datatype_name(p_type); - if (ShaderLanguage::is_sampler_type(p_type)) { - type = type.replace("sampler", "texture"); //we use textures instead of samplers + if (!RS::get_singleton()->is_low_end() && ShaderLanguage::is_sampler_type(p_type)) { + type = type.replace("sampler", "texture"); //we use textures instead of samplers in Vulkan GLSL } return type; } @@ -289,7 +289,7 @@ String ShaderCompiler::_get_sampler_name(ShaderLanguage::TextureFilter p_filter, return actions.sampler_array_name + "[" + itos(p_filter + (p_repeat == ShaderLanguage::REPEAT_ENABLE ? ShaderLanguage::FILTER_DEFAULT : 0)) + "]"; } -void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added) { +void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const StringName &p_for_func, const HashMap<StringName, String> &p_func_code, String &r_to_add, HashSet<StringName> &added) { int fidx = -1; for (int i = 0; i < p_node->functions.size(); i++) { @@ -303,8 +303,8 @@ void ShaderCompiler::_dump_function_deps(const SL::ShaderNode *p_node, const Str Vector<StringName> uses_functions; - for (Set<StringName>::Element *E = p_node->functions[fidx].uses_function.front(); E; E = E->next()) { - uses_functions.push_back(E->get()); + for (const StringName &E : p_node->functions[fidx].uses_function) { + uses_functions.push_back(E); } uses_functions.sort_custom<StringName::AlphCompare>(); //ensure order is deterministic so the same shader is always produced @@ -538,7 +538,11 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene continue; // Instances are indexed directly, don't need index uniforms. } if (SL::is_sampler_type(uniform.type)) { - ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + uniform.texture_binding) + ") uniform "; + // Texture layouts are different for OpenGL GLSL and Vulkan GLSL + if (!RS::get_singleton()->is_low_end()) { + ucode = "layout(set = " + itos(actions.texture_layout_set) + ", binding = " + itos(actions.base_texture_binding_index + uniform.texture_binding) + ") "; + } + ucode += "uniform "; } bool is_buffer_global = !SL::is_sampler_type(uniform.type) && uniform.scope == SL::ShaderNode::Uniform::SCOPE_GLOBAL; @@ -681,9 +685,13 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } vcode += ";\n"; - - r_gen_code.stage_globals[STAGE_VERTEX] += "layout(location=" + itos(index) + ") " + interp_mode + "out " + vcode; - r_gen_code.stage_globals[STAGE_FRAGMENT] += "layout(location=" + itos(index) + ") " + interp_mode + "in " + vcode; + // GLSL ES 3.0 does not allow layout qualifiers for varyings + if (!RS::get_singleton()->is_low_end()) { + r_gen_code.stage_globals[STAGE_VERTEX] += "layout(location=" + itos(index) + ") "; + r_gen_code.stage_globals[STAGE_FRAGMENT] += "layout(location=" + itos(index) + ") "; + } + r_gen_code.stage_globals[STAGE_VERTEX] += interp_mode + "out " + vcode; + r_gen_code.stage_globals[STAGE_FRAGMENT] += interp_mode + "in " + vcode; index += inc; } @@ -727,7 +735,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene } } - Map<StringName, String> function_code; + HashMap<StringName, String> function_code; //code for functions for (int i = 0; i < pnode->functions.size(); i++) { @@ -740,7 +748,7 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene //place functions in actual code - Set<StringName> added_funcs_per_stage[STAGE_MAX]; + HashSet<StringName> added_funcs_per_stage[STAGE_MAX]; for (int i = 0; i < pnode->functions.size(); i++) { SL::FunctionNode *fnode = pnode->functions[i].function; @@ -1125,8 +1133,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene code += ", "; } String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); - if (is_texture_func && i == 1) { - //need to map from texture to sampler in order to sample + 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 StringName texture_uniform; bool correct_texture_uniform = false; diff --git a/servers/rendering/shader_compiler.h b/servers/rendering/shader_compiler.h index 347ecf2988..2656ee68a6 100644 --- a/servers/rendering/shader_compiler.h +++ b/servers/rendering/shader_compiler.h @@ -45,14 +45,14 @@ public: }; struct IdentifierActions { - Map<StringName, Stage> entry_point_stages; + HashMap<StringName, Stage> entry_point_stages; - Map<StringName, Pair<int *, int>> render_mode_values; - Map<StringName, bool *> render_mode_flags; - Map<StringName, bool *> usage_flag_pointers; - Map<StringName, bool *> write_flag_pointers; + HashMap<StringName, Pair<int *, int>> render_mode_values; + HashMap<StringName, bool *> render_mode_flags; + HashMap<StringName, bool *> usage_flag_pointers; + HashMap<StringName, bool *> write_flag_pointers; - Map<StringName, ShaderLanguage::ShaderNode::Uniform> *uniforms; + HashMap<StringName, ShaderLanguage::ShaderNode::Uniform> *uniforms; }; struct GeneratedCode { @@ -74,7 +74,7 @@ public: String uniforms; String stage_globals[STAGE_MAX]; - Map<String, String> code; + HashMap<String, String> code; bool uses_global_textures; bool uses_fragment_time; @@ -82,10 +82,10 @@ public: }; struct DefaultIdentifierActions { - Map<StringName, String> renames; - Map<StringName, String> render_mode_defines; - Map<StringName, String> usage_defines; - Map<StringName, String> custom_samplers; + HashMap<StringName, String> renames; + HashMap<StringName, String> render_mode_defines; + HashMap<StringName, String> usage_defines; + HashMap<StringName, String> custom_samplers; ShaderLanguage::TextureFilter default_filter; ShaderLanguage::TextureRepeat default_repeat; String sampler_array_name; @@ -103,20 +103,20 @@ private: String _get_sampler_name(ShaderLanguage::TextureFilter p_filter, ShaderLanguage::TextureRepeat p_repeat); - void _dump_function_deps(const ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const Map<StringName, String> &p_func_code, String &r_to_add, Set<StringName> &added); + void _dump_function_deps(const ShaderLanguage::ShaderNode *p_node, const StringName &p_for_func, const HashMap<StringName, String> &p_func_code, String &r_to_add, HashSet<StringName> &added); String _dump_node_code(const ShaderLanguage::Node *p_node, int p_level, GeneratedCode &r_gen_code, IdentifierActions &p_actions, const DefaultIdentifierActions &p_default_actions, bool p_assigning, bool p_scope = true); const ShaderLanguage::ShaderNode *shader = nullptr; const ShaderLanguage::FunctionNode *function = nullptr; StringName current_func_name; StringName time_name; - Set<StringName> texture_functions; + HashSet<StringName> texture_functions; - Set<StringName> used_name_defines; - Set<StringName> used_flag_pointers; - Set<StringName> used_rmode_defines; - Set<StringName> internal_functions; - Set<StringName> fragment_varyings; + HashSet<StringName> used_name_defines; + HashSet<StringName> used_flag_pointers; + HashSet<StringName> used_rmode_defines; + HashSet<StringName> internal_functions; + HashSet<StringName> fragment_varyings; DefaultIdentifierActions actions; diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index b07fbc55e4..b25296e3b0 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -4005,7 +4005,7 @@ uint32_t ShaderLanguage::get_datatype_size(ShaderLanguage::DataType p_type) { } void ShaderLanguage::get_keyword_list(List<String> *r_keywords) { - Set<String> kws; + HashSet<String> kws; int idx = 0; @@ -4022,8 +4022,8 @@ void ShaderLanguage::get_keyword_list(List<String> *r_keywords) { idx++; } - for (Set<String>::Element *E = kws.front(); E; E = E->next()) { - r_keywords->push_back(E->get()); + for (const String &E : kws) { + r_keywords->push_back(E); } } @@ -4042,7 +4042,7 @@ bool ShaderLanguage::is_control_flow_keyword(String p_keyword) { } void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) { - Set<String> kws; + HashSet<String> kws; int idx = 0; @@ -4052,8 +4052,8 @@ void ShaderLanguage::get_builtin_funcs(List<String> *r_keywords) { idx++; } - for (Set<String>::Element *E = kws.front(); E; E = E->next()) { - r_keywords->push_back(E->get()); + for (const String &E : kws) { + r_keywords->push_back(E); } } @@ -4326,9 +4326,9 @@ bool ShaderLanguage::_propagate_function_call_sampler_uniform_settings(StringNam arg->tex_argument_check = true; arg->tex_argument_filter = p_filter; arg->tex_argument_repeat = p_repeat; - for (KeyValue<StringName, Set<int>> &E : arg->tex_argument_connect) { - for (Set<int>::Element *F = E.value.front(); F; F = F->next()) { - if (!_propagate_function_call_sampler_uniform_settings(E.key, F->get(), p_filter, p_repeat)) { + for (KeyValue<StringName, HashSet<int>> &E : arg->tex_argument_connect) { + for (const int &F : E.value) { + if (!_propagate_function_call_sampler_uniform_settings(E.key, F, p_filter, p_repeat)) { return false; } } @@ -4360,9 +4360,9 @@ bool ShaderLanguage::_propagate_function_call_sampler_builtin_reference(StringNa arg->tex_builtin_check = true; arg->tex_builtin = p_builtin; - for (KeyValue<StringName, Set<int>> &E : arg->tex_argument_connect) { - for (Set<int>::Element *F = E.value.front(); F; F = F->next()) { - if (!_propagate_function_call_sampler_builtin_reference(E.key, F->get(), p_builtin)) { + for (KeyValue<StringName, HashSet<int>> &E : arg->tex_argument_connect) { + for (const int &F : E.value) { + if (!_propagate_function_call_sampler_builtin_reference(E.key, F, p_builtin)) { return false; } } @@ -5082,7 +5082,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons for (int j = 0; j < base_function->arguments.size(); j++) { if (base_function->arguments[j].name == varname) { if (!base_function->arguments[j].tex_argument_connect.has(call_function->name)) { - base_function->arguments.write[j].tex_argument_connect[call_function->name] = Set<int>(); + base_function->arguments.write[j].tex_argument_connect[call_function->name] = HashSet<int>(); } base_function->arguments.write[j].tex_argument_connect[call_function->name].insert(i); found = true; @@ -5365,6 +5365,11 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (tk.type == TK_CURSOR) { //do nothing } else if (tk.type == TK_PERIOD) { +#ifdef DEBUG_ENABLED + uint32_t prev_keyword_completion_context = keyword_completion_context; + keyword_completion_context = CF_UNSPECIFIED; +#endif + DataType dt = expr->get_datatype(); String st = expr->get_datatype_name(); @@ -5405,9 +5410,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons StringName member_struct_name = ""; int array_size = 0; - Set<char> position_symbols; - Set<char> color_symbols; - Set<char> texture_symbols; + RBSet<char> position_symbols; + RBSet<char> color_symbols; + RBSet<char> texture_symbols; bool mix_error = false; @@ -5720,6 +5725,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons } expr = mn; +#ifdef DEBUG_ENABLED + keyword_completion_context = prev_keyword_completion_context; +#endif + //todo //member (period) has priority over any operator //creates a subindexing expression in place @@ -6634,7 +6643,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun StringName func_name = parent_function->name; if (!used_local_vars.has(func_name)) { - used_local_vars.insert(func_name, Map<StringName, Usage>()); + used_local_vars.insert(func_name, HashMap<StringName, Usage>()); } used_local_vars[func_name].insert(name, Usage(tk_line)); @@ -7048,7 +7057,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun _set_tkpos(pos); continue; } else { - Set<int> constants; + HashSet<int> constants; for (int i = 0; i < switch_block->statements.size(); i++) { // Checks for duplicates. ControlFlowNode *flow = static_cast<ControlFlowNode *>(switch_block->statements[i]); if (flow) { @@ -7551,15 +7560,15 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun return OK; } -String ShaderLanguage::_get_shader_type_list(const Set<String> &p_shader_types) const { +String ShaderLanguage::_get_shader_type_list(const HashSet<String> &p_shader_types) const { // Return a list of shader types as an human-readable string String valid_types; - for (const Set<String>::Element *E = p_shader_types.front(); E; E = E->next()) { + for (const String &E : p_shader_types) { if (!valid_types.is_empty()) { valid_types += ", "; } - valid_types += "'" + E->get() + "'"; + valid_types += "'" + E + "'"; } return valid_types; @@ -7625,7 +7634,7 @@ Error ShaderLanguage::_validate_datatype(DataType p_type) { return OK; } -Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const Set<String> &p_shader_types) { +Error ShaderLanguage::_parse_shader(const HashMap<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const HashSet<String> &p_shader_types) { Token tk = _get_token(); TkPos prev_pos; Token next; @@ -7685,7 +7694,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct stages = &p_functions; const FunctionInfo &constants = p_functions.has("constants") ? p_functions["constants"] : FunctionInfo(); - Map<String, String> defined_modes; + HashMap<String, String> defined_modes; while (tk.type != TK_EOF) { switch (tk.type) { @@ -7776,7 +7785,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct st.shader_struct = st_node; int member_count = 0; - Set<String> member_names; + HashSet<String> member_names; while (true) { // variables list #ifdef DEBUG_ENABLED @@ -9221,7 +9230,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct return OK; } -bool ShaderLanguage::has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name) { +bool ShaderLanguage::has_builtin(const HashMap<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name) { for (const KeyValue<StringName, ShaderLanguage::FunctionInfo> &E : p_functions) { if (E.value.built_ins.has(p_name)) { return true; @@ -9363,19 +9372,19 @@ String ShaderLanguage::get_shader_type(const String &p_code) { #ifdef DEBUG_ENABLED void ShaderLanguage::_check_warning_accums() { - for (const KeyValue<ShaderWarning::Code, Map<StringName, Map<StringName, Usage>> *> &E : warnings_check_map2) { - for (Map<StringName, Map<StringName, Usage>>::Element *T = (*E.value).front(); T; T = T->next()) { - for (const KeyValue<StringName, Usage> &U : T->get()) { + for (const KeyValue<ShaderWarning::Code, HashMap<StringName, HashMap<StringName, Usage>> *> &E : warnings_check_map2) { + for (const KeyValue<StringName, HashMap<StringName, Usage>> &T : *E.value) { + for (const KeyValue<StringName, Usage> &U : T.value) { if (!U.value.used) { _add_warning(E.key, U.value.decl_line, U.key); } } } } - for (const KeyValue<ShaderWarning::Code, Map<StringName, Usage> *> &E : warnings_check_map) { - for (const Map<StringName, Usage>::Element *U = (*E.value).front(); U; U = U->next()) { - if (!U->get().used) { - _add_warning(E.key, U->get().decl_line, U->key()); + for (const KeyValue<ShaderWarning::Code, HashMap<StringName, Usage> *> &E : warnings_check_map) { + for (const KeyValue<StringName, Usage> &U : (*E.value)) { + if (!U.value.used) { + _add_warning(E.key, U.value.decl_line, U.key); } } } @@ -9533,7 +9542,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ case COMPLETION_IDENTIFIER: case COMPLETION_FUNCTION_CALL: { bool comp_ident = completion_type == COMPLETION_IDENTIFIER; - Map<String, ScriptLanguage::CodeCompletionKind> matches; + HashMap<String, ScriptLanguage::CodeCompletionKind> matches; StringName skip_function; BlockNode *block = completion_block; @@ -9780,7 +9789,7 @@ Error ShaderLanguage::complete(const String &p_code, const ShaderCompileInfo &p_ } int idx2 = 0; - Set<int> out_args; + HashSet<int> out_args; while (builtin_func_out_args[idx2].name != nullptr) { if (builtin_func_out_args[idx2].name == builtin_func_defs[idx].name) { for (int i = 0; i < BuiltinFuncOutArgs::MAX_ARGS; i++) { diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h index b572a39d2c..5d216bd66e 100644 --- a/servers/rendering/shader_language.h +++ b/servers/rendering/shader_language.h @@ -35,7 +35,7 @@ #include "core/string/string_name.h" #include "core/string/ustring.h" #include "core/templates/list.h" -#include "core/templates/map.h" +#include "core/templates/rb_map.h" #include "core/typedefs.h" #include "core/variant/variant.h" @@ -501,7 +501,7 @@ public: BlockNode *parent_block = nullptr; enum BlockType { - BLOCK_TYPE_STANDART, + BLOCK_TYPE_STANDARD, BLOCK_TYPE_FOR_INIT, BLOCK_TYPE_FOR_CONDITION, BLOCK_TYPE_FOR_EXPRESSION, @@ -510,7 +510,7 @@ public: BLOCK_TYPE_DEFAULT, }; - int block_type = BLOCK_TYPE_STANDART; + int block_type = BLOCK_TYPE_STANDARD; SubClassTag block_tag = SubClassTag::TAG_GLOBAL; struct Variable { @@ -523,7 +523,7 @@ public: ConstantNode::Value value; }; - Map<StringName, Variable> variables; + HashMap<StringName, Variable> variables; List<Node *> statements; bool single_statement = false; bool use_comma_between_statements = false; @@ -587,7 +587,7 @@ public: bool is_const; int array_size; - Map<StringName, Set<int>> tex_argument_connect; + HashMap<StringName, HashSet<int>> tex_argument_connect; }; StringName name; @@ -620,7 +620,7 @@ public: struct Function { StringName name; FunctionNode *function = nullptr; - Set<StringName> uses_function; + HashSet<StringName> uses_function; bool callable; }; @@ -693,10 +693,10 @@ public: } }; - Map<StringName, Constant> constants; - Map<StringName, Varying> varyings; - Map<StringName, Uniform> uniforms; - Map<StringName, Struct> structs; + HashMap<StringName, Constant> constants; + HashMap<StringName, Varying> varyings; + HashMap<StringName, Uniform> uniforms; + HashMap<StringName, Struct> structs; Vector<StringName> render_modes; Vector<Function> functions; @@ -853,13 +853,13 @@ public: }; struct FunctionInfo { - Map<StringName, BuiltInInfo> built_ins; - Map<StringName, StageFunctionInfo> stage_functions; + HashMap<StringName, BuiltInInfo> built_ins; + HashMap<StringName, StageFunctionInfo> stage_functions; bool can_discard = false; bool main_function = false; }; - static bool has_builtin(const Map<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name); + static bool has_builtin(const HashMap<StringName, ShaderLanguage::FunctionInfo> &p_functions, const StringName &p_name); typedef DataType (*GlobalVariableGetTypeFunc)(const StringName &p_name); @@ -889,15 +889,15 @@ private: } }; - Map<StringName, Usage> used_constants; - Map<StringName, Usage> used_varyings; - Map<StringName, Usage> used_uniforms; - Map<StringName, Usage> used_functions; - Map<StringName, Usage> used_structs; - Map<ShaderWarning::Code, Map<StringName, Usage> *> warnings_check_map; + HashMap<StringName, Usage> used_constants; + HashMap<StringName, Usage> used_varyings; + HashMap<StringName, Usage> used_uniforms; + HashMap<StringName, Usage> used_functions; + HashMap<StringName, Usage> used_structs; + HashMap<ShaderWarning::Code, HashMap<StringName, Usage> *> warnings_check_map; - Map<StringName, Map<StringName, Usage>> used_local_vars; - Map<ShaderWarning::Code, Map<StringName, Map<StringName, Usage>> *> warnings_check_map2; + HashMap<StringName, HashMap<StringName, Usage>> used_local_vars; + HashMap<ShaderWarning::Code, HashMap<StringName, HashMap<StringName, Usage>> *> warnings_check_map2; List<ShaderWarning> warnings; @@ -1035,7 +1035,7 @@ private: uint32_t keyword_completion_context; #endif // DEBUG_ENABLED - const Map<StringName, FunctionInfo> *stages = nullptr; + const HashMap<StringName, FunctionInfo> *stages = nullptr; bool _get_completable_identifier(BlockNode *p_block, CompletionType p_type, StringName &identifier); static const BuiltinFuncDef builtin_func_defs[]; @@ -1064,10 +1064,10 @@ private: Node *_parse_and_reduce_expression(BlockNode *p_block, const FunctionInfo &p_function_info); Error _parse_block(BlockNode *p_block, const FunctionInfo &p_function_info, bool p_just_one = false, bool p_can_break = false, bool p_can_continue = false); - String _get_shader_type_list(const Set<String> &p_shader_types) const; + String _get_shader_type_list(const HashSet<String> &p_shader_types) const; String _get_qualifier_str(ArgumentQualifier p_qualifier) const; - Error _parse_shader(const Map<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const Set<String> &p_shader_types); + Error _parse_shader(const HashMap<StringName, FunctionInfo> &p_functions, const Vector<ModeInfo> &p_render_modes, const HashSet<String> &p_shader_types); Error _find_last_flow_op_in_block(BlockNode *p_block, FlowOperation p_op); Error _find_last_flow_op_in_op(ControlFlowNode *p_flow, FlowOperation p_op); @@ -1090,10 +1090,10 @@ public: static String get_shader_type(const String &p_code); struct ShaderCompileInfo { - Map<StringName, FunctionInfo> functions; + HashMap<StringName, FunctionInfo> functions; Vector<ModeInfo> render_modes; VaryingFunctionNames varying_function_names = VaryingFunctionNames(); - Set<String> shader_types; + HashSet<String> shader_types; GlobalVariableGetTypeFunc global_variable_type_func = nullptr; }; diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp index 27a69fbc2e..e0dd417758 100644 --- a/servers/rendering/shader_types.cpp +++ b/servers/rendering/shader_types.cpp @@ -31,7 +31,7 @@ #include "shader_types.h" #include "core/math/math_defs.h" -const Map<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(RS::ShaderMode p_mode) const { +const HashMap<StringName, ShaderLanguage::FunctionInfo> &ShaderTypes::get_functions(RS::ShaderMode p_mode) const { return shader_modes[p_mode].functions; } @@ -39,7 +39,7 @@ const Vector<ShaderLanguage::ModeInfo> &ShaderTypes::get_modes(RS::ShaderMode p_ return shader_modes[p_mode].modes; } -const Set<String> &ShaderTypes::get_types() const { +const HashSet<String> &ShaderTypes::get_types() const { return shader_types; } @@ -192,26 +192,26 @@ ShaderTypes::ShaderTypes() { // spatial render modes { - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "blend", "mix", "add", "sub", "mul" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "depth_draw", "opaque", "always", "never" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "depth_prepass_alpha" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "depth_test_disabled" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "sss_mode_skin" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "cull", "back", "front", "disabled" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "unshaded" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "wireframe" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "diffuse", "lambert", "lambert_wrap", "burley", "toon" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "specular", "schlick_ggx", "toon", "disabled" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "skip_vertex_transform" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "world_vertex_coords" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "ensure_correct_normals" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "shadows_disabled" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "ambient_light_disabled" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "shadow_to_opacity" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "vertex_lighting" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "particle_trails" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "alpha_to_coverage" }); - shader_modes[RS::SHADER_SPATIAL].modes.push_back({ "alpha_to_coverage_and_one" }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("blend"), "mix", "add", "sub", "mul" }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("depth_draw"), "opaque", "always", "never" }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("depth_prepass_alpha") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("depth_test_disabled") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("sss_mode_skin") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("cull"), "back", "front", "disabled" }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("unshaded") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("wireframe") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("diffuse"), "lambert", "lambert_wrap", "burley", "toon" }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("specular"), "schlick_ggx", "toon", "disabled" }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("skip_vertex_transform") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("world_vertex_coords") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("ensure_correct_normals") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("shadows_disabled") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("ambient_light_disabled") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("shadow_to_opacity") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("vertex_lighting") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("particle_trails") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage") }); + shader_modes[RS::SHADER_SPATIAL].modes.push_back({ PNAME("alpha_to_coverage_and_one") }); } /************ CANVAS ITEM **************************/ @@ -299,10 +299,10 @@ ShaderTypes::ShaderTypes() { // canvasitem render modes { - shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "skip_vertex_transform" }); - shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "blend", "mix", "add", "sub", "mul", "premul_alpha", "disabled" }); - shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "unshaded" }); - shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ "light_only" }); + shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ PNAME("skip_vertex_transform") }); + shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ PNAME("blend"), "mix", "add", "sub", "mul", "premul_alpha", "disabled" }); + shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ PNAME("unshaded") }); + shader_modes[RS::SHADER_CANVAS_ITEM].modes.push_back({ PNAME("light_only") }); } /************ PARTICLES **************************/ @@ -380,10 +380,10 @@ ShaderTypes::ShaderTypes() { // particles render modes { - shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "collision_use_scale" }); - shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "disable_force" }); - shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "disable_velocity" }); - shader_modes[RS::SHADER_PARTICLES].modes.push_back({ "keep_data" }); + shader_modes[RS::SHADER_PARTICLES].modes.push_back({ PNAME("collision_use_scale") }); + shader_modes[RS::SHADER_PARTICLES].modes.push_back({ PNAME("disable_force") }); + shader_modes[RS::SHADER_PARTICLES].modes.push_back({ PNAME("disable_velocity") }); + shader_modes[RS::SHADER_PARTICLES].modes.push_back({ PNAME("keep_data") }); } /************ SKY **************************/ @@ -430,9 +430,9 @@ ShaderTypes::ShaderTypes() { // sky render modes { - shader_modes[RS::SHADER_SKY].modes.push_back({ "use_half_res_pass" }); - shader_modes[RS::SHADER_SKY].modes.push_back({ "use_quarter_res_pass" }); - shader_modes[RS::SHADER_SKY].modes.push_back({ "disable_fog" }); + shader_modes[RS::SHADER_SKY].modes.push_back({ PNAME("use_half_res_pass") }); + shader_modes[RS::SHADER_SKY].modes.push_back({ PNAME("use_quarter_res_pass") }); + shader_modes[RS::SHADER_SKY].modes.push_back({ PNAME("disable_fog") }); } /************ FOG **************************/ diff --git a/servers/rendering/shader_types.h b/servers/rendering/shader_types.h index 385083b670..107525cd15 100644 --- a/servers/rendering/shader_types.h +++ b/servers/rendering/shader_types.h @@ -31,29 +31,29 @@ #ifndef SHADERTYPES_H #define SHADERTYPES_H -#include "core/templates/ordered_hash_map.h" +#include "core/templates/rb_map.h" #include "servers/rendering_server.h" #include "shader_language.h" class ShaderTypes { struct Type { - Map<StringName, ShaderLanguage::FunctionInfo> functions; + HashMap<StringName, ShaderLanguage::FunctionInfo> functions; Vector<ShaderLanguage::ModeInfo> modes; }; - Map<RS::ShaderMode, Type> shader_modes; + HashMap<RS::ShaderMode, Type> shader_modes; static ShaderTypes *singleton; - Set<String> shader_types; + HashSet<String> shader_types; List<String> shader_types_list; public: static ShaderTypes *get_singleton() { return singleton; } - const Map<StringName, ShaderLanguage::FunctionInfo> &get_functions(RS::ShaderMode p_mode) const; + const HashMap<StringName, ShaderLanguage::FunctionInfo> &get_functions(RS::ShaderMode p_mode) const; const Vector<ShaderLanguage::ModeInfo> &get_modes(RS::ShaderMode p_mode) const; - const Set<String> &get_types() const; + const HashSet<String> &get_types() const; const List<String> &get_types_list() const; ShaderTypes(); diff --git a/servers/rendering/shader_warnings.cpp b/servers/rendering/shader_warnings.cpp index 639b9bd165..855dc23d94 100644 --- a/servers/rendering/shader_warnings.cpp +++ b/servers/rendering/shader_warnings.cpp @@ -109,10 +109,10 @@ ShaderWarning::Code ShaderWarning::get_code_from_name(const String &p_name) { ERR_FAIL_V_MSG(WARNING_MAX, "Invalid shader warning name: " + p_name); } -static Map<int, uint32_t> *code_to_flags_map = nullptr; +static HashMap<int, uint32_t> *code_to_flags_map = nullptr; static void init_code_to_flags_map() { - code_to_flags_map = memnew((Map<int, uint32_t>)); + code_to_flags_map = memnew((HashMap<int, uint32_t>)); code_to_flags_map->insert(ShaderWarning::FLOAT_COMPARISON, ShaderWarning::FLOAT_COMPARISON_FLAG); code_to_flags_map->insert(ShaderWarning::UNUSED_CONSTANT, ShaderWarning::UNUSED_CONSTANT_FLAG); code_to_flags_map->insert(ShaderWarning::UNUSED_FUNCTION, ShaderWarning::UNUSED_FUNCTION_FLAG); @@ -124,7 +124,7 @@ static void init_code_to_flags_map() { code_to_flags_map->insert(ShaderWarning::DEVICE_LIMIT_EXCEEDED, ShaderWarning::DEVICE_LIMIT_EXCEEDED_FLAG); } -ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, bool> &p_map) { +ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const HashMap<Code, bool> &p_map) { uint32_t result = 0U; if (code_to_flags_map == nullptr) { diff --git a/servers/rendering/shader_warnings.h b/servers/rendering/shader_warnings.h index e309907181..8edf85842f 100644 --- a/servers/rendering/shader_warnings.h +++ b/servers/rendering/shader_warnings.h @@ -34,8 +34,9 @@ #ifdef DEBUG_ENABLED #include "core/string/string_name.h" +#include "core/templates/hash_map.h" #include "core/templates/list.h" -#include "core/templates/map.h" +#include "core/templates/rb_map.h" #include "core/variant/variant.h" class ShaderWarning { @@ -82,7 +83,7 @@ public: static String get_name_from_code(Code p_code); static Code get_code_from_name(const String &p_name); - static CodeFlags get_flags_from_codemap(const Map<Code, bool> &p_map); + static CodeFlags get_flags_from_codemap(const HashMap<Code, bool> &p_map); ShaderWarning(Code p_code = WARNING_MAX, int p_line = -1, const StringName &p_subject = "", const Vector<Variant> &p_extra_args = Vector<Variant>()); }; diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index 136664e333..766ca88e34 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2885,6 +2885,7 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/shading/overrides/force_lambert_over_burley.mobile", true); GLOBAL_DEF("rendering/driver/depth_prepass/enable", true); + GLOBAL_DEF("rendering/driver/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple"); GLOBAL_DEF_RST("rendering/textures/default_filters/use_nearest_mipmap_filter", false); GLOBAL_DEF_RST("rendering/textures/default_filters/anisotropic_filtering_level", 2); @@ -2933,7 +2934,7 @@ RenderingServer::RenderingServer() { ProjectSettings::get_singleton()->set_custom_property_info("rendering/scaling_3d/mode", PropertyInfo(Variant::INT, "rendering/scaling_3d/mode", - PROPERTY_HINT_ENUM, "Bilinear (Fastest),FSR (Fast)")); + PROPERTY_HINT_ENUM, "Bilinear (Fastest),FSR 1.0 (Fast)")); ProjectSettings::get_singleton()->set_custom_property_info("rendering/scaling_3d/scale", PropertyInfo(Variant::FLOAT, @@ -3002,44 +3003,15 @@ RenderingServer::RenderingServer() { GLOBAL_DEF("rendering/limits/cluster_builder/max_clustered_elements", 512); ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/cluster_builder/max_clustered_elements", PropertyInfo(Variant::FLOAT, "rendering/limits/cluster_builder/max_clustered_elements", PROPERTY_HINT_RANGE, "32,8192,1")); - GLOBAL_DEF_RST_BASIC("xr/shaders/enabled", false); + // OpenGL limits + GLOBAL_DEF_RST("rendering/limits/opengl/max_renderable_elements", 65536); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/opengl/max_renderable_elements", PropertyInfo(Variant::INT, "rendering/limits/opengl/max_renderable_elements", PROPERTY_HINT_RANGE, "1024,65536,1")); + GLOBAL_DEF_RST("rendering/limits/opengl/max_renderable_lights", 32); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/opengl/max_renderable_lights", PropertyInfo(Variant::INT, "rendering/limits/opengl/max_renderable_lights", PROPERTY_HINT_RANGE, "2,256,1")); + GLOBAL_DEF_RST("rendering/limits/opengl/max_lights_per_object", 8); + ProjectSettings::get_singleton()->set_custom_property_info("rendering/limits/opengl/max_lights_per_object", PropertyInfo(Variant::INT, "rendering/limits/opengl/max_lights_per_object", PROPERTY_HINT_RANGE, "2,1024,1")); - GLOBAL_DEF_RST("rendering/2d/options/use_software_skinning", true); - GLOBAL_DEF_RST("rendering/2d/options/ninepatch_mode", 1); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/options/ninepatch_mode", PropertyInfo(Variant::INT, "rendering/2d/options/ninepatch_mode", PROPERTY_HINT_ENUM, "Fixed,Scaling")); - - GLOBAL_DEF_RST("rendering/2d/opengl/batching_send_null", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/batching_send_null", PropertyInfo(Variant::INT, "rendering/2d/opengl/batching_send_null", PROPERTY_HINT_ENUM, "Default (On),Off,On")); - GLOBAL_DEF_RST("rendering/2d/opengl/batching_stream", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/batching_stream", PropertyInfo(Variant::INT, "rendering/2d/opengl/batching_stream", PROPERTY_HINT_ENUM, "Default (Off),Off,On")); - GLOBAL_DEF_RST("rendering/2d/opengl/legacy_orphan_buffers", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/legacy_orphan_buffers", PropertyInfo(Variant::INT, "rendering/2d/opengl/legacy_orphan_buffers", PROPERTY_HINT_ENUM, "Default (On),Off,On")); - GLOBAL_DEF_RST("rendering/2d/opengl/legacy_stream", 0); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/2d/opengl/legacy_stream", PropertyInfo(Variant::INT, "rendering/2d/opengl/legacy_stream", PROPERTY_HINT_ENUM, "Default (On),Off,On")); - - GLOBAL_DEF("rendering/batching/options/use_batching", false); - GLOBAL_DEF_RST("rendering/batching/options/use_batching_in_editor", false); - GLOBAL_DEF("rendering/batching/options/single_rect_fallback", false); - GLOBAL_DEF("rendering/batching/parameters/max_join_item_commands", 16); - GLOBAL_DEF("rendering/batching/parameters/colored_vertex_format_threshold", 0.25f); - GLOBAL_DEF("rendering/batching/lights/scissor_area_threshold", 1.0f); - GLOBAL_DEF("rendering/batching/lights/max_join_items", 32); - GLOBAL_DEF("rendering/batching/parameters/batch_buffer_size", 16384); - GLOBAL_DEF("rendering/batching/parameters/item_reordering_lookahead", 4); - GLOBAL_DEF("rendering/batching/debug/flash_batching", false); - GLOBAL_DEF("rendering/batching/debug/diagnose_frame", false); - GLOBAL_DEF("rendering/gles2/compatibility/disable_half_float", false); - GLOBAL_DEF("rendering/gles2/compatibility/enable_high_float.Android", false); - GLOBAL_DEF("rendering/batching/precision/uv_contract", false); - GLOBAL_DEF("rendering/batching/precision/uv_contract_amount", 100); - - ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/max_join_item_commands", PropertyInfo(Variant::INT, "rendering/batching/parameters/max_join_item_commands", PROPERTY_HINT_RANGE, "0,65535")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/colored_vertex_format_threshold", PropertyInfo(Variant::FLOAT, "rendering/batching/parameters/colored_vertex_format_threshold", PROPERTY_HINT_RANGE, "0.0,1.0,0.01")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/batch_buffer_size", PropertyInfo(Variant::INT, "rendering/batching/parameters/batch_buffer_size", PROPERTY_HINT_RANGE, "1024,65535,1024")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/lights/scissor_area_threshold", PropertyInfo(Variant::FLOAT, "rendering/batching/lights/scissor_area_threshold", PROPERTY_HINT_RANGE, "0.0,1.0")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/lights/max_join_items", PropertyInfo(Variant::INT, "rendering/batching/lights/max_join_items", PROPERTY_HINT_RANGE, "0,512")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/parameters/item_reordering_lookahead", PropertyInfo(Variant::INT, "rendering/batching/parameters/item_reordering_lookahead", PROPERTY_HINT_RANGE, "0,256")); - ProjectSettings::get_singleton()->set_custom_property_info("rendering/batching/precision/uv_contract_amount", PropertyInfo(Variant::INT, "rendering/batching/precision/uv_contract_amount", PROPERTY_HINT_RANGE, "0,10000")); + GLOBAL_DEF_RST_BASIC("xr/shaders/enabled", false); } RenderingServer::~RenderingServer() { diff --git a/servers/text_server.h b/servers/text_server.h index b08aa26917..f96146a549 100644 --- a/servers/text_server.h +++ b/servers/text_server.h @@ -159,7 +159,7 @@ public: void _draw_hex_code_box_number(const RID &p_canvas, int64_t p_size, const Vector2 &p_pos, uint8_t p_index, const Color &p_color) const; protected: - Map<char32_t, char32_t> diacritics_map; + HashMap<char32_t, char32_t> diacritics_map; void _diacritics_map_add(const String &p_from, char32_t p_to); void _init_diacritics_map(); diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h index cd06d4a087..8371dfcbb5 100644 --- a/servers/xr/xr_positional_tracker.h +++ b/servers/xr/xr_positional_tracker.h @@ -60,8 +60,8 @@ private: String profile; // this is interface dependent, for OpenXR this will be the interaction profile bound for to the tracker TrackerHand hand; // if known, the hand this tracker is held in - Map<StringName, Ref<XRPose>> poses; - Map<StringName, Variant> inputs; + HashMap<StringName, Ref<XRPose>> poses; + HashMap<StringName, Variant> inputs; protected: static void _bind_methods(); |