Browse Source

Merge pull request #93068 from BastiaanOlij/compositor_motion_vectors

Track compositor effects that use motion vectors
Rémi Verschelde 1 year ago
parent
commit
3a11eb9818

+ 3 - 3
servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp

@@ -1040,7 +1040,7 @@ void MeshStorage::update_mesh_instances() {
 
 	//process skeletons and blend shapes
 	uint64_t frame = RSG::rasterizer->get_frame_number();
-	bool uses_motion_vectors = (RSG::viewport->get_num_viewports_with_motion_vectors() > 0);
+	bool uses_motion_vectors = (RSG::viewport->get_num_viewports_with_motion_vectors() > 0) || (RendererCompositorStorage::get_singleton()->get_num_compositor_effects_with_motion_vectors() > 0);
 	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
 
 	while (dirty_mesh_instance_arrays.first()) {
@@ -1711,7 +1711,7 @@ void MeshStorage::multimesh_instance_set_transform(RID p_multimesh, int p_index,
 
 	_multimesh_make_local(multimesh);
 
-	bool uses_motion_vectors = (RSG::viewport->get_num_viewports_with_motion_vectors() > 0);
+	bool uses_motion_vectors = (RSG::viewport->get_num_viewports_with_motion_vectors() > 0) || (RendererCompositorStorage::get_singleton()->get_num_compositor_effects_with_motion_vectors() > 0);
 	if (uses_motion_vectors) {
 		_multimesh_enable_motion_vectors(multimesh);
 	}
@@ -1934,7 +1934,7 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
 	ERR_FAIL_NULL(multimesh);
 	ERR_FAIL_COND(p_buffer.size() != (multimesh->instances * (int)multimesh->stride_cache));
 
-	bool uses_motion_vectors = (RSG::viewport->get_num_viewports_with_motion_vectors() > 0);
+	bool uses_motion_vectors = (RSG::viewport->get_num_viewports_with_motion_vectors() > 0) || (RendererCompositorStorage::get_singleton()->get_num_compositor_effects_with_motion_vectors() > 0);
 	if (uses_motion_vectors) {
 		_multimesh_enable_motion_vectors(multimesh);
 	}

+ 2 - 2
servers/rendering/renderer_rd/storage_rd/particles_storage.cpp

@@ -1306,7 +1306,7 @@ void ParticlesStorage::_particles_update_buffers(Particles *particles) {
 		userdata_count = particle_shader_data->userdata_count;
 	}
 
-	bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0;
+	bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0 || (RendererCompositorStorage::get_singleton()->get_num_compositor_effects_with_motion_vectors() > 0);
 	bool index_draw_order = particles->draw_order == RS::ParticlesDrawOrder::PARTICLES_DRAW_ORDER_INDEX;
 	bool enable_motion_vectors = uses_motion_vectors && index_draw_order && !particles->instance_motion_vectors_enabled;
 	bool only_instances_changed = false;
@@ -1389,7 +1389,7 @@ void ParticlesStorage::update_particles() {
 
 	RENDER_TIMESTAMP("Update GPUParticles");
 	uint32_t frame = RSG::rasterizer->get_frame_number();
-	bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0;
+	bool uses_motion_vectors = RSG::viewport->get_num_viewports_with_motion_vectors() > 0 || (RendererCompositorStorage::get_singleton()->get_num_compositor_effects_with_motion_vectors() > 0);
 	while (particle_update_list.first()) {
 		//use transform feedback to process particles
 

+ 37 - 1
servers/rendering/storage/compositor_storage.cpp

@@ -53,7 +53,23 @@ void RendererCompositorStorage::compositor_effect_initialize(RID p_rid) {
 }
 
 void RendererCompositorStorage::compositor_effect_free(RID p_rid) {
-	// TODO remove this RID from any compositor that uses it.
+	CompositorEffect *effect = compositor_effects_owner.get_or_null(p_rid);
+	ERR_FAIL_NULL(effect);
+
+	// Remove this RID from any compositor that uses it.
+	List<RID> compositor_rids;
+	compositor_owner.get_owned_list(&compositor_rids);
+	for (const RID &compositor_rid : compositor_rids) {
+		Compositor *compositor = compositor_owner.get_or_null(compositor_rid);
+		if (compositor) {
+			compositor->compositor_effects.erase(p_rid);
+		}
+	}
+
+	// Update motion vector count if needed.
+	if (effect->is_enabled && effect->flags.has_flag(RS::CompositorEffectFlags::COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS)) {
+		num_compositor_effects_with_motion_vectors--;
+	}
 
 	compositor_effects_owner.free(p_rid);
 }
@@ -70,6 +86,14 @@ void RendererCompositorStorage::compositor_effect_set_enabled(RID p_effect, bool
 	CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
 	ERR_FAIL_NULL(effect);
 
+	if (effect->is_enabled != p_enabled && effect->flags.has_flag(RS::CompositorEffectFlags::COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS)) {
+		if (p_enabled) {
+			num_compositor_effects_with_motion_vectors++;
+		} else {
+			num_compositor_effects_with_motion_vectors--;
+		}
+	}
+
 	effect->is_enabled = p_enabled;
 }
 
@@ -98,6 +122,18 @@ void RendererCompositorStorage::compositor_effect_set_flag(RID p_effect, RS::Com
 	CompositorEffect *effect = compositor_effects_owner.get_or_null(p_effect);
 	ERR_FAIL_NULL(effect);
 
+	if (effect->is_enabled && p_flag == RS::CompositorEffectFlags::COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS) {
+		bool was_set = effect->flags.has_flag(RS::CompositorEffectFlags::COMPOSITOR_EFFECT_FLAG_NEEDS_MOTION_VECTORS);
+
+		if (was_set != p_set) {
+			if (p_set) {
+				num_compositor_effects_with_motion_vectors++;
+			} else {
+				num_compositor_effects_with_motion_vectors--;
+			}
+		}
+	}
+
 	if (p_set) {
 		effect->flags.set_flag(p_flag);
 	} else {

+ 2 - 0
servers/rendering/storage/compositor_storage.h

@@ -37,6 +37,7 @@
 class RendererCompositorStorage {
 private:
 	static RendererCompositorStorage *singleton;
+	int num_compositor_effects_with_motion_vectors = 0;
 
 	// Compositor effect
 	struct CompositorEffect {
@@ -59,6 +60,7 @@ private:
 
 public:
 	static RendererCompositorStorage *get_singleton() { return singleton; }
+	int get_num_compositor_effects_with_motion_vectors() const { return num_compositor_effects_with_motion_vectors; }
 
 	RendererCompositorStorage();
 	virtual ~RendererCompositorStorage();