瀏覽代碼

Merge pull request #74019 from BastiaanOlij/split_last_effects

Move roughness limiter and sort into their own classes
Rémi Verschelde 2 年之前
父節點
當前提交
0511da260f

+ 79 - 0
servers/rendering/renderer_rd/effects/roughness_limiter.cpp

@@ -0,0 +1,79 @@
+/**************************************************************************/
+/*  roughness_limiter.cpp                                                 */
+/**************************************************************************/
+/*                         This file is part of:                          */
+/*                             GODOT ENGINE                               */
+/*                        https://godotengine.org                         */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
+/*                                                                        */
+/* 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 "roughness_limiter.h"
+#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
+#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
+
+using namespace RendererRD;
+
+RoughnessLimiter::RoughnessLimiter() {
+	// Initialize roughness limiter
+	Vector<String> shader_modes;
+	shader_modes.push_back("");
+
+	shader.initialize(shader_modes);
+
+	shader_version = shader.version_create();
+
+	pipeline = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, 0));
+}
+
+RoughnessLimiter::~RoughnessLimiter() {
+	shader.version_free(shader_version);
+}
+
+void RoughnessLimiter::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) {
+	UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+	ERR_FAIL_NULL(uniform_set_cache);
+	MaterialStorage *material_storage = MaterialStorage::get_singleton();
+	ERR_FAIL_NULL(material_storage);
+
+	push_constant.screen_size[0] = p_size.x;
+	push_constant.screen_size[1] = p_size.y;
+	push_constant.curve = p_curve;
+
+	RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+	RID rl_shader = shader.version_get_shader(shader_version, 0);
+
+	RD::Uniform u_source_normal(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_normal }));
+	RD::Uniform u_roughness(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_roughness }));
+
+	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipeline);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(rl_shader, 0, u_source_normal), 0);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(rl_shader, 1, u_roughness), 1);
+
+	RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(RoughnessLimiterPushConstant)); //not used but set anyway
+
+	RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.x, p_size.y, 1);
+
+	RD::get_singleton()->compute_list_end();
+}

+ 19 - 85
servers/rendering/renderer_rd/effects_rd.h → servers/rendering/renderer_rd/effects/roughness_limiter.h

@@ -1,5 +1,5 @@
 /**************************************************************************/
-/*  effects_rd.h                                                          */
+/*  roughness_limiter.h                                                   */
 /**************************************************************************/
 /*                         This file is part of:                          */
 /*                             GODOT ENGINE                               */
@@ -28,106 +28,40 @@
 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */
 /**************************************************************************/
 
-#ifndef EFFECTS_RD_H
-#define EFFECTS_RD_H
+#ifndef ROUGHNESS_LIMITER_RD_H
+#define ROUGHNESS_LIMITER_RD_H
 
-#include "core/math/projection.h"
 #include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
-#include "servers/rendering/renderer_rd/shaders/roughness_limiter.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sort.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/roughness_limiter.glsl.gen.h"
 #include "servers/rendering/renderer_scene_render.h"
 
 #include "servers/rendering_server.h"
 
-class EffectsRD {
-private:
-	bool prefer_raster_effects;
+namespace RendererRD {
+
+// Note, this logic is unused at the time of writing. It should be re-incorporated into the renderer at some point.
 
+class RoughnessLimiter {
+private:
 	struct RoughnessLimiterPushConstant {
 		int32_t screen_size[2];
 		float curve;
 		uint32_t pad;
 	};
 
-	struct RoughnessLimiter {
-		RoughnessLimiterPushConstant push_constant;
-		RoughnessLimiterShaderRD shader;
-		RID shader_version;
-		RID pipeline;
-
-	} roughness_limiter;
-
-	enum SortMode {
-		SORT_MODE_BLOCK,
-		SORT_MODE_STEP,
-		SORT_MODE_INNER,
-		SORT_MODE_MAX
-	};
-
-	struct Sort {
-		struct PushConstant {
-			uint32_t total_elements;
-			uint32_t pad[3];
-			int32_t job_params[4];
-		};
-
-		SortShaderRD shader;
-		RID shader_version;
-		RID pipelines[SORT_MODE_MAX];
-	} sort;
-
-	RID default_sampler;
-	RID default_mipmap_sampler;
-	RID index_buffer;
-	RID index_array;
-
-	HashMap<RID, RID> texture_to_uniform_set_cache;
-	HashMap<RID, RID> input_to_uniform_set_cache;
-
-	HashMap<RID, RID> image_to_uniform_set_cache;
-
-	struct TexturePair {
-		RID texture1;
-		RID texture2;
-		_FORCE_INLINE_ bool operator<(const TexturePair &p_pair) const {
-			if (texture1 == p_pair.texture1) {
-				return texture2 < p_pair.texture2;
-			} else {
-				return texture1 < p_pair.texture1;
-			}
-		}
-	};
-
-	struct TextureSamplerPair {
-		RID texture;
-		RID sampler;
-		_FORCE_INLINE_ bool operator<(const TextureSamplerPair &p_pair) const {
-			if (texture == p_pair.texture) {
-				return sampler < p_pair.sampler;
-			} else {
-				return texture < p_pair.texture;
-			}
-		}
-	};
-
-	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_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps = false);
+	RoughnessLimiterPushConstant push_constant;
+	RoughnessLimiterShaderRD shader;
+	RID shader_version;
+	RID pipeline;
 
+protected:
 public:
-	bool get_prefer_raster_effects();
+	RoughnessLimiter();
+	~RoughnessLimiter();
 
 	void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve);
-
-	void sort_buffer(RID p_uniform_set, int p_size);
-
-	EffectsRD(bool p_prefer_raster_effects);
-	~EffectsRD();
 };
 
-#endif // EFFECTS_RD_H
+} // namespace RendererRD
+
+#endif // ROUGHNESS_LIMITER_RD_H

+ 124 - 0
servers/rendering/renderer_rd/effects/sort_effects.cpp

@@ -0,0 +1,124 @@
+/**************************************************************************/
+/*  sort_effects.cpp                                                      */
+/**************************************************************************/
+/*                         This file is part of:                          */
+/*                             GODOT ENGINE                               */
+/*                        https://godotengine.org                         */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
+/*                                                                        */
+/* 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 "sort_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;
+
+SortEffects::SortEffects() {
+	Vector<String> sort_modes;
+	sort_modes.push_back("\n#define MODE_SORT_BLOCK\n");
+	sort_modes.push_back("\n#define MODE_SORT_STEP\n");
+	sort_modes.push_back("\n#define MODE_SORT_INNER\n");
+
+	shader.initialize(sort_modes);
+
+	shader_version = shader.version_create();
+
+	for (int i = 0; i < SORT_MODE_MAX; i++) {
+		pipelines[i] = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, i));
+	}
+}
+
+SortEffects::~SortEffects() {
+	shader.version_free(shader_version);
+}
+
+void SortEffects::sort_buffer(RID p_uniform_set, int p_size) {
+	PushConstant push_constant;
+	push_constant.total_elements = p_size;
+
+	bool done = true;
+
+	int numThreadGroups = ((p_size - 1) >> 9) + 1;
+
+	if (numThreadGroups > 1) {
+		done = false;
+	}
+
+	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+
+	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[SORT_MODE_BLOCK]);
+	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_uniform_set, 1);
+	RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
+	RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
+
+	int presorted = 512;
+
+	while (!done) {
+		RD::get_singleton()->compute_list_add_barrier(compute_list);
+
+		done = true;
+		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[SORT_MODE_STEP]);
+
+		numThreadGroups = 0;
+
+		if (p_size > presorted) {
+			if (p_size > presorted * 2) {
+				done = false;
+			}
+
+			int pow2 = presorted;
+			while (pow2 < p_size) {
+				pow2 *= 2;
+			}
+			numThreadGroups = pow2 >> 9;
+		}
+
+		unsigned int nMergeSize = presorted * 2;
+
+		for (unsigned int nMergeSubSize = nMergeSize >> 1; nMergeSubSize > 256; nMergeSubSize = nMergeSubSize >> 1) {
+			push_constant.job_params[0] = nMergeSubSize;
+			if (nMergeSubSize == nMergeSize >> 1) {
+				push_constant.job_params[1] = (2 * nMergeSubSize - 1);
+				push_constant.job_params[2] = -1;
+			} else {
+				push_constant.job_params[1] = nMergeSubSize;
+				push_constant.job_params[2] = 1;
+			}
+			push_constant.job_params[3] = 0;
+
+			RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
+			RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
+			RD::get_singleton()->compute_list_add_barrier(compute_list);
+		}
+
+		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[SORT_MODE_INNER]);
+		RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
+		RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
+
+		presorted *= 2;
+	}
+
+	RD::get_singleton()->compute_list_end();
+}

+ 71 - 0
servers/rendering/renderer_rd/effects/sort_effects.h

@@ -0,0 +1,71 @@
+/**************************************************************************/
+/*  sort_effects.h                                                        */
+/**************************************************************************/
+/*                         This file is part of:                          */
+/*                             GODOT ENGINE                               */
+/*                        https://godotengine.org                         */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
+/*                                                                        */
+/* 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 SORT_EFFECTS_RD_H
+#define SORT_EFFECTS_RD_H
+
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
+#include "servers/rendering/renderer_rd/shaders/effects/sort.glsl.gen.h"
+#include "servers/rendering/renderer_scene_render.h"
+
+#include "servers/rendering_server.h"
+
+namespace RendererRD {
+
+class SortEffects {
+private:
+	enum SortMode {
+		SORT_MODE_BLOCK,
+		SORT_MODE_STEP,
+		SORT_MODE_INNER,
+		SORT_MODE_MAX
+	};
+
+	struct PushConstant {
+		uint32_t total_elements;
+		uint32_t pad[3];
+		int32_t job_params[4];
+	};
+
+	SortShaderRD shader;
+	RID shader_version;
+	RID pipelines[SORT_MODE_MAX];
+
+protected:
+public:
+	SortEffects();
+	~SortEffects();
+
+	void sort_buffer(RID p_uniform_set, int p_size);
+};
+
+} // namespace RendererRD
+
+#endif // SORT_EFFECTS_RD_H

+ 0 - 246
servers/rendering/renderer_rd/effects_rd.cpp

@@ -1,246 +0,0 @@
-/**************************************************************************/
-/*  effects_rd.cpp                                                        */
-/**************************************************************************/
-/*                         This file is part of:                          */
-/*                             GODOT ENGINE                               */
-/*                        https://godotengine.org                         */
-/**************************************************************************/
-/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
-/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */
-/*                                                                        */
-/* 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 "effects_rd.h"
-
-#include "core/config/project_settings.h"
-#include "core/math/math_defs.h"
-#include "core/os/os.h"
-
-#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
-#include "thirdparty/misc/cubemap_coeffs.h"
-
-bool EffectsRD::get_prefer_raster_effects() {
-	return prefer_raster_effects;
-}
-
-RID EffectsRD::_get_uniform_set_from_image(RID p_image) {
-	if (image_to_uniform_set_cache.has(p_image)) {
-		RID uniform_set = image_to_uniform_set_cache[p_image];
-		if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
-			return uniform_set;
-		}
-	}
-	Vector<RD::Uniform> uniforms;
-	RD::Uniform u;
-	u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
-	u.binding = 0;
-	u.append_id(p_image);
-	uniforms.push_back(u);
-	//any thing with the same configuration (one texture in binding 0 for set 0), is good
-	RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, roughness_limiter.shader.version_get_shader(roughness_limiter.shader_version, 0), 1);
-
-	image_to_uniform_set_cache[p_image] = uniform_set;
-
-	return uniform_set;
-}
-
-RID EffectsRD::_get_compute_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps) {
-	if (texture_to_compute_uniform_set_cache.has(p_texture)) {
-		RID uniform_set = texture_to_compute_uniform_set_cache[p_texture];
-		if (RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
-			return uniform_set;
-		}
-	}
-
-	Vector<RD::Uniform> uniforms;
-	RD::Uniform u;
-	u.uniform_type = RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE;
-	u.binding = 0;
-	u.append_id(p_use_mipmaps ? default_mipmap_sampler : default_sampler);
-	u.append_id(p_texture);
-	uniforms.push_back(u);
-	//any thing with the same configuration (one texture in binding 0 for set 0), is good
-	RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, roughness_limiter.shader.version_get_shader(roughness_limiter.shader_version, 0), 0);
-
-	texture_to_compute_uniform_set_cache[p_texture] = uniform_set;
-
-	return uniform_set;
-}
-
-void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve) {
-	roughness_limiter.push_constant.screen_size[0] = p_size.x;
-	roughness_limiter.push_constant.screen_size[1] = p_size.y;
-	roughness_limiter.push_constant.curve = p_curve;
-
-	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness_limiter.pipeline);
-	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_normal), 0);
-	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_roughness), 1);
-
-	RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness_limiter.push_constant, sizeof(RoughnessLimiterPushConstant)); //not used but set anyway
-
-	RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_size.x, p_size.y, 1);
-
-	RD::get_singleton()->compute_list_end();
-}
-
-void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
-	Sort::PushConstant push_constant;
-	push_constant.total_elements = p_size;
-
-	bool done = true;
-
-	int numThreadGroups = ((p_size - 1) >> 9) + 1;
-
-	if (numThreadGroups > 1) {
-		done = false;
-	}
-
-	RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
-
-	RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sort.pipelines[SORT_MODE_BLOCK]);
-	RD::get_singleton()->compute_list_bind_uniform_set(compute_list, p_uniform_set, 1);
-	RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(Sort::PushConstant));
-	RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
-
-	int presorted = 512;
-
-	while (!done) {
-		RD::get_singleton()->compute_list_add_barrier(compute_list);
-
-		done = true;
-		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sort.pipelines[SORT_MODE_STEP]);
-
-		numThreadGroups = 0;
-
-		if (p_size > presorted) {
-			if (p_size > presorted * 2) {
-				done = false;
-			}
-
-			int pow2 = presorted;
-			while (pow2 < p_size) {
-				pow2 *= 2;
-			}
-			numThreadGroups = pow2 >> 9;
-		}
-
-		unsigned int nMergeSize = presorted * 2;
-
-		for (unsigned int nMergeSubSize = nMergeSize >> 1; nMergeSubSize > 256; nMergeSubSize = nMergeSubSize >> 1) {
-			push_constant.job_params[0] = nMergeSubSize;
-			if (nMergeSubSize == nMergeSize >> 1) {
-				push_constant.job_params[1] = (2 * nMergeSubSize - 1);
-				push_constant.job_params[2] = -1;
-			} else {
-				push_constant.job_params[1] = nMergeSubSize;
-				push_constant.job_params[2] = 1;
-			}
-			push_constant.job_params[3] = 0;
-
-			RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(Sort::PushConstant));
-			RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
-			RD::get_singleton()->compute_list_add_barrier(compute_list);
-		}
-
-		RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, sort.pipelines[SORT_MODE_INNER]);
-		RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(Sort::PushConstant));
-		RD::get_singleton()->compute_list_dispatch(compute_list, numThreadGroups, 1, 1);
-
-		presorted *= 2;
-	}
-
-	RD::get_singleton()->compute_list_end();
-}
-
-EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
-	prefer_raster_effects = p_prefer_raster_effects;
-
-	if (!prefer_raster_effects) {
-		// Initialize roughness limiter
-		Vector<String> shader_modes;
-		shader_modes.push_back("");
-
-		roughness_limiter.shader.initialize(shader_modes);
-
-		roughness_limiter.shader_version = roughness_limiter.shader.version_create();
-
-		roughness_limiter.pipeline = RD::get_singleton()->compute_pipeline_create(roughness_limiter.shader.version_get_shader(roughness_limiter.shader_version, 0));
-	}
-
-	{
-		Vector<String> sort_modes;
-		sort_modes.push_back("\n#define MODE_SORT_BLOCK\n");
-		sort_modes.push_back("\n#define MODE_SORT_STEP\n");
-		sort_modes.push_back("\n#define MODE_SORT_INNER\n");
-
-		sort.shader.initialize(sort_modes);
-
-		sort.shader_version = sort.shader.version_create();
-
-		for (int i = 0; i < SORT_MODE_MAX; i++) {
-			sort.pipelines[i] = RD::get_singleton()->compute_pipeline_create(sort.shader.version_get_shader(sort.shader_version, i));
-		}
-	}
-
-	RD::SamplerState sampler;
-	sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
-	sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
-	sampler.max_lod = 0;
-
-	default_sampler = RD::get_singleton()->sampler_create(sampler);
-	RD::get_singleton()->set_resource_name(default_sampler, "Default Linear Sampler");
-
-	sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
-	sampler.mip_filter = RD::SAMPLER_FILTER_LINEAR;
-	sampler.max_lod = 1e20;
-
-	default_mipmap_sampler = RD::get_singleton()->sampler_create(sampler);
-	RD::get_singleton()->set_resource_name(default_mipmap_sampler, "Default MipMap Sampler");
-
-	{ //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);
-	}
-}
-
-EffectsRD::~EffectsRD() {
-	RD::get_singleton()->free(default_sampler);
-	RD::get_singleton()->free(default_mipmap_sampler);
-	RD::get_singleton()->free(index_buffer); //array gets freed as dependency
-
-	if (!prefer_raster_effects) {
-		roughness_limiter.shader.version_free(roughness_limiter.shader_version);
-	}
-	sort.shader.version_free(sort.shader_version);
-}

+ 3 - 5
servers/rendering/renderer_rd/environment/sky.cpp

@@ -276,9 +276,7 @@ void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bo
 	int mipmaps = p_mipmaps;
 	uint32_t w = p_size, h = p_size;
 
-	EffectsRD *effects = RendererCompositorRD::get_singleton()->get_effects();
-	ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialized");
-	bool prefer_raster_effects = effects->get_prefer_raster_effects();
+	bool render_buffers_can_be_storage = RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage();
 
 	if (p_use_array) {
 		int num_layers = p_low_quality ? 8 : p_roughness_layers;
@@ -348,7 +346,7 @@ void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bo
 	tf.array_layers = 6;
 	tf.mipmaps = p_low_quality ? 7 : mipmaps - 1;
 	tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
-	if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
+	if (render_buffers_can_be_storage) {
 		tf.usage_bits |= RD::TEXTURE_USAGE_STORAGE_BIT;
 	}
 
@@ -364,7 +362,7 @@ void SkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bo
 			mm.size.height = mmh;
 			mm.view = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), downsampled_radiance_cubemap, 0, j, 1, RD::TEXTURE_SLICE_CUBEMAP);
 			RD::get_singleton()->set_resource_name(mm.view, "Downsampled Radiance Cubemap Mip " + itos(j) + " ");
-			if (prefer_raster_effects) {
+			if (render_buffers_can_be_storage) {
 				// we need a framebuffer for each side of our cubemap
 
 				for (int k = 0; k < 6; k++) {

+ 0 - 4
servers/rendering/renderer_rd/renderer_compositor_rd.cpp

@@ -148,7 +148,6 @@ uint64_t RendererCompositorRD::frame = 1;
 void RendererCompositorRD::finalize() {
 	memdelete(scene);
 	memdelete(canvas);
-	memdelete(effects);
 	memdelete(fog);
 	memdelete(particles_storage);
 	memdelete(light_storage);
@@ -320,9 +319,6 @@ RendererCompositorRD::RendererCompositorRD() {
 	}
 
 	scene->init();
-
-	// now we're ready to create our effects,
-	effects = memnew(EffectsRD(!scene->_render_buffers_can_be_storage()));
 }
 
 RendererCompositorRD::~RendererCompositorRD() {

+ 0 - 3
servers/rendering/renderer_rd/renderer_compositor_rd.h

@@ -33,7 +33,6 @@
 
 #include "core/os/os.h"
 #include "servers/rendering/renderer_compositor.h"
-#include "servers/rendering/renderer_rd/effects_rd.h"
 #include "servers/rendering/renderer_rd/environment/fog.h"
 #include "servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h"
 #include "servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h"
@@ -60,7 +59,6 @@ protected:
 	RendererRD::ParticlesStorage *particles_storage = nullptr;
 	RendererRD::TextureStorage *texture_storage = nullptr;
 	RendererRD::Fog *fog = nullptr;
-	EffectsRD *effects = nullptr;
 	RendererSceneRenderRD *scene = nullptr;
 
 	enum BlitMode {
@@ -115,7 +113,6 @@ public:
 		return scene->get_gi();
 	}
 	RendererFog *get_fog() { return fog; }
-	EffectsRD *get_effects() { return effects; }
 	RendererCanvasRender *get_canvas() { return canvas; }
 	RendererSceneRender *get_scene() { return scene; }
 

+ 0 - 0
servers/rendering/renderer_rd/shaders/roughness_limiter.glsl → servers/rendering/renderer_rd/shaders/effects/roughness_limiter.glsl


+ 0 - 0
servers/rendering/renderer_rd/shaders/sort.glsl → servers/rendering/renderer_rd/shaders/effects/sort.glsl


+ 10 - 1
servers/rendering/renderer_rd/storage_rd/particles_storage.cpp

@@ -47,6 +47,10 @@ ParticlesStorage::ParticlesStorage() {
 
 	MaterialStorage *material_storage = MaterialStorage::get_singleton();
 
+	/* Effects */
+
+	sort_effects = memnew(SortEffects);
+
 	/* Particles */
 
 	{
@@ -206,6 +210,11 @@ ParticlesStorage::~ParticlesStorage() {
 	material_storage->material_free(particles_shader.default_material);
 	material_storage->shader_free(particles_shader.default_shader);
 
+	if (sort_effects) {
+		memdelete(sort_effects);
+		sort_effects = nullptr;
+	}
+
 	singleton = nullptr;
 }
 
@@ -1228,7 +1237,7 @@ void ParticlesStorage::particles_set_view_axis(RID p_particles, const Vector3 &p
 		RD::get_singleton()->compute_list_dispatch_threads(compute_list, particles->amount, 1, 1);
 
 		RD::get_singleton()->compute_list_end();
-		RendererCompositorRD::get_singleton()->get_effects()->sort_buffer(particles->particles_sort_uniform_set, particles->amount);
+		sort_effects->sort_buffer(particles->particles_sort_uniform_set, particles->amount);
 	}
 
 	if (particles->trails_enabled && particles->trail_bind_poses.size() > 1) {

+ 4 - 0
servers/rendering/renderer_rd/storage_rd/particles_storage.h

@@ -34,6 +34,7 @@
 #include "core/templates/local_vector.h"
 #include "core/templates/rid_owner.h"
 #include "core/templates/self_list.h"
+#include "servers/rendering/renderer_rd/effects/sort_effects.h"
 #include "servers/rendering/renderer_rd/shaders/particles.glsl.gen.h"
 #include "servers/rendering/renderer_rd/shaders/particles_copy.glsl.gen.h"
 #include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
@@ -47,6 +48,9 @@ class ParticlesStorage : public RendererParticlesStorage {
 private:
 	static ParticlesStorage *singleton;
 
+	/* EFFECTS */
+	SortEffects *sort_effects = nullptr;
+
 	/* PARTICLES */
 
 	struct ParticleData {