Browse Source

Fix breakages of volumetric fog on voxel GI changes

Pedro J. Estébanez 2 years ago
parent
commit
2beed0d5dc

+ 27 - 18
servers/rendering/renderer_rd/environment/fog.cpp

@@ -463,15 +463,19 @@ Fog::VolumetricFog::~VolumetricFog() {
 	if (fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog_uniform_set)) {
 	if (fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(fog_uniform_set)) {
 		RD::get_singleton()->free(fog_uniform_set);
 		RD::get_singleton()->free(fog_uniform_set);
 	}
 	}
-	if (process_uniform_set_density.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set_density)) {
-		RD::get_singleton()->free(process_uniform_set_density);
-	}
-	if (process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set)) {
-		RD::get_singleton()->free(process_uniform_set);
-	}
-	if (process_uniform_set2.is_valid() && RD::get_singleton()->uniform_set_is_valid(process_uniform_set2)) {
-		RD::get_singleton()->free(process_uniform_set2);
+
+	// At this point, due to cascade deletions, the sets may no longer be valid, but still they must work as a group.
+	gi_dependent_sets.valid = RD::get_singleton()->uniform_set_is_valid(gi_dependent_sets.process_uniform_set_density);
+#ifdef DEV_ENABLED
+	gi_dependent_sets.assert_actual_validity();
+#endif
+	if (gi_dependent_sets.valid) {
+		RD::get_singleton()->free(gi_dependent_sets.copy_uniform_set);
+		RD::get_singleton()->free(gi_dependent_sets.process_uniform_set_density);
+		RD::get_singleton()->free(gi_dependent_sets.process_uniform_set);
+		RD::get_singleton()->free(gi_dependent_sets.process_uniform_set2);
 	}
 	}
+
 	if (sdfgi_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_uniform_set)) {
 	if (sdfgi_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_uniform_set)) {
 		RD::get_singleton()->free(sdfgi_uniform_set);
 		RD::get_singleton()->free(sdfgi_uniform_set);
 	}
 	}
@@ -713,7 +717,10 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
 		RD::get_singleton()->compute_list_end();
 		RD::get_singleton()->compute_list_end();
 	}
 	}
 
 
-	if (fog->process_uniform_set_density.is_null() || !RD::get_singleton()->uniform_set_is_valid(fog->process_uniform_set_density)) {
+#ifdef DEV_ENABLED
+	fog->gi_dependent_sets.assert_actual_validity();
+#endif
+	if (!fog->gi_dependent_sets.valid) {
 		//re create uniform set if needed
 		//re create uniform set if needed
 		Vector<RD::Uniform> uniforms;
 		Vector<RD::Uniform> uniforms;
 		Vector<RD::Uniform> copy_uniforms;
 		Vector<RD::Uniform> copy_uniforms;
@@ -910,9 +917,9 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
 			uniforms.push_back(u);
 			uniforms.push_back(u);
 		}
 		}
 
 
-		fog->copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0);
+		fog->gi_dependent_sets.copy_uniform_set = RD::get_singleton()->uniform_set_create(copy_uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY), 0);
 
 
-		fog->process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0);
+		fog->gi_dependent_sets.process_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0);
 
 
 		RID aux7 = uniforms.write[7].get_id(0);
 		RID aux7 = uniforms.write[7].get_id(0);
 		RID aux8 = uniforms.write[8].get_id(0);
 		RID aux8 = uniforms.write[8].get_id(0);
@@ -920,11 +927,13 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
 		uniforms.write[7].set_id(0, aux8);
 		uniforms.write[7].set_id(0, aux8);
 		uniforms.write[8].set_id(0, aux7);
 		uniforms.write[8].set_id(0, aux7);
 
 
-		fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0);
+		fog->gi_dependent_sets.process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG), 0);
 
 
 		uniforms.remove_at(8);
 		uniforms.remove_at(8);
 		uniforms.write[7].set_id(0, aux7);
 		uniforms.write[7].set_id(0, aux7);
-		fog->process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0);
+		fog->gi_dependent_sets.process_uniform_set_density = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY), 0);
+
+		fog->gi_dependent_sets.valid = true;
 	}
 	}
 
 
 	bool using_sdfgi = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.0001 && RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_enabled(p_settings.env) && (p_settings.sdfgi.is_valid());
 	bool using_sdfgi = RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_gi_inject(p_settings.env) > 0.0001 && RendererSceneRenderRD::get_singleton()->environment_get_sdfgi_enabled(p_settings.env) && (p_settings.sdfgi.is_valid());
@@ -1067,7 +1076,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
 
 
 	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[using_sdfgi ? VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY]);
 	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[using_sdfgi ? VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY_WITH_SDFGI : VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_DENSITY]);
 
 
-	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->process_uniform_set_density, 0);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set_density, 0);
 
 
 	if (using_sdfgi) {
 	if (using_sdfgi) {
 		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->sdfgi_uniform_set, 1);
 		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->sdfgi_uniform_set, 1);
@@ -1078,7 +1087,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
 	// Copy fog to history buffer
 	// Copy fog to history buffer
 	if (RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) {
 	if (RendererSceneRenderRD::get_singleton()->environment_get_volumetric_fog_temporal_reprojection(p_settings.env)) {
 		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY]);
 		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_COPY]);
-		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->copy_uniform_set, 0);
+		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.copy_uniform_set, 0);
 		RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);
 		RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);
 		RD::get_singleton()->compute_list_add_barrier(compute_list);
 		RD::get_singleton()->compute_list_add_barrier(compute_list);
 	}
 	}
@@ -1090,7 +1099,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
 		RENDER_TIMESTAMP("Filter Fog");
 		RENDER_TIMESTAMP("Filter Fog");
 
 
 		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]);
 		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]);
-		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->process_uniform_set, 0);
+		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set, 0);
 		RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);
 		RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);
 
 
 		RD::get_singleton()->compute_list_end();
 		RD::get_singleton()->compute_list_end();
@@ -1101,7 +1110,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
 
 
 		compute_list = RD::get_singleton()->compute_list_begin();
 		compute_list = RD::get_singleton()->compute_list_begin();
 		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]);
 		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FILTER]);
-		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->process_uniform_set2, 0);
+		RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set2, 0);
 		RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);
 		RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, fog->depth);
 
 
 		RD::get_singleton()->compute_list_add_barrier(compute_list);
 		RD::get_singleton()->compute_list_add_barrier(compute_list);
@@ -1112,7 +1121,7 @@ void Fog::volumetric_fog_update(const VolumetricFogSettings &p_settings, const P
 	RD::get_singleton()->draw_command_begin_label("Integrate Fog");
 	RD::get_singleton()->draw_command_begin_label("Integrate Fog");
 
 
 	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG]);
 	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, volumetric_fog.process_pipelines[VolumetricFogShader::VOLUMETRIC_FOG_PROCESS_SHADER_FOG]);
-	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->process_uniform_set, 0);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, fog->gi_dependent_sets.process_uniform_set, 0);
 	RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, 1);
 	RD::get_singleton()->compute_list_dispatch_threads(compute_list, fog->width, fog->height, 1);
 
 
 	RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER);
 	RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_RASTER);

+ 19 - 4
servers/rendering/renderer_rd/environment/fog.h

@@ -301,10 +301,25 @@ public:
 		RID emissive_map;
 		RID emissive_map;
 
 
 		RID fog_uniform_set;
 		RID fog_uniform_set;
-		RID copy_uniform_set;
-		RID process_uniform_set_density;
-		RID process_uniform_set;
-		RID process_uniform_set2;
+
+		struct {
+			bool valid = false;
+			RID copy_uniform_set;
+			RID process_uniform_set_density;
+			RID process_uniform_set;
+			RID process_uniform_set2;
+
+#ifdef DEV_ENABLED
+			void assert_actual_validity() {
+				// It's all-or-nothing, or something else has changed that requires dev attention.
+				DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(copy_uniform_set));
+				DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(process_uniform_set_density));
+				DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(process_uniform_set));
+				DEV_ASSERT(valid == RD::get_singleton()->uniform_set_is_valid(process_uniform_set2));
+			}
+#endif
+		} gi_dependent_sets;
+
 		RID sdfgi_uniform_set;
 		RID sdfgi_uniform_set;
 		RID sky_uniform_set;
 		RID sky_uniform_set;
 
 

+ 10 - 8
servers/rendering/renderer_rd/environment/gi.cpp

@@ -3695,14 +3695,16 @@ void GI::setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBu
 		if (p_render_buffers->has_custom_data(RB_SCOPE_FOG)) {
 		if (p_render_buffers->has_custom_data(RB_SCOPE_FOG)) {
 			Ref<Fog::VolumetricFog> fog = p_render_buffers->get_custom_data(RB_SCOPE_FOG);
 			Ref<Fog::VolumetricFog> fog = p_render_buffers->get_custom_data(RB_SCOPE_FOG);
 
 
-			if (RD::get_singleton()->uniform_set_is_valid(fog->fog_uniform_set)) {
-				RD::get_singleton()->free(fog->fog_uniform_set);
-				RD::get_singleton()->free(fog->process_uniform_set);
-				RD::get_singleton()->free(fog->process_uniform_set2);
-			}
-			fog->fog_uniform_set = RID();
-			fog->process_uniform_set = RID();
-			fog->process_uniform_set2 = RID();
+#ifdef DEV_ENABLED
+			fog->gi_dependent_sets.assert_actual_validity();
+#endif
+			if (fog->gi_dependent_sets.valid) {
+				RD::get_singleton()->free(fog->gi_dependent_sets.copy_uniform_set);
+				RD::get_singleton()->free(fog->gi_dependent_sets.process_uniform_set_density);
+				RD::get_singleton()->free(fog->gi_dependent_sets.process_uniform_set);
+				RD::get_singleton()->free(fog->gi_dependent_sets.process_uniform_set2);
+				fog->gi_dependent_sets.valid = false;
+			}
 		}
 		}
 	}
 	}