2
0
Эх сурвалжийг харах

Merge pull request #108636 from clayjohn/MSAA-depth-mobile

Add depth resolve to the mobile renderer
Thaddeus Crews 1 сар өмнө
parent
commit
8c7c96e2c4

+ 53 - 10
servers/rendering/renderer_rd/effects/resolve.cpp

@@ -34,26 +34,43 @@
 
 using namespace RendererRD;
 
-Resolve::Resolve() {
-	Vector<String> resolve_modes;
-	resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n");
-	resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n");
-	resolve_modes.push_back("\n#define MODE_RESOLVE_DEPTH\n");
+Resolve::Resolve(bool p_prefer_raster_effects) {
+	prefer_raster_effects = p_prefer_raster_effects;
 
-	resolve.shader.initialize(resolve_modes);
+	if (prefer_raster_effects) {
+		Vector<String> resolve_modes;
+		resolve_modes.push_back("");
 
-	resolve.shader_version = resolve.shader.version_create();
+		resolve_raster.shader.initialize(resolve_modes);
+		resolve_raster.shader_version = resolve_raster.shader.version_create();
+		resolve_raster.pipeline.setup(resolve_raster.shader.version_get_shader(resolve_raster.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+	} else {
+		Vector<String> resolve_modes;
+		resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n");
+		resolve_modes.push_back("\n#define MODE_RESOLVE_GI\n#define VOXEL_GI_RESOLVE\n");
+		resolve_modes.push_back("\n#define MODE_RESOLVE_DEPTH\n");
 
-	for (int i = 0; i < RESOLVE_MODE_MAX; i++) {
-		resolve.pipelines[i] = RD::get_singleton()->compute_pipeline_create(resolve.shader.version_get_shader(resolve.shader_version, i));
+		resolve.shader.initialize(resolve_modes);
+
+		resolve.shader_version = resolve.shader.version_create();
+
+		for (int i = 0; i < RESOLVE_MODE_MAX; i++) {
+			resolve.pipelines[i] = RD::get_singleton()->compute_pipeline_create(resolve.shader.version_get_shader(resolve.shader_version, i));
+		}
 	}
 }
 
 Resolve::~Resolve() {
-	resolve.shader.version_free(resolve.shader_version);
+	if (prefer_raster_effects) {
+		resolve_raster.shader.version_free(resolve_raster.shader_version);
+	} else {
+		resolve.shader.version_free(resolve.shader_version);
+	}
 }
 
 void Resolve::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples) {
+	ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute shader resolve with the mobile renderer.");
+
 	UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
 	ERR_FAIL_NULL(uniform_set_cache);
 	MaterialStorage *material_storage = MaterialStorage::get_singleton();
@@ -96,6 +113,8 @@ void Resolve::resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID
 }
 
 void Resolve::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples) {
+	ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use the compute shader resolve with the mobile renderer.");
+
 	UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
 	ERR_FAIL_NULL(uniform_set_cache);
 	MaterialStorage *material_storage = MaterialStorage::get_singleton();
@@ -127,3 +146,27 @@ void Resolve::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_scr
 
 	RD::get_singleton()->compute_list_end();
 }
+
+void Resolve::resolve_depth_raster(RID p_source_rd_texture, RID p_dest_framebuffer, int p_samples) {
+	RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
+	UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+
+	memset(&resolve_raster.push_constant, 0, sizeof(ResolvePushConstant));
+	resolve_raster.push_constant.samples = p_samples;
+
+	RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, 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 = resolve_raster.shader.version_get_shader(resolve_raster.shader_version, 0);
+	ERR_FAIL_COND(shader.is_null());
+
+	RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer);
+	RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, resolve_raster.pipeline.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_set_push_constant(draw_list, &resolve_raster.push_constant, sizeof(ResolvePushConstant));
+
+	RD::get_singleton()->draw_list_draw(draw_list, false, 1u, 3u);
+	RD::get_singleton()->draw_list_end();
+}

+ 13 - 1
servers/rendering/renderer_rd/effects/resolve.h

@@ -30,12 +30,16 @@
 
 #pragma once
 
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
 #include "servers/rendering/renderer_rd/shaders/effects/resolve.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/resolve_raster.glsl.gen.h"
 
 namespace RendererRD {
 
 class Resolve {
 private:
+	bool prefer_raster_effects;
+
 	struct ResolvePushConstant {
 		int32_t screen_size[2];
 		int32_t samples;
@@ -56,12 +60,20 @@ private:
 		RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels
 	} resolve;
 
+	struct ResolveRasterShader {
+		ResolvePushConstant push_constant;
+		ResolveRasterShaderRD shader;
+		RID shader_version;
+		PipelineCacheRD pipeline;
+	} resolve_raster;
+
 public:
-	Resolve();
+	Resolve(bool p_prefer_raster_effects);
 	~Resolve();
 
 	void resolve_gi(RID p_source_depth, RID p_source_normal_roughness, RID p_source_voxel_gi, RID p_dest_depth, RID p_dest_normal_roughness, RID p_dest_voxel_gi, Vector2i p_screen_size, int p_samples);
 	void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples);
+	void resolve_depth_raster(RID p_source_rd_texture, RID p_dest_framebuffer, int p_samples);
 };
 
 } // namespace RendererRD

+ 0 - 6
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp

@@ -5044,7 +5044,6 @@ RenderForwardClustered::RenderForwardClustered() {
 	_update_shader_quality_settings();
 	_update_global_pipeline_data_requirements_from_project();
 
-	resolve_effects = memnew(RendererRD::Resolve());
 	taa = memnew(RendererRD::TAA);
 	fsr2_effect = memnew(RendererRD::FSR2Effect);
 	ss_effects = memnew(RendererRD::SSEffects);
@@ -5082,11 +5081,6 @@ RenderForwardClustered::~RenderForwardClustered() {
 	}
 #endif
 
-	if (resolve_effects != nullptr) {
-		memdelete(resolve_effects);
-		resolve_effects = nullptr;
-	}
-
 	RD::get_singleton()->free(shadow_sampler);
 	RSG::light_storage->directional_shadow_atlas_set_size(0);
 

+ 0 - 2
servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h

@@ -37,7 +37,6 @@
 #include "servers/rendering/renderer_rd/effects/metal_fx.h"
 #endif
 #include "servers/rendering/renderer_rd/effects/motion_vectors_store.h"
-#include "servers/rendering/renderer_rd/effects/resolve.h"
 #include "servers/rendering/renderer_rd/effects/ss_effects.h"
 #include "servers/rendering/renderer_rd/effects/taa.h"
 #include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h"
@@ -716,7 +715,6 @@ private:
 
 	/* Effects */
 
-	RendererRD::Resolve *resolve_effects = nullptr;
 	RendererRD::TAA *taa = nullptr;
 	RendererRD::FSR2Effect *fsr2_effect = nullptr;
 	RendererRD::SSEffects *ss_effects = nullptr;

+ 3 - 5
servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp

@@ -233,8 +233,6 @@ RID RenderForwardMobile::RenderBufferDataForwardMobile::get_color_fbs(Framebuffe
 	if (use_msaa) {
 		color_buffer_id = textures.size();
 		textures.push_back(render_buffers->get_internal_texture()); // color buffer for resolve
-
-		// TODO add support for resolving depth buffer!!!
 	}
 
 	// Now define our subpasses
@@ -1252,7 +1250,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 			RD::get_singleton()->draw_list_end();
 		} else {
 			// We're done with our subpasses so end our container pass
-			// note, if MSAA is used we should get an automatic resolve here
+			// note, if MSAA is used we should get an automatic resolve of the color buffer here.
 
 			RD::get_singleton()->draw_list_end();
 
@@ -1276,8 +1274,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
 				_render_buffers_ensure_depth_texture(p_render_data);
 
 				if (scene_state.used_depth_texture) {
-					// Copy depth texture to backbuffer so we can read from it
-					_render_buffers_copy_depth_texture(p_render_data);
+					// Copy depth texture to backbuffer so we can read from it.
+					_render_buffers_copy_depth_texture(p_render_data, use_msaa);
 				}
 			}
 

+ 13 - 2
servers/rendering/renderer_rd/renderer_scene_render_rd.cpp

@@ -412,7 +412,7 @@ void RendererSceneRenderRD::_render_buffers_ensure_depth_texture(const RenderDat
 	rb->create_texture(RB_SCOPE_BUFFERS, RB_TEX_BACK_DEPTH, RD::DATA_FORMAT_R32_SFLOAT, usage_bits, RD::TEXTURE_SAMPLES_1);
 }
 
-void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataRD *p_render_data) {
+void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataRD *p_render_data, bool p_use_msaa) {
 	Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
 	ERR_FAIL_COND(rb.is_null());
 
@@ -433,7 +433,13 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR
 			copy_effects->copy_to_rect(depth_texture, depth_back_texture, Rect2i(0, 0, size.x, size.y));
 		} else {
 			RID depth_back_fb = FramebufferCacheRD::get_singleton()->get_cache(depth_back_texture);
-			copy_effects->copy_to_fb_rect(depth_texture, depth_back_fb, Rect2i(0, 0, size.x, size.y));
+			if (p_use_msaa) {
+				static const int texture_multisamples[RS::VIEWPORT_MSAA_MAX] = { 1, 2, 4, 8 };
+
+				resolve_effects->resolve_depth_raster(rb->get_depth_msaa(v), depth_back_fb, texture_multisamples[rb->get_msaa_3d()]);
+			} else {
+				copy_effects->copy_to_fb_rect(depth_texture, depth_back_fb, Rect2i(0, 0, size.x, size.y));
+			}
 		}
 	}
 
@@ -1716,6 +1722,7 @@ void RendererSceneRenderRD::init() {
 #ifdef METAL_ENABLED
 	mfx_spatial = memnew(RendererRD::MFXSpatialEffect);
 #endif
+	resolve_effects = memnew(RendererRD::Resolve(!can_use_storage));
 }
 
 RendererSceneRenderRD::~RendererSceneRenderRD() {
@@ -1753,6 +1760,10 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
 	}
 #endif
 
+	if (resolve_effects) {
+		memdelete(resolve_effects);
+	}
+
 	if (sky.sky_scene_state.uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sky.sky_scene_state.uniform_set)) {
 		RD::get_singleton()->free(sky.sky_scene_state.uniform_set);
 	}

+ 3 - 1
servers/rendering/renderer_rd/renderer_scene_render_rd.h

@@ -39,6 +39,7 @@
 #ifdef METAL_ENABLED
 #include "servers/rendering/renderer_rd/effects/metal_fx.h"
 #endif
+#include "servers/rendering/renderer_rd/effects/resolve.h"
 #include "servers/rendering/renderer_rd/effects/smaa.h"
 #include "servers/rendering/renderer_rd/effects/tone_mapper.h"
 #include "servers/rendering/renderer_rd/effects/vrs.h"
@@ -66,6 +67,7 @@ protected:
 	RendererRD::ToneMapper *tone_mapper = nullptr;
 	RendererRD::FSR *fsr = nullptr;
 	RendererRD::VRS *vrs = nullptr;
+	RendererRD::Resolve *resolve_effects = nullptr;
 #ifdef METAL_ENABLED
 	RendererRD::MFXSpatialEffect *mfx_spatial = nullptr;
 #endif
@@ -108,7 +110,7 @@ protected:
 	void _render_buffers_ensure_screen_texture(const RenderDataRD *p_render_data);
 	void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
 	void _render_buffers_ensure_depth_texture(const RenderDataRD *p_render_data);
-	void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
+	void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data, bool p_use_msaa = false);
 	void _render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data);
 	void _post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data);
 	void _disable_clear_request(const RenderDataRD *p_render_data);

+ 46 - 0
servers/rendering/renderer_rd/shaders/effects/resolve_raster.glsl

@@ -0,0 +1,46 @@
+/* clang-format off */
+#[vertex]
+
+#version 450
+
+#VERSION_DEFINES
+
+layout(location = 0) out vec2 uv_interp;
+/* clang-format on */
+
+void main() {
+	vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0));
+	gl_Position = vec4(base_arr[gl_VertexIndex], 0.0, 1.0);
+	uv_interp = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0
+}
+
+/* clang-format off */
+#[fragment]
+
+#version 450
+
+#VERSION_DEFINES
+
+layout(location = 0) in vec2 uv_interp;
+
+layout(set = 0, binding = 0) uniform sampler2DMS source_depth;
+
+layout(push_constant, std430) uniform Params {
+    ivec2 pad;
+	int sample_count;
+    int pad2;
+}
+params;
+
+layout (location = 0) out float out_depth;
+
+void main() {
+    ivec2 pos = ivec2(gl_FragCoord.xy);
+
+	float depth_avg = 0.0;
+	for (int i = 0; i < params.sample_count; i++) {
+		depth_avg += texelFetch(source_depth, pos, i).r;
+	}
+	depth_avg /= float(params.sample_count);
+	out_depth = depth_avg;
+}