OverviewFilesCommitsIssuesDocsReleasesPeers

nvidia-rtx-godot / servers / rendering / renderer_rd / effects / copy_effects.h

414 lines · c ref:
/**************************************************************************/
/*  copy_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.                 */
/**************************************************************************/

#pragma once

#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/pipeline_deferred_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_rd/shaders/effects/cube_to_dp.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/effects/cube_to_octmap.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/effects/octmap_downsampler.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/effects/octmap_downsampler_raster.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/effects/octmap_filter.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/effects/octmap_filter_raster.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/effects/octmap_roughness.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/effects/octmap_roughness_raster.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/effects/specular_merge.glsl.gen.h"

namespace RendererRD {

class CopyEffects {
public:
	enum RasterEffects {
		RASTER_EFFECT_COPY = 1 << 0,
		RASTER_EFFECT_GAUSSIAN_BLUR = 1 << 1,
		RASTER_EFFECT_OCTMAP = 1 << 2,
	};

private:
	BitField<RasterEffects> raster_effects;

	// Blur raster shader

	enum BlurRasterMode {
		BLUR_MIPMAP,

		BLUR_MODE_GAUSSIAN_BLUR,
		BLUR_MODE_GAUSSIAN_GLOW_GATHER,
		BLUR_MODE_GAUSSIAN_GLOW_DOWNSAMPLE,
		BLUR_MODE_GAUSSIAN_GLOW_UPSAMPLE,
		BLUR_MODE_COPY,

		BLUR_MODE_SET_COLOR,

		BLUR_MODE_MAX
	};

	enum {
		BLUR_FLAG_USE_ORTHOGONAL_PROJECTION = (1 << 1),
	};

	struct BlurRasterPushConstant {
		float dest_pixel_size[2];
		float source_pixel_size[2];

		float pad[2];
		uint32_t flags;
		float level;

		//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 luminance_multiplier;
	};

	struct BlurRaster {
		BlurRasterPushConstant push_constant;
		BlurRasterShaderRD shader;
		RID shader_version;
		PipelineCacheRD pipelines[BLUR_MODE_MAX];
		RID glow_sampler;
	} 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_OCTMAP_TO_PANORAMA,
		COPY_MODE_OCTMAP_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_ALPHA_TO_ONE = (1 << 8),
		COPY_FLAG_SANITIZE_INF_NAN = (1 << 9),
	};

	struct CopyPushConstant {
		int32_t section[4];
		int32_t target[2];
		uint32_t flags;
		float luminance_multiplier;
		// 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_scale;
		// DOF.
		float camera_z_far;
		float camera_z_near;
		// Octmap.
		float octmap_border_size[2];
		//SET color
		float set_color[4];
	};

	struct Copy {
		CopyPushConstant push_constant;
		CopyShaderRD shader;
		RID shader_version;
		PipelineDeferredRD 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_SET_COLOR,
		COPY_TO_FB_COPY_DEPTH, // R32F -> gl_FragDepth (depth-only framebuffer)

		// These variants are disabled unless XR shaders are enabled.
		// They should be listed last.
		COPY_TO_FB_MULTIVIEW,
		COPY_TO_FB_MULTIVIEW_WITH_DEPTH,

		COPY_TO_FB_MAX,
	};

	enum CopyToFBFlags {
		COPY_TO_FB_FLAG_FLIP_Y = (1 << 0),
		COPY_TO_FB_FLAG_USE_SECTION = (1 << 1),
		COPY_TO_FB_FLAG_FORCE_LUMINANCE = (1 << 2),
		COPY_TO_FB_FLAG_ALPHA_TO_ZERO = (1 << 3),
		COPY_TO_FB_FLAG_SRGB = (1 << 4),
		COPY_TO_FB_FLAG_ALPHA_TO_ONE = (1 << 5),
		COPY_TO_FB_FLAG_LINEAR = (1 << 6),
		COPY_TO_FB_FLAG_NORMAL = (1 << 7),
		COPY_TO_FB_FLAG_USE_SRC_SECTION = (1 << 8),
	};

	static const uint32_t COPY_TO_FB_FLAG_MODE_SHIFT = 28;
	static const uint32_t COPY_TO_FB_FLAG_MODE_MASK = 0xF;

	struct CopyToFbPushConstant {
		float section[4];
		float pixel_size[2];
		float luminance_multiplier;
		uint32_t flags;

		float set_color[4];
	};

	struct CopyToFb {
		CopyToFbPushConstant push_constant;
		CopyToFbShaderRD shader;
		RID shader_version;
		PipelineCacheRD pipelines[COPY_TO_FB_MAX];

	} copy_to_fb;

	// Copy to DP

	struct CopyToDPPushConstant {
		float z_far;
		float z_near;
		float texel_size[2];
	};

	struct CopyToDP {
		CubeToDpShaderRD shader;
		RID shader_version;
		PipelineCacheRD pipeline;
	} cube_to_dp;

	// Copy to Octmap

	struct CopyToOctmapPushConstant {
		float border_size;
		uint32_t pad[3];
	};

	struct CopyToOctmap {
		CopyToOctmapPushConstant push_constant;
		CubeToOctmapShaderRD shader;
		RID shader_version;
		PipelineCacheRD pipeline;
	} cube_to_octmap;

	// Octmap effects

	struct OctmapDownsamplerPushConstant {
		float border_size;
		uint32_t size;
		uint32_t pad[2];
	};

	enum OctmapDownsamplerMode {
		DOWNSAMPLER_MODE_FLAG_RGB10_A2 = (1 << 0),

		DOWNSAMPLER_MODE_COMPUTE_MAX = (DOWNSAMPLER_MODE_FLAG_RGB10_A2 + 1),
		DOWNSAMPLER_MODE_RASTER_MAX = 1,
	};

	struct OctmapDownsampler {
		OctmapDownsamplerPushConstant push_constant;
		OctmapDownsamplerShaderRD compute_shader;
		OctmapDownsamplerRasterShaderRD raster_shader;
		RID shader_version;
		PipelineDeferredRD compute_pipelines[DOWNSAMPLER_MODE_COMPUTE_MAX];
		PipelineCacheRD raster_pipeline;
	} octmap_downsampler;

	enum OctmapFilterMode {
		FILTER_MODE_FLAG_HIGH_QUALITY = (1 << 0),
		FILTER_MODE_FLAG_ARRAY = (1 << 1),
		FILTER_MODE_FLAG_RGB10_A2 = (1 << 2),

		FILTER_MODE_COMPUTE_MAX = ((FILTER_MODE_FLAG_HIGH_QUALITY | FILTER_MODE_FLAG_ARRAY | FILTER_MODE_FLAG_RGB10_A2) + 1),
		FILTER_MODE_RASTER_MAX = (FILTER_MODE_FLAG_HIGH_QUALITY + 1),
	};

	struct OctmapFilterPushConstant {
		float border_size[2];
		uint32_t pad1;
		uint32_t pad2;
	};

	struct OctmapFilterRasterPushConstant {
		float border_size[2];
		uint32_t mip_level;
		uint32_t pad;
	};

	struct OctmapFilter {
		OctmapFilterShaderRD compute_shader;
		OctmapFilterRasterShaderRD raster_shader;
		RID shader_version;
		PipelineDeferredRD compute_pipelines[FILTER_MODE_COMPUTE_MAX];
		PipelineCacheRD raster_pipelines[FILTER_MODE_RASTER_MAX];

		RID uniform_set;
		RID image_uniform_set;
		RID coefficient_buffer;
		bool use_high_quality;

	} filter;

	enum OctmapRoughnessMode {
		ROUGHNESS_MODE_RGBA16F,
		ROUGHNESS_MODE_RGB10_A2,
		ROUGHNESS_MODE_MAX,
	};

	struct OctmapRoughnessPushConstant {
		uint32_t sample_count;
		float roughness;
		uint32_t source_size;
		uint32_t dest_size;

		float border_size[2];
		uint32_t use_direct_write;
		uint32_t pad;
	};

	struct OctmapRoughness {
		OctmapRoughnessPushConstant push_constant;
		OctmapRoughnessShaderRD compute_shader;
		OctmapRoughnessRasterShaderRD raster_shader;
		RID shader_version;
		PipelineDeferredRD compute_pipelines[ROUGHNESS_MODE_MAX];
		PipelineCacheRD raster_pipeline;
	} roughness;

	// Merge specular

	enum SpecularMergeMode {
		SPECULAR_MERGE_ADD,
		SPECULAR_MERGE_SSR,
		SPECULAR_MERGE_ADDITIVE_ADD,
		SPECULAR_MERGE_ADDITIVE_SSR,

		SPECULAR_MERGE_ADD_MULTIVIEW,
		SPECULAR_MERGE_SSR_MULTIVIEW,
		SPECULAR_MERGE_ADDITIVE_ADD_MULTIVIEW,
		SPECULAR_MERGE_ADDITIVE_SSR_MULTIVIEW,

		SPECULAR_MERGE_MAX
	};

	/* Specular merge must be done using raster, rather than compute
	 * because it must continue the existing color buffer
	 */

	struct SpecularMerge {
		SpecularMergeShaderRD shader;
		RID shader_version;
		PipelineCacheRD pipelines[SPECULAR_MERGE_MAX];

	} specular_merge;

	static CopyEffects *singleton;

public:
	enum CopyToFbFlagMode {
		COPY_TO_FB_FLAG_MODE_NONE = 0,
		COPY_TO_FB_FLAG_MODE_LOG_LUMINANCE = 1,
		COPY_TO_FB_FLAG_MODE_ALPHA_TO_LUMINANCE = 2,
	};

	static CopyEffects *get_singleton();

	CopyEffects(BitField<RasterEffects> p_raster_effects);
	~CopyEffects();

	BitField<RasterEffects> get_raster_effects() { return raster_effects; }

	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, bool p_sanitize_inf_nan = false);
	void copy_octmap_to_panorama(RID p_source_octmap, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array, const Size2 &p_source_octmap_border_size);
	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_r32f_to_depth_fb(RID p_source_r32f, RID p_dest_depth_framebuffer, const Rect2i &p_rect);
	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, bool alpha_to_one = false, bool p_linear = false, bool p_normal = false, const Rect2 &p_src_rect = Rect2(), float p_linear_luminance_multiplier = 1.0, bool p_bilinear_filtering = true, CopyToFbFlagMode p_flag_mode = COPY_TO_FB_FLAG_MODE_NONE);
	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_to_drawlist(RD::DrawListID p_draw_list, RD::FramebufferFormatID p_fb_format, RID p_source_rd_texture, bool p_linear = false, float p_linear_luminance_multiplier = 1.0);
	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, const Size2i &p_size, bool p_8bit_dst = false);
	void gaussian_blur_raster(RID p_source_rd_texture, RID p_dest_texture, const Rect2i &p_region, const Size2i &p_size);
	void gaussian_glow(RID p_source_rd_texture, RID p_back_texture, const Size2i &p_size, float p_strength = 1.0, 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_scale = 1.0);
	void gaussian_glow_downsample_raster(RID p_source_rd_texture, RID p_dest_texture, float p_luminance_multiplier, const Size2i &p_size, float p_strength = 1.0, 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);
	void gaussian_glow_upsample_raster(RID p_source_rd_texture, RID p_dest_texture, RID p_blend_texture, float p_luminance_multiplier, const Size2i &p_source_size, const Size2i &p_dest_size, float p_level, float p_base_strength, bool p_use_debanding);

	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_texture, const Size2i &p_size);

	void set_color(RID p_dest_texture, const Color &p_color, const Rect2i &p_region, bool p_8bit_dst = false);
	void set_color_raster(RID p_dest_texture, const Color &p_color, const Rect2i &p_region);

	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 copy_cubemap_to_octmap(RID p_source_rd_texture, RID p_dst_framebuffer, float p_border_size);
	void octmap_downsample(RID p_source_octmap, RID p_dest_octmap, const Size2i &p_size, float p_border_size);
	void octmap_downsample_raster(RID p_source_octmap, RID p_dest_framebuffer, const Size2i &p_size, float p_border_size);
	void octmap_filter(RID p_source_octmap, const Vector<RID> &p_dest_octmap, bool p_use_array, float p_border_size);
	void octmap_filter_raster(RID p_source_octmap, RID p_dest_framebuffer, uint32_t p_mip_level, float p_border_size);
	void octmap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_sample_count, float p_roughness, uint32_t p_source_size, uint32_t p_dest_size, float p_border_size);
	void octmap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_sample_count, float p_roughness, uint32_t p_source_size, uint32_t p_dest_size, float p_border_size);

	void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection, uint32_t p_view_count);
};

} // namespace RendererRD