summaryrefslogtreecommitdiff
path: root/servers
diff options
context:
space:
mode:
Diffstat (limited to 'servers')
-rw-r--r--servers/SCsub1
-rw-r--r--servers/audio/audio_driver_dummy.cpp67
-rw-r--r--servers/audio/audio_driver_dummy.h22
-rw-r--r--servers/audio/audio_stream.cpp29
-rw-r--r--servers/movie_writer/SCsub5
-rw-r--r--servers/movie_writer/movie_writer.cpp171
-rw-r--r--servers/movie_writer/movie_writer.h88
-rw-r--r--servers/movie_writer/movie_writer_mjpeg.cpp263
-rw-r--r--servers/movie_writer/movie_writer_mjpeg.h73
-rw-r--r--servers/movie_writer/movie_writer_pngwav.cpp168
-rw-r--r--servers/movie_writer/movie_writer_pngwav.h71
-rw-r--r--servers/navigation_server_2d.cpp12
-rw-r--r--servers/navigation_server_2d.h6
-rw-r--r--servers/navigation_server_3d.cpp5
-rw-r--r--servers/navigation_server_3d.h6
-rw-r--r--servers/register_server_types.cpp16
-rw-r--r--servers/rendering/SCsub1
-rw-r--r--servers/rendering/dummy/SCsub7
-rw-r--r--servers/rendering/dummy/environment/fog.h55
-rw-r--r--servers/rendering/dummy/environment/gi.h82
-rw-r--r--servers/rendering/dummy/rasterizer_dummy.h12
-rw-r--r--servers/rendering/dummy/rasterizer_storage_dummy.h147
-rw-r--r--servers/rendering/dummy/storage/SCsub5
-rw-r--r--servers/rendering/dummy/storage/material_storage.h3
-rw-r--r--servers/rendering/dummy/storage/mesh_storage.h7
-rw-r--r--servers/rendering/dummy/storage/texture_storage.cpp43
-rw-r--r--servers/rendering/dummy/storage/texture_storage.h9
-rw-r--r--servers/rendering/dummy/storage/utilities.h98
-rw-r--r--servers/rendering/environment/renderer_fog.h53
-rw-r--r--servers/rendering/environment/renderer_gi.h81
-rw-r--r--servers/rendering/renderer_canvas_cull.cpp21
-rw-r--r--servers/rendering/renderer_canvas_cull.h2
-rw-r--r--servers/rendering/renderer_canvas_render.cpp6
-rw-r--r--servers/rendering/renderer_canvas_render.h8
-rw-r--r--servers/rendering/renderer_compositor.h8
-rw-r--r--servers/rendering/renderer_rd/SCsub1
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/cluster_builder_rd.h8
-rw-r--r--servers/rendering/renderer_rd/effects/copy_effects.cpp402
-rw-r--r--servers/rendering/renderer_rd/effects/copy_effects.h96
-rw-r--r--servers/rendering/renderer_rd/effects/resolve.cpp130
-rw-r--r--servers/rendering/renderer_rd/effects/resolve.h74
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp363
-rw-r--r--servers/rendering/renderer_rd/effects_rd.h112
-rw-r--r--servers/rendering/renderer_rd/environment/SCsub5
-rw-r--r--servers/rendering/renderer_rd/environment/fog.cpp128
-rw-r--r--servers/rendering/renderer_rd/environment/fog.h83
-rw-r--r--servers/rendering/renderer_rd/environment/gi.cpp (renamed from servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp)1326
-rw-r--r--servers/rendering/renderer_rd/environment/gi.h (renamed from servers/rendering/renderer_rd/renderer_scene_gi_rd.h)202
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp284
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h27
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp17
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h9
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp56
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h12
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp3
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h4
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp3
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.h6
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp15
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.h26
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp166
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h26
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp110
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.h19
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp751
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h306
-rw-r--r--servers/rendering/renderer_rd/shaders/SCsub3
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/SCsub2
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl (renamed from servers/rendering/renderer_rd/shaders/cube_to_dp.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler.glsl (renamed from servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_inc.glsl (renamed from servers/rendering/renderer_rd/shaders/cubemap_downsampler_inc.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl (renamed from servers/rendering/renderer_rd/shaders/cubemap_downsampler_raster.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_filter.glsl (renamed from servers/rendering/renderer_rd/shaders/cubemap_filter.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_filter_raster.glsl (renamed from servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_roughness.glsl (renamed from servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl (renamed from servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_raster.glsl (renamed from servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/resolve.glsl (renamed from servers/rendering/renderer_rd/shaders/resolve.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/SCsub17
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/gi.glsl (renamed from servers/rendering/renderer_rd/shaders/gi.glsl)44
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl (renamed from servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl)10
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl (renamed from servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl)48
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl (renamed from servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl (renamed from servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl (renamed from servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl (renamed from servers/rendering/renderer_rd/shaders/voxel_gi.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl (renamed from servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/voxel_gi_sdf.glsl (renamed from servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl)0
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl20
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl8
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl7
-rw-r--r--servers/rendering/renderer_rd/shaders/taa_resolve.glsl3
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl1
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.cpp38
-rw-r--r--servers/rendering/renderer_rd/storage_rd/light_storage.h7
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.cpp14
-rw-r--r--servers/rendering/renderer_rd/storage_rd/material_storage.h86
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp32
-rw-r--r--servers/rendering/renderer_rd/storage_rd/mesh_storage.h10
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.cpp43
-rw-r--r--servers/rendering/renderer_rd/storage_rd/particles_storage.h6
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.cpp6
-rw-r--r--servers/rendering/renderer_rd/storage_rd/texture_storage.h4
-rw-r--r--servers/rendering/renderer_rd/storage_rd/utilities.cpp337
-rw-r--r--servers/rendering/renderer_rd/storage_rd/utilities.h122
-rw-r--r--servers/rendering/renderer_scene_cull.cpp28
-rw-r--r--servers/rendering/renderer_scene_cull.h34
-rw-r--r--servers/rendering/renderer_storage.h240
-rw-r--r--servers/rendering/renderer_viewport.cpp22
-rw-r--r--servers/rendering/renderer_viewport.h2
-rw-r--r--servers/rendering/rendering_server_default.cpp59
-rw-r--r--servers/rendering/rendering_server_default.h17
-rw-r--r--servers/rendering/rendering_server_globals.cpp4
-rw-r--r--servers/rendering/rendering_server_globals.h7
-rw-r--r--servers/rendering/storage/light_storage.h1
-rw-r--r--servers/rendering/storage/material_storage.h4
-rw-r--r--servers/rendering/storage/mesh_storage.h4
-rw-r--r--servers/rendering/storage/particles_storage.h1
-rw-r--r--servers/rendering/storage/texture_storage.h11
-rw-r--r--servers/rendering/storage/utilities.cpp (renamed from servers/rendering/renderer_storage.cpp)16
-rw-r--r--servers/rendering/storage/utilities.h186
-rw-r--r--servers/rendering_server.h2
-rw-r--r--servers/text/text_server_extension.cpp30
-rw-r--r--servers/text/text_server_extension.h10
-rw-r--r--servers/text_server.cpp6
-rw-r--r--servers/text_server.h7
-rw-r--r--servers/xr/xr_interface_extension.cpp2
128 files changed, 5039 insertions, 2945 deletions
diff --git a/servers/SCsub b/servers/SCsub
index 66a1b9b26f..2ce90e970b 100644
--- a/servers/SCsub
+++ b/servers/SCsub
@@ -14,6 +14,7 @@ SConscript("audio/SCsub")
SConscript("text/SCsub")
SConscript("debugger/SCsub")
SConscript("extensions/SCsub")
+SConscript("movie_writer/SCsub")
lib = env.add_library("servers", env.servers_sources)
diff --git a/servers/audio/audio_driver_dummy.cpp b/servers/audio/audio_driver_dummy.cpp
index 635e4601c7..60eb657923 100644
--- a/servers/audio/audio_driver_dummy.cpp
+++ b/servers/audio/audio_driver_dummy.cpp
@@ -33,22 +33,24 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
+AudioDriverDummy *AudioDriverDummy::singleton = nullptr;
+
Error AudioDriverDummy::init() {
active = false;
thread_exited = false;
exit_thread = false;
samples_in = nullptr;
- mix_rate = GLOBAL_GET("audio/driver/mix_rate");
- speaker_mode = SPEAKER_MODE_STEREO;
- channels = 2;
-
- int latency = GLOBAL_GET("audio/driver/output_latency");
- buffer_frames = closest_power_of_2(latency * mix_rate / 1000);
+ if (mix_rate == -1) {
+ mix_rate = GLOBAL_GET("audio/driver/mix_rate");
+ }
+ channels = get_channels();
samples_in = memnew_arr(int32_t, (size_t)buffer_frames * channels);
- thread.start(AudioDriverDummy::thread_func, this);
+ if (use_threads) {
+ thread.start(AudioDriverDummy::thread_func, this);
+ }
return OK;
};
@@ -93,11 +95,56 @@ void AudioDriverDummy::unlock() {
mutex.unlock();
};
+void AudioDriverDummy::set_use_threads(bool p_use_threads) {
+ use_threads = p_use_threads;
+}
+
+void AudioDriverDummy::set_speaker_mode(SpeakerMode p_mode) {
+ speaker_mode = p_mode;
+}
+
+void AudioDriverDummy::set_mix_rate(int p_rate) {
+ mix_rate = p_rate;
+}
+
+uint32_t AudioDriverDummy::get_channels() const {
+ static const int channels_for_mode[4] = { 2, 4, 8, 16 };
+ return channels_for_mode[speaker_mode];
+}
+
+void AudioDriverDummy::mix_audio(int p_frames, int32_t *p_buffer) {
+ ERR_FAIL_COND(!active); // If not active, should not mix.
+ ERR_FAIL_COND(use_threads == true); // If using threads, this will not work well.
+
+ uint32_t todo = p_frames;
+ while (todo) {
+ uint32_t to_mix = MIN(buffer_frames, todo);
+ lock();
+ audio_server_process(to_mix, samples_in);
+ unlock();
+
+ uint32_t total_samples = to_mix * channels;
+
+ for (uint32_t i = 0; i < total_samples; i++) {
+ p_buffer[i] = samples_in[i];
+ }
+
+ todo -= to_mix;
+ p_buffer += total_samples;
+ }
+}
+
void AudioDriverDummy::finish() {
- exit_thread = true;
- thread.wait_to_finish();
+ if (use_threads) {
+ exit_thread = true;
+ thread.wait_to_finish();
+ }
if (samples_in) {
memdelete_arr(samples_in);
};
-};
+}
+
+AudioDriverDummy::AudioDriverDummy() {
+ singleton = this;
+}
diff --git a/servers/audio/audio_driver_dummy.h b/servers/audio/audio_driver_dummy.h
index 68b523e086..232a8d5e1f 100644
--- a/servers/audio/audio_driver_dummy.h
+++ b/servers/audio/audio_driver_dummy.h
@@ -44,9 +44,9 @@ class AudioDriverDummy : public AudioDriver {
static void thread_func(void *p_udata);
- unsigned int buffer_frames;
- unsigned int mix_rate;
- SpeakerMode speaker_mode;
+ uint32_t buffer_frames = 4096;
+ int32_t mix_rate = -1;
+ SpeakerMode speaker_mode = SPEAKER_MODE_STEREO;
int channels;
@@ -54,6 +54,10 @@ class AudioDriverDummy : public AudioDriver {
bool thread_exited;
mutable bool exit_thread;
+ bool use_threads = true;
+
+ static AudioDriverDummy *singleton;
+
public:
const char *get_name() const {
return "Dummy";
@@ -67,7 +71,17 @@ public:
virtual void unlock();
virtual void finish();
- AudioDriverDummy() {}
+ void set_use_threads(bool p_use_threads);
+ void set_speaker_mode(SpeakerMode p_mode);
+ void set_mix_rate(int p_rate);
+
+ uint32_t get_channels() const;
+
+ void mix_audio(int p_frames, int32_t *p_buffer);
+
+ static AudioDriverDummy *get_dummy_singleton() { return singleton; }
+
+ AudioDriverDummy();
~AudioDriverDummy() {}
};
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 3983bc5cb1..5d9a9e61dc 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -135,9 +135,10 @@ int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
uint64_t mix_increment = uint64_t(((get_stream_sampling_rate() * p_rate_scale * playback_speed_scale) / double(target_rate)) * double(FP_LEN));
- int mixed_frames_total = p_frames;
+ int mixed_frames_total = -1;
- for (int i = 0; i < p_frames; i++) {
+ int i;
+ for (i = 0; i < p_frames; i++) {
uint32_t idx = CUBIC_INTERP_HISTORY + uint32_t(mix_offset >> FP_BITS);
//standard cubic interpolation (great quality/performance ratio)
//this used to be moved to a LUT for greater performance, but nowadays CPU speed is generally faster than memory.
@@ -147,7 +148,7 @@ int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
AudioFrame y2 = internal_buffer[idx - 1];
AudioFrame y3 = internal_buffer[idx - 0];
- if (idx <= internal_buffer_end && idx >= internal_buffer_end && mixed_frames_total == p_frames) {
+ if (idx >= internal_buffer_end && mixed_frames_total == -1) {
// The internal buffer ends somewhere in this range, and we haven't yet recorded the number of good frames we have.
mixed_frames_total = i;
}
@@ -167,24 +168,20 @@ int AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
internal_buffer[1] = internal_buffer[INTERNAL_BUFFER_LEN + 1];
internal_buffer[2] = internal_buffer[INTERNAL_BUFFER_LEN + 2];
internal_buffer[3] = internal_buffer[INTERNAL_BUFFER_LEN + 3];
- if (is_playing()) {
- int mixed_frames = _mix_internal(internal_buffer + 4, INTERNAL_BUFFER_LEN);
- if (mixed_frames != INTERNAL_BUFFER_LEN) {
- // internal_buffer[mixed_frames] is the first frame of silence.
- internal_buffer_end = mixed_frames;
- } else {
- // The internal buffer does not contain the first frame of silence.
- internal_buffer_end = -1;
- }
+ int mixed_frames = _mix_internal(internal_buffer + 4, INTERNAL_BUFFER_LEN);
+ if (mixed_frames != INTERNAL_BUFFER_LEN) {
+ // internal_buffer[mixed_frames] is the first frame of silence.
+ internal_buffer_end = mixed_frames;
} else {
- //fill with silence, not playing
- for (int j = 0; j < INTERNAL_BUFFER_LEN; ++j) {
- internal_buffer[j + 4] = AudioFrame(0, 0);
- }
+ // The internal buffer does not contain the first frame of silence.
+ internal_buffer_end = -1;
}
mix_offset -= (INTERNAL_BUFFER_LEN << FP_BITS);
}
}
+ if (mixed_frames_total == -1 && i == p_frames) {
+ mixed_frames_total = p_frames;
+ }
return mixed_frames_total;
}
diff --git a/servers/movie_writer/SCsub b/servers/movie_writer/SCsub
new file mode 100644
index 0000000000..86681f9c74
--- /dev/null
+++ b/servers/movie_writer/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import("env")
+
+env.add_source_files(env.servers_sources, "*.cpp")
diff --git a/servers/movie_writer/movie_writer.cpp b/servers/movie_writer/movie_writer.cpp
new file mode 100644
index 0000000000..9f96b8cfda
--- /dev/null
+++ b/servers/movie_writer/movie_writer.cpp
@@ -0,0 +1,171 @@
+/*************************************************************************/
+/* movie_writer.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "movie_writer.h"
+#include "core/config/project_settings.h"
+
+MovieWriter *MovieWriter::writers[MovieWriter::MAX_WRITERS];
+uint32_t MovieWriter::writer_count = 0;
+
+void MovieWriter::add_writer(MovieWriter *p_writer) {
+ ERR_FAIL_COND(writer_count == MAX_WRITERS);
+ writers[writer_count++] = p_writer;
+}
+
+MovieWriter *MovieWriter::find_writer_for_file(const String &p_file) {
+ for (int32_t i = writer_count - 1; i >= 0; i--) { // More recent last, to have override ability.
+ if (writers[i]->handles_file(p_file)) {
+ return writers[i];
+ }
+ }
+ return nullptr;
+}
+
+uint32_t MovieWriter::get_audio_mix_rate() const {
+ uint32_t ret = 0;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_audio_mix_rate, ret)) {
+ return ret;
+ }
+ return 48000;
+}
+AudioServer::SpeakerMode MovieWriter::get_audio_speaker_mode() const {
+ AudioServer::SpeakerMode ret = AudioServer::SPEAKER_MODE_STEREO;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_audio_speaker_mode, ret)) {
+ return ret;
+ }
+ return AudioServer::SPEAKER_MODE_STEREO;
+}
+
+Error MovieWriter::write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) {
+ Error ret = OK;
+ if (GDVIRTUAL_REQUIRED_CALL(_write_begin, p_movie_size, p_fps, p_base_path, ret)) {
+ return ret;
+ }
+ return ERR_UNCONFIGURED;
+}
+
+Error MovieWriter::write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) {
+ Error ret = OK;
+ if (GDVIRTUAL_REQUIRED_CALL(_write_frame, p_image, p_audio_data, ret)) {
+ return ret;
+ }
+ return ERR_UNCONFIGURED;
+}
+
+void MovieWriter::write_end() {
+ GDVIRTUAL_REQUIRED_CALL(_write_end);
+}
+
+bool MovieWriter::handles_file(const String &p_path) const {
+ bool ret = false;
+ if (GDVIRTUAL_REQUIRED_CALL(_handles_file, p_path, ret)) {
+ return ret;
+ }
+ return false;
+}
+
+void MovieWriter::get_supported_extensions(List<String> *r_extensions) const {
+ Vector<String> exts;
+ if (GDVIRTUAL_REQUIRED_CALL(_get_supported_extensions, exts)) {
+ for (int i = 0; i < exts.size(); i++) {
+ r_extensions->push_back(exts[i]);
+ }
+ }
+}
+
+void MovieWriter::begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) {
+ mix_rate = get_audio_mix_rate();
+ AudioDriverDummy::get_dummy_singleton()->set_mix_rate(mix_rate);
+ AudioDriverDummy::get_dummy_singleton()->set_speaker_mode(AudioDriver::SpeakerMode(get_audio_speaker_mode()));
+ fps = p_fps;
+ if ((mix_rate % fps) != 0) {
+ WARN_PRINT("MovieWriter's audio mix rate (" + itos(mix_rate) + ") can not be divided by the recording FPS (" + itos(fps) + "). Audio may go out of sync over time.");
+ }
+
+ audio_channels = AudioDriverDummy::get_dummy_singleton()->get_channels();
+ audio_mix_buffer.resize(mix_rate * audio_channels / fps);
+
+ write_begin(p_movie_size, p_fps, p_base_path);
+}
+
+void MovieWriter::_bind_methods() {
+ ClassDB::bind_static_method("MovieWriter", D_METHOD("add_writer", "writer"), &MovieWriter::add_writer);
+
+ GDVIRTUAL_BIND(_get_audio_mix_rate)
+ GDVIRTUAL_BIND(_get_audio_speaker_mode)
+
+ GDVIRTUAL_BIND(_handles_file, "path")
+
+ GDVIRTUAL_BIND(_write_begin, "movie_size", "fps", "base_path")
+ GDVIRTUAL_BIND(_write_frame, "frame_image", "audio_frame_block")
+ GDVIRTUAL_BIND(_write_end)
+
+ GLOBAL_DEF("editor/movie_writer/mix_rate", 48000);
+ ProjectSettings::get_singleton()->set_custom_property_info("editor/movie_writer/mix_rate", PropertyInfo(Variant::INT, "editor/movie_writer/mix_rate", PROPERTY_HINT_RANGE, "8000,192000,1,suffix:Hz"));
+ GLOBAL_DEF("editor/movie_writer/speaker_mode", 0);
+ ProjectSettings::get_singleton()->set_custom_property_info("editor/movie_writer/speaker_mode", PropertyInfo(Variant::INT, "editor/movie_writer/speaker_mode", PROPERTY_HINT_ENUM, "Stereo,3.1,5.1,7.1"));
+ GLOBAL_DEF("editor/movie_writer/mjpeg_quality", 0.75);
+ ProjectSettings::get_singleton()->set_custom_property_info("editor/movie_writer/mjpeg_quality", PropertyInfo(Variant::FLOAT, "editor/movie_writer/mjpeg_quality", PROPERTY_HINT_RANGE, "0.01,1.0,0.01"));
+ // used by the editor
+ GLOBAL_DEF_BASIC("editor/movie_writer/movie_file", "");
+ GLOBAL_DEF_BASIC("editor/movie_writer/disable_vsync", false);
+ GLOBAL_DEF_BASIC("editor/movie_writer/fps", 60);
+ ProjectSettings::get_singleton()->set_custom_property_info("editor/movie_writer/fps", PropertyInfo(Variant::INT, "editor/movie_writer/fps", PROPERTY_HINT_RANGE, "1,300,1,suffix:FPS"));
+}
+
+void MovieWriter::set_extensions_hint() {
+ RBSet<String> found;
+ for (uint32_t i = 0; i < writer_count; i++) {
+ List<String> extensions;
+ writers[i]->get_supported_extensions(&extensions);
+ for (const String &ext : extensions) {
+ found.insert(ext);
+ }
+ }
+
+ String ext_hint;
+
+ for (const String &S : found) {
+ if (ext_hint != "") {
+ ext_hint += ",";
+ }
+ ext_hint += "*." + S;
+ }
+ ProjectSettings::get_singleton()->set_custom_property_info("editor/movie_writer/movie_file", PropertyInfo(Variant::STRING, "editor/movie_writer/movie_file", PROPERTY_HINT_GLOBAL_SAVE_FILE, ext_hint));
+}
+
+void MovieWriter::add_frame(const Ref<Image> &p_image) {
+ AudioDriverDummy::get_dummy_singleton()->mix_audio(mix_rate / fps, audio_mix_buffer.ptr());
+ write_frame(p_image, audio_mix_buffer.ptr());
+}
+
+void MovieWriter::end() {
+ write_end();
+}
diff --git a/servers/movie_writer/movie_writer.h b/servers/movie_writer/movie_writer.h
new file mode 100644
index 0000000000..1ec6e93052
--- /dev/null
+++ b/servers/movie_writer/movie_writer.h
@@ -0,0 +1,88 @@
+/*************************************************************************/
+/* movie_writer.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 MOVIE_WRITER_H
+#define MOVIE_WRITER_H
+
+#include "core/templates/local_vector.h"
+#include "servers/audio/audio_driver_dummy.h"
+#include "servers/audio_server.h"
+
+class MovieWriter : public Object {
+ GDCLASS(MovieWriter, Object);
+
+ uint64_t fps = 0;
+ uint64_t mix_rate = 0;
+ uint32_t audio_channels = 0;
+
+ LocalVector<int32_t> audio_mix_buffer;
+
+ enum {
+ MAX_WRITERS = 8
+ };
+ static MovieWriter *writers[];
+ static uint32_t writer_count;
+
+protected:
+ virtual uint32_t get_audio_mix_rate() const;
+ virtual AudioServer::SpeakerMode get_audio_speaker_mode() const;
+
+ virtual Error write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path);
+ virtual Error write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data);
+ virtual void write_end();
+
+ GDVIRTUAL0RC(uint32_t, _get_audio_mix_rate)
+ GDVIRTUAL0RC(AudioServer::SpeakerMode, _get_audio_speaker_mode)
+
+ GDVIRTUAL1RC(bool, _handles_file, const String &)
+ GDVIRTUAL0RC(Vector<String>, _get_supported_extensions)
+
+ GDVIRTUAL3R(Error, _write_begin, const Size2i &, uint32_t, const String &)
+ GDVIRTUAL2R(Error, _write_frame, const Ref<Image> &, GDNativeConstPtr<int32_t>)
+ GDVIRTUAL0(_write_end)
+
+ static void _bind_methods();
+
+public:
+ virtual bool handles_file(const String &p_path) const;
+ virtual void get_supported_extensions(List<String> *r_extensions) const;
+
+ static void add_writer(MovieWriter *p_writer);
+ static MovieWriter *find_writer_for_file(const String &p_file);
+
+ void begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path);
+ void add_frame(const Ref<Image> &p_image);
+
+ static void set_extensions_hint();
+
+ void end();
+};
+
+#endif // MOVIE_WRITER_H
diff --git a/servers/movie_writer/movie_writer_mjpeg.cpp b/servers/movie_writer/movie_writer_mjpeg.cpp
new file mode 100644
index 0000000000..7d9e6e3b87
--- /dev/null
+++ b/servers/movie_writer/movie_writer_mjpeg.cpp
@@ -0,0 +1,263 @@
+/*************************************************************************/
+/* movie_writer_mjpeg.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "movie_writer_mjpeg.h"
+#include "core/config/project_settings.h"
+
+uint32_t MovieWriterMJPEG::get_audio_mix_rate() const {
+ return mix_rate;
+}
+AudioServer::SpeakerMode MovieWriterMJPEG::get_audio_speaker_mode() const {
+ return speaker_mode;
+}
+
+bool MovieWriterMJPEG::handles_file(const String &p_path) const {
+ return p_path.get_extension().to_lower() == "avi";
+}
+
+void MovieWriterMJPEG::get_supported_extensions(List<String> *r_extensions) const {
+ r_extensions->push_back("avi");
+}
+
+Error MovieWriterMJPEG::write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) {
+ // Quick & Dirty MJPEG Code based on - https://docs.microsoft.com/en-us/windows/win32/directshow/avi-riff-file-reference
+
+ base_path = p_base_path.get_basename();
+ if (base_path.is_relative_path()) {
+ base_path = "res://" + base_path;
+ }
+
+ base_path += ".avi";
+
+ f = FileAccess::open(base_path, FileAccess::WRITE_READ);
+
+ fps = p_fps;
+
+ ERR_FAIL_COND_V(f.is_null(), ERR_CANT_OPEN);
+
+ f->store_buffer((const uint8_t *)"RIFF", 4);
+ f->store_32(0); // Total length (update later)
+ f->store_buffer((const uint8_t *)"AVI ", 4);
+ f->store_buffer((const uint8_t *)"LIST", 4);
+ f->store_32(300); // 4 + 4 + 4 + 56 + 4 + 4 + 132 + 4 + 4 + 84
+ f->store_buffer((const uint8_t *)"hdrl", 4);
+ f->store_buffer((const uint8_t *)"avih", 4);
+ f->store_32(56);
+
+ f->store_32(1000000 / p_fps); // Microsecs per frame.
+ f->store_32(7000); // Max bytes per second
+ f->store_32(0); // Padding Granularity
+ f->store_32(16);
+ total_frames_ofs = f->get_position();
+ f->store_32(0); // Total frames (update later)
+ f->store_32(0); // Initial frames
+ f->store_32(1); // Streams
+ f->store_32(0); // Suggested buffer size
+ f->store_32(p_movie_size.width); // Movie Width
+ f->store_32(p_movie_size.height); // Movie Height
+ for (uint32_t i = 0; i < 4; i++) {
+ f->store_32(0); // Reserved.
+ }
+ f->store_buffer((const uint8_t *)"LIST", 4);
+ f->store_32(132); // 4 + 4 + 4 + 48 + 4 + 4 + 40 + 4 + 4 + 16
+ f->store_buffer((const uint8_t *)"strl", 4);
+ f->store_buffer((const uint8_t *)"strh", 4);
+ f->store_32(48);
+ f->store_buffer((const uint8_t *)"vids", 4);
+ f->store_buffer((const uint8_t *)"MJPG", 4);
+ f->store_32(0); // Flags
+ f->store_16(0); // Priority
+ f->store_16(0); // Language
+ f->store_32(0); // Initial Frames
+ f->store_32(1); // Scale
+ f->store_32(p_fps); // FPS
+ f->store_32(0); // Start
+ total_frames_ofs2 = f->get_position();
+ f->store_32(0); // Number of frames (to be updated later)
+ f->store_32(0); // Suggested Buffer Size
+ f->store_32(0); // Quality
+ f->store_32(0); // Sample Size
+
+ f->store_buffer((const uint8_t *)"strf", 4);
+ f->store_32(40); // Size.
+ f->store_32(40); // Size.
+
+ f->store_32(p_movie_size.width); // Width
+ f->store_32(p_movie_size.height); // Width
+ f->store_16(1); // Planes
+ f->store_16(24); // Bitcount
+ f->store_buffer((const uint8_t *)"MJPG", 4); // Compression
+
+ f->store_32(((p_movie_size.width * 24 / 8 + 3) & 0xFFFFFFFC) * p_movie_size.height); // SizeImage
+ f->store_32(0); // XPelsXMeter
+ f->store_32(0); // YPelsXMeter
+ f->store_32(0); // ClrUsed
+ f->store_32(0); // ClrImportant
+
+ f->store_buffer((const uint8_t *)"LIST", 4);
+ f->store_32(16);
+
+ f->store_buffer((const uint8_t *)"odml", 4);
+ f->store_buffer((const uint8_t *)"dmlh", 4);
+ f->store_32(4); // sizes
+
+ total_frames_ofs3 = f->get_position();
+ f->store_32(0); // Number of frames (to be updated later)
+
+ // Audio //
+
+ const uint32_t bit_depth = 32;
+ uint32_t channels = 2;
+ switch (speaker_mode) {
+ case AudioServer::SPEAKER_MODE_STEREO:
+ channels = 2;
+ break;
+ case AudioServer::SPEAKER_SURROUND_31:
+ channels = 4;
+ break;
+ case AudioServer::SPEAKER_SURROUND_51:
+ channels = 6;
+ break;
+ case AudioServer::SPEAKER_SURROUND_71:
+ channels = 8;
+ break;
+ }
+ uint32_t blockalign = bit_depth / 8 * channels;
+
+ f->store_buffer((const uint8_t *)"LIST", 4);
+ f->store_32(84); // 4 + 4 + 4 + 48 + 4 + 4 + 16
+ f->store_buffer((const uint8_t *)"strl", 4);
+ f->store_buffer((const uint8_t *)"strh", 4);
+ f->store_32(48);
+ f->store_buffer((const uint8_t *)"auds", 4);
+ f->store_32(0); // Handler
+ f->store_32(0); // Flags
+ f->store_16(0); // Priority
+ f->store_16(0); // Language
+ f->store_32(0); // Initial Frames
+ f->store_32(blockalign); // Scale
+ f->store_32(mix_rate * blockalign); // mix rate
+ f->store_32(0); // Start
+ total_audio_frames_ofs4 = f->get_position();
+ f->store_32(0); // Number of frames (to be updated later)
+ f->store_32(12288); // Suggested Buffer Size
+ f->store_32(0xFFFFFFFF); // Quality
+ f->store_32(blockalign); // Block Align to 32 bits
+
+ audio_block_size = (mix_rate / fps) * blockalign;
+
+ f->store_buffer((const uint8_t *)"strf", 4);
+ f->store_32(16); // Standard format, no extra fields
+ f->store_16(1); // Compression code, standard PCM
+ f->store_16(channels);
+ f->store_32(mix_rate); // Samples (frames) / Sec
+ f->store_32(mix_rate * blockalign); // Bytes / sec
+ f->store_16(blockalign); // Bytes / sec
+ f->store_16(bit_depth); // Bytes / sec
+
+ f->store_buffer((const uint8_t *)"LIST", 4);
+ movi_data_ofs = f->get_position();
+ f->store_32(0); // Number of frames (to be updated later)
+ f->store_buffer((const uint8_t *)"movi", 4);
+
+ return OK;
+}
+
+Error MovieWriterMJPEG::write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) {
+ ERR_FAIL_COND_V(!f.is_valid(), ERR_UNCONFIGURED);
+
+ Vector<uint8_t> jpg_buffer = p_image->save_jpg_to_buffer(quality);
+ uint32_t s = jpg_buffer.size();
+
+ f->store_buffer((const uint8_t *)"00db", 4); // Stream 0, Video
+ f->store_32(jpg_buffer.size()); // sizes
+ f->store_buffer(jpg_buffer.ptr(), jpg_buffer.size());
+ if (jpg_buffer.size() & 1) {
+ f->store_8(0);
+ s++;
+ }
+ jpg_frame_sizes.push_back(s);
+
+ f->store_buffer((const uint8_t *)"01wb", 4); // Stream 1, Audio.
+ f->store_32(audio_block_size);
+ f->store_buffer((const uint8_t *)p_audio_data, audio_block_size);
+
+ frame_count++;
+
+ return OK;
+}
+
+void MovieWriterMJPEG::write_end() {
+ if (f.is_valid()) {
+ // Finalize the file (frame indices)
+ f->store_buffer((const uint8_t *)"idx1", 4);
+ f->store_32(8 * 4 * frame_count);
+ uint32_t ofs = 4;
+ uint32_t all_data_size = 0;
+ for (uint32_t i = 0; i < frame_count; i++) {
+ f->store_buffer((const uint8_t *)"00db", 4);
+ f->store_32(16); // AVI_KEYFRAME
+ f->store_32(ofs);
+ f->store_32(jpg_frame_sizes[i]);
+
+ ofs += jpg_frame_sizes[i] + 8;
+
+ f->store_buffer((const uint8_t *)"01wb", 4);
+ f->store_32(16); // AVI_KEYFRAME
+ f->store_32(ofs);
+ f->store_32(audio_block_size);
+
+ ofs += audio_block_size + 8;
+ all_data_size += jpg_frame_sizes[i] + audio_block_size;
+ }
+
+ uint32_t file_size = f->get_position();
+ f->seek(4);
+ f->store_32(file_size - 78);
+ f->seek(total_frames_ofs);
+ f->store_32(frame_count);
+ f->seek(total_frames_ofs2);
+ f->store_32(frame_count);
+ f->seek(total_frames_ofs3);
+ f->store_32(frame_count);
+ f->seek(total_audio_frames_ofs4);
+ f->store_32(frame_count * mix_rate / fps);
+ f->seek(movi_data_ofs);
+ f->store_32(all_data_size + 4 + 16 * frame_count);
+
+ f.unref();
+ }
+}
+
+MovieWriterMJPEG::MovieWriterMJPEG() {
+ mix_rate = GLOBAL_GET("editor/movie_writer/mix_rate");
+ speaker_mode = AudioServer::SpeakerMode(int(GLOBAL_GET("editor/movie_writer/speaker_mode")));
+ quality = GLOBAL_GET("editor/movie_writer/mjpeg_quality");
+}
diff --git a/servers/movie_writer/movie_writer_mjpeg.h b/servers/movie_writer/movie_writer_mjpeg.h
new file mode 100644
index 0000000000..233267df30
--- /dev/null
+++ b/servers/movie_writer/movie_writer_mjpeg.h
@@ -0,0 +1,73 @@
+/*************************************************************************/
+/* movie_writer_mjpeg.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 MOVIE_WRITER_MJPEG_H
+#define MOVIE_WRITER_MJPEG_H
+
+#include "servers/movie_writer/movie_writer.h"
+
+class MovieWriterMJPEG : public MovieWriter {
+ GDCLASS(MovieWriterMJPEG, MovieWriter)
+
+ uint32_t mix_rate = 48000;
+ AudioServer::SpeakerMode speaker_mode = AudioServer::SPEAKER_MODE_STEREO;
+ String base_path;
+ uint32_t frame_count = 0;
+ uint32_t fps = 0;
+ float quality = 0.75;
+
+ uint32_t audio_block_size = 0;
+
+ Vector<uint32_t> jpg_frame_sizes;
+
+ uint64_t total_frames_ofs = 0;
+ uint64_t total_frames_ofs2 = 0;
+ uint64_t total_frames_ofs3 = 0;
+ uint64_t total_audio_frames_ofs4 = 0;
+ uint64_t movi_data_ofs = 0;
+
+ Ref<FileAccess> f;
+
+protected:
+ virtual uint32_t get_audio_mix_rate() const override;
+ virtual AudioServer::SpeakerMode get_audio_speaker_mode() const override;
+ virtual void get_supported_extensions(List<String> *r_extensions) const override;
+
+ virtual Error write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) override;
+ virtual Error write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) override;
+ virtual void write_end() override;
+
+ virtual bool handles_file(const String &p_path) const override;
+
+public:
+ MovieWriterMJPEG();
+};
+
+#endif // MOVIE_WRITER_MJPEG_H
diff --git a/servers/movie_writer/movie_writer_pngwav.cpp b/servers/movie_writer/movie_writer_pngwav.cpp
new file mode 100644
index 0000000000..bd79b0bd98
--- /dev/null
+++ b/servers/movie_writer/movie_writer_pngwav.cpp
@@ -0,0 +1,168 @@
+/*************************************************************************/
+/* movie_writer_pngwav.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "movie_writer_pngwav.h"
+#include "core/config/project_settings.h"
+#include "core/io/dir_access.h"
+
+uint32_t MovieWriterPNGWAV::get_audio_mix_rate() const {
+ return mix_rate;
+}
+AudioServer::SpeakerMode MovieWriterPNGWAV::get_audio_speaker_mode() const {
+ return speaker_mode;
+}
+
+void MovieWriterPNGWAV::get_supported_extensions(List<String> *r_extensions) const {
+ r_extensions->push_back("png");
+}
+
+bool MovieWriterPNGWAV::handles_file(const String &p_path) const {
+ return p_path.get_extension().to_lower() == "png";
+}
+
+String MovieWriterPNGWAV::zeros_str(uint32_t p_index) {
+ char zeros[MAX_TRAILING_ZEROS + 1];
+ for (uint32_t i = 0; i < MAX_TRAILING_ZEROS; i++) {
+ uint32_t idx = MAX_TRAILING_ZEROS - i - 1;
+ uint32_t digit = (p_index / uint32_t(Math::pow(double(10), double(idx)))) % 10;
+ zeros[i] = '0' + digit;
+ }
+ zeros[MAX_TRAILING_ZEROS] = 0;
+ return zeros;
+}
+
+Error MovieWriterPNGWAV::write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) {
+ // Quick & Dirty PNGWAV Code based on - https://docs.microsoft.com/en-us/windows/win32/directshow/avi-riff-file-reference
+
+ base_path = p_base_path.get_basename();
+ if (base_path.is_relative_path()) {
+ base_path = "res://" + base_path;
+ }
+
+ {
+ //Remove existing files before writing anew
+ uint32_t idx = 0;
+ Ref<DirAccess> d = DirAccess::open(base_path.get_base_dir());
+ String file = base_path.get_file();
+ while (true) {
+ String path = file + zeros_str(idx) + ".png";
+ if (d->remove(path) != OK) {
+ break;
+ }
+ }
+ }
+
+ f_wav = FileAccess::open(base_path + ".wav", FileAccess::WRITE_READ);
+ ERR_FAIL_COND_V(f_wav.is_null(), ERR_CANT_OPEN);
+
+ fps = p_fps;
+
+ f_wav->store_buffer((const uint8_t *)"RIFF", 4);
+ int total_size = 4 /* WAVE */ + 8 /* fmt+size */ + 16 /* format */ + 8 /* data+size */;
+ f_wav->store_32(total_size); //will store final later
+ f_wav->store_buffer((const uint8_t *)"WAVE", 4);
+
+ /* FORMAT CHUNK */
+
+ f_wav->store_buffer((const uint8_t *)"fmt ", 4);
+
+ uint32_t channels = 2;
+ switch (speaker_mode) {
+ case AudioServer::SPEAKER_MODE_STEREO:
+ channels = 2;
+ break;
+ case AudioServer::SPEAKER_SURROUND_31:
+ channels = 4;
+ break;
+ case AudioServer::SPEAKER_SURROUND_51:
+ channels = 6;
+ break;
+ case AudioServer::SPEAKER_SURROUND_71:
+ channels = 8;
+ break;
+ }
+
+ f_wav->store_32(16); //standard format, no extra fields
+ f_wav->store_16(1); // compression code, standard PCM
+ f_wav->store_16(channels); //CHANNELS: 2
+
+ f_wav->store_32(mix_rate);
+
+ /* useless stuff the format asks for */
+
+ int bits_per_sample = 32;
+ int blockalign = bits_per_sample / 8 * channels;
+ int bytes_per_sec = mix_rate * blockalign;
+
+ audio_block_size = (mix_rate / fps) * blockalign;
+
+ f_wav->store_32(bytes_per_sec);
+ f_wav->store_16(blockalign); // block align (unused)
+ f_wav->store_16(bits_per_sample);
+
+ /* DATA CHUNK */
+
+ f_wav->store_buffer((const uint8_t *)"data", 4);
+
+ f_wav->store_32(0); //data size... wooh
+ wav_data_size_pos = f_wav->get_position();
+
+ return OK;
+}
+
+Error MovieWriterPNGWAV::write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) {
+ ERR_FAIL_COND_V(!f_wav.is_valid(), ERR_UNCONFIGURED);
+
+ Vector<uint8_t> png_buffer = p_image->save_png_to_buffer();
+
+ Ref<FileAccess> fi = FileAccess::open(base_path + zeros_str(frame_count) + ".png", FileAccess::WRITE);
+ fi->store_buffer(png_buffer.ptr(), png_buffer.size());
+ f_wav->store_buffer((const uint8_t *)p_audio_data, audio_block_size);
+
+ frame_count++;
+
+ return OK;
+}
+
+void MovieWriterPNGWAV::write_end() {
+ if (f_wav.is_valid()) {
+ uint32_t total_size = 4 /* WAVE */ + 8 /* fmt+size */ + 16 /* format */ + 8 /* data+size */;
+ uint32_t datasize = f_wav->get_position() - wav_data_size_pos;
+ f_wav->seek(4);
+ f_wav->store_32(total_size + datasize);
+ f_wav->seek(0x28);
+ f_wav->store_32(datasize);
+ }
+}
+
+MovieWriterPNGWAV::MovieWriterPNGWAV() {
+ mix_rate = GLOBAL_GET("editor/movie_writer/mix_rate");
+ speaker_mode = AudioServer::SpeakerMode(int(GLOBAL_GET("editor/movie_writer/speaker_mode")));
+}
diff --git a/servers/movie_writer/movie_writer_pngwav.h b/servers/movie_writer/movie_writer_pngwav.h
new file mode 100644
index 0000000000..64608ce387
--- /dev/null
+++ b/servers/movie_writer/movie_writer_pngwav.h
@@ -0,0 +1,71 @@
+/*************************************************************************/
+/* movie_writer_pngwav.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 MOVIE_WRITER_PNGWAV_H
+#define MOVIE_WRITER_PNGWAV_H
+
+#include "servers/movie_writer/movie_writer.h"
+
+class MovieWriterPNGWAV : public MovieWriter {
+ GDCLASS(MovieWriterPNGWAV, MovieWriter)
+
+ enum {
+ MAX_TRAILING_ZEROS = 8 // more than 10 days at 60fps, no hard drive can put up with this anyway :)
+ };
+
+ uint32_t mix_rate = 48000;
+ AudioServer::SpeakerMode speaker_mode = AudioServer::SPEAKER_MODE_STEREO;
+ String base_path;
+ uint32_t frame_count = 0;
+ uint32_t fps = 0;
+
+ uint32_t audio_block_size = 0;
+
+ Ref<FileAccess> f_wav;
+ uint32_t wav_data_size_pos = 0;
+
+ String zeros_str(uint32_t p_index);
+
+protected:
+ virtual uint32_t get_audio_mix_rate() const override;
+ virtual AudioServer::SpeakerMode get_audio_speaker_mode() const override;
+ virtual void get_supported_extensions(List<String> *r_extensions) const override;
+
+ virtual Error write_begin(const Size2i &p_movie_size, uint32_t p_fps, const String &p_base_path) override;
+ virtual Error write_frame(const Ref<Image> &p_image, const int32_t *p_audio_data) override;
+ virtual void write_end() override;
+
+ virtual bool handles_file(const String &p_path) const override;
+
+public:
+ MovieWriterPNGWAV();
+};
+
+#endif // MOVIE_WRITER_PNGWAV_H
diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp
index 0442089503..5e9f1c824a 100644
--- a/servers/navigation_server_2d.cpp
+++ b/servers/navigation_server_2d.cpp
@@ -159,6 +159,8 @@ void NavigationServer2D::_emit_map_changed(RID p_map) {
}
void NavigationServer2D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_maps"), &NavigationServer2D::get_maps);
+
ClassDB::bind_method(D_METHOD("map_create"), &NavigationServer2D::map_create);
ClassDB::bind_method(D_METHOD("map_set_active", "map", "active"), &NavigationServer2D::map_set_active);
ClassDB::bind_method(D_METHOD("map_is_active", "nap"), &NavigationServer2D::map_is_active);
@@ -173,11 +175,14 @@ void NavigationServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer2D::map_get_regions);
ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer2D::map_get_agents);
+ ClassDB::bind_method(D_METHOD("map_force_update", "map"), &NavigationServer2D::map_force_update);
+
ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer2D::region_create);
ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer2D::region_set_enter_cost);
ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer2D::region_get_enter_cost);
ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &NavigationServer2D::region_set_travel_cost);
ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &NavigationServer2D::region_get_travel_cost);
+ ClassDB::bind_method(D_METHOD("region_owns_point", "region", "point"), &NavigationServer2D::region_owns_point);
ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer2D::region_set_map);
ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer2D::region_get_map);
ClassDB::bind_method(D_METHOD("region_set_navigation_layers", "region", "navigation_layers"), &NavigationServer2D::region_set_navigation_layers);
@@ -217,6 +222,8 @@ NavigationServer2D::~NavigationServer2D() {
singleton = nullptr;
}
+Array FORWARD_0_C(get_maps);
+
Array FORWARD_1_C(map_get_regions, RID, p_map, rid_to_rid);
Array FORWARD_1_C(map_get_agents, RID, p_map, rid_to_rid);
@@ -231,6 +238,10 @@ void FORWARD_2_C(map_set_active, RID, p_map, bool, p_active, rid_to_rid, bool_to
bool FORWARD_1_C(map_is_active, RID, p_map, rid_to_rid);
+void NavigationServer2D::map_force_update(RID p_map) {
+ NavigationServer3D::get_singleton_mut()->map_force_update(p_map);
+}
+
void FORWARD_2_C(map_set_cell_size, RID, p_map, real_t, p_cell_size, rid_to_rid, real_to_real);
real_t FORWARD_1_C(map_get_cell_size, RID, p_map, rid_to_rid);
@@ -248,6 +259,7 @@ void FORWARD_2_C(region_set_enter_cost, RID, p_region, real_t, p_enter_cost, rid
real_t FORWARD_1_C(region_get_enter_cost, RID, p_region, rid_to_rid);
void FORWARD_2_C(region_set_travel_cost, RID, p_region, real_t, p_travel_cost, rid_to_rid, real_to_real);
real_t FORWARD_1_C(region_get_travel_cost, RID, p_region, rid_to_rid);
+bool FORWARD_2_C(region_owns_point, RID, p_region, const Vector2 &, p_point, rid_to_rid, v2_to_v3);
void FORWARD_2_C(region_set_map, RID, p_region, RID, p_map, rid_to_rid, rid_to_rid);
void FORWARD_2_C(region_set_navigation_layers, RID, p_region, uint32_t, p_navigation_layers, rid_to_rid, uint32_to_uint32);
diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h
index 30f553d10b..1b15c7ff37 100644
--- a/servers/navigation_server_2d.h
+++ b/servers/navigation_server_2d.h
@@ -53,6 +53,8 @@ public:
/// MUST be used in single thread!
static NavigationServer2D *get_singleton_mut() { return singleton; }
+ virtual Array get_maps() const;
+
/// Create a new map.
virtual RID map_create() const;
@@ -83,6 +85,8 @@ public:
virtual Array map_get_regions(RID p_map) const;
virtual Array map_get_agents(RID p_map) const;
+ virtual void map_force_update(RID p_map);
+
/// Creates a new region.
virtual RID region_create() const;
@@ -94,6 +98,8 @@ public:
virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) const;
virtual real_t region_get_travel_cost(RID p_region) const;
+ virtual bool region_owns_point(RID p_region, const Vector2 &p_point) const;
+
/// Set the map of this region.
virtual void region_set_map(RID p_region, RID p_map) const;
virtual RID region_get_map(RID p_region) const;
diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp
index 60bbcec8d4..6c48c4a8de 100644
--- a/servers/navigation_server_3d.cpp
+++ b/servers/navigation_server_3d.cpp
@@ -33,6 +33,8 @@
NavigationServer3D *NavigationServer3D::singleton = nullptr;
void NavigationServer3D::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_maps"), &NavigationServer3D::get_maps);
+
ClassDB::bind_method(D_METHOD("map_create"), &NavigationServer3D::map_create);
ClassDB::bind_method(D_METHOD("map_set_active", "map", "active"), &NavigationServer3D::map_set_active);
ClassDB::bind_method(D_METHOD("map_is_active", "nap"), &NavigationServer3D::map_is_active);
@@ -51,11 +53,14 @@ void NavigationServer3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("map_get_regions", "map"), &NavigationServer3D::map_get_regions);
ClassDB::bind_method(D_METHOD("map_get_agents", "map"), &NavigationServer3D::map_get_agents);
+ ClassDB::bind_method(D_METHOD("map_force_update", "map"), &NavigationServer3D::map_force_update);
+
ClassDB::bind_method(D_METHOD("region_create"), &NavigationServer3D::region_create);
ClassDB::bind_method(D_METHOD("region_set_enter_cost", "region", "enter_cost"), &NavigationServer3D::region_set_enter_cost);
ClassDB::bind_method(D_METHOD("region_get_enter_cost", "region"), &NavigationServer3D::region_get_enter_cost);
ClassDB::bind_method(D_METHOD("region_set_travel_cost", "region", "travel_cost"), &NavigationServer3D::region_set_travel_cost);
ClassDB::bind_method(D_METHOD("region_get_travel_cost", "region"), &NavigationServer3D::region_get_travel_cost);
+ ClassDB::bind_method(D_METHOD("region_owns_point", "region", "point"), &NavigationServer3D::region_owns_point);
ClassDB::bind_method(D_METHOD("region_set_map", "region", "map"), &NavigationServer3D::region_set_map);
ClassDB::bind_method(D_METHOD("region_get_map", "region"), &NavigationServer3D::region_get_map);
ClassDB::bind_method(D_METHOD("region_set_navigation_layers", "region", "navigation_layers"), &NavigationServer3D::region_set_navigation_layers);
diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h
index 9c04d68622..cf91596604 100644
--- a/servers/navigation_server_3d.h
+++ b/servers/navigation_server_3d.h
@@ -56,6 +56,8 @@ public:
/// MUST be used in single thread!
static NavigationServer3D *get_singleton_mut();
+ virtual Array get_maps() const = 0;
+
/// Create a new map.
virtual RID map_create() const = 0;
@@ -94,6 +96,8 @@ public:
virtual Array map_get_regions(RID p_map) const = 0;
virtual Array map_get_agents(RID p_map) const = 0;
+ virtual void map_force_update(RID p_map) = 0;
+
/// Creates a new region.
virtual RID region_create() const = 0;
@@ -105,6 +109,8 @@ public:
virtual void region_set_travel_cost(RID p_region, real_t p_travel_cost) const = 0;
virtual real_t region_get_travel_cost(RID p_region) const = 0;
+ virtual bool region_owns_point(RID p_region, const Vector3 &p_point) const = 0;
+
/// Set the map of this region.
virtual void region_set_map(RID p_region, RID p_map) const = 0;
virtual RID region_get_map(RID p_region) const = 0;
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 8bbe987cb7..db473f6296 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -57,6 +57,9 @@
#include "camera_server.h"
#include "debugger/servers_debugger.h"
#include "display_server.h"
+#include "movie_writer/movie_writer.h"
+#include "movie_writer/movie_writer_mjpeg.h"
+#include "movie_writer/movie_writer_pngwav.h"
#include "navigation_server_2d.h"
#include "navigation_server_3d.h"
#include "physics_2d/godot_physics_server_2d.h"
@@ -107,6 +110,9 @@ static bool has_server_feature_callback(const String &p_feature) {
return false;
}
+static MovieWriterMJPEG *writer_mjpeg = nullptr;
+static MovieWriterPNGWAV *writer_pngwav = nullptr;
+
void register_server_types() {
shader_types = memnew(ShaderTypes);
@@ -239,6 +245,8 @@ void register_server_types() {
GDREGISTER_CLASS(PhysicsTestMotionParameters3D);
GDREGISTER_CLASS(PhysicsTestMotionResult3D);
+ GDREGISTER_VIRTUAL_CLASS(MovieWriter);
+
ServersDebugger::initialize();
// Physics 2D
@@ -254,11 +262,19 @@ void register_server_types() {
PhysicsServer3DManager::register_server("GodotPhysics3D", &_createGodotPhysics3DCallback);
PhysicsServer3DManager::set_default_server("GodotPhysics3D");
+
+ writer_mjpeg = memnew(MovieWriterMJPEG);
+ MovieWriter::add_writer(writer_mjpeg);
+
+ writer_pngwav = memnew(MovieWriterPNGWAV);
+ MovieWriter::add_writer(writer_pngwav);
}
void unregister_server_types() {
ServersDebugger::deinitialize();
memdelete(shader_types);
+ memdelete(writer_mjpeg);
+ memdelete(writer_pngwav);
}
void register_server_singletons() {
diff --git a/servers/rendering/SCsub b/servers/rendering/SCsub
index 06d1d28b08..cf26ca029d 100644
--- a/servers/rendering/SCsub
+++ b/servers/rendering/SCsub
@@ -4,5 +4,6 @@ Import("env")
env.add_source_files(env.servers_sources, "*.cpp")
+SConscript("dummy/SCsub")
SConscript("renderer_rd/SCsub")
SConscript("storage/SCsub")
diff --git a/servers/rendering/dummy/SCsub b/servers/rendering/dummy/SCsub
new file mode 100644
index 0000000000..aa688af6cd
--- /dev/null
+++ b/servers/rendering/dummy/SCsub
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+Import("env")
+
+env.add_source_files(env.servers_sources, "*.cpp")
+
+SConscript("storage/SCsub")
diff --git a/servers/rendering/dummy/environment/fog.h b/servers/rendering/dummy/environment/fog.h
new file mode 100644
index 0000000000..8a2be90507
--- /dev/null
+++ b/servers/rendering/dummy/environment/fog.h
@@ -0,0 +1,55 @@
+/*************************************************************************/
+/* fog.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 FOG_DUMMY_H
+#define FOG_DUMMY_H
+
+#include "servers/rendering/environment/renderer_fog.h"
+
+namespace RendererDummy {
+
+class Fog : public RendererFog {
+public:
+ /* FOG VOLUMES */
+
+ virtual RID fog_volume_allocate() override { return RID(); }
+ virtual void fog_volume_initialize(RID p_rid) override {}
+ virtual void fog_free(RID p_rid) override {}
+
+ virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override {}
+ virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override {}
+ virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override {}
+ virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override { return AABB(); }
+ virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override { return RS::FOG_VOLUME_SHAPE_BOX; }
+};
+
+} // namespace RendererDummy
+
+#endif // !FOG_DUMMY_H
diff --git a/servers/rendering/dummy/environment/gi.h b/servers/rendering/dummy/environment/gi.h
new file mode 100644
index 0000000000..9c7647c2de
--- /dev/null
+++ b/servers/rendering/dummy/environment/gi.h
@@ -0,0 +1,82 @@
+/*************************************************************************/
+/* gi.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 GI_DUMMY_H
+#define GI_DUMMY_H
+
+#include "servers/rendering/environment/renderer_gi.h"
+
+namespace RendererDummy {
+
+class GI : public RendererGI {
+public:
+ /* VOXEL GI API */
+
+ virtual RID voxel_gi_allocate() override { return RID(); }
+ virtual void voxel_gi_free(RID p_rid) override {}
+ virtual void voxel_gi_initialize(RID p_rid) override {}
+ virtual void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {}
+
+ virtual AABB voxel_gi_get_bounds(RID p_voxel_gi) const override { return AABB(); }
+ virtual Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const override { return Vector3i(); }
+ virtual Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const override { return Vector<uint8_t>(); }
+ virtual Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const override { return Vector<uint8_t>(); }
+ virtual Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const override { return Vector<uint8_t>(); }
+
+ virtual Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const override { return Vector<int>(); }
+ virtual Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const override { return Transform3D(); }
+
+ virtual void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) override {}
+ virtual float voxel_gi_get_dynamic_range(RID p_voxel_gi) const override { return 0; }
+
+ virtual void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) override {}
+ virtual float voxel_gi_get_propagation(RID p_voxel_gi) const override { return 0; }
+
+ virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_range) override {}
+ virtual float voxel_gi_get_energy(RID p_voxel_gi) const override { return 0.0; }
+
+ virtual void voxel_gi_set_bias(RID p_voxel_gi, float p_range) override {}
+ virtual float voxel_gi_get_bias(RID p_voxel_gi) const override { return 0.0; }
+
+ virtual void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) override {}
+ virtual float voxel_gi_get_normal_bias(RID p_voxel_gi) const override { return 0.0; }
+
+ virtual void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) override {}
+ virtual bool voxel_gi_is_interior(RID p_voxel_gi) const override { return false; }
+
+ virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) override {}
+ virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override { return false; }
+
+ virtual uint32_t voxel_gi_get_version(RID p_voxel_gi) const override { return 0; }
+};
+
+} // namespace RendererDummy
+
+#endif // !GI_DUMMY_H
diff --git a/servers/rendering/dummy/rasterizer_dummy.h b/servers/rendering/dummy/rasterizer_dummy.h
index 5c6fcc8386..d867114384 100644
--- a/servers/rendering/dummy/rasterizer_dummy.h
+++ b/servers/rendering/dummy/rasterizer_dummy.h
@@ -34,14 +34,16 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "scene/resources/mesh.h"
+#include "servers/rendering/dummy/environment/fog.h"
+#include "servers/rendering/dummy/environment/gi.h"
#include "servers/rendering/dummy/rasterizer_canvas_dummy.h"
#include "servers/rendering/dummy/rasterizer_scene_dummy.h"
-#include "servers/rendering/dummy/rasterizer_storage_dummy.h"
#include "servers/rendering/dummy/storage/light_storage.h"
#include "servers/rendering/dummy/storage/material_storage.h"
#include "servers/rendering/dummy/storage/mesh_storage.h"
#include "servers/rendering/dummy/storage/particles_storage.h"
#include "servers/rendering/dummy/storage/texture_storage.h"
+#include "servers/rendering/dummy/storage/utilities.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering_server.h"
@@ -52,21 +54,25 @@ private:
protected:
RasterizerCanvasDummy canvas;
+ RendererDummy::Utilities utilities;
RendererDummy::LightStorage light_storage;
RendererDummy::MaterialStorage material_storage;
RendererDummy::MeshStorage mesh_storage;
RendererDummy::ParticlesStorage particles_storage;
RendererDummy::TextureStorage texture_storage;
- RasterizerStorageDummy storage;
+ RendererDummy::GI gi;
+ RendererDummy::Fog fog;
RasterizerSceneDummy scene;
public:
+ RendererUtilities *get_utilities() override { return &utilities; };
RendererLightStorage *get_light_storage() override { return &light_storage; };
RendererMaterialStorage *get_material_storage() override { return &material_storage; };
RendererMeshStorage *get_mesh_storage() override { return &mesh_storage; };
RendererParticlesStorage *get_particles_storage() override { return &particles_storage; };
RendererTextureStorage *get_texture_storage() override { return &texture_storage; };
- RendererStorage *get_storage() override { return &storage; }
+ RendererGI *get_gi() override { return &gi; };
+ RendererFog *get_fog() override { return &fog; };
RendererCanvasRender *get_canvas() override { return &canvas; }
RendererSceneRender *get_scene() override { return &scene; }
diff --git a/servers/rendering/dummy/rasterizer_storage_dummy.h b/servers/rendering/dummy/rasterizer_storage_dummy.h
deleted file mode 100644
index 596960786a..0000000000
--- a/servers/rendering/dummy/rasterizer_storage_dummy.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/*************************************************************************/
-/* rasterizer_storage_dummy.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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 RASTERIZER_STORAGE_DUMMY_H
-#define RASTERIZER_STORAGE_DUMMY_H
-
-#include "servers/rendering/renderer_storage.h"
-#include "storage/texture_storage.h"
-
-class RasterizerStorageDummy : public RendererStorage {
-public:
- void base_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
-
- /* VOXEL GI API */
-
- RID voxel_gi_allocate() override { return RID(); }
- void voxel_gi_initialize(RID p_rid) override {}
- void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override {}
-
- AABB voxel_gi_get_bounds(RID p_voxel_gi) const override { return AABB(); }
- Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const override { return Vector3i(); }
- Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const override { return Vector<uint8_t>(); }
- Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const override { return Vector<uint8_t>(); }
- Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const override { return Vector<uint8_t>(); }
-
- Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const override { return Vector<int>(); }
- Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const override { return Transform3D(); }
-
- void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) override {}
- float voxel_gi_get_dynamic_range(RID p_voxel_gi) const override { return 0; }
-
- void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) override {}
- float voxel_gi_get_propagation(RID p_voxel_gi) const override { return 0; }
-
- void voxel_gi_set_energy(RID p_voxel_gi, float p_range) override {}
- float voxel_gi_get_energy(RID p_voxel_gi) const override { return 0.0; }
-
- void voxel_gi_set_bias(RID p_voxel_gi, float p_range) override {}
- float voxel_gi_get_bias(RID p_voxel_gi) const override { return 0.0; }
-
- void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) override {}
- float voxel_gi_get_normal_bias(RID p_voxel_gi) const override { return 0.0; }
-
- void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) override {}
- bool voxel_gi_is_interior(RID p_voxel_gi) const override { return false; }
-
- void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) override {}
- bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override { return false; }
-
- void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) override {}
- float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const override { return 0; }
-
- uint32_t voxel_gi_get_version(RID p_voxel_gi) override { return 0; }
-
- /* OCCLUDER */
-
- void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) {}
-
- /* FOG VOLUMES */
-
- RID fog_volume_allocate() override { return RID(); }
- void fog_volume_initialize(RID p_rid) override {}
-
- void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override {}
- void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override {}
- void fog_volume_set_material(RID p_fog_volume, RID p_material) override {}
- AABB fog_volume_get_aabb(RID p_fog_volume) const override { return AABB(); }
- RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override { return RS::FOG_VOLUME_SHAPE_BOX; }
-
- /* VISIBILITY NOTIFIER */
- virtual RID visibility_notifier_allocate() override { return RID(); }
- virtual void visibility_notifier_initialize(RID p_notifier) override {}
- virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) override {}
- virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) override {}
-
- virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override { return AABB(); }
- virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override {}
-
- /* STORAGE */
-
- RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; }
- bool free(RID p_rid) override {
- if (RendererDummy::TextureStorage::get_singleton()->owns_texture(p_rid)) {
- RendererDummy::TextureStorage::get_singleton()->texture_free(p_rid);
- return true;
- }
- return false;
- }
-
- virtual void update_memory_info() override {}
- virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) override { return 0; }
-
- bool has_os_feature(const String &p_feature) const override {
- return p_feature == "rgtc" || p_feature == "bptc" || p_feature == "s3tc" || p_feature == "etc" || p_feature == "etc2";
- }
-
- void update_dirty_resources() override {}
-
- void set_debug_generate_wireframes(bool p_generate) override {}
-
- String get_video_adapter_name() const override { return String(); }
- String get_video_adapter_vendor() const override { return String(); }
- RenderingDevice::DeviceType get_video_adapter_type() const override { return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER; }
- String get_video_adapter_api_version() const override { return String(); }
-
- static RendererStorage *base_singleton;
-
- void capture_timestamps_begin() override {}
- void capture_timestamp(const String &p_name) override {}
- uint32_t get_captured_timestamps_count() const override { return 0; }
- uint64_t get_captured_timestamps_frame() const override { return 0; }
- uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override { return 0; }
- uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override { return 0; }
- String get_captured_timestamp_name(uint32_t p_index) const override { return String(); }
-
- RasterizerStorageDummy() {}
- ~RasterizerStorageDummy() {}
-};
-
-#endif // !RASTERIZER_STORAGE_DUMMY_H
diff --git a/servers/rendering/dummy/storage/SCsub b/servers/rendering/dummy/storage/SCsub
new file mode 100644
index 0000000000..86681f9c74
--- /dev/null
+++ b/servers/rendering/dummy/storage/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import("env")
+
+env.add_source_files(env.servers_sources, "*.cpp")
diff --git a/servers/rendering/dummy/storage/material_storage.h b/servers/rendering/dummy/storage/material_storage.h
index 8890be8ea9..d4809f81e3 100644
--- a/servers/rendering/dummy/storage/material_storage.h
+++ b/servers/rendering/dummy/storage/material_storage.h
@@ -32,6 +32,7 @@
#define MATERIAL_STORAGE_DUMMY_H
#include "servers/rendering/storage/material_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererDummy {
@@ -87,7 +88,7 @@ public:
virtual bool material_is_animated(RID p_material) override { return false; }
virtual bool material_casts_shadows(RID p_material) override { return false; }
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override {}
- virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override {}
+ virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override {}
};
} // namespace RendererDummy
diff --git a/servers/rendering/dummy/storage/mesh_storage.h b/servers/rendering/dummy/storage/mesh_storage.h
index dfbd265bba..78b19d721d 100644
--- a/servers/rendering/dummy/storage/mesh_storage.h
+++ b/servers/rendering/dummy/storage/mesh_storage.h
@@ -32,6 +32,7 @@
#define MESH_STORAGE_DUMMY_H
#include "servers/rendering/storage/mesh_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererDummy {
@@ -121,7 +122,11 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override {}
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override { return Transform2D(); }
- virtual void skeleton_update_dependency(RID p_base, RendererStorage::DependencyTracker *p_instance) override {}
+ virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
+
+ /* OCCLUDER */
+
+ void occluder_set_mesh(RID p_occluder, const PackedVector3Array &p_vertices, const PackedInt32Array &p_indices) {}
};
} // namespace RendererDummy
diff --git a/servers/rendering/dummy/storage/texture_storage.cpp b/servers/rendering/dummy/storage/texture_storage.cpp
new file mode 100644
index 0000000000..62e2a306a2
--- /dev/null
+++ b/servers/rendering/dummy/storage/texture_storage.cpp
@@ -0,0 +1,43 @@
+/*************************************************************************/
+/* texture_storage.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "texture_storage.h"
+
+using namespace RendererDummy;
+
+TextureStorage *TextureStorage::singleton = nullptr;
+
+TextureStorage::TextureStorage() {
+ singleton = this;
+}
+
+TextureStorage::~TextureStorage() {
+ singleton = nullptr;
+}
diff --git a/servers/rendering/dummy/storage/texture_storage.h b/servers/rendering/dummy/storage/texture_storage.h
index 11d827a6e3..fe10f6489c 100644
--- a/servers/rendering/dummy/storage/texture_storage.h
+++ b/servers/rendering/dummy/storage/texture_storage.h
@@ -38,6 +38,8 @@ namespace RendererDummy {
class TextureStorage : public RendererTextureStorage {
private:
+ static TextureStorage *singleton;
+
struct DummyTexture {
Ref<Image> image;
};
@@ -45,11 +47,12 @@ private:
public:
static TextureStorage *get_singleton() {
- // Here we cheat until we can retire RasterizerStorageDummy::free()
-
- return (TextureStorage *)RSG::texture_storage;
+ return singleton;
};
+ TextureStorage();
+ ~TextureStorage();
+
virtual bool can_create_resources_async() const override { return false; }
/* Canvas Texture API */
diff --git a/servers/rendering/dummy/storage/utilities.h b/servers/rendering/dummy/storage/utilities.h
new file mode 100644
index 0000000000..f090309e88
--- /dev/null
+++ b/servers/rendering/dummy/storage/utilities.h
@@ -0,0 +1,98 @@
+/*************************************************************************/
+/* utilities.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 UTILITIES_DUMMY_H
+#define UTILITIES_DUMMY_H
+
+#include "servers/rendering/storage/utilities.h"
+#include "texture_storage.h"
+
+namespace RendererDummy {
+
+class Utilities : public RendererUtilities {
+public:
+ /* INSTANCES */
+
+ virtual RS::InstanceType get_base_type(RID p_rid) const override { return RS::INSTANCE_NONE; }
+ virtual bool free(RID p_rid) override {
+ if (RendererDummy::TextureStorage::get_singleton()->owns_texture(p_rid)) {
+ RendererDummy::TextureStorage::get_singleton()->texture_free(p_rid);
+ return true;
+ }
+ return false;
+ }
+
+ /* DEPENDENCIES */
+
+ virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) override {}
+
+ /* VISIBILITY NOTIFIER */
+
+ virtual RID visibility_notifier_allocate() override { return RID(); }
+ virtual void visibility_notifier_initialize(RID p_notifier) override {}
+ virtual void visibility_notifier_free(RID p_notifier) override {}
+
+ virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) override {}
+ virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) override {}
+
+ virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override { return AABB(); }
+ virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override {}
+
+ /* TIMING */
+
+ virtual void capture_timestamps_begin() override {}
+ virtual void capture_timestamp(const String &p_name) override {}
+ virtual uint32_t get_captured_timestamps_count() const override { return 0; }
+ virtual uint64_t get_captured_timestamps_frame() const override { return 0; }
+ virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override { return 0; }
+ virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override { return 0; }
+ virtual String get_captured_timestamp_name(uint32_t p_index) const override { return String(); }
+
+ /* MISC */
+
+ virtual void update_dirty_resources() override {}
+ virtual void set_debug_generate_wireframes(bool p_generate) override {}
+
+ virtual bool has_os_feature(const String &p_feature) const override {
+ return p_feature == "rgtc" || p_feature == "bptc" || p_feature == "s3tc" || p_feature == "etc" || p_feature == "etc2";
+ }
+
+ virtual void update_memory_info() override {}
+
+ virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) override { return 0; }
+ virtual String get_video_adapter_name() const override { return String(); }
+ virtual String get_video_adapter_vendor() const override { return String(); }
+ virtual RenderingDevice::DeviceType get_video_adapter_type() const override { return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER; }
+ virtual String get_video_adapter_api_version() const override { return String(); }
+};
+
+} // namespace RendererDummy
+
+#endif // !UTILITIES_DUMMY_H
diff --git a/servers/rendering/environment/renderer_fog.h b/servers/rendering/environment/renderer_fog.h
new file mode 100644
index 0000000000..ac50da0fc0
--- /dev/null
+++ b/servers/rendering/environment/renderer_fog.h
@@ -0,0 +1,53 @@
+/*************************************************************************/
+/* renderer_fog.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 RENDERER_FOG_H
+#define RENDERER_FOG_H
+
+#include "servers/rendering_server.h"
+
+class RendererFog {
+public:
+ virtual ~RendererFog() {}
+
+ /* FOG VOLUMES */
+
+ virtual RID fog_volume_allocate() = 0;
+ virtual void fog_volume_initialize(RID p_rid) = 0;
+ virtual void fog_free(RID p_rid) = 0;
+
+ virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) = 0;
+ virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) = 0;
+ virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) = 0;
+ virtual AABB fog_volume_get_aabb(RID p_fog_volume) const = 0;
+ virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const = 0;
+};
+
+#endif // !RENDERER_FOG_H
diff --git a/servers/rendering/environment/renderer_gi.h b/servers/rendering/environment/renderer_gi.h
new file mode 100644
index 0000000000..4f93bb8675
--- /dev/null
+++ b/servers/rendering/environment/renderer_gi.h
@@ -0,0 +1,81 @@
+/*************************************************************************/
+/* renderer_gi.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 RENDERER_GI_H
+#define RENDERER_GI_H
+
+#include "servers/rendering_server.h"
+
+class RendererGI {
+public:
+ virtual ~RendererGI() {}
+
+ /* VOXEL GI API */
+
+ virtual RID voxel_gi_allocate() = 0;
+ virtual void voxel_gi_free(RID p_rid) = 0;
+ virtual void voxel_gi_initialize(RID p_rid) = 0;
+
+ virtual void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0;
+
+ virtual AABB voxel_gi_get_bounds(RID p_voxel_gi) const = 0;
+ virtual Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const = 0;
+ virtual Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const = 0;
+ virtual Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const = 0;
+ virtual Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const = 0;
+
+ virtual Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const = 0;
+ virtual Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const = 0;
+
+ virtual void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) = 0;
+ virtual float voxel_gi_get_dynamic_range(RID p_voxel_gi) const = 0;
+
+ virtual void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) = 0;
+ virtual float voxel_gi_get_propagation(RID p_voxel_gi) const = 0;
+
+ virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_energy) = 0;
+ virtual float voxel_gi_get_energy(RID p_voxel_gi) const = 0;
+
+ virtual void voxel_gi_set_bias(RID p_voxel_gi, float p_bias) = 0;
+ virtual float voxel_gi_get_bias(RID p_voxel_gi) const = 0;
+
+ virtual void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) = 0;
+ virtual float voxel_gi_get_normal_bias(RID p_voxel_gi) const = 0;
+
+ virtual void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) = 0;
+ virtual bool voxel_gi_is_interior(RID p_voxel_gi) const = 0;
+
+ virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) = 0;
+ virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const = 0;
+
+ virtual uint32_t voxel_gi_get_version(RID p_probe) const = 0;
+};
+
+#endif // !RENDERER_GI_H
diff --git a/servers/rendering/renderer_canvas_cull.cpp b/servers/rendering/renderer_canvas_cull.cpp
index bc1e8eb348..dea68ac61c 100644
--- a/servers/rendering/renderer_canvas_cull.cpp
+++ b/servers/rendering/renderer_canvas_cull.cpp
@@ -76,10 +76,11 @@ void RendererCanvasCull::_render_canvas_item_tree(RID p_to_render_target, Canvas
}
}
-void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2D p_transform, RendererCanvasCull::Item *p_material_owner, RendererCanvasCull::Item **r_items, int &r_index) {
+void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2D p_transform, RendererCanvasCull::Item *p_material_owner, RendererCanvasCull::Item **r_items, int &r_index, int p_z) {
int child_item_count = p_canvas_item->child_items.size();
RendererCanvasCull::Item **child_items = p_canvas_item->child_items.ptrw();
for (int i = 0; i < child_item_count; i++) {
+ int abs_z = 0;
if (child_items[i]->visible) {
if (r_items) {
r_items[r_index] = child_items[i];
@@ -87,12 +88,20 @@ void _collect_ysort_children(RendererCanvasCull::Item *p_canvas_item, Transform2
child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.columns[2]);
child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : nullptr;
child_items[i]->ysort_index = r_index;
+ child_items[i]->ysort_parent_abs_z_index = p_z;
+
+ // Y sorted canvas items are flattened into r_items. Calculate their absolute z index to use when rendering r_items.
+ if (child_items[i]->z_relative) {
+ abs_z = CLAMP(p_z + child_items[i]->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
+ } else {
+ abs_z = child_items[i]->z_index;
+ }
}
r_index++;
if (child_items[i]->sort_y) {
- _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index);
+ _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index, abs_z);
}
}
}
@@ -277,6 +286,7 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
ci->final_clip_owner = p_canvas_clip;
}
+ int parent_z = p_z;
if (ci->z_relative) {
p_z = CLAMP(p_z + ci->z_index, RS::CANVAS_ITEM_Z_MIN, RS::CANVAS_ITEM_Z_MAX);
} else {
@@ -287,22 +297,23 @@ void RendererCanvasCull::_cull_canvas_item(Item *p_canvas_item, const Transform2
if (allow_y_sort) {
if (ci->ysort_children_count == -1) {
ci->ysort_children_count = 0;
- _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count);
+ _collect_ysort_children(ci, Transform2D(), p_material_owner, nullptr, ci->ysort_children_count, p_z);
}
child_item_count = ci->ysort_children_count + 1;
child_items = (Item **)alloca(child_item_count * sizeof(Item *));
+ ci->ysort_parent_abs_z_index = parent_z;
child_items[0] = ci;
int i = 1;
- _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i);
+ _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i, p_z);
ci->ysort_xform = ci->xform.affine_inverse();
SortArray<Item *, ItemPtrSort> sorter;
sorter.sort(child_items, child_item_count);
for (i = 0; i < child_item_count; i++) {
- _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false);
+ _cull_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, child_items[i]->ysort_parent_abs_z_index, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner, false);
}
} else {
RendererCanvasRender::Item *canvas_group_from = nullptr;
diff --git a/servers/rendering/renderer_canvas_cull.h b/servers/rendering/renderer_canvas_cull.h
index 963cca7630..48d0598c9f 100644
--- a/servers/rendering/renderer_canvas_cull.h
+++ b/servers/rendering/renderer_canvas_cull.h
@@ -53,6 +53,7 @@ public:
Transform2D ysort_xform;
Vector2 ysort_pos;
int ysort_index;
+ int ysort_parent_abs_z_index; // Absolute Z index of parent. Only populated and used when y-sorting.
Vector<Item *> child_items;
@@ -84,6 +85,7 @@ public:
ysort_xform = Transform2D();
ysort_pos = Vector2();
ysort_index = 0;
+ ysort_parent_abs_z_index = 0;
}
};
diff --git a/servers/rendering/renderer_canvas_render.cpp b/servers/rendering/renderer_canvas_render.cpp
index 163a24247e..f93fdd500a 100644
--- a/servers/rendering/renderer_canvas_render.cpp
+++ b/servers/rendering/renderer_canvas_render.cpp
@@ -128,3 +128,9 @@ const Rect2 &RendererCanvasRender::Item::get_rect() const {
rect_dirty = false;
return rect;
}
+
+RendererCanvasRender::Item::CommandMesh::~CommandMesh() {
+ if (mesh_instance.is_valid()) {
+ RSG::mesh_storage->mesh_free(mesh_instance);
+ }
+}
diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h
index 1724a99b20..52b2f82089 100644
--- a/servers/rendering/renderer_canvas_render.h
+++ b/servers/rendering/renderer_canvas_render.h
@@ -31,7 +31,7 @@
#ifndef RENDERINGSERVERCANVASRENDER_H
#define RENDERINGSERVERCANVASRENDER_H
-#include "servers/rendering/renderer_storage.h"
+#include "servers/rendering_server.h"
class RendererCanvasRender {
public:
@@ -257,11 +257,7 @@ public:
RID texture;
CommandMesh() { type = TYPE_MESH; }
- ~CommandMesh() {
- if (mesh_instance.is_valid()) {
- RendererStorage::base_singleton->free(mesh_instance);
- }
- }
+ ~CommandMesh();
};
struct CommandMultiMesh : public Command {
diff --git a/servers/rendering/renderer_compositor.h b/servers/rendering/renderer_compositor.h
index df3df1077a..a67eb25736 100644
--- a/servers/rendering/renderer_compositor.h
+++ b/servers/rendering/renderer_compositor.h
@@ -31,14 +31,16 @@
#ifndef RENDERING_SERVER_COMPOSITOR_H
#define RENDERING_SERVER_COMPOSITOR_H
+#include "servers/rendering/environment/renderer_fog.h"
+#include "servers/rendering/environment/renderer_gi.h"
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_scene.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/storage/light_storage.h"
#include "servers/rendering/storage/material_storage.h"
#include "servers/rendering/storage/mesh_storage.h"
#include "servers/rendering/storage/particles_storage.h"
#include "servers/rendering/storage/texture_storage.h"
+#include "servers/rendering/storage/utilities.h"
#include "servers/rendering_server.h"
class RendererSceneRender;
@@ -76,12 +78,14 @@ protected:
public:
static RendererCompositor *create();
+ virtual RendererUtilities *get_utilities() = 0;
virtual RendererLightStorage *get_light_storage() = 0;
virtual RendererMaterialStorage *get_material_storage() = 0;
virtual RendererMeshStorage *get_mesh_storage() = 0;
virtual RendererParticlesStorage *get_particles_storage() = 0;
virtual RendererTextureStorage *get_texture_storage() = 0;
- virtual RendererStorage *get_storage() = 0;
+ virtual RendererGI *get_gi() = 0;
+ virtual RendererFog *get_fog() = 0;
virtual RendererCanvasRender *get_canvas() = 0;
virtual RendererSceneRender *get_scene() = 0;
diff --git a/servers/rendering/renderer_rd/SCsub b/servers/rendering/renderer_rd/SCsub
index 774a6b7951..10b83dca11 100644
--- a/servers/rendering/renderer_rd/SCsub
+++ b/servers/rendering/renderer_rd/SCsub
@@ -5,6 +5,7 @@ Import("env")
env.add_source_files(env.servers_sources, "*.cpp")
SConscript("effects/SCsub")
+SConscript("environment/SCsub")
SConscript("forward_clustered/SCsub")
SConscript("forward_mobile/SCsub")
SConscript("shaders/SCsub")
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
index 0b36fe3964..228933d618 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp
@@ -413,7 +413,7 @@ void ClusterBuilderRD::bake_cluster() {
StateUniform state;
- RendererStorageRD::store_camera(adjusted_projection, state.projection);
+ RendererRD::MaterialStorage::store_camera(adjusted_projection, state.projection);
state.inv_z_far = 1.0 / z_far;
state.screen_to_clusters_shift = get_shift_from_power_of_2(cluster_size);
state.screen_to_clusters_shift -= divisor; //screen is smaller, shift one less
diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h
index e82193ea6a..74ca530ff6 100644
--- a/servers/rendering/renderer_rd/cluster_builder_rd.h
+++ b/servers/rendering/renderer_rd/cluster_builder_rd.h
@@ -31,10 +31,10 @@
#ifndef CLUSTER_BUILDER_RD_H
#define CLUSTER_BUILDER_RD_H
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/cluster_debug.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/cluster_render.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/cluster_store.glsl.gen.h"
+#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
class ClusterBuilderSharedDataRD {
friend class ClusterBuilderRD;
@@ -261,7 +261,7 @@ public:
e.type = ELEMENT_TYPE_OMNI_LIGHT;
e.original_index = cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT];
- RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv);
+ RendererRD::MaterialStorage::store_transform_transposed_3x4(xform, e.transform_inv);
cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT]++;
@@ -309,7 +309,7 @@ public:
e.type = ELEMENT_TYPE_SPOT_LIGHT;
e.original_index = cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]; //use omni since they share index
- RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv);
+ RendererRD::MaterialStorage::store_transform_transposed_3x4(xform, e.transform_inv);
cluster_count_by_type[ELEMENT_TYPE_SPOT_LIGHT]++;
}
@@ -356,7 +356,7 @@ public:
e.type = (p_box_type == BOX_TYPE_DECAL) ? ELEMENT_TYPE_DECAL : ELEMENT_TYPE_REFLECTION_PROBE;
e.original_index = cluster_count_by_type[e.type];
- RendererStorageRD::store_transform_transposed_3x4(xform, e.transform_inv);
+ RendererRD::MaterialStorage::store_transform_transposed_3x4(xform, e.transform_inv);
cluster_count_by_type[e.type]++;
render_element_count++;
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.cpp b/servers/rendering/renderer_rd/effects/copy_effects.cpp
index 6b786fdf16..c30e8ed58f 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.cpp
+++ b/servers/rendering/renderer_rd/effects/copy_effects.cpp
@@ -29,9 +29,11 @@
/*************************************************************************/
#include "copy_effects.h"
+#include "core/config/project_settings.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"
+#include "thirdparty/misc/cubemap_coeffs.h"
using namespace RendererRD;
@@ -123,16 +125,157 @@ CopyEffects::CopyEffects(bool p_prefer_raster_effects) {
}
}
}
+
+ {
+ // Initialize copier
+ Vector<String> copy_modes;
+ copy_modes.push_back("\n");
+
+ cube_to_dp.shader.initialize(copy_modes);
+
+ cube_to_dp.shader_version = cube_to_dp.shader.version_create();
+ RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);
+ RD::PipelineDepthStencilState dss;
+ dss.enable_depth_test = true;
+ dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS;
+ dss.enable_depth_write = true;
+ cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0);
+ }
+
+ {
+ //Initialize cubemap downsampler
+ Vector<String> cubemap_downsampler_modes;
+ cubemap_downsampler_modes.push_back("");
+
+ if (prefer_raster_effects) {
+ cubemap_downsampler.raster_shader.initialize(cubemap_downsampler_modes);
+
+ cubemap_downsampler.shader_version = cubemap_downsampler.raster_shader.version_create();
+
+ cubemap_downsampler.raster_pipeline.setup(cubemap_downsampler.raster_shader.version_get_shader(cubemap_downsampler.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ } else {
+ cubemap_downsampler.compute_shader.initialize(cubemap_downsampler_modes);
+
+ cubemap_downsampler.shader_version = cubemap_downsampler.compute_shader.version_create();
+
+ cubemap_downsampler.compute_pipeline = RD::get_singleton()->compute_pipeline_create(cubemap_downsampler.compute_shader.version_get_shader(cubemap_downsampler.shader_version, 0));
+ cubemap_downsampler.raster_pipeline.clear();
+ }
+ }
+
+ {
+ // Initialize cubemap filter
+ filter.use_high_quality = GLOBAL_GET("rendering/reflections/sky_reflections/fast_filter_high_quality");
+
+ Vector<String> cubemap_filter_modes;
+ cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n");
+ cubemap_filter_modes.push_back("\n#define USE_LOW_QUALITY\n");
+ cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n#define USE_TEXTURE_ARRAY\n");
+ cubemap_filter_modes.push_back("\n#define USE_LOW_QUALITY\n#define USE_TEXTURE_ARRAY\n");
+
+ if (filter.use_high_quality) {
+ filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(high_quality_coeffs));
+ RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0]);
+ } else {
+ filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(low_quality_coeffs));
+ RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0]);
+ }
+
+ if (prefer_raster_effects) {
+ filter.raster_shader.initialize(cubemap_filter_modes);
+
+ // array variants are not supported in raster
+ filter.raster_shader.set_variant_enabled(FILTER_MODE_HIGH_QUALITY_ARRAY, false);
+ filter.raster_shader.set_variant_enabled(FILTER_MODE_LOW_QUALITY_ARRAY, false);
+
+ filter.shader_version = filter.raster_shader.version_create();
+
+ for (int i = 0; i < FILTER_MODE_MAX; i++) {
+ if (filter.raster_shader.is_variant_enabled(i)) {
+ filter.raster_pipelines[i].setup(filter.raster_shader.version_get_shader(filter.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+ } else {
+ filter.raster_pipelines[i].clear();
+ }
+ }
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.append_id(filter.coefficient_buffer);
+ uniforms.push_back(u);
+ }
+ filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.raster_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1);
+ } else {
+ filter.compute_shader.initialize(cubemap_filter_modes);
+ filter.shader_version = filter.compute_shader.version_create();
+
+ for (int i = 0; i < FILTER_MODE_MAX; i++) {
+ filter.compute_pipelines[i] = RD::get_singleton()->compute_pipeline_create(filter.compute_shader.version_get_shader(filter.shader_version, i));
+ filter.raster_pipelines[i].clear();
+ }
+
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 0;
+ u.append_id(filter.coefficient_buffer);
+ uniforms.push_back(u);
+ }
+ filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1);
+ }
+ }
+
+ {
+ // Initialize roughness
+ Vector<String> cubemap_roughness_modes;
+ cubemap_roughness_modes.push_back("");
+
+ if (prefer_raster_effects) {
+ roughness.raster_shader.initialize(cubemap_roughness_modes);
+
+ roughness.shader_version = roughness.raster_shader.version_create();
+
+ roughness.raster_pipeline.setup(roughness.raster_shader.version_get_shader(roughness.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
+
+ } else {
+ roughness.compute_shader.initialize(cubemap_roughness_modes);
+
+ roughness.shader_version = roughness.compute_shader.version_create();
+
+ roughness.compute_pipeline = RD::get_singleton()->compute_pipeline_create(roughness.compute_shader.version_get_shader(roughness.shader_version, 0));
+ roughness.raster_pipeline.clear();
+ }
+ }
}
CopyEffects::~CopyEffects() {
if (prefer_raster_effects) {
blur_raster.shader.version_free(blur_raster.shader_version);
+ cubemap_downsampler.raster_shader.version_free(cubemap_downsampler.shader_version);
+ filter.raster_shader.version_free(filter.shader_version);
+ roughness.raster_shader.version_free(roughness.shader_version);
} else {
copy.shader.version_free(copy.shader_version);
+ cubemap_downsampler.compute_shader.version_free(cubemap_downsampler.shader_version);
+ filter.compute_shader.version_free(filter.shader_version);
+ roughness.compute_shader.version_free(roughness.shader_version);
+ }
+
+ RD::get_singleton()->free(filter.coefficient_buffer);
+
+ if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) {
+ RD::get_singleton()->free(filter.image_uniform_set);
+ }
+
+ if (RD::get_singleton()->uniform_set_is_valid(filter.uniform_set)) {
+ RD::get_singleton()->free(filter.uniform_set);
}
copy_to_fb.shader.version_free(copy_to_fb.shader_version);
+ cube_to_dp.shader.version_free(cube_to_dp.shader_version);
singleton = nullptr;
}
@@ -681,3 +824,262 @@ void CopyEffects::set_color(RID p_dest_texture, const Color &p_color, const Rect
RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_region.size.width, p_region.size.height, 1);
RD::get_singleton()->compute_list_end();
}
+
+void CopyEffects::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) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ CopyToDPPushConstant push_constant;
+ push_constant.screen_rect[0] = p_rect.position.x;
+ push_constant.screen_rect[1] = p_rect.position.y;
+ push_constant.screen_rect[2] = p_rect.size.width;
+ push_constant.screen_rect[3] = p_rect.size.height;
+ push_constant.z_far = p_z_far;
+ push_constant.z_near = p_z_near;
+ push_constant.texel_size[0] = 1.0f / p_dst_size.x;
+ push_constant.texel_size[1] = 1.0f / p_dst_size.y;
+ push_constant.texel_size[0] *= p_dp_flip ? -1.0f : 1.0f; // Encode dp flip as x size sign
+
+ // setup our uniforms
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, 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 = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_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_bind_index_array(draw_list, material_storage->get_quad_index_array());
+
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_TRANSFER);
+}
+
+void CopyEffects::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) {
+ ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap downsample with the mobile renderer.");
+
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ cubemap_downsampler.push_constant.face_size = p_size.x;
+ cubemap_downsampler.push_constant.face_id = 0; // we render all 6 sides to each layer in one call
+
+ // setup our uniforms
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_cubemap }));
+ RD::Uniform u_dest_cubemap(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_cubemap }));
+
+ RID shader = cubemap_downsampler.compute_shader.version_get_shader(cubemap_downsampler.shader_version, 0);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cubemap_downsampler.compute_pipeline);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_cubemap), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_cubemap), 1);
+
+ int x_groups = (p_size.x - 1) / 8 + 1;
+ int y_groups = (p_size.y - 1) / 8 + 1;
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &cubemap_downsampler.push_constant, sizeof(CubemapDownsamplerPushConstant));
+
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 6); // one z_group for each face
+
+ RD::get_singleton()->compute_list_end();
+}
+
+void CopyEffects::cubemap_downsample_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, const Size2i &p_size) {
+ ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap downsample with the clustered renderer.");
+ ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap downsample must process one side at a time.");
+
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ cubemap_downsampler.push_constant.face_size = p_size.x;
+ cubemap_downsampler.push_constant.face_id = p_face_id;
+
+ // setup our uniforms
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_cubemap }));
+
+ RID shader = cubemap_downsampler.raster_shader.version_get_shader(cubemap_downsampler.shader_version, 0);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cubemap_downsampler.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_cubemap), 0);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
+
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &cubemap_downsampler.push_constant, sizeof(CubemapDownsamplerPushConstant));
+
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+}
+
+void CopyEffects::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) {
+ ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap filter with the mobile renderer.");
+
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ Vector<RD::Uniform> uniforms;
+ for (int i = 0; i < p_dest_cubemap.size(); i++) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = i;
+ u.append_id(p_dest_cubemap[i]);
+ uniforms.push_back(u);
+ }
+ if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) {
+ RD::get_singleton()->free(filter.image_uniform_set);
+ }
+ filter.image_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, 0), 2);
+
+ // setup our uniforms
+ RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_cubemap }));
+
+ int mode = p_use_array ? FILTER_MODE_HIGH_QUALITY_ARRAY : FILTER_MODE_HIGH_QUALITY;
+ mode = filter.use_high_quality ? mode : mode + 1;
+
+ RID shader = filter.compute_shader.version_get_shader(filter.shader_version, mode);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, filter.compute_pipelines[mode]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_cubemap), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.uniform_set, 1);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.image_uniform_set, 2);
+
+ int x_groups = p_use_array ? 1792 : 342; // (128 * 128 * 7) / 64 : (128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) / 64
+
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, 6, 1); // one y_group for each face
+
+ RD::get_singleton()->compute_list_end();
+}
+
+void CopyEffects::cubemap_filter_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_mip_level) {
+ ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap filter with the clustered renderer.");
+ ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap filter must process one side at a time.");
+
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ // TODO implement!
+ CubemapFilterRasterPushConstant push_constant;
+ push_constant.mip_level = p_mip_level;
+ push_constant.face_id = p_face_id;
+
+ // setup our uniforms
+ RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::Uniform u_source_cubemap(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_cubemap }));
+
+ CubemapFilterMode mode = filter.use_high_quality ? FILTER_MODE_HIGH_QUALITY : FILTER_MODE_LOW_QUALITY;
+
+ RID shader = filter.raster_shader.version_get_shader(filter.shader_version, mode);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, filter.raster_pipelines[mode].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_cubemap), 0);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, filter.uniform_set, 1);
+ RD::get_singleton()->draw_list_bind_index_array(draw_list, material_storage->get_quad_index_array());
+
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CubemapFilterRasterPushConstant));
+
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+}
+
+void CopyEffects::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) {
+ ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap roughness with the mobile renderer.");
+
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant));
+
+ roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id;
+ roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in.
+ roughness.push_constant.sample_count = p_sample_count;
+ roughness.push_constant.use_direct_write = p_roughness == 0.0;
+ roughness.push_constant.face_size = p_size;
+
+ // setup our uniforms
+ RID default_mipmap_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::Uniform u_source_rd_texture(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_mipmap_sampler, p_source_rd_texture }));
+ RD::Uniform u_dest_texture(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_texture }));
+
+ RID shader = roughness.compute_shader.version_get_shader(roughness.shader_version, 0);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.compute_pipeline);
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_rd_texture), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_texture), 1);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
+
+ int x_groups = (p_size - 1) / 8 + 1;
+ int y_groups = (p_size - 1) / 8 + 1;
+
+ RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, p_face_id > 9 ? 6 : 1);
+
+ RD::get_singleton()->compute_list_end();
+}
+
+void CopyEffects::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) {
+ ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap roughness with the clustered renderer.");
+ ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap roughness must process one side at a time.");
+
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant));
+
+ roughness.push_constant.face_id = p_face_id;
+ roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in.
+ roughness.push_constant.sample_count = p_sample_count;
+ roughness.push_constant.use_direct_write = p_roughness == 0.0;
+ roughness.push_constant.face_size = p_size;
+
+ // setup our uniforms
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, 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 = roughness.raster_shader.version_get_shader(roughness.shader_version, 0);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, roughness.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_bind_index_array(draw_list, material_storage->get_quad_index_array());
+
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
+
+ RD::get_singleton()->draw_list_draw(draw_list, true);
+ RD::get_singleton()->draw_list_end();
+}
diff --git a/servers/rendering/renderer_rd/effects/copy_effects.h b/servers/rendering/renderer_rd/effects/copy_effects.h
index e522408d20..882b446964 100644
--- a/servers/rendering/renderer_rd/effects/copy_effects.h
+++ b/servers/rendering/renderer_rd/effects/copy_effects.h
@@ -35,6 +35,13 @@
#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/cubemap_downsampler.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/cubemap_filter.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/cubemap_filter_raster.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/cubemap_roughness.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_raster.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering_server.h"
@@ -189,6 +196,84 @@ private:
} copy_to_fb;
+ // Copy to DP
+
+ struct CopyToDPPushConstant {
+ float z_far;
+ float z_near;
+ float texel_size[2];
+ float screen_rect[4];
+ };
+
+ struct CopyToDP {
+ CubeToDpShaderRD shader;
+ RID shader_version;
+ PipelineCacheRD pipeline;
+ } cube_to_dp;
+
+ // Cubemap effects
+
+ struct CubemapDownsamplerPushConstant {
+ uint32_t face_size;
+ uint32_t face_id;
+ float pad[2];
+ };
+
+ struct CubemapDownsampler {
+ CubemapDownsamplerPushConstant push_constant;
+ CubemapDownsamplerShaderRD compute_shader;
+ CubemapDownsamplerRasterShaderRD raster_shader;
+ RID shader_version;
+ RID compute_pipeline;
+ PipelineCacheRD raster_pipeline;
+ } cubemap_downsampler;
+
+ enum CubemapFilterMode {
+ FILTER_MODE_HIGH_QUALITY,
+ FILTER_MODE_LOW_QUALITY,
+ FILTER_MODE_HIGH_QUALITY_ARRAY,
+ FILTER_MODE_LOW_QUALITY_ARRAY,
+ FILTER_MODE_MAX,
+ };
+
+ struct CubemapFilterRasterPushConstant {
+ uint32_t mip_level;
+ uint32_t face_id;
+ float pad[2];
+ };
+
+ struct CubemapFilter {
+ CubemapFilterShaderRD compute_shader;
+ CubemapFilterRasterShaderRD raster_shader;
+ RID shader_version;
+ RID compute_pipelines[FILTER_MODE_MAX];
+ PipelineCacheRD raster_pipelines[FILTER_MODE_MAX];
+
+ RID uniform_set;
+ RID image_uniform_set;
+ RID coefficient_buffer;
+ bool use_high_quality;
+
+ } filter;
+
+ struct CubemapRoughnessPushConstant {
+ uint32_t face_id;
+ uint32_t sample_count;
+ float roughness;
+ uint32_t use_direct_write;
+ float face_size;
+ float pad[3];
+ };
+
+ struct CubemapRoughness {
+ CubemapRoughnessPushConstant push_constant;
+ CubemapRoughnessShaderRD compute_shader;
+ CubemapRoughnessRasterShaderRD raster_shader;
+ RID shader_version;
+ RID compute_pipeline;
+ PipelineCacheRD raster_pipeline;
+ } roughness;
+
static CopyEffects *singleton;
public:
@@ -197,6 +282,8 @@ public:
CopyEffects(bool p_prefer_raster_effects);
~CopyEffects();
+ bool get_prefer_raster_effects() { return prefer_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);
void copy_cubemap_to_panorama(RID p_source_cube, RID p_dest_panorama, const Size2i &p_panorama_size, float p_lod, bool p_is_array);
void copy_depth_to_rect(RID p_source_rd_texture, RID p_dest_framebuffer, const Rect2i &p_rect, bool p_flip_y = false);
@@ -213,6 +300,15 @@ public:
void make_mipmap_raster(RID p_source_rd_texture, RID p_dest_framebuffer, 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 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 cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size);
+ void cubemap_downsample_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, const Size2i &p_size);
+ void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array);
+ void cubemap_filter_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_mip_level);
+
+ void cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
+ void cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
};
} // namespace RendererRD
diff --git a/servers/rendering/renderer_rd/effects/resolve.cpp b/servers/rendering/renderer_rd/effects/resolve.cpp
new file mode 100644
index 0000000000..6c49a2ebce
--- /dev/null
+++ b/servers/rendering/renderer_rd/effects/resolve.cpp
@@ -0,0 +1,130 @@
+/*************************************************************************/
+/* resolve.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "resolve.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;
+
+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.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);
+}
+
+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, uint32_t p_barrier) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ ResolvePushConstant push_constant;
+ push_constant.screen_size[0] = p_screen_size.x;
+ push_constant.screen_size[1] = p_screen_size.y;
+ push_constant.samples = p_samples;
+
+ // setup our uniforms
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::Uniform u_source_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_depth }));
+ RD::Uniform u_source_normal_roughness(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 1, Vector<RID>({ default_sampler, p_source_normal_roughness }));
+ RD::Uniform u_dest_depth(RD::UNIFORM_TYPE_IMAGE, 0, Vector<RID>({ p_dest_depth }));
+ RD::Uniform u_dest_normal_roughness(RD::UNIFORM_TYPE_IMAGE, 1, Vector<RID>({ p_dest_normal_roughness }));
+
+ ResolveMode mode = p_source_voxel_gi.is_valid() ? RESOLVE_MODE_GI_VOXEL_GI : RESOLVE_MODE_GI;
+ RID shader = resolve.shader.version_get_shader(resolve.shader_version, mode);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[mode]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_depth, u_source_normal_roughness), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_depth, u_dest_normal_roughness), 1);
+ if (p_source_voxel_gi.is_valid()) {
+ RD::Uniform u_source_voxel_gi(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_voxel_gi }));
+ RD::Uniform u_dest_voxel_gi(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_voxel_gi);
+
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 2, u_source_voxel_gi), 2);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 3, u_dest_voxel_gi), 3);
+ }
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1);
+
+ RD::get_singleton()->compute_list_end(p_barrier);
+}
+
+void Resolve::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) {
+ UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton();
+ ERR_FAIL_NULL(uniform_set_cache);
+ MaterialStorage *material_storage = MaterialStorage::get_singleton();
+ ERR_FAIL_NULL(material_storage);
+
+ ResolvePushConstant push_constant;
+ push_constant.screen_size[0] = p_screen_size.x;
+ push_constant.screen_size[1] = p_screen_size.y;
+ push_constant.samples = p_samples;
+
+ // setup our uniforms
+ RID default_sampler = material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
+
+ RD::Uniform u_source_depth(RD::UNIFORM_TYPE_SAMPLER_WITH_TEXTURE, 0, Vector<RID>({ default_sampler, p_source_depth }));
+ RD::Uniform u_dest_depth(RD::UNIFORM_TYPE_IMAGE, 0, p_dest_depth);
+
+ ResolveMode mode = RESOLVE_MODE_DEPTH;
+ RID shader = resolve.shader.version_get_shader(resolve.shader_version, mode);
+ ERR_FAIL_COND(shader.is_null());
+
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[mode]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 0, u_source_depth), 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set_cache->get_cache(shader, 1, u_dest_depth), 1);
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1);
+
+ RD::get_singleton()->compute_list_end(p_barrier);
+}
diff --git a/servers/rendering/renderer_rd/effects/resolve.h b/servers/rendering/renderer_rd/effects/resolve.h
new file mode 100644
index 0000000000..d4b24a610f
--- /dev/null
+++ b/servers/rendering/renderer_rd/effects/resolve.h
@@ -0,0 +1,74 @@
+/*************************************************************************/
+/* resolve.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 RESOLVE_RD_H
+#define RESOLVE_RD_H
+
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
+#include "servers/rendering/renderer_rd/shaders/effects/resolve.glsl.gen.h"
+#include "servers/rendering/renderer_scene_render.h"
+
+#include "servers/rendering_server.h"
+
+namespace RendererRD {
+
+class Resolve {
+private:
+ struct ResolvePushConstant {
+ int32_t screen_size[2];
+ int32_t samples;
+ uint32_t pad;
+ };
+
+ enum ResolveMode {
+ RESOLVE_MODE_GI,
+ RESOLVE_MODE_GI_VOXEL_GI,
+ RESOLVE_MODE_DEPTH,
+ RESOLVE_MODE_MAX
+ };
+
+ struct ResolveShader {
+ ResolvePushConstant push_constant;
+ ResolveShaderRD shader;
+ RID shader_version;
+ RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels
+ } resolve;
+
+public:
+ Resolve();
+ ~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, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+ void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
+};
+
+} // namespace RendererRD
+
+#endif // !RESOLVE_RD_H
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index bf97c6fbe9..d45ddbc392 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -86,7 +86,7 @@ RID EffectsRD::_get_uniform_set_from_texture(RID p_texture, bool p_use_mipmaps)
u.append_id(p_texture);
uniforms.push_back(u);
// anything with the same configuration (one texture in binding 0 for set 0), is good
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0), 0);
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, specular_merge.shader.version_get_shader(specular_merge.shader_version, 0), 0);
texture_to_uniform_set_cache[p_texture] = uniform_set;
@@ -473,28 +473,6 @@ void EffectsRD::merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_bas
RD::get_singleton()->draw_list_end();
}
-void EffectsRD::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) {
- CopyToDPPushConstant push_constant;
- push_constant.screen_rect[0] = p_rect.position.x;
- push_constant.screen_rect[1] = p_rect.position.y;
- push_constant.screen_rect[2] = p_rect.size.width;
- push_constant.screen_rect[3] = p_rect.size.height;
- push_constant.z_far = p_z_far;
- push_constant.z_near = p_z_near;
- push_constant.texel_size[0] = 1.0f / p_dst_size.x;
- push_constant.texel_size[1] = 1.0f / p_dst_size.y;
- push_constant.texel_size[0] *= p_dp_flip ? -1.0f : 1.0f; // Encode dp flip as x size sign
-
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dst_framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cube_to_dp.pipeline.get_render_pipeline(RD::INVALID_ID, RD::get_singleton()->framebuffer_get_format(p_dst_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
-
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CopyToDPPushConstant));
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end(RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_TRANSFER);
-}
-
void EffectsRD::luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set) {
ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute version of luminance reduction with the mobile renderer.");
@@ -1253,189 +1231,6 @@ void EffectsRD::roughness_limit(RID p_source_normal, RID p_roughness, const Size
RD::get_singleton()->compute_list_end();
}
-void EffectsRD::cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) {
- ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap roughness with the mobile renderer.");
-
- memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant));
-
- roughness.push_constant.face_id = p_face_id > 9 ? 0 : p_face_id;
- roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in.
- roughness.push_constant.sample_count = p_sample_count;
- roughness.push_constant.use_direct_write = p_roughness == 0.0;
- roughness.push_constant.face_size = p_size;
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, roughness.compute_pipeline);
-
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_rd_texture, true), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_texture), 1);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
-
- int x_groups = (p_size - 1) / 8 + 1;
- int y_groups = (p_size - 1) / 8 + 1;
-
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, p_face_id > 9 ? 6 : 1);
-
- RD::get_singleton()->compute_list_end();
-}
-
-void EffectsRD::cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size) {
- ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap roughness with the clustered renderer.");
- ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap roughness must process one side at a time.");
-
- memset(&roughness.push_constant, 0, sizeof(CubemapRoughnessPushConstant));
-
- roughness.push_constant.face_id = p_face_id;
- roughness.push_constant.roughness = p_roughness * p_roughness; // Shader expects roughness, not perceptual roughness, so multiply before passing in.
- roughness.push_constant.sample_count = p_sample_count;
- roughness.push_constant.use_direct_write = p_roughness == 0.0;
- roughness.push_constant.face_size = p_size;
-
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, roughness.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, _get_uniform_set_from_texture(p_source_rd_texture), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
-
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &roughness.push_constant, sizeof(CubemapRoughnessPushConstant));
-
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
-}
-
-void EffectsRD::cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size) {
- ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap downsample with the mobile renderer.");
-
- cubemap_downsampler.push_constant.face_size = p_size.x;
- cubemap_downsampler.push_constant.face_id = 0; // we render all 6 sides to each layer in one call
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, cubemap_downsampler.compute_pipeline);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cubemap), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_cubemap), 1);
-
- int x_groups = (p_size.x - 1) / 8 + 1;
- int y_groups = (p_size.y - 1) / 8 + 1;
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &cubemap_downsampler.push_constant, sizeof(CubemapDownsamplerPushConstant));
-
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, y_groups, 6); // one z_group for each face
-
- RD::get_singleton()->compute_list_end();
-}
-
-void EffectsRD::cubemap_downsample_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, const Size2i &p_size) {
- ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap downsample with the clustered renderer.");
- ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap downsample must process one side at a time.");
-
- cubemap_downsampler.push_constant.face_size = p_size.x;
- cubemap_downsampler.push_constant.face_id = p_face_id;
-
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, cubemap_downsampler.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, _get_uniform_set_from_texture(p_source_cubemap), 0);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
-
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &cubemap_downsampler.push_constant, sizeof(CubemapDownsamplerPushConstant));
-
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
-}
-
-void EffectsRD::cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array) {
- ERR_FAIL_COND_MSG(prefer_raster_effects, "Can't use compute based cubemap filter with the mobile renderer.");
-
- Vector<RD::Uniform> uniforms;
- for (int i = 0; i < p_dest_cubemap.size(); i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = i;
- u.append_id(p_dest_cubemap[i]);
- uniforms.push_back(u);
- }
- if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) {
- RD::get_singleton()->free(filter.image_uniform_set);
- }
- filter.image_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, 0), 2);
-
- int pipeline = p_use_array ? FILTER_MODE_HIGH_QUALITY_ARRAY : FILTER_MODE_HIGH_QUALITY;
- pipeline = filter.use_high_quality ? pipeline : pipeline + 1;
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, filter.compute_pipelines[pipeline]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_cubemap, true), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.uniform_set, 1);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, filter.image_uniform_set, 2);
-
- int x_groups = p_use_array ? 1792 : 342; // (128 * 128 * 7) / 64 : (128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) / 64
-
- RD::get_singleton()->compute_list_dispatch(compute_list, x_groups, 6, 1); // one y_group for each face
-
- RD::get_singleton()->compute_list_end();
-}
-
-void EffectsRD::cubemap_filter_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_mip_level) {
- ERR_FAIL_COND_MSG(!prefer_raster_effects, "Can't use raster based cubemap filter with the clustered renderer.");
- ERR_FAIL_COND_MSG(p_face_id >= 6, "Raster implementation of cubemap filter must process one side at a time.");
-
- // TODO implement!
- CubemapFilterRasterPushConstant push_constant;
- push_constant.mip_level = p_mip_level;
- push_constant.face_id = p_face_id;
-
- CubemapFilterMode mode = filter.use_high_quality ? FILTER_MODE_HIGH_QUALITY : FILTER_MODE_LOW_QUALITY;
-
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_dest_framebuffer, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
- RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, filter.raster_pipelines[mode].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, _get_uniform_set_from_texture(p_source_cubemap), 0);
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, filter.uniform_set, 1);
- RD::get_singleton()->draw_list_bind_index_array(draw_list, index_array);
-
- RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(CubemapFilterRasterPushConstant));
-
- RD::get_singleton()->draw_list_draw(draw_list, true);
- RD::get_singleton()->draw_list_end();
-}
-
-void EffectsRD::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, uint32_t p_barrier) {
- ResolvePushConstant push_constant;
- push_constant.screen_size[0] = p_screen_size.x;
- push_constant.screen_size[1] = p_screen_size.y;
- push_constant.samples = p_samples;
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[p_source_voxel_gi.is_valid() ? RESOLVE_MODE_GI_VOXEL_GI : RESOLVE_MODE_GI]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture_pair(p_source_depth, p_source_normal_roughness), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_image_pair(p_dest_depth, p_dest_normal_roughness), 1);
- if (p_source_voxel_gi.is_valid()) {
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_voxel_gi), 2);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_voxel_gi), 3);
- }
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1);
-
- RD::get_singleton()->compute_list_end(p_barrier);
-}
-
-void EffectsRD::resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier) {
- ResolvePushConstant push_constant;
- push_constant.screen_size[0] = p_screen_size.x;
- push_constant.screen_size[1] = p_screen_size.y;
- push_constant.samples = p_samples;
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, resolve.pipelines[RESOLVE_MODE_DEPTH]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_compute_uniform_set_from_texture(p_source_depth), 0);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, _get_uniform_set_from_image(p_dest_depth), 1);
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(ResolvePushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_screen_size.x, p_screen_size.y, 1);
-
- RD::get_singleton()->compute_list_end(p_barrier);
-}
-
void EffectsRD::sort_buffer(RID p_uniform_set, int p_size) {
Sort::PushConstant push_constant;
push_constant.total_elements = p_size;
@@ -1529,28 +1324,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
prefer_raster_effects = p_prefer_raster_effects;
- {
- // Initialize roughness
- Vector<String> cubemap_roughness_modes;
- cubemap_roughness_modes.push_back("");
-
- if (prefer_raster_effects) {
- roughness.raster_shader.initialize(cubemap_roughness_modes);
-
- roughness.shader_version = roughness.raster_shader.version_create();
-
- roughness.raster_pipeline.setup(roughness.raster_shader.version_get_shader(roughness.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
-
- } else {
- roughness.compute_shader.initialize(cubemap_roughness_modes);
-
- roughness.shader_version = roughness.compute_shader.version_create();
-
- roughness.compute_pipeline = RD::get_singleton()->compute_pipeline_create(roughness.compute_shader.version_get_shader(roughness.shader_version, 0));
- roughness.raster_pipeline.clear();
- }
- }
-
if (prefer_raster_effects) {
Vector<String> luminance_reduce_modes;
luminance_reduce_modes.push_back("\n#define FIRST_PASS\n"); // LUMINANCE_REDUCE_FRAGMENT_FIRST
@@ -1584,22 +1357,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
}
}
- {
- // Initialize copier
- Vector<String> copy_modes;
- copy_modes.push_back("\n");
-
- cube_to_dp.shader.initialize(copy_modes);
-
- cube_to_dp.shader_version = cube_to_dp.shader.version_create();
- RID shader = cube_to_dp.shader.version_get_shader(cube_to_dp.shader_version, 0);
- RD::PipelineDepthStencilState dss;
- dss.enable_depth_test = true;
- dss.depth_compare_operator = RD::COMPARE_OP_ALWAYS;
- dss.enable_depth_write = true;
- cube_to_dp.pipeline.setup(shader, RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), dss, RD::PipelineColorBlendState(), 0);
- }
-
if (!prefer_raster_effects) {
{
// Initialize depth buffer for screen space effects
@@ -1760,92 +1517,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
roughness_limiter.pipeline = RD::get_singleton()->compute_pipeline_create(roughness_limiter.shader.version_get_shader(roughness_limiter.shader_version, 0));
}
- {
- //Initialize cubemap downsampler
- Vector<String> cubemap_downsampler_modes;
- cubemap_downsampler_modes.push_back("");
-
- if (prefer_raster_effects) {
- cubemap_downsampler.raster_shader.initialize(cubemap_downsampler_modes);
-
- cubemap_downsampler.shader_version = cubemap_downsampler.raster_shader.version_create();
-
- cubemap_downsampler.raster_pipeline.setup(cubemap_downsampler.raster_shader.version_get_shader(cubemap_downsampler.shader_version, 0), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
- } else {
- cubemap_downsampler.compute_shader.initialize(cubemap_downsampler_modes);
-
- cubemap_downsampler.shader_version = cubemap_downsampler.compute_shader.version_create();
-
- cubemap_downsampler.compute_pipeline = RD::get_singleton()->compute_pipeline_create(cubemap_downsampler.compute_shader.version_get_shader(cubemap_downsampler.shader_version, 0));
- cubemap_downsampler.raster_pipeline.clear();
- }
- }
-
- {
- // Initialize cubemap filter
- filter.use_high_quality = GLOBAL_GET("rendering/reflections/sky_reflections/fast_filter_high_quality");
-
- Vector<String> cubemap_filter_modes;
- cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n");
- cubemap_filter_modes.push_back("\n#define USE_LOW_QUALITY\n");
- cubemap_filter_modes.push_back("\n#define USE_HIGH_QUALITY\n#define USE_TEXTURE_ARRAY\n");
- cubemap_filter_modes.push_back("\n#define USE_LOW_QUALITY\n#define USE_TEXTURE_ARRAY\n");
-
- if (filter.use_high_quality) {
- filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(high_quality_coeffs));
- RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(high_quality_coeffs), &high_quality_coeffs[0]);
- } else {
- filter.coefficient_buffer = RD::get_singleton()->storage_buffer_create(sizeof(low_quality_coeffs));
- RD::get_singleton()->buffer_update(filter.coefficient_buffer, 0, sizeof(low_quality_coeffs), &low_quality_coeffs[0]);
- }
-
- if (prefer_raster_effects) {
- filter.raster_shader.initialize(cubemap_filter_modes);
-
- // array variants are not supported in raster
- filter.raster_shader.set_variant_enabled(FILTER_MODE_HIGH_QUALITY_ARRAY, false);
- filter.raster_shader.set_variant_enabled(FILTER_MODE_LOW_QUALITY_ARRAY, false);
-
- filter.shader_version = filter.raster_shader.version_create();
-
- for (int i = 0; i < FILTER_MODE_MAX; i++) {
- if (filter.raster_shader.is_variant_enabled(i)) {
- filter.raster_pipelines[i].setup(filter.raster_shader.version_get_shader(filter.shader_version, i), RD::RENDER_PRIMITIVE_TRIANGLES, RD::PipelineRasterizationState(), RD::PipelineMultisampleState(), RD::PipelineDepthStencilState(), RD::PipelineColorBlendState::create_disabled(), 0);
- } else {
- filter.raster_pipelines[i].clear();
- }
- }
-
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 0;
- u.append_id(filter.coefficient_buffer);
- uniforms.push_back(u);
- }
- filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.raster_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1);
- } else {
- filter.compute_shader.initialize(cubemap_filter_modes);
- filter.shader_version = filter.compute_shader.version_create();
-
- for (int i = 0; i < FILTER_MODE_MAX; i++) {
- filter.compute_pipelines[i] = RD::get_singleton()->compute_pipeline_create(filter.compute_shader.version_get_shader(filter.shader_version, i));
- filter.raster_pipelines[i].clear();
- }
-
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 0;
- u.append_id(filter.coefficient_buffer);
- uniforms.push_back(u);
- }
- filter.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, filter.compute_shader.version_get_shader(filter.shader_version, filter.use_high_quality ? 0 : 1), 1);
- }
- }
-
if (!prefer_raster_effects) {
Vector<String> specular_modes;
specular_modes.push_back("\n#define MODE_MERGE\n");
@@ -2009,21 +1680,6 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
ssil.pipelines[i] = RD::get_singleton()->compute_pipeline_create(ssil.interleave_shader.version_get_shader(ssil.interleave_shader_version, i - SSIL_INTERLEAVE));
}
}
-
- {
- 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.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));
- }
- }
}
{
@@ -2083,34 +1739,18 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
}
EffectsRD::~EffectsRD() {
- if (RD::get_singleton()->uniform_set_is_valid(filter.image_uniform_set)) {
- RD::get_singleton()->free(filter.image_uniform_set);
- }
-
- if (RD::get_singleton()->uniform_set_is_valid(filter.uniform_set)) {
- RD::get_singleton()->free(filter.uniform_set);
- }
-
RD::get_singleton()->free(default_sampler);
RD::get_singleton()->free(default_mipmap_sampler);
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
- RD::get_singleton()->free(filter.coefficient_buffer);
FSR_upscale.shader.version_free(FSR_upscale.shader_version);
TAA_resolve.shader.version_free(TAA_resolve.shader_version);
if (prefer_raster_effects) {
luminance_reduce_raster.shader.version_free(luminance_reduce_raster.shader_version);
- roughness.raster_shader.version_free(roughness.shader_version);
- cubemap_downsampler.raster_shader.version_free(cubemap_downsampler.shader_version);
- filter.raster_shader.version_free(filter.shader_version);
} else {
luminance_reduce.shader.version_free(luminance_reduce.shader_version);
- roughness.compute_shader.version_free(roughness.shader_version);
- cubemap_downsampler.compute_shader.version_free(cubemap_downsampler.shader_version);
- filter.compute_shader.version_free(filter.shader_version);
}
if (!prefer_raster_effects) {
- resolve.shader.version_free(resolve.shader_version);
specular_merge.shader.version_free(specular_merge.shader_version);
ss_effects.downsample_shader.version_free(ss_effects.downsample_shader_version);
ssao.blur_shader.version_free(ssao.blur_shader_version);
@@ -2133,6 +1773,5 @@ EffectsRD::~EffectsRD() {
RD::get_singleton()->free(ssil.importance_map_load_counter);
RD::get_singleton()->free(ssil.projection_uniform_buffer);
}
- cube_to_dp.shader.version_free(cube_to_dp.shader_version);
sort.shader.version_free(sort.shader_version);
}
diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h
index 787873642e..76627a8d7d 100644
--- a/servers/rendering/renderer_rd/effects_rd.h
+++ b/servers/rendering/renderer_rd/effects_rd.h
@@ -33,17 +33,9 @@
#include "core/math/camera_matrix.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
-#include "servers/rendering/renderer_rd/shaders/cube_to_dp.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/cubemap_downsampler_raster.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/cubemap_filter.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/fsr_upscale.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/luminance_reduce.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/resolve.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/roughness_limiter.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/screen_space_reflection_filter.glsl.gen.h"
@@ -105,24 +97,6 @@ private:
RID pipeline;
} TAA_resolve;
- struct CubemapRoughnessPushConstant {
- uint32_t face_id;
- uint32_t sample_count;
- float roughness;
- uint32_t use_direct_write;
- float face_size;
- float pad[3];
- };
-
- struct CubemapRoughness {
- CubemapRoughnessPushConstant push_constant;
- CubemapRoughnessShaderRD compute_shader;
- CubemapRoughnessRasterShaderRD raster_shader;
- RID shader_version;
- RID compute_pipeline;
- PipelineCacheRD raster_pipeline;
- } roughness;
-
enum LuminanceReduceMode {
LUMINANCE_REDUCE_READ,
LUMINANCE_REDUCE,
@@ -168,19 +142,6 @@ private:
PipelineCacheRD pipelines[LUMINANCE_REDUCE_FRAGMENT_MAX];
} luminance_reduce_raster;
- struct CopyToDPPushConstant {
- float z_far;
- float z_near;
- float texel_size[2];
- float screen_rect[4];
- };
-
- struct CoptToDP {
- CubeToDpShaderRD shader;
- RID shader_version;
- PipelineCacheRD pipeline;
- } cube_to_dp;
-
struct SSEffectsDownsamplePushConstant {
float pixel_size[2];
float z_far;
@@ -420,49 +381,6 @@ private:
} roughness_limiter;
- struct CubemapDownsamplerPushConstant {
- uint32_t face_size;
- uint32_t face_id;
- float pad[2];
- };
-
- struct CubemapDownsampler {
- CubemapDownsamplerPushConstant push_constant;
- CubemapDownsamplerShaderRD compute_shader;
- CubemapDownsamplerRasterShaderRD raster_shader;
- RID shader_version;
- RID compute_pipeline;
- PipelineCacheRD raster_pipeline;
- } cubemap_downsampler;
-
- enum CubemapFilterMode {
- FILTER_MODE_HIGH_QUALITY,
- FILTER_MODE_LOW_QUALITY,
- FILTER_MODE_HIGH_QUALITY_ARRAY,
- FILTER_MODE_LOW_QUALITY_ARRAY,
- FILTER_MODE_MAX,
- };
-
- struct CubemapFilterRasterPushConstant {
- uint32_t mip_level;
- uint32_t face_id;
- float pad[2];
- };
-
- struct CubemapFilter {
- CubemapFilterShaderRD compute_shader;
- CubemapFilterRasterShaderRD raster_shader;
- RID shader_version;
- RID compute_pipelines[FILTER_MODE_MAX];
- PipelineCacheRD raster_pipelines[FILTER_MODE_MAX];
-
- RID uniform_set;
- RID image_uniform_set;
- RID coefficient_buffer;
- bool use_high_quality;
-
- } filter;
-
enum SpecularMergeMode {
SPECULAR_MERGE_ADD,
SPECULAR_MERGE_SSR,
@@ -579,26 +497,6 @@ private:
RID pipelines[3]; //3 quality levels
} sss;
- struct ResolvePushConstant {
- int32_t screen_size[2];
- int32_t samples;
- uint32_t pad;
- };
-
- enum ResolveMode {
- RESOLVE_MODE_GI,
- RESOLVE_MODE_GI_VOXEL_GI,
- RESOLVE_MODE_DEPTH,
- RESOLVE_MODE_MAX
- };
-
- struct Resolve {
- ResolvePushConstant push_constant;
- ResolveShaderRD shader;
- RID shader_version;
- RID pipelines[RESOLVE_MODE_MAX]; //3 quality levels
- } resolve;
-
enum SortMode {
SORT_MODE_BLOCK,
SORT_MODE_STEP,
@@ -671,9 +569,6 @@ public:
void fsr_upscale(RID p_source_rd_texture, RID p_secondary_texture, RID p_destination_texture, const Size2i &p_internal_size, const Size2i &p_size, float p_fsr_upscale_sharpness);
void taa_resolve(RID p_frame, RID p_temp, RID p_depth, RID p_velocity, RID p_prev_velocity, RID p_history, Size2 p_resolution, float p_z_near, float p_z_far);
- void cubemap_roughness(RID p_source_rd_texture, RID p_dest_texture, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
- void cubemap_roughness_raster(RID p_source_rd_texture, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_sample_count, float p_roughness, float p_size);
- 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 luminance_reduction(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
void luminance_reduction_raster(RID p_source_texture, const Size2i p_source_size, const Vector<RID> p_reduce, Vector<RID> p_fb, RID p_prev_luminance, float p_min_luminance, float p_max_luminance, float p_adjust, bool p_set = false);
@@ -724,18 +619,11 @@ public:
void screen_space_indirect_lighting(RID p_diffuse, RID p_destination, RID p_normal_buffer, RID p_depth_mipmaps_texture, RID p_ao, const Vector<RID> p_ao_slices, RID p_ao_pong, const Vector<RID> p_ao_pong_slices, RID p_importance_map, RID p_importance_map_pong, RID p_edges, const Vector<RID> p_edges_slices, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings, bool p_invalidate_uniform_sets, RID &r_gather_uniform_set, RID &r_importance_map_uniform_set, RID &r_projection_uniform_set);
void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve);
- void cubemap_downsample(RID p_source_cubemap, RID p_dest_cubemap, const Size2i &p_size);
- void cubemap_downsample_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, const Size2i &p_size);
- void cubemap_filter(RID p_source_cubemap, Vector<RID> p_dest_cubemap, bool p_use_array);
- void cubemap_filter_raster(RID p_source_cubemap, RID p_dest_framebuffer, uint32_t p_face_id, uint32_t p_mip_level);
void screen_space_reflection(RID p_diffuse, RID p_normal_roughness, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, RID p_blur_radius, RID p_blur_radius2, RID p_metallic, const Color &p_metallic_mask, RID p_depth, RID p_scale_depth, RID p_scale_normal, RID p_output, RID p_output_blur, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const CameraMatrix &p_camera);
void merge_specular(RID p_dest_framebuffer, RID p_specular, RID p_base, RID p_reflection);
void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality);
- 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, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
- void resolve_depth(RID p_source_depth, RID p_dest_depth, Vector2i p_screen_size, int p_samples, uint32_t p_barrier = RD::BARRIER_MASK_ALL);
-
void sort_buffer(RID p_uniform_set, int p_size);
EffectsRD(bool p_prefer_raster_effects);
diff --git a/servers/rendering/renderer_rd/environment/SCsub b/servers/rendering/renderer_rd/environment/SCsub
new file mode 100644
index 0000000000..86681f9c74
--- /dev/null
+++ b/servers/rendering/renderer_rd/environment/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import("env")
+
+env.add_source_files(env.servers_sources, "*.cpp")
diff --git a/servers/rendering/renderer_rd/environment/fog.cpp b/servers/rendering/renderer_rd/environment/fog.cpp
new file mode 100644
index 0000000000..2a6c96480e
--- /dev/null
+++ b/servers/rendering/renderer_rd/environment/fog.cpp
@@ -0,0 +1,128 @@
+/*************************************************************************/
+/* fog.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "fog.h"
+
+using namespace RendererRD;
+
+Fog *Fog::singleton = nullptr;
+
+Fog::Fog() {
+ singleton = this;
+}
+
+Fog::~Fog() {
+ singleton = nullptr;
+}
+
+/* FOG VOLUMES */
+
+RID Fog::fog_volume_allocate() {
+ return fog_volume_owner.allocate_rid();
+}
+
+void Fog::fog_volume_initialize(RID p_rid) {
+ fog_volume_owner.initialize_rid(p_rid, FogVolume());
+}
+
+void Fog::fog_free(RID p_rid) {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid);
+ fog_volume->dependency.deleted_notify(p_rid);
+ fog_volume_owner.free(p_rid);
+}
+
+void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND(!fog_volume);
+
+ if (p_shape == fog_volume->shape) {
+ return;
+ }
+
+ fog_volume->shape = p_shape;
+ fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
+}
+
+void Fog::fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND(!fog_volume);
+
+ fog_volume->extents = p_extents;
+ fog_volume->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
+}
+
+void Fog::fog_volume_set_material(RID p_fog_volume, RID p_material) {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND(!fog_volume);
+ fog_volume->material = p_material;
+}
+
+RID Fog::fog_volume_get_material(RID p_fog_volume) const {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND_V(!fog_volume, RID());
+
+ return fog_volume->material;
+}
+
+RS::FogVolumeShape Fog::fog_volume_get_shape(RID p_fog_volume) const {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND_V(!fog_volume, RS::FOG_VOLUME_SHAPE_BOX);
+
+ return fog_volume->shape;
+}
+
+AABB Fog::fog_volume_get_aabb(RID p_fog_volume) const {
+ FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND_V(!fog_volume, AABB());
+
+ switch (fog_volume->shape) {
+ case RS::FOG_VOLUME_SHAPE_ELLIPSOID:
+ case RS::FOG_VOLUME_SHAPE_CONE:
+ case RS::FOG_VOLUME_SHAPE_CYLINDER:
+ case RS::FOG_VOLUME_SHAPE_BOX: {
+ AABB aabb;
+ aabb.position = -fog_volume->extents;
+ aabb.size = fog_volume->extents * 2;
+ return aabb;
+ }
+ default: {
+ // Need some size otherwise will get culled
+ return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
+ }
+ }
+
+ return AABB();
+}
+
+Vector3 Fog::fog_volume_get_extents(RID p_fog_volume) const {
+ const FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
+ ERR_FAIL_COND_V(!fog_volume, Vector3());
+ return fog_volume->extents;
+}
diff --git a/servers/rendering/renderer_rd/environment/fog.h b/servers/rendering/renderer_rd/environment/fog.h
new file mode 100644
index 0000000000..55a01c3616
--- /dev/null
+++ b/servers/rendering/renderer_rd/environment/fog.h
@@ -0,0 +1,83 @@
+/*************************************************************************/
+/* fog.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 FOG_RD_H
+#define FOG_RD_H
+
+#include "core/templates/local_vector.h"
+#include "core/templates/rid_owner.h"
+#include "servers/rendering/environment/renderer_fog.h"
+#include "servers/rendering/storage/utilities.h"
+
+namespace RendererRD {
+
+class Fog : public RendererFog {
+public:
+ struct FogVolume {
+ RID material;
+ Vector3 extents = Vector3(1, 1, 1);
+
+ RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX;
+
+ Dependency dependency;
+ };
+
+private:
+ static Fog *singleton;
+
+ mutable RID_Owner<FogVolume, true> fog_volume_owner;
+
+public:
+ static Fog *get_singleton() { return singleton; }
+
+ Fog();
+ ~Fog();
+
+ /* FOG VOLUMES */
+
+ FogVolume *get_fog_volume(RID p_rid) { return fog_volume_owner.get_or_null(p_rid); };
+ bool owns_fog_volume(RID p_rid) { return fog_volume_owner.owns(p_rid); };
+
+ virtual RID fog_volume_allocate() override;
+ virtual void fog_volume_initialize(RID p_rid) override;
+ virtual void fog_free(RID p_rid) override;
+
+ virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override;
+ virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override;
+ virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) override;
+ virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const override;
+ RID fog_volume_get_material(RID p_fog_volume) const;
+ virtual AABB fog_volume_get_aabb(RID p_fog_volume) const override;
+ Vector3 fog_volume_get_extents(RID p_fog_volume) const;
+};
+
+} // namespace RendererRD
+
+#endif // !FOG_RD_H
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/environment/gi.cpp
index 7aede6bb48..a749e7d5bc 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
+++ b/servers/rendering/renderer_rd/environment/gi.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* renderer_scene_gi_rd.cpp */
+/* gi.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,24 +28,354 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "renderer_scene_gi_rd.h"
+#include "gi.h"
#include "core/config/project_settings.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
-const Vector3i RendererSceneGIRD::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);
+using namespace RendererRD;
+
+const Vector3i GI::SDFGI::Cascade::DIRTY_ALL = Vector3i(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF);
+
+GI *GI::singleton = nullptr;
+
+////////////////////////////////////////////////////////////////////////////////
+// VOXEL GI STORAGE
+
+RID GI::voxel_gi_allocate() {
+ return voxel_gi_owner.allocate_rid();
+}
+
+void GI::voxel_gi_free(RID p_voxel_gi) {
+ voxel_gi_allocate_data(p_voxel_gi, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ voxel_gi->dependency.deleted_notify(p_voxel_gi);
+ voxel_gi_owner.free(p_voxel_gi);
+}
+
+void GI::voxel_gi_initialize(RID p_voxel_gi) {
+ voxel_gi_owner.initialize_rid(p_voxel_gi, VoxelGI());
+}
+
+void GI::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
+
+ if (voxel_gi->octree_buffer.is_valid()) {
+ RD::get_singleton()->free(voxel_gi->octree_buffer);
+ RD::get_singleton()->free(voxel_gi->data_buffer);
+ if (voxel_gi->sdf_texture.is_valid()) {
+ RD::get_singleton()->free(voxel_gi->sdf_texture);
+ }
+
+ voxel_gi->sdf_texture = RID();
+ voxel_gi->octree_buffer = RID();
+ voxel_gi->data_buffer = RID();
+ voxel_gi->octree_buffer_size = 0;
+ voxel_gi->data_buffer_size = 0;
+ voxel_gi->cell_count = 0;
+ }
+
+ voxel_gi->to_cell_xform = p_to_cell_xform;
+ voxel_gi->bounds = p_aabb;
+ voxel_gi->octree_size = p_octree_size;
+ voxel_gi->level_counts = p_level_counts;
+
+ if (p_octree_cells.size()) {
+ ERR_FAIL_COND(p_octree_cells.size() % 32 != 0); //cells size must be a multiple of 32
+
+ uint32_t cell_count = p_octree_cells.size() / 32;
+
+ ERR_FAIL_COND(p_data_cells.size() != (int)cell_count * 16); //see that data size matches
+
+ voxel_gi->cell_count = cell_count;
+ voxel_gi->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells);
+ voxel_gi->octree_buffer_size = p_octree_cells.size();
+ voxel_gi->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells);
+ voxel_gi->data_buffer_size = p_data_cells.size();
+
+ if (p_distance_field.size()) {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf.width = voxel_gi->octree_size.x;
+ tf.height = voxel_gi->octree_size.y;
+ tf.depth = voxel_gi->octree_size.z;
+ tf.texture_type = RD::TEXTURE_TYPE_3D;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
+ Vector<Vector<uint8_t>> s;
+ s.push_back(p_distance_field);
+ voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s);
+ }
+#if 0
+ {
+ RD::TextureFormat tf;
+ tf.format = RD::DATA_FORMAT_R8_UNORM;
+ tf.width = voxel_gi->octree_size.x;
+ tf.height = voxel_gi->octree_size.y;
+ tf.depth = voxel_gi->octree_size.z;
+ tf.type = RD::TEXTURE_TYPE_3D;
+ tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
+ tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UNORM);
+ tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UINT);
+ voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ }
+ RID shared_tex;
+ {
+ RD::TextureView tv;
+ tv.format_override = RD::DATA_FORMAT_R8_UINT;
+ shared_tex = RD::get_singleton()->texture_create_shared(tv, voxel_gi->sdf_texture);
+ }
+ //update SDF texture
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 1;
+ u.append_id(voxel_gi->octree_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.binding = 2;
+ u.append_id(voxel_gi->data_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 3;
+ u.append_id(shared_tex);
+ uniforms.push_back(u);
+ }
+
+ RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, voxel_gi_sdf_shader_version_shader, 0);
+
+ {
+ uint32_t push_constant[4] = { 0, 0, 0, 0 };
+
+ for (int i = 0; i < voxel_gi->level_counts.size() - 1; i++) {
+ push_constant[0] += voxel_gi->level_counts[i];
+ }
+ push_constant[1] = push_constant[0] + voxel_gi->level_counts[voxel_gi->level_counts.size() - 1];
+
+ print_line("offset: " + itos(push_constant[0]));
+ print_line("size: " + itos(push_constant[1]));
+ //create SDF
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, voxel_gi_sdf_shader_pipeline);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set, 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, push_constant, sizeof(uint32_t) * 4);
+ RD::get_singleton()->compute_list_dispatch(compute_list, voxel_gi->octree_size.x / 4, voxel_gi->octree_size.y / 4, voxel_gi->octree_size.z / 4);
+ RD::get_singleton()->compute_list_end();
+ }
+
+ RD::get_singleton()->free(uniform_set);
+ RD::get_singleton()->free(shared_tex);
+ }
+#endif
+ }
+
+ voxel_gi->version++;
+ voxel_gi->data_version++;
+
+ voxel_gi->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
+}
+
+AABB GI::voxel_gi_get_bounds(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, AABB());
+
+ return voxel_gi->bounds;
+}
+
+Vector3i GI::voxel_gi_get_octree_size(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Vector3i());
+ return voxel_gi->octree_size;
+}
+
+Vector<uint8_t> GI::voxel_gi_get_octree_cells(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>());
+
+ if (voxel_gi->octree_buffer.is_valid()) {
+ return RD::get_singleton()->buffer_get_data(voxel_gi->octree_buffer);
+ }
+ return Vector<uint8_t>();
+}
+
+Vector<uint8_t> GI::voxel_gi_get_data_cells(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>());
+
+ if (voxel_gi->data_buffer.is_valid()) {
+ return RD::get_singleton()->buffer_get_data(voxel_gi->data_buffer);
+ }
+ return Vector<uint8_t>();
+}
+
+Vector<uint8_t> GI::voxel_gi_get_distance_field(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>());
+
+ if (voxel_gi->data_buffer.is_valid()) {
+ return RD::get_singleton()->texture_get_data(voxel_gi->sdf_texture, 0);
+ }
+ return Vector<uint8_t>();
+}
+
+Vector<int> GI::voxel_gi_get_level_counts(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Vector<int>());
+
+ return voxel_gi->level_counts;
+}
+
+Transform3D GI::voxel_gi_get_to_cell_xform(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, Transform3D());
+
+ return voxel_gi->to_cell_xform;
+}
+
+void GI::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
+
+ voxel_gi->dynamic_range = p_range;
+ voxel_gi->version++;
+}
+
+float GI::voxel_gi_get_dynamic_range(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+
+ return voxel_gi->dynamic_range;
+}
+
+void GI::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
+
+ voxel_gi->propagation = p_range;
+ voxel_gi->version++;
+}
+
+float GI::voxel_gi_get_propagation(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->propagation;
+}
+
+void GI::voxel_gi_set_energy(RID p_voxel_gi, float p_energy) {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
+
+ voxel_gi->energy = p_energy;
+}
+
+float GI::voxel_gi_get_energy(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->energy;
+}
+
+void GI::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
+
+ voxel_gi->bias = p_bias;
+}
+
+float GI::voxel_gi_get_bias(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->bias;
+}
+
+void GI::voxel_gi_set_normal_bias(RID p_voxel_gi, float p_normal_bias) {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
+
+ voxel_gi->normal_bias = p_normal_bias;
+}
+
+float GI::voxel_gi_get_normal_bias(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->normal_bias;
+}
+
+void GI::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
+
+ voxel_gi->interior = p_enable;
+}
+
+void GI::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND(!voxel_gi);
+
+ voxel_gi->use_two_bounces = p_enable;
+ voxel_gi->version++;
+}
+
+bool GI::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, false);
+ return voxel_gi->use_two_bounces;
+}
+
+bool GI::voxel_gi_is_interior(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->interior;
+}
+
+uint32_t GI::voxel_gi_get_version(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->version;
+}
+
+uint32_t GI::voxel_gi_get_data_version(RID p_voxel_gi) {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, 0);
+ return voxel_gi->data_version;
+}
+
+RID GI::voxel_gi_get_octree_buffer(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, RID());
+ return voxel_gi->octree_buffer;
+}
+
+RID GI::voxel_gi_get_data_buffer(RID p_voxel_gi) const {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, RID());
+ return voxel_gi->data_buffer;
+}
+
+RID GI::voxel_gi_get_sdf_texture(RID p_voxel_gi) {
+ VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
+ ERR_FAIL_COND_V(!voxel_gi, RID());
+
+ return voxel_gi->sdf_texture;
+}
////////////////////////////////////////////////////////////////////////////////
// SDFGI
-void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, RendererSceneGIRD *p_gi) {
+void GI::SDFGI::create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- storage = p_gi->storage;
gi = p_gi;
num_cascades = p_env->sdfgi_cascades;
min_cell_size = p_env->sdfgi_min_cell_size;
@@ -755,7 +1085,7 @@ void RendererSceneGIRD::SDFGI::create(RendererSceneEnvironmentRD *p_env, const V
reads_sky = p_env->sdfgi_read_sky_light;
}
-void RendererSceneGIRD::SDFGI::erase() {
+void GI::SDFGI::erase() {
for (uint32_t i = 0; i < cascades.size(); i++) {
const SDFGI::Cascade &c = cascades[i];
RD::get_singleton()->free(c.light_data);
@@ -791,9 +1121,26 @@ void RendererSceneGIRD::SDFGI::erase() {
RD::get_singleton()->free(ambient_texture);
RD::get_singleton()->free(cascades_ubo);
+
+ for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {
+ if (RD::get_singleton()->uniform_set_is_valid(debug_uniform_set[v])) {
+ RD::get_singleton()->free(debug_uniform_set[v]);
+ }
+ debug_uniform_set[v] = RID();
+ }
+
+ if (RD::get_singleton()->uniform_set_is_valid(debug_probes_uniform_set)) {
+ RD::get_singleton()->free(debug_probes_uniform_set);
+ }
+ debug_probes_uniform_set = RID();
+
+ if (debug_probes_scene_data_ubo.is_valid()) {
+ RD::get_singleton()->free(debug_probes_scene_data_ubo);
+ debug_probes_scene_data_ubo = RID();
+ }
}
-void RendererSceneGIRD::SDFGI::update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position) {
+void GI::SDFGI::update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position) {
bounce_feedback = p_env->sdfgi_bounce_feedback;
energy = p_env->sdfgi_energy;
normal_bias = p_env->sdfgi_normal_bias;
@@ -851,7 +1198,7 @@ void RendererSceneGIRD::SDFGI::update(RendererSceneEnvironmentRD *p_env, const V
}
}
-void RendererSceneGIRD::SDFGI::update_light() {
+void GI::SDFGI::update_light() {
RD::get_singleton()->draw_command_begin_label("SDFGI Update dynamic Light");
/* Update dynamic light */
@@ -898,7 +1245,7 @@ void RendererSceneGIRD::SDFGI::update_light() {
RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky) {
+void GI::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env, RendererSceneSkyRD::Sky *p_sky) {
RD::get_singleton()->draw_command_begin_label("SDFGI Update Probes");
SDFGIShader::IntegratePushConstant push_constant;
@@ -925,7 +1272,7 @@ void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env,
if (p_env->background == RS::ENV_BG_CLEAR_COLOR) {
push_constant.sky_mode = SDFGIShader::IntegratePushConstant::SKY_MODE_COLOR;
- Color c = storage->get_default_clear_color().srgb_to_linear();
+ Color c = RSG::texture_storage->get_default_clear_color().srgb_to_linear();
push_constant.sky_color[0] = c.r;
push_constant.sky_color[1] = c.g;
push_constant.sky_color[2] = c.b;
@@ -990,7 +1337,7 @@ void RendererSceneGIRD::SDFGI::update_probes(RendererSceneEnvironmentRD *p_env,
RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneGIRD::SDFGI::store_probes() {
+void GI::SDFGI::store_probes() {
RD::get_singleton()->barrier(RD::BARRIER_MASK_COMPUTE, RD::BARRIER_MASK_COMPUTE);
RD::get_singleton()->draw_command_begin_label("SDFGI Store Probes");
@@ -1035,7 +1382,7 @@ void RendererSceneGIRD::SDFGI::store_probes() {
RD::get_singleton()->draw_command_end_label();
}
-int RendererSceneGIRD::SDFGI::get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const {
+int GI::SDFGI::get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const {
int dirty_count = 0;
for (uint32_t i = 0; i < cascades.size(); i++) {
const SDFGI::Cascade &c = cascades[i];
@@ -1091,7 +1438,7 @@ int RendererSceneGIRD::SDFGI::get_pending_region_data(int p_region, Vector3i &r_
return -1;
}
-void RendererSceneGIRD::SDFGI::update_cascades() {
+void GI::SDFGI::update_cascades() {
//update cascades
SDFGI::Cascade::UBO cascade_data[SDFGI::MAX_CASCADES];
int32_t probe_divisor = cascade_size / SDFGI::PROBE_DIVISOR;
@@ -1112,160 +1459,177 @@ void RendererSceneGIRD::SDFGI::update_cascades() {
RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE);
}
-void RendererSceneGIRD::SDFGI::debug_draw(const CameraMatrix &p_projection, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture) {
+void GI::SDFGI::debug_draw(uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
- if (!debug_uniform_set.is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set)) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.binding = 1;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
- if (i < cascades.size()) {
- u.append_id(cascades[i].sdf_tex);
- } else {
- u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ for (uint32_t v = 0; v < p_view_count; v++) {
+ if (!debug_uniform_set[v].is_valid() || !RD::get_singleton()->uniform_set_is_valid(debug_uniform_set[v])) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
+ if (i < cascades.size()) {
+ u.append_id(cascades[i].sdf_tex);
+ } else {
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
}
+ uniforms.push_back(u);
}
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 2;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
- if (i < cascades.size()) {
- u.append_id(cascades[i].light_tex);
- } else {
- u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
+ if (i < cascades.size()) {
+ u.append_id(cascades[i].light_tex);
+ } else {
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
}
+ uniforms.push_back(u);
}
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 3;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
- if (i < cascades.size()) {
- u.append_id(cascades[i].light_aniso_0_tex);
- } else {
- u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ {
+ RD::Uniform u;
+ u.binding = 3;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
+ if (i < cascades.size()) {
+ u.append_id(cascades[i].light_aniso_0_tex);
+ } else {
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
}
+ uniforms.push_back(u);
}
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 4;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
- if (i < cascades.size()) {
- u.append_id(cascades[i].light_aniso_1_tex);
- } else {
- u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ {
+ RD::Uniform u;
+ u.binding = 4;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t i = 0; i < SDFGI::MAX_CASCADES; i++) {
+ if (i < cascades.size()) {
+ u.append_id(cascades[i].light_aniso_1_tex);
+ } else {
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
}
+ uniforms.push_back(u);
}
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 5;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.append_id(occlusion_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 8;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 9;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.append_id(cascades_ubo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 10;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.append_id(p_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 11;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.append_id(lightprobe_texture);
- uniforms.push_back(u);
+ {
+ RD::Uniform u;
+ u.binding = 5;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.append_id(occlusion_texture);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 8;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 9;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.append_id(cascades_ubo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 10;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.append_id(p_texture_views[v]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 11;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.append_id(lightprobe_texture);
+ uniforms.push_back(u);
+ }
+ debug_uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_shader_version, 0);
}
- debug_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_shader_version, 0);
- }
-
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.debug_pipeline);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set, 0);
-
- SDFGIShader::DebugPushConstant push_constant;
- push_constant.grid_size[0] = cascade_size;
- push_constant.grid_size[1] = cascade_size;
- push_constant.grid_size[2] = cascade_size;
- push_constant.max_cascades = cascades.size();
- push_constant.screen_size[0] = p_width;
- push_constant.screen_size[1] = p_height;
- push_constant.probe_axis_size = probe_axis_count;
- push_constant.use_occlusion = uses_occlusion;
- push_constant.y_mult = y_mult;
- Vector2 vp_half = p_projection.get_viewport_half_extents();
- push_constant.cam_extent[0] = vp_half.x;
- push_constant.cam_extent[1] = vp_half.y;
- push_constant.cam_extent[2] = -p_projection.get_z_near();
-
- push_constant.cam_transform[0] = p_transform.basis.rows[0][0];
- push_constant.cam_transform[1] = p_transform.basis.rows[1][0];
- push_constant.cam_transform[2] = p_transform.basis.rows[2][0];
- push_constant.cam_transform[3] = 0;
- push_constant.cam_transform[4] = p_transform.basis.rows[0][1];
- push_constant.cam_transform[5] = p_transform.basis.rows[1][1];
- push_constant.cam_transform[6] = p_transform.basis.rows[2][1];
- push_constant.cam_transform[7] = 0;
- push_constant.cam_transform[8] = p_transform.basis.rows[0][2];
- push_constant.cam_transform[9] = p_transform.basis.rows[1][2];
- push_constant.cam_transform[10] = p_transform.basis.rows[2][2];
- push_constant.cam_transform[11] = 0;
- push_constant.cam_transform[12] = p_transform.origin.x;
- push_constant.cam_transform[13] = p_transform.origin.y;
- push_constant.cam_transform[14] = p_transform.origin.z;
- push_constant.cam_transform[15] = 1;
-
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DebugPushConstant));
-
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_width, p_height, 1);
- RD::get_singleton()->compute_list_end();
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, gi->sdfgi_shader.debug_pipeline);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, debug_uniform_set[v], 0);
+
+ SDFGIShader::DebugPushConstant push_constant;
+ push_constant.grid_size[0] = cascade_size;
+ push_constant.grid_size[1] = cascade_size;
+ push_constant.grid_size[2] = cascade_size;
+ push_constant.max_cascades = cascades.size();
+ push_constant.screen_size[0] = p_width;
+ push_constant.screen_size[1] = p_height;
+ push_constant.probe_axis_size = probe_axis_count;
+ push_constant.use_occlusion = uses_occlusion;
+ push_constant.y_mult = y_mult;
+
+ push_constant.z_near = -p_projections[v].get_z_near();
+
+ push_constant.cam_transform[0] = p_transform.basis.rows[0][0];
+ push_constant.cam_transform[1] = p_transform.basis.rows[1][0];
+ push_constant.cam_transform[2] = p_transform.basis.rows[2][0];
+ push_constant.cam_transform[3] = 0;
+ push_constant.cam_transform[4] = p_transform.basis.rows[0][1];
+ push_constant.cam_transform[5] = p_transform.basis.rows[1][1];
+ push_constant.cam_transform[6] = p_transform.basis.rows[2][1];
+ push_constant.cam_transform[7] = 0;
+ push_constant.cam_transform[8] = p_transform.basis.rows[0][2];
+ push_constant.cam_transform[9] = p_transform.basis.rows[1][2];
+ push_constant.cam_transform[10] = p_transform.basis.rows[2][2];
+ push_constant.cam_transform[11] = 0;
+ push_constant.cam_transform[12] = p_transform.origin.x;
+ push_constant.cam_transform[13] = p_transform.origin.y;
+ push_constant.cam_transform[14] = p_transform.origin.z;
+ push_constant.cam_transform[15] = 1;
+
+ // need to properly unproject for asymmetric projection matrices in stereo..
+ CameraMatrix inv_projection = p_projections[v].inverse();
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ push_constant.inv_projection[i * 4 + j] = inv_projection.matrix[i][j];
+ }
+ }
+
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(SDFGIShader::DebugPushConstant));
+
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, p_width, p_height, 1);
+ RD::get_singleton()->compute_list_end();
+ }
Size2 rtsize = texture_storage->render_target_get_size(p_render_target);
- copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true);
+ copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true, false, false, false, RID(), p_view_count > 1);
}
-void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) {
+void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- SDFGIShader::DebugProbesPushConstant push_constant;
+ // setup scene data
+ {
+ SDFGIShader::DebugProbesSceneData scene_data;
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- push_constant.projection[i * 4 + j] = p_camera_with_transform.matrix[i][j];
+ if (debug_probes_scene_data_ubo.is_null()) {
+ debug_probes_scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIShader::DebugProbesSceneData));
}
+
+ for (uint32_t v = 0; v < p_view_count; v++) {
+ RendererRD::MaterialStorage::store_camera(p_camera_with_transforms[v], scene_data.projection[v]);
+ }
+
+ RD::get_singleton()->buffer_update(debug_probes_scene_data_ubo, 0, sizeof(SDFGIShader::DebugProbesSceneData), &scene_data, RD::BARRIER_MASK_RASTER);
}
+ // setup push constant
+ SDFGIShader::DebugProbesPushConstant push_constant;
+
//gen spheres from strips
uint32_t band_points = 16;
push_constant.band_power = 4;
@@ -1314,14 +1678,26 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr
u.append_id(occlusion_texture);
uniforms.push_back(u);
}
+ {
+ RD::Uniform u;
+ u.binding = 5;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.append_id(debug_probes_scene_data_ubo);
+ uniforms.push_back(u);
+ }
debug_probes_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, gi->sdfgi_shader.debug_probes.version_get_shader(gi->sdfgi_shader.debug_probes_shader, 0), 0);
}
- RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, gi->sdfgi_shader.debug_probes_pipeline[SDFGIShader::PROBE_DEBUG_PROBES].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, debug_probes_uniform_set, 0);
- RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant));
- RD::get_singleton()->draw_list_draw(p_draw_list, false, total_probes, total_points);
+ SDFGIShader::ProbeDebugMode mode = p_view_count > 1 ? SDFGIShader::PROBE_DEBUG_PROBES_MULTIVIEW : SDFGIShader::PROBE_DEBUG_PROBES;
+
+ RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_framebuffer, RD::INITIAL_ACTION_CONTINUE, p_will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
+ RD::get_singleton()->draw_command_begin_label("Debug SDFGI");
+
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, gi->sdfgi_shader.debug_probes_pipeline[mode].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, debug_probes_uniform_set, 0);
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant));
+ RD::get_singleton()->draw_list_draw(draw_list, false, total_probes, total_points);
if (gi->sdfgi_debug_probe_dir != Vector3()) {
uint32_t cascade = 0;
@@ -1373,14 +1749,17 @@ void RendererSceneGIRD::SDFGI::debug_probes(RD::DrawListID p_draw_list, RID p_fr
uint32_t cell_count = probe_cells * 2 * probe_cells * 2 * probe_cells * 2;
- RD::get_singleton()->draw_list_bind_render_pipeline(p_draw_list, gi->sdfgi_shader.debug_probes_pipeline[SDFGIShader::PROBE_DEBUG_VISIBILITY].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
- RD::get_singleton()->draw_list_bind_uniform_set(p_draw_list, debug_probes_uniform_set, 0);
- RD::get_singleton()->draw_list_set_push_constant(p_draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant));
- RD::get_singleton()->draw_list_draw(p_draw_list, false, cell_count, total_points);
+ RD::get_singleton()->draw_list_bind_render_pipeline(draw_list, gi->sdfgi_shader.debug_probes_pipeline[p_view_count > 1 ? SDFGIShader::PROBE_DEBUG_VISIBILITY_MULTIVIEW : SDFGIShader::PROBE_DEBUG_VISIBILITY].get_render_pipeline(RD::INVALID_FORMAT_ID, RD::get_singleton()->framebuffer_get_format(p_framebuffer)));
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, debug_probes_uniform_set, 0);
+ RD::get_singleton()->draw_list_set_push_constant(draw_list, &push_constant, sizeof(SDFGIShader::DebugProbesPushConstant));
+ RD::get_singleton()->draw_list_draw(draw_list, false, cell_count, total_points);
}
+
+ RD::get_singleton()->draw_command_end_label();
+ RD::get_singleton()->draw_list_end();
}
-void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) {
+void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) {
/* Update general SDFGI Buffer */
SDFGIData sdfgi_data;
@@ -1545,7 +1924,7 @@ void RendererSceneGIRD::SDFGI::pre_process_gi(const Transform3D &p_transform, Re
}
}
-void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) {
+void GI::SDFGI::render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render) {
//print_line("rendering region " + itos(p_region));
RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but...
@@ -1904,7 +2283,7 @@ void RendererSceneGIRD::SDFGI::render_region(RID p_render_buffers, int p_region,
}
}
-void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render) {
+void GI::SDFGI::render_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render) {
RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND(!rb); // we wouldn't be here if this failed but...
@@ -2026,10 +2405,10 @@ void RendererSceneGIRD::SDFGI::render_static_lights(RID p_render_buffers, uint32
////////////////////////////////////////////////////////////////////////////////
// VoxelGIInstance
-void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
+void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- uint32_t data_version = storage->voxel_gi_get_data_version(probe);
+ uint32_t data_version = gi->voxel_gi_get_data_version(probe);
// (RE)CREATE IF NEEDED
@@ -2048,11 +2427,11 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
dynamic_maps.clear();
- Vector3i octree_size = storage->voxel_gi_get_octree_size(probe);
+ Vector3i octree_size = gi->voxel_gi_get_octree_size(probe);
if (octree_size != Vector3i()) {
//can create a 3D texture
- Vector<int> levels = storage->voxel_gi_get_level_counts(probe);
+ Vector<int> levels = gi->voxel_gi_get_level_counts(probe);
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
@@ -2092,14 +2471,14 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
- u.append_id(storage->voxel_gi_get_octree_buffer(probe));
+ u.append_id(gi->voxel_gi_get_octree_buffer(probe));
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 2;
- u.append_id(storage->voxel_gi_get_data_buffer(probe));
+ u.append_id(gi->voxel_gi_get_data_buffer(probe));
uniforms.push_back(u);
}
@@ -2114,7 +2493,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 9;
- u.append_id(storage->voxel_gi_get_sdf_texture(probe));
+ u.append_id(gi->voxel_gi_get_sdf_texture(probe));
uniforms.push_back(u);
}
{
@@ -2268,7 +2647,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 9;
- u.append_id(storage->voxel_gi_get_sdf_texture(probe));
+ u.append_id(gi->voxel_gi_get_sdf_texture(probe));
uniforms.push_back(u);
}
{
@@ -2337,7 +2716,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 9;
- u.append_id(storage->voxel_gi_get_sdf_texture(probe));
+ u.append_id(gi->voxel_gi_get_sdf_texture(probe));
uniforms.push_back(u);
}
{
@@ -2388,7 +2767,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
light_count = MIN(gi->voxel_gi_max_lights, (uint32_t)p_light_instances.size());
{
- Transform3D to_cell = storage->voxel_gi_get_to_cell_xform(probe);
+ Transform3D to_cell = gi->voxel_gi_get_to_cell_xform(probe);
Transform3D to_probe_xform = (transform * to_cell.affine_inverse()).affine_inverse();
//update lights
@@ -2439,7 +2818,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
if (mipmaps.size()) {
//can update mipmaps
- Vector3i probe_size = storage->voxel_gi_get_octree_size(probe);
+ Vector3i probe_size = gi->voxel_gi_get_octree_size(probe);
VoxelGIPushConstant push_constant;
@@ -2448,8 +2827,8 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
push_constant.limits[2] = probe_size.z;
push_constant.stack_size = mipmaps.size();
push_constant.emission_scale = 1.0;
- push_constant.propagation = storage->voxel_gi_get_propagation(probe);
- push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe);
+ push_constant.propagation = gi->voxel_gi_get_propagation(probe);
+ push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe);
push_constant.light_count = light_count;
push_constant.aniso_strength = 0;
@@ -2461,7 +2840,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
int passes;
if (p_update_light_instances) {
- passes = storage->voxel_gi_is_using_two_bounces(probe) ? 2 : 1;
+ passes = gi->voxel_gi_is_using_two_bounces(probe) ? 2 : 1;
} else {
passes = 1; //only re-blitting is necessary
}
@@ -2528,13 +2907,13 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
has_dynamic_object_data = false; //clear until dynamic object data is used again
if (p_dynamic_objects.size() && dynamic_maps.size()) {
- Vector3i octree_size = storage->voxel_gi_get_octree_size(probe);
+ Vector3i octree_size = gi->voxel_gi_get_octree_size(probe);
int multiplier = dynamic_maps[0].size / MAX(MAX(octree_size.x, octree_size.y), octree_size.z);
Transform3D oversample_scale;
oversample_scale.basis.scale(Vector3(multiplier, multiplier, multiplier));
- Transform3D to_cell = oversample_scale * storage->voxel_gi_get_to_cell_xform(probe);
+ Transform3D to_cell = oversample_scale * gi->voxel_gi_get_to_cell_xform(probe);
Transform3D to_world_xform = transform * to_cell.affine_inverse();
Transform3D to_probe_xform = to_world_xform.affine_inverse();
@@ -2634,7 +3013,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
push_constant.z_base = xform.origin[z_axis];
push_constant.z_sign = (z_flip ? -1.0 : 1.0);
push_constant.pos_multiplier = float(1.0) / multiplier;
- push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe);
+ push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe);
push_constant.flip_x = x_flip;
push_constant.flip_y = y_flip;
push_constant.rect_pos[0] = rect.position[0];
@@ -2646,7 +3025,7 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
push_constant.prev_rect_size[0] = 0;
push_constant.prev_rect_size[1] = 0;
push_constant.on_mipmap = false;
- push_constant.propagation = storage->voxel_gi_get_propagation(probe);
+ push_constant.propagation = gi->voxel_gi_get_propagation(probe);
push_constant.pad[0] = 0;
push_constant.pad[1] = 0;
push_constant.pad[2] = 0;
@@ -2728,24 +3107,24 @@ void RendererSceneGIRD::VoxelGIInstance::update(bool p_update_light_instances, c
has_dynamic_object_data = true; //clear until dynamic object data is used again
}
- last_probe_version = storage->voxel_gi_get_version(probe);
+ last_probe_version = gi->voxel_gi_get_version(probe);
}
-void RendererSceneGIRD::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
+void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
if (mipmaps.size() == 0) {
return;
}
- CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(storage->voxel_gi_get_to_cell_xform(probe).affine_inverse());
+ CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(gi->voxel_gi_get_to_cell_xform(probe).affine_inverse());
int level = 0;
- Vector3i octree_size = storage->voxel_gi_get_octree_size(probe);
+ Vector3i octree_size = gi->voxel_gi_get_octree_size(probe);
VoxelGIDebugPushConstant push_constant;
push_constant.alpha = p_alpha;
- push_constant.dynamic_range = storage->voxel_gi_get_dynamic_range(probe);
+ push_constant.dynamic_range = gi->voxel_gi_get_dynamic_range(probe);
push_constant.cell_offset = mipmaps[level].cell_offset;
push_constant.level = level;
@@ -2768,7 +3147,7 @@ void RendererSceneGIRD::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 1;
- u.append_id(storage->voxel_gi_get_data_buffer(probe));
+ u.append_id(gi->voxel_gi_get_data_buffer(probe));
uniforms.push_back(u);
}
{
@@ -2810,23 +3189,24 @@ void RendererSceneGIRD::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p
}
////////////////////////////////////////////////////////////////////////////////
-// GIRD
+// GI
+
+GI::GI() {
+ singleton = this;
-RendererSceneGIRD::RendererSceneGIRD() {
sdfgi_ray_count = RS::EnvironmentSDFGIRayCount(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/probe_ray_count")), 0, int32_t(RS::ENV_SDFGI_RAY_COUNT_MAX - 1)));
sdfgi_frames_to_converge = RS::EnvironmentSDFGIFramesToConverge(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_converge")), 0, int32_t(RS::ENV_SDFGI_CONVERGE_MAX - 1)));
sdfgi_frames_to_update_light = RS::EnvironmentSDFGIFramesToUpdateLight(CLAMP(int32_t(GLOBAL_GET("rendering/global_illumination/sdfgi/frames_to_update_lights")), 0, int32_t(RS::ENV_SDFGI_UPDATE_LIGHT_MAX - 1)));
}
-RendererSceneGIRD::~RendererSceneGIRD() {
+GI::~GI() {
+ singleton = nullptr;
}
-void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky) {
+void GI::init(RendererSceneSkyRD *p_sky) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- storage = p_storage;
-
/* GI */
{
@@ -2962,17 +3342,38 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
//calculate tables
String defines = "\n#define SDFGI_OCT_SIZE " + itos(SDFGI::LIGHTPROBE_OCT_SIZE) + "\n";
Vector<String> gi_modes;
- gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n");
- gi_modes.push_back("\n#define USE_SDFGI\n");
- gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n");
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_VOXEL_GI_INSTANCES\n");
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n");
- gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n");
+ gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_VOXEL_GI
+ gi_modes.push_back("\n#define USE_SDFGI\n"); // MODE_SDFGI
+ gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_COMBINED
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_HALF_RES_VOXEL_GI
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n"); // MODE_HALF_RES_SDFGI
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n"); // MODE_HALF_RES_COMBINED
+
+ gi_modes.push_back("\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_VOXEL_GI_MULTIVIEW
+ gi_modes.push_back("\n#define USE_SDFGI\n#define USE_MULTIVIEW\n"); // MODE_SDFGI_MULTIVIEW
+ gi_modes.push_back("\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_COMBINED_MULTIVIEW
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_HALF_RES_VOXEL_GI_MULTIVIEW
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n#define USE_MULTIVIEW\n"); // MODE_HALF_RES_SDFGI_MULTIVIEW
+ gi_modes.push_back("\n#define MODE_HALF_RES\n#define USE_SDFGI\n\n#define USE_VOXEL_GI_INSTANCES\n#define USE_MULTIVIEW\n"); // MODE_HALF_RES_COMBINED_MULTIVIEW
shader.initialize(gi_modes, defines);
+
+ if (!RendererCompositorRD::singleton->is_xr_enabled()) {
+ shader.set_variant_enabled(MODE_VOXEL_GI_MULTIVIEW, false);
+ shader.set_variant_enabled(MODE_SDFGI_MULTIVIEW, false);
+ shader.set_variant_enabled(MODE_COMBINED_MULTIVIEW, false);
+ shader.set_variant_enabled(MODE_HALF_RES_VOXEL_GI_MULTIVIEW, false);
+ shader.set_variant_enabled(MODE_HALF_RES_SDFGI_MULTIVIEW, false);
+ shader.set_variant_enabled(MODE_HALF_RES_COMBINED_MULTIVIEW, false);
+ }
+
shader_version = shader.version_create();
for (int i = 0; i < MODE_MAX; i++) {
- pipelines[i] = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, i));
+ if (shader.is_variant_enabled(i)) {
+ pipelines[i] = RD::get_singleton()->compute_pipeline_create(shader.version_get_shader(shader_version, i));
+ } else {
+ pipelines[i] = RID();
+ }
}
sdfgi_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SDFGIData));
@@ -2991,9 +3392,14 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
Vector<String> versions;
versions.push_back("\n#define MODE_PROBES\n");
+ versions.push_back("\n#define MODE_PROBES\n#define USE_MULTIVIEW\n");
versions.push_back("\n#define MODE_VISIBILITY\n");
+ versions.push_back("\n#define MODE_VISIBILITY\n#define USE_MULTIVIEW\n");
sdfgi_shader.debug_probes.initialize(versions, defines);
+
+ // TODO disable multiview versions if turned off
+
sdfgi_shader.debug_probes_shader = sdfgi_shader.debug_probes.version_create();
{
@@ -3004,6 +3410,8 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
ds.enable_depth_write = true;
ds.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
for (int i = 0; i < SDFGIShader::PROBE_DEBUG_MAX; i++) {
+ // TODO check if version is enabled
+
RID debug_probes_shader_version = sdfgi_shader.debug_probes.version_get_shader(sdfgi_shader.debug_probes_shader, i);
sdfgi_shader.debug_probes_pipeline[i].setup(debug_probes_shader_version, RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS, rs, RD::PipelineMultisampleState(), ds, RD::PipelineColorBlendState::create_disabled(), 0);
}
@@ -3013,7 +3421,7 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution");
}
-void RendererSceneGIRD::free() {
+void GI::free() {
RD::get_singleton()->free(default_voxel_gi_buffer);
RD::get_singleton()->free(voxel_gi_lights_uniform);
RD::get_singleton()->free(sdfgi_ubo);
@@ -3032,7 +3440,7 @@ void RendererSceneGIRD::free() {
}
}
-RendererSceneGIRD::SDFGI *RendererSceneGIRD::create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) {
+GI::SDFGI *GI::create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size) {
SDFGI *sdfgi = memnew(SDFGI);
sdfgi->create(p_env, p_world_position, p_requested_history_size, this);
@@ -3040,7 +3448,7 @@ RendererSceneGIRD::SDFGI *RendererSceneGIRD::create_sdfgi(RendererSceneEnvironme
return sdfgi;
}
-void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) {
+void GI::setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
r_voxel_gi_instances_used = 0;
@@ -3069,7 +3477,7 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra
RID base_probe = gipi->probe;
- Transform3D to_cell = storage->voxel_gi_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera;
+ Transform3D to_cell = voxel_gi_get_to_cell_xform(gipi->probe) * gipi->transform.affine_inverse() * to_camera;
gipd.xform[0] = to_cell.basis.rows[0][0];
gipd.xform[1] = to_cell.basis.rows[1][0];
@@ -3088,16 +3496,16 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra
gipd.xform[14] = to_cell.origin.z;
gipd.xform[15] = 1;
- Vector3 bounds = storage->voxel_gi_get_octree_size(base_probe);
+ Vector3 bounds = voxel_gi_get_octree_size(base_probe);
gipd.bounds[0] = bounds.x;
gipd.bounds[1] = bounds.y;
gipd.bounds[2] = bounds.z;
- gipd.dynamic_range = storage->voxel_gi_get_dynamic_range(base_probe) * storage->voxel_gi_get_energy(base_probe);
- gipd.bias = storage->voxel_gi_get_bias(base_probe);
- gipd.normal_bias = storage->voxel_gi_get_normal_bias(base_probe);
- gipd.blend_ambient = !storage->voxel_gi_is_interior(base_probe);
+ gipd.dynamic_range = voxel_gi_get_dynamic_range(base_probe) * voxel_gi_get_energy(base_probe);
+ gipd.bias = voxel_gi_get_bias(base_probe);
+ gipd.normal_bias = voxel_gi_get_normal_bias(base_probe);
+ gipd.blend_ambient = !voxel_gi_is_interior(base_probe);
gipd.mipmaps = gipi->mipmaps.size();
}
@@ -3108,17 +3516,19 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra
texture = texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE);
}
- if (texture != rb->gi.voxel_gi_textures[i]) {
+ if (texture != rb->rbgi.voxel_gi_textures[i]) {
voxel_gi_instances_changed = true;
- rb->gi.voxel_gi_textures[i] = texture;
+ rb->rbgi.voxel_gi_textures[i] = texture;
}
}
if (voxel_gi_instances_changed) {
- if (RD::get_singleton()->uniform_set_is_valid(rb->gi.uniform_set)) {
- RD::get_singleton()->free(rb->gi.uniform_set);
+ for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {
+ if (RD::get_singleton()->uniform_set_is_valid(rb->rbgi.uniform_set[v])) {
+ RD::get_singleton()->free(rb->rbgi.uniform_set[v]);
+ }
+ rb->rbgi.uniform_set[v] = RID();
}
- rb->gi.uniform_set = RID();
if (rb->volumetric_fog) {
if (RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) {
RD::get_singleton()->free(rb->volumetric_fog->fog_uniform_set);
@@ -3140,21 +3550,76 @@ void RendererSceneGIRD::setup_voxel_gi_instances(RID p_render_buffers, const Tra
}
}
-void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) {
+void GI::RenderBuffersGI::free() {
+ for (uint32_t v = 0; v < RendererSceneRender::MAX_RENDER_VIEWS; v++) {
+ if (RD::get_singleton()->uniform_set_is_valid(uniform_set[v])) {
+ RD::get_singleton()->free(uniform_set[v]);
+ }
+ uniform_set[v] = RID();
+ }
+
+ if (scene_data_ubo.is_valid()) {
+ RD::get_singleton()->free(scene_data_ubo);
+ scene_data_ubo = RID();
+ }
+
+ if (ambient_buffer.is_valid()) {
+ if (view_count == 1) {
+ // Only one view? then these are copies of our main buffers.
+ ambient_view[0] = RID();
+ reflection_view[0] = RID();
+ } else {
+ // Multiple views? free our slices.
+ for (uint32_t v = 0; v < view_count; v++) {
+ RD::get_singleton()->free(ambient_view[v]);
+ RD::get_singleton()->free(reflection_view[v]);
+ ambient_view[v] = RID();
+ reflection_view[v] = RID();
+ }
+ }
+
+ // Now we can free our buffers.
+ RD::get_singleton()->free(ambient_buffer);
+ RD::get_singleton()->free(reflection_buffer);
+ ambient_buffer = RID();
+ reflection_buffer = RID();
+ view_count = 0;
+ }
+
+ if (voxel_gi_buffer.is_valid()) {
+ RD::get_singleton()->free(voxel_gi_buffer);
+ voxel_gi_buffer = RID();
+ }
+}
+
+void GI::process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_voxel_gi_buffer, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
+ ERR_FAIL_COND_MSG(p_view_count > 2, "Maximum of 2 views supported for Processing GI.");
+
RD::get_singleton()->draw_command_begin_label("GI Render");
RendererSceneRenderRD::RenderBuffers *rb = p_scene_render->render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND(rb == nullptr);
- if (rb->ambient_buffer.is_null() || rb->gi.using_half_size_gi != half_resolution) {
- if (rb->ambient_buffer.is_valid()) {
- RD::get_singleton()->free(rb->ambient_buffer);
- RD::get_singleton()->free(rb->reflection_buffer);
+ if (rb->rbgi.ambient_buffer.is_null() || rb->rbgi.using_half_size_gi != half_resolution || rb->rbgi.view_count != p_view_count) {
+ // Free our old buffer if applicable
+ if (rb->rbgi.ambient_buffer.is_valid()) {
+ if (rb->rbgi.view_count > 1) {
+ for (uint32_t v = 0; v < rb->rbgi.view_count; v++) {
+ RD::get_singleton()->free(rb->rbgi.ambient_view[v]);
+ RD::get_singleton()->free(rb->rbgi.reflection_view[v]);
+ }
+ }
+ RD::get_singleton()->free(rb->rbgi.ambient_buffer);
+ RD::get_singleton()->free(rb->rbgi.reflection_buffer);
}
+ // Remember the view count we're using
+ rb->rbgi.view_count = p_view_count;
+
+ // Create textures for our ambient and reflection data
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = rb->internal_width;
@@ -3163,252 +3628,309 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_
tf.width >>= 1;
tf.height >>= 1;
}
+ if (p_view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.array_layers = p_view_count;
+ } else {
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ tf.array_layers = 1;
+ }
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
- rb->reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
- rb->ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
- rb->gi.using_half_size_gi = half_resolution;
- }
-
- PushConstant push_constant;
-
- push_constant.screen_size[0] = rb->internal_width;
- push_constant.screen_size[1] = rb->internal_height;
- push_constant.z_near = p_projection.get_z_near();
- push_constant.z_far = p_projection.get_z_far();
- push_constant.orthogonal = p_projection.is_orthogonal();
- push_constant.proj_info[0] = -2.0f / (rb->internal_width * p_projection.matrix[0][0]);
- push_constant.proj_info[1] = -2.0f / (rb->internal_height * p_projection.matrix[1][1]);
- push_constant.proj_info[2] = (1.0f - p_projection.matrix[0][2]) / p_projection.matrix[0][0];
- push_constant.proj_info[3] = (1.0f + p_projection.matrix[1][2]) / p_projection.matrix[1][1];
- push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size());
- push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH;
-
- bool use_sdfgi = rb->sdfgi != nullptr;
- bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0;
-
- push_constant.cam_rotation[0] = p_transform.basis[0][0];
- push_constant.cam_rotation[1] = p_transform.basis[1][0];
- push_constant.cam_rotation[2] = p_transform.basis[2][0];
- push_constant.cam_rotation[3] = 0;
- push_constant.cam_rotation[4] = p_transform.basis[0][1];
- push_constant.cam_rotation[5] = p_transform.basis[1][1];
- push_constant.cam_rotation[6] = p_transform.basis[2][1];
- push_constant.cam_rotation[7] = 0;
- push_constant.cam_rotation[8] = p_transform.basis[0][2];
- push_constant.cam_rotation[9] = p_transform.basis[1][2];
- push_constant.cam_rotation[10] = p_transform.basis[2][2];
- push_constant.cam_rotation[11] = 0;
-
- if (rb->gi.uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->gi.uniform_set)) {
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.binding = 1;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
- u.append_id(rb->sdfgi->cascades[j].sdf_tex);
- } else {
- u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
- }
+ rb->rbgi.ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ rb->rbgi.reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ rb->rbgi.using_half_size_gi = half_resolution;
+
+ if (p_view_count == 1) {
+ // Just one view? Copy our buffers
+ rb->rbgi.ambient_view[0] = rb->rbgi.ambient_buffer;
+ rb->rbgi.reflection_view[0] = rb->rbgi.reflection_buffer;
+ } else {
+ // More then one view? Create slices for each view
+ for (uint32_t v = 0; v < p_view_count; v++) {
+ rb->rbgi.ambient_view[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->rbgi.ambient_buffer, v, 0);
+ rb->rbgi.reflection_view[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->rbgi.reflection_buffer, v, 0);
}
- uniforms.push_back(u);
}
- {
- RD::Uniform u;
- u.binding = 2;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
- u.append_id(rb->sdfgi->cascades[j].light_tex);
- } else {
- u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+
+ // Setup our scene data
+ {
+ SceneData scene_data;
+
+ if (rb->rbgi.scene_data_ubo.is_null()) {
+ rb->rbgi.scene_data_ubo = RD::get_singleton()->uniform_buffer_create(sizeof(SceneData));
+ }
+
+ for (uint32_t v = 0; v < p_view_count; v++) {
+ RendererRD::MaterialStorage::store_camera(p_projections[v].inverse(), scene_data.inv_projection[v]);
+ scene_data.eye_offset[v][0] = p_eye_offsets[v].x;
+ scene_data.eye_offset[v][1] = p_eye_offsets[v].y;
+ scene_data.eye_offset[v][2] = p_eye_offsets[v].z;
+ scene_data.eye_offset[v][3] = 0.0;
+ }
+
+ // Note that we will be ignoring the origin of this transform.
+ RendererRD::MaterialStorage::store_transform(p_cam_transform, scene_data.cam_transform);
+
+ scene_data.screen_size[0] = rb->internal_width;
+ scene_data.screen_size[1] = rb->internal_height;
+
+ RD::get_singleton()->buffer_update(rb->rbgi.scene_data_ubo, 0, sizeof(SceneData), &scene_data, RD::BARRIER_MASK_COMPUTE);
+ }
+
+ // Now compute the contents of our buffers.
+ RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true);
+
+ for (uint32_t v = 0; v < p_view_count; v++) {
+ // Render each eye seperately.
+ // We need to look into whether we can make our compute shader use Multiview but not sure that works or makes a difference..
+
+ // setup our push constant
+
+ PushConstant push_constant;
+
+ push_constant.view_index = v;
+ push_constant.orthogonal = p_projections[v].is_orthogonal();
+ push_constant.max_voxel_gi_instances = MIN((uint64_t)MAX_VOXEL_GI_INSTANCES, p_voxel_gi_instances.size());
+ push_constant.high_quality_vct = voxel_gi_quality == RS::VOXEL_GI_QUALITY_HIGH;
+
+ push_constant.z_near = p_projections[v].get_z_near();
+ push_constant.z_far = p_projections[v].get_z_far();
+
+ push_constant.proj_info[0] = -2.0f / (rb->internal_width * p_projections[v].matrix[0][0]);
+ push_constant.proj_info[1] = -2.0f / (rb->internal_height * p_projections[v].matrix[1][1]);
+ push_constant.proj_info[2] = (1.0f - p_projections[v].matrix[0][2]) / p_projections[v].matrix[0][0];
+ push_constant.proj_info[3] = (1.0f + p_projections[v].matrix[1][2]) / p_projections[v].matrix[1][1];
+
+ bool use_sdfgi = rb->sdfgi != nullptr;
+ bool use_voxel_gi_instances = push_constant.max_voxel_gi_instances > 0;
+
+ // setup our uniform set
+ if (rb->rbgi.uniform_set[v].is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->rbgi.uniform_set[v])) {
+ Vector<RD::Uniform> uniforms;
+ {
+ RD::Uniform u;
+ u.binding = 1;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
+ u.append_id(rb->sdfgi->cascades[j].sdf_tex);
+ } else {
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
}
+ uniforms.push_back(u);
}
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 3;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
- u.append_id(rb->sdfgi->cascades[j].light_aniso_0_tex);
+ {
+ RD::Uniform u;
+ u.binding = 2;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
+ u.append_id(rb->sdfgi->cascades[j].light_tex);
+ } else {
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 3;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
+ u.append_id(rb->sdfgi->cascades[j].light_aniso_0_tex);
+ } else {
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.binding = 4;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
+ if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
+ u.append_id(rb->sdfgi->cascades[j].light_aniso_1_tex);
+ } else {
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ }
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 5;
+ if (rb->sdfgi) {
+ u.append_id(rb->sdfgi->occlusion_texture);
} else {
u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
}
+ uniforms.push_back(u);
}
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.binding = 4;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- for (uint32_t j = 0; j < SDFGI::MAX_CASCADES; j++) {
- if (rb->sdfgi && j < rb->sdfgi->cascades.size()) {
- u.append_id(rb->sdfgi->cascades[j].light_aniso_1_tex);
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 6;
+ u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
+ u.binding = 7;
+ u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 9;
+ u.append_id(rb->rbgi.ambient_view[v]);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
+ u.binding = 10;
+ u.append_id(rb->rbgi.reflection_view[v]);
+ uniforms.push_back(u);
+ }
+
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 11;
+ if (rb->sdfgi) {
+ u.append_id(rb->sdfgi->lightprobe_texture);
} else {
- u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE));
}
+ uniforms.push_back(u);
}
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 5;
- if (rb->sdfgi) {
- u.append_id(rb->sdfgi->occlusion_texture);
- } else {
- u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_3D_WHITE));
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 12;
+ u.append_id(rb->views[v].view_depth);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 13;
+ u.append_id(p_normal_roughness_views[v]);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 14;
+ RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK);
+ u.append_id(buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 15;
+ u.append_id(sdfgi_ubo);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 16;
+ u.append_id(rb->rbgi.voxel_gi_buffer);
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 17;
+ for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) {
+ u.append_id(rb->rbgi.voxel_gi_textures[i]);
+ }
+ uniforms.push_back(u);
+ }
+ {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 18;
+ u.append_id(rb->rbgi.scene_data_ubo);
+ uniforms.push_back(u);
}
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 6;
- u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.binding = 7;
- u.append_id(material_storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_LINEAR_WITH_MIPMAPS, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED));
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 9;
- u.append_id(rb->ambient_buffer);
- uniforms.push_back(u);
+ rb->rbgi.uniform_set[v] = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, 0), 0);
}
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 10;
- u.append_id(rb->reflection_buffer);
- uniforms.push_back(u);
- }
+ Mode mode;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 11;
- if (rb->sdfgi) {
- u.append_id(rb->sdfgi->lightprobe_texture);
+ if (p_view_count > 1) {
+ if (rb->rbgi.using_half_size_gi) {
+ mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_HALF_RES_COMBINED_MULTIVIEW : (use_sdfgi ? MODE_HALF_RES_SDFGI_MULTIVIEW : MODE_HALF_RES_VOXEL_GI_MULTIVIEW);
} else {
- u.append_id(texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE));
+ mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED_MULTIVIEW : (use_sdfgi ? MODE_SDFGI_MULTIVIEW : MODE_VOXEL_GI_MULTIVIEW);
}
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 12;
- u.append_id(rb->depth_texture);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 13;
- u.append_id(p_normal_roughness_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 14;
- RID buffer = p_voxel_gi_buffer.is_valid() ? p_voxel_gi_buffer : texture_storage->texture_rd_get_default(RendererRD::DEFAULT_RD_TEXTURE_BLACK);
- u.append_id(buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 15;
- u.append_id(sdfgi_ubo);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 16;
- u.append_id(rb->gi.voxel_gi_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 17;
- for (int i = 0; i < MAX_VOXEL_GI_INSTANCES; i++) {
- u.append_id(rb->gi.voxel_gi_textures[i]);
+ } else {
+ if (rb->rbgi.using_half_size_gi) {
+ mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_VOXEL_GI);
+ } else {
+ mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_VOXEL_GI);
}
- uniforms.push_back(u);
}
- rb->gi.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, 0), 0);
- }
-
- Mode mode;
+ RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[mode]);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->rbgi.uniform_set[v], 0);
+ RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
- if (rb->gi.using_half_size_gi) {
- mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_VOXEL_GI);
- } else {
- mode = (use_sdfgi && use_voxel_gi_instances) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_VOXEL_GI);
+ if (rb->rbgi.using_half_size_gi) {
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->internal_width >> 1, rb->internal_height >> 1, 1);
+ } else {
+ RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->internal_width, rb->internal_height, 1);
+ }
}
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true);
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[mode]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi.uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
-
- if (rb->gi.using_half_size_gi) {
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->internal_width >> 1, rb->internal_height >> 1, 1);
- } else {
- RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->internal_width, rb->internal_height, 1);
- }
//do barrier later to allow oeverlap
//RD::get_singleton()->compute_list_end(RD::BARRIER_MASK_NO_BARRIER); //no barriers, let other compute, raster and transfer happen at the same time
RD::get_singleton()->draw_command_end_label();
}
-RID RendererSceneGIRD::voxel_gi_instance_create(RID p_base) {
+RID GI::voxel_gi_instance_create(RID p_base) {
VoxelGIInstance voxel_gi;
voxel_gi.gi = this;
- voxel_gi.storage = storage;
voxel_gi.probe = p_base;
RID rid = voxel_gi_instance_owner.make_rid(voxel_gi);
return rid;
}
-void RendererSceneGIRD::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) {
+void GI::voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) {
VoxelGIInstance *voxel_gi = get_probe_instance(p_probe);
ERR_FAIL_COND(!voxel_gi);
voxel_gi->transform = p_xform;
}
-bool RendererSceneGIRD::voxel_gi_needs_update(RID p_probe) const {
+bool GI::voxel_gi_needs_update(RID p_probe) const {
VoxelGIInstance *voxel_gi = get_probe_instance(p_probe);
ERR_FAIL_COND_V(!voxel_gi, false);
- return voxel_gi->last_probe_version != storage->voxel_gi_get_version(voxel_gi->probe);
+ return voxel_gi->last_probe_version != voxel_gi_get_version(voxel_gi->probe);
}
-void RendererSceneGIRD::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
+void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
VoxelGIInstance *voxel_gi = get_probe_instance(p_probe);
ERR_FAIL_COND(!voxel_gi);
voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render);
}
-void RendererSceneGIRD::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
+void GI::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_voxel_gi);
ERR_FAIL_COND(!voxel_gi);
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/environment/gi.h
index 122644498b..294b8d3cfd 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
+++ b/servers/rendering/renderer_rd/environment/gi.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* renderer_scene_gi_rd.h */
+/* gi.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,33 +28,73 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef RENDERING_SERVER_SCENE_GI_RD_H
-#define RENDERING_SERVER_SCENE_GI_RD_H
+#ifndef GI_RD_H
+#define GI_RD_H
#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
+#include "servers/rendering/environment/renderer_gi.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
-#include "servers/rendering/renderer_rd/shaders/gi.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/voxel_gi.glsl.gen.h"
-#include "servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/environment/gi.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl.gen.h"
+#include "servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl.gen.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
+#include "servers/rendering/storage/utilities.h"
// Forward declare RenderDataRD and RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
struct RenderDataRD;
class RendererSceneRenderRD;
-class RendererSceneGIRD {
+namespace RendererRD {
+
+class GI : public RendererGI {
+public:
+ /* VOXEL GI STORAGE */
+
+ struct VoxelGI {
+ RID octree_buffer;
+ RID data_buffer;
+ RID sdf_texture;
+
+ uint32_t octree_buffer_size = 0;
+ uint32_t data_buffer_size = 0;
+
+ Vector<int> level_counts;
+
+ int cell_count = 0;
+
+ Transform3D to_cell_xform;
+ AABB bounds;
+ Vector3i octree_size;
+
+ float dynamic_range = 2.0;
+ float energy = 1.0;
+ float bias = 1.4;
+ float normal_bias = 0.0;
+ float propagation = 0.7;
+ bool interior = false;
+ bool use_two_bounces = false;
+
+ uint32_t version = 1;
+ uint32_t data_version = 1;
+
+ Dependency dependency;
+ };
+
private:
- RendererStorageRD *storage = nullptr;
+ static GI *singleton;
+
+ /* VOXEL GI STORAGE */
+
+ mutable RID_Owner<VoxelGI, true> voxel_gi_owner;
/* VOXEL_GI INSTANCE */
@@ -196,10 +236,13 @@ private:
uint32_t use_occlusion;
float y_mult;
- float cam_extent[3];
uint32_t probe_axis_size;
+ float z_near;
+ float reserved1;
+ float reserved2;
float cam_transform[16];
+ float inv_projection[16];
};
SdfgiDebugShaderRD debug;
@@ -209,13 +252,17 @@ private:
enum ProbeDebugMode {
PROBE_DEBUG_PROBES,
+ PROBE_DEBUG_PROBES_MULTIVIEW,
PROBE_DEBUG_VISIBILITY,
+ PROBE_DEBUG_VISIBILITY_MULTIVIEW,
PROBE_DEBUG_MAX
};
- struct DebugProbesPushConstant {
- float projection[16];
+ struct DebugProbesSceneData {
+ float projection[2][16];
+ };
+ struct DebugProbesPushConstant {
uint32_t band_power;
uint32_t sections_in_band;
uint32_t band_mask;
@@ -324,14 +371,64 @@ private:
} sdfgi_shader;
public:
+ static GI *get_singleton() { return singleton; }
+
+ /* VOXEL GI API */
+
+ VoxelGI *get_voxel_gi(RID p_rid) { return voxel_gi_owner.get_or_null(p_rid); };
+ bool owns_voxel_gi(RID p_rid) { return voxel_gi_owner.owns(p_rid); };
+
+ virtual RID voxel_gi_allocate() override;
+ virtual void voxel_gi_free(RID p_voxel_gi) override;
+ virtual void voxel_gi_initialize(RID p_voxel_gi) override;
+
+ virtual void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) override;
+
+ virtual AABB voxel_gi_get_bounds(RID p_voxel_gi) const override;
+ virtual Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const override;
+ virtual Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const override;
+ virtual Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const override;
+ virtual Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const override;
+
+ virtual Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const override;
+ virtual Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const override;
+
+ virtual void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) override;
+ virtual float voxel_gi_get_dynamic_range(RID p_voxel_gi) const override;
+
+ virtual void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) override;
+ virtual float voxel_gi_get_propagation(RID p_voxel_gi) const override;
+
+ virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_energy) override;
+ virtual float voxel_gi_get_energy(RID p_voxel_gi) const override;
+
+ virtual void voxel_gi_set_bias(RID p_voxel_gi, float p_bias) override;
+ virtual float voxel_gi_get_bias(RID p_voxel_gi) const override;
+
+ virtual void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) override;
+ virtual float voxel_gi_get_normal_bias(RID p_voxel_gi) const override;
+
+ virtual void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) override;
+ virtual bool voxel_gi_is_interior(RID p_voxel_gi) const override;
+
+ virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) override;
+ virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const override;
+
+ virtual uint32_t voxel_gi_get_version(RID p_probe) const override;
+ uint32_t voxel_gi_get_data_version(RID p_probe);
+
+ RID voxel_gi_get_octree_buffer(RID p_voxel_gi) const;
+ RID voxel_gi_get_data_buffer(RID p_voxel_gi) const;
+
+ RID voxel_gi_get_sdf_texture(RID p_voxel_gi);
+
/* VOXEL_GI INSTANCE */
//@TODO VoxelGIInstance is still directly used in the render code, we'll address this when we refactor the render code itself.
struct VoxelGIInstance {
// access to our containers
- RendererStorageRD *storage = nullptr;
- RendererSceneGIRD *gi = nullptr;
+ GI *gi = nullptr;
RID probe;
RID texture;
@@ -454,8 +551,7 @@ public:
};
// access to our containers
- RendererStorageRD *storage = nullptr;
- RendererSceneGIRD *gi = nullptr;
+ GI *gi = nullptr;
// used for rendering (voxelization)
RID render_albedo;
@@ -497,7 +593,8 @@ public:
float min_cell_size = 0;
uint32_t probe_axis_count = 0; //amount of probes per axis, this is an odd number because it encloses endpoints
- RID debug_uniform_set;
+ RID debug_uniform_set[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID debug_probes_scene_data_ubo;
RID debug_probes_uniform_set;
RID cascades_ubo;
@@ -516,7 +613,7 @@ public:
int32_t cascade_dynamic_light_count[SDFGI::MAX_CASCADES]; //used dynamically
RID integrate_sky_uniform_set;
- void create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, RendererSceneGIRD *p_gi);
+ void create(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size, GI *p_gi);
void erase();
void update(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position);
void update_light();
@@ -525,8 +622,8 @@ public:
int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const;
void update_cascades();
- void debug_draw(const CameraMatrix &p_projection, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture);
- void debug_probes(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
+ void debug_draw(uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views);
+ void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth);
void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render);
void render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render);
@@ -561,8 +658,18 @@ public:
RID full_dispatch;
RID full_mask;
- RID uniform_set;
+ /* GI buffers */
+ RID ambient_buffer;
+ RID reflection_buffer;
+ RID ambient_view[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID reflection_view[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID uniform_set[RendererSceneRender::MAX_RENDER_VIEWS];
bool using_half_size_gi = false;
+ uint32_t view_count = 1;
+
+ RID scene_data_ubo;
+
+ void free();
};
struct SDFGIData {
@@ -611,19 +718,28 @@ public:
uint32_t mipmaps; // 4 - 96
};
- struct PushConstant {
- int32_t screen_size[2];
- float z_near;
- float z_far;
+ struct SceneData {
+ float inv_projection[2][16];
+ float cam_transform[16];
+ float eye_offset[2][4];
- float proj_info[4];
+ int32_t screen_size[2];
+ float pad1;
+ float pad2;
+ };
+ struct PushConstant {
+ uint32_t view_index;
uint32_t max_voxel_gi_instances;
uint32_t high_quality_vct;
uint32_t orthogonal;
- uint32_t pad;
- float cam_rotation[12];
+ float proj_info[4];
+
+ float z_near;
+ float z_far;
+ float pad1;
+ float pad2;
};
RID sdfgi_ubo;
@@ -634,6 +750,14 @@ public:
MODE_HALF_RES_VOXEL_GI,
MODE_HALF_RES_SDFGI,
MODE_HALF_RES_COMBINED,
+
+ MODE_VOXEL_GI_MULTIVIEW,
+ MODE_SDFGI_MULTIVIEW,
+ MODE_COMBINED_MULTIVIEW,
+ MODE_HALF_RES_VOXEL_GI_MULTIVIEW,
+ MODE_HALF_RES_SDFGI_MULTIVIEW,
+ MODE_HALF_RES_COMBINED_MULTIVIEW,
+
MODE_MAX
};
@@ -644,16 +768,16 @@ public:
RID shader_version;
RID pipelines[MODE_MAX];
- RendererSceneGIRD();
- ~RendererSceneGIRD();
+ GI();
+ ~GI();
- void init(RendererStorageRD *p_storage, RendererSceneSkyRD *p_sky);
+ void init(RendererSceneSkyRD *p_sky);
void free();
SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size);
void setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render);
- void process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render);
+ void process_gi(RID p_render_buffers, RID *p_normal_roughness_views, RID p_voxel_gi_buffer, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render);
RID voxel_gi_instance_create(RID p_base);
void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform);
@@ -662,4 +786,6 @@ public:
void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
};
-#endif /* !RENDERING_SERVER_SCENE_GI_RD_H */
+} // namespace RendererRD
+
+#endif /* !GI_RD_H */
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index d390614e53..f759fa3aa5 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -30,6 +30,7 @@
#include "render_forward_clustered.h"
#include "core/config/project_settings.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h"
@@ -48,6 +49,13 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
if (!specular.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
+ if (view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.array_layers = view_count;
+ } else {
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ tf.array_layers = 1;
+ }
tf.width = width;
tf.height = height;
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
@@ -64,7 +72,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
Vector<RID> fb;
fb.push_back(specular);
- specular_only_fb = RD::get_singleton()->framebuffer_create(fb);
+ specular_only_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, view_count);
}
} else {
@@ -76,7 +84,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular()
Vector<RID> fb;
fb.push_back(specular_msaa);
- specular_only_fb = RD::get_singleton()->framebuffer_create(fb);
+ specular_only_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, view_count);
}
}
}
@@ -106,6 +114,13 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_velocity()
void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi() {
if (!voxelgi_buffer.is_valid()) {
RD::TextureFormat tf;
+ if (view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.array_layers = view_count;
+ } else {
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ tf.array_layers = 1;
+ }
tf.format = RD::DATA_FORMAT_R8G8_UINT;
tf.width = width;
tf.height = height;
@@ -116,6 +131,14 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi()
tf_aa.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
tf_aa.samples = texture_samples;
voxelgi_buffer_msaa = RD::get_singleton()->texture_create(tf_aa, RD::TextureView());
+
+ if (view_count == 1) {
+ voxelgi_msaa_views[0] = voxelgi_buffer_msaa;
+ } else {
+ for (uint32_t v = 0; v < view_count; v++) {
+ voxelgi_msaa_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), voxelgi_buffer_msaa, v, 0);
+ }
+ }
} else {
tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
}
@@ -124,6 +147,14 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi()
voxelgi_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ if (view_count == 1) {
+ voxelgi_views[0] = voxelgi_buffer;
+ } else {
+ for (uint32_t v = 0; v < view_count; v++) {
+ voxelgi_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), voxelgi_buffer, v, 0);
+ }
+ }
+
Vector<RID> fb;
if (msaa != RS::VIEWPORT_MSAA_DISABLED) {
fb.push_back(depth_msaa);
@@ -135,7 +166,7 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_voxelgi()
fb.push_back(voxelgi_buffer);
}
- depth_normal_roughness_voxelgi_fb = RD::get_singleton()->framebuffer_create(fb);
+ depth_normal_roughness_voxelgi_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, view_count);
}
}
@@ -144,7 +175,25 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
RD::get_singleton()->free(voxelgi_buffer);
voxelgi_buffer = RID();
+ if (view_count == 1) {
+ voxelgi_views[0] = RID();
+ } else {
+ for (uint32_t v = 0; v < view_count; v++) {
+ RD::get_singleton()->free(voxelgi_views[v]);
+ voxelgi_views[v] = RID();
+ }
+ }
+
if (voxelgi_buffer_msaa.is_valid()) {
+ if (view_count == 1) {
+ voxelgi_msaa_views[0] = RID();
+ } else {
+ for (uint32_t v = 0; v < view_count; v++) {
+ RD::get_singleton()->free(voxelgi_msaa_views[v]);
+ voxelgi_msaa_views[v] = RID();
+ }
+ }
+
RD::get_singleton()->free(voxelgi_buffer_msaa);
voxelgi_buffer_msaa = RID();
}
@@ -153,11 +202,35 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
}
if (color_msaa.is_valid()) {
+ if (view_count == 1) {
+ color_views[0] = RID();
+ color_msaa_views[0] = RID();
+ } else {
+ for (uint32_t v = 0; v < view_count; v++) {
+ RD::get_singleton()->free(color_views[v]);
+ RD::get_singleton()->free(color_msaa_views[v]);
+ color_views[v] = RID();
+ color_msaa_views[v] = RID();
+ }
+ }
+
RD::get_singleton()->free(color_msaa);
color_msaa = RID();
}
if (depth_msaa.is_valid()) {
+ if (view_count == 1) {
+ depth_views[0] = RID();
+ depth_msaa_views[0] = RID();
+ } else {
+ for (uint32_t v = 0; v < view_count; v++) {
+ RD::get_singleton()->free(depth_views[v]);
+ RD::get_singleton()->free(depth_msaa_views[v]);
+ depth_views[v] = RID();
+ depth_msaa_views[v] = RID();
+ }
+ }
+
RD::get_singleton()->free(depth_msaa);
depth_msaa = RID();
}
@@ -178,12 +251,31 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
color_framebuffers.clear(); // Color pass framebuffers are freed automatically by their dependency relations
if (normal_roughness_buffer.is_valid()) {
+ if (view_count == 1) {
+ normal_roughness_views[0] = RID();
+ } else {
+ for (uint32_t v = 0; v < view_count; v++) {
+ RD::get_singleton()->free(normal_roughness_views[v]);
+ normal_roughness_views[v] = RID();
+ }
+ }
+
RD::get_singleton()->free(normal_roughness_buffer);
+ normal_roughness_buffer = RID();
+
if (normal_roughness_buffer_msaa.is_valid()) {
+ if (view_count == 1) {
+ normal_roughness_msaa_views[0] = RID();
+ } else {
+ for (uint32_t v = 0; v < view_count; v++) {
+ RD::get_singleton()->free(normal_roughness_msaa_views[v]);
+ normal_roughness_msaa_views[v] = RID();
+ }
+ }
RD::get_singleton()->free(normal_roughness_buffer_msaa);
normal_roughness_buffer_msaa = RID();
}
- normal_roughness_buffer = RID();
+
depth_normal_roughness_fb = RID();
}
@@ -254,11 +346,27 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
color_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
- tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
+ tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
tf.usage_bits = RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
depth_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
+ if (view_count == 1) {
+ // just reuse
+ color_views[0] = color;
+ depth_views[0] = depth;
+ color_msaa_views[0] = color_msaa;
+ depth_msaa_views[0] = depth_msaa;
+ } else {
+ // create slices
+ for (uint32_t v = 0; v < view_count; v++) {
+ color_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), color, v, 0);
+ depth_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), depth, v, 0);
+ color_msaa_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), color_msaa, v, 0);
+ depth_msaa_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), depth_msaa, v, 0);
+ }
+ }
+
{
Vector<RID> fb;
fb.push_back(color_msaa);
@@ -308,6 +416,8 @@ RID RenderForwardClustered::RenderBufferDataForwardClustered::get_color_pass_fb(
}
void RenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferDataForwardClustered *rb) {
+ ERR_FAIL_COND_MSG(rb->view_count > 2, "Only support up to two views for roughness texture");
+
if (rb->normal_roughness_buffer.is_valid()) {
return;
}
@@ -316,10 +426,17 @@ void RenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferData
tf.format = RD::DATA_FORMAT_R8G8B8A8_UNORM;
tf.width = rb->width;
tf.height = rb->height;
+ if (rb->view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ tf.array_layers = rb->view_count;
+ } else {
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ tf.array_layers = 1;
+ }
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ tf.usage_bits |= RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
} else {
tf.usage_bits |= RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
}
@@ -330,16 +447,30 @@ void RenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferData
Vector<RID> fb;
fb.push_back(rb->depth);
fb.push_back(rb->normal_roughness_buffer);
- rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb);
+ rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, rb->view_count);
} else {
- tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
+ tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
tf.samples = rb->texture_samples;
rb->normal_roughness_buffer_msaa = RD::get_singleton()->texture_create(tf, RD::TextureView());
Vector<RID> fb;
fb.push_back(rb->depth_msaa);
fb.push_back(rb->normal_roughness_buffer_msaa);
- rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb);
+ rb->depth_normal_roughness_fb = RD::get_singleton()->framebuffer_create(fb, RD::INVALID_ID, rb->view_count);
+ }
+
+ if (rb->view_count == 1) {
+ rb->normal_roughness_views[0] = rb->normal_roughness_buffer;
+ if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
+ rb->normal_roughness_msaa_views[0] = rb->normal_roughness_buffer_msaa;
+ }
+ } else {
+ for (uint32_t v = 0; v < rb->view_count; v++) {
+ rb->normal_roughness_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->normal_roughness_buffer, v, 0);
+ if (rb->msaa != RS::VIEWPORT_MSAA_DISABLED) {
+ rb->normal_roughness_msaa_views[v] = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->normal_roughness_buffer_msaa, v, 0);
+ }
+ }
}
}
@@ -503,22 +634,21 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS;
} break;
case PASS_MODE_SHADOW_DP: {
- ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for shadow DP pass");
+ ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for shadow DP pass");
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_DP;
} break;
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
- ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for depth/roughness pass");
- pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS;
+ pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS;
} break;
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: {
- ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for voxel GI pass");
- pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI;
+ pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI;
} break;
case PASS_MODE_DEPTH_MATERIAL: {
ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for material pass");
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL;
} break;
case PASS_MODE_SDF: {
+ // Note, SDF is prepared in world space, this shouldn't be a multiview buffer even when stereoscopic rendering is used.
ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for SDF pass");
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_SDF;
} break;
@@ -683,15 +813,15 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
CameraMatrix projection = correction * p_render_data->cam_projection;
//store camera into ubo
- RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix);
- RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
- RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
- RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix);
+ RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix);
+ RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix);
for (uint32_t v = 0; v < p_render_data->view_count; v++) {
projection = correction * p_render_data->view_projection[v];
- RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
- RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
scene_state.ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x;
scene_state.ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y;
@@ -707,10 +837,10 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
scene_state.ubo.pancake_shadows = p_pancake_shadows;
- RendererStorageRD::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);
scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x;
@@ -805,7 +935,7 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
Basis sky_transform = environment_get_sky_orientation(p_render_data->environment);
sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;
- RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
+ RendererRD::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
@@ -876,15 +1006,15 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
CameraMatrix prev_projection = prev_correction * p_render_data->prev_cam_projection;
//store camera into ubo
- RendererStorageRD::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix);
- RendererStorageRD::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix);
- RendererStorageRD::store_transform(p_render_data->prev_cam_transform, scene_state.prev_ubo.inv_view_matrix);
- RendererStorageRD::store_transform(p_render_data->prev_cam_transform.affine_inverse(), scene_state.prev_ubo.view_matrix);
+ RendererRD::MaterialStorage::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix);
+ RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->prev_cam_transform, scene_state.prev_ubo.inv_view_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->prev_cam_transform.affine_inverse(), scene_state.prev_ubo.view_matrix);
for (uint32_t v = 0; v < p_render_data->view_count; v++) {
prev_projection = prev_correction * p_render_data->view_projection[v];
- RendererStorageRD::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix_view[v]);
- RendererStorageRD::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(prev_projection.inverse(), scene_state.prev_ubo.inv_projection_matrix_view[v]);
}
scene_state.prev_ubo.taa_jitter[0] = p_render_data->prev_taa_jitter.x;
scene_state.prev_ubo.taa_jitter[1] = p_render_data->prev_taa_jitter.y;
@@ -940,11 +1070,11 @@ void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, i
}
if (inst->store_transform_cache) {
- RendererStorageRD::store_transform(inst->transform, instance_data.transform);
- RendererStorageRD::store_transform(inst->prev_transform, instance_data.prev_transform);
+ RendererRD::MaterialStorage::store_transform(inst->transform, instance_data.transform);
+ RendererRD::MaterialStorage::store_transform(inst->prev_transform, instance_data.prev_transform);
} else {
- RendererStorageRD::store_transform(Transform3D(), instance_data.transform);
- RendererStorageRD::store_transform(Transform3D(), instance_data.prev_transform);
+ RendererRD::MaterialStorage::store_transform(Transform3D(), instance_data.transform);
+ RendererRD::MaterialStorage::store_transform(Transform3D(), instance_data.prev_transform);
}
instance_data.flags = inst->flags_cache;
@@ -1268,7 +1398,7 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps
Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
to_lm = to_lm.inverse().transposed(); //will transform normals
- RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
+ RendererRD::MaterialStorage::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
scene_state.lightmap_ids[i] = p_lightmaps[i];
scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap);
@@ -1323,9 +1453,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
using_voxelgi = true;
}
- if (p_render_data->view_count > 1) {
- depth_pass_mode = PASS_MODE_DEPTH;
- } else if (!p_render_data->environment.is_valid() && using_voxelgi) {
+ if (!p_render_data->environment.is_valid() && using_voxelgi) {
depth_pass_mode = PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI;
} else if (p_render_data->environment.is_valid() && (environment_is_ssr_enabled(p_render_data->environment) || environment_is_sdfgi_enabled(p_render_data->environment) || using_voxelgi)) {
if (environment_is_sdfgi_enabled(p_render_data->environment)) {
@@ -1531,9 +1659,13 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (needs_pre_resolve) {
RD::get_singleton()->barrier(RD::BARRIER_MASK_RASTER, RD::BARRIER_MASK_COMPUTE);
}
- storage->get_effects()->resolve_gi(render_buffer->depth_msaa, render_buffer->normal_roughness_buffer_msaa, using_voxelgi ? render_buffer->voxelgi_buffer_msaa : RID(), render_buffer->depth, render_buffer->normal_roughness_buffer, using_voxelgi ? render_buffer->voxelgi_buffer : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
+ for (uint32_t v = 0; v < render_buffer->view_count; v++) {
+ resolve_effects->resolve_gi(render_buffer->depth_msaa_views[v], render_buffer->normal_roughness_msaa_views[v], using_voxelgi ? render_buffer->voxelgi_msaa_views[v] : RID(), render_buffer->depth_views[v], render_buffer->normal_roughness_views[v], using_voxelgi ? render_buffer->voxelgi_views[v] : RID(), Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
+ }
} else if (finish_depth) {
- storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
+ for (uint32_t v = 0; v < render_buffer->view_count; v++) {
+ resolve_effects->resolve_depth(render_buffer->depth_msaa_views[v], render_buffer->depth_views[v], Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
+ }
}
RD::get_singleton()->draw_command_end_label();
}
@@ -1541,7 +1673,8 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
continue_depth = !finish_depth;
}
- _pre_opaque_render(p_render_data, using_ssao, using_ssil, using_sdfgi || using_voxelgi, render_buffer ? render_buffer->normal_roughness_buffer : RID(), render_buffer ? render_buffer->voxelgi_buffer : RID());
+ RID null_rids[2];
+ _pre_opaque_render(p_render_data, using_ssao, using_ssil, using_sdfgi || using_voxelgi, render_buffer ? render_buffer->normal_roughness_views : null_rids, render_buffer ? render_buffer->voxelgi_buffer : RID());
RD::get_singleton()->draw_command_begin_label("Render Opaque Pass");
@@ -1604,18 +1737,17 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
if (debug_sdfgi_probes) {
- //debug voxelgis
+ //debug sdfgi
bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only);
bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only);
CameraMatrix dc;
dc.set_depth_correction(true);
- CameraMatrix cm = (dc * p_render_data->cam_projection) * CameraMatrix(p_render_data->cam_transform.affine_inverse());
- RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
- RD::get_singleton()->draw_command_begin_label("Debug SDFGI");
- _debug_sdfgi_probes(p_render_data->render_buffers, draw_list, color_only_framebuffer, cm);
- RD::get_singleton()->draw_command_end_label();
- RD::get_singleton()->draw_list_end();
+ CameraMatrix cms[RendererSceneRender::MAX_RENDER_VIEWS];
+ for (uint32_t v = 0; v < p_render_data->view_count; v++) {
+ cms[v] = (dc * p_render_data->view_projection[v]) * CameraMatrix(p_render_data->cam_transform.affine_inverse());
+ }
+ _debug_sdfgi_probes(p_render_data->render_buffers, color_only_framebuffer, p_render_data->view_count, cms, will_continue_color, will_continue_depth);
}
if (draw_sky || draw_sky_fog_only) {
@@ -1635,14 +1767,20 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
if (render_buffer && !can_continue_color && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color);
+ // Handle views individual, might want to look at rewriting our resolve to do both layers in one pass.
+ for (uint32_t v = 0; v < render_buffer->view_count; v++) {
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa_views[v], render_buffer->color_views[v]);
+ }
+ // TODO mame this do multiview
if (using_separate_specular) {
RD::get_singleton()->texture_resolve_multisample(render_buffer->specular_msaa, render_buffer->specular);
}
}
if (render_buffer && !can_continue_depth && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
+ for (uint32_t v = 0; v < render_buffer->view_count; v++) {
+ resolve_effects->resolve_depth(render_buffer->depth_msaa_views[v], render_buffer->depth_views[v], Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
+ }
}
if (using_separate_specular) {
@@ -1661,7 +1799,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
} else {
//just mix specular back
RENDER_TIMESTAMP("Merge Specular");
- storage->get_effects()->merge_specular(color_only_framebuffer, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID());
+ RendererCompositorRD::singleton->get_effects()->merge_specular(color_only_framebuffer, render_buffer->specular, render_buffer->msaa == RS::VIEWPORT_MSAA_DISABLED ? RID() : render_buffer->color, RID());
}
}
@@ -1697,11 +1835,13 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RD::get_singleton()->draw_command_begin_label("Resolve");
if (render_buffer && render_buffer->msaa != RS::VIEWPORT_MSAA_DISABLED) {
- RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa, render_buffer->color);
- if (render_buffer->use_taa) {
+ for (uint32_t v = 0; v < render_buffer->view_count; v++) {
+ RD::get_singleton()->texture_resolve_multisample(render_buffer->color_msaa_views[v], render_buffer->color_views[v]);
+ resolve_effects->resolve_depth(render_buffer->depth_msaa_views[v], render_buffer->depth_views[v], Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
+ }
+ if (render_buffer->use_taa) { // TODO make TAA stereo capable, this will need to be handled in a separate PR
RD::get_singleton()->texture_resolve_multisample(render_buffer->velocity_buffer_msaa, render_buffer->velocity_buffer);
}
- storage->get_effects()->resolve_depth(render_buffer->depth_msaa, render_buffer->depth, Vector2i(render_buffer->width, render_buffer->height), texture_multisamples[render_buffer->msaa]);
}
RD::get_singleton()->draw_command_end_label();
@@ -2050,7 +2190,7 @@ void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i
to_bounds.origin = p_bounds.position;
to_bounds.basis.scale(p_bounds.size);
- RendererStorageRD::store_transform(to_bounds.affine_inverse() * render_data.cam_transform, scene_state.ubo.sdf_to_bounds);
+ RendererRD::MaterialStorage::store_transform(to_bounds.affine_inverse() * render_data.cam_transform, scene_state.ubo.sdf_to_bounds);
_setup_environment(&render_data, true, Vector2(1, 1), false, Color());
@@ -2749,7 +2889,7 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet
sdcache->surface_index = p_surface;
if (ginstance->data->dirty_dependencies) {
- storage->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
+ RSG::utilities->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
}
//shadow
@@ -2992,16 +3132,16 @@ void RenderForwardClustered::_update_dirty_geometry_instances() {
}
}
-void RenderForwardClustered::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) {
+void RenderForwardClustered::_geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) {
switch (p_notification) {
- case RendererStorage::DEPENDENCY_CHANGED_MATERIAL:
- case RendererStorage::DEPENDENCY_CHANGED_MESH:
- case RendererStorage::DEPENDENCY_CHANGED_PARTICLES:
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
- case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: {
+ case Dependency::DEPENDENCY_CHANGED_MATERIAL:
+ case Dependency::DEPENDENCY_CHANGED_MESH:
+ case Dependency::DEPENDENCY_CHANGED_PARTICLES:
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
+ case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {
static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata);
if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
ginstance->instance_count = RendererRD::MeshStorage::get_singleton()->multimesh_get_instances_to_draw(ginstance->data->base);
@@ -3012,12 +3152,12 @@ void RenderForwardClustered::_geometry_instance_dependency_changed(RendererStora
} break;
}
}
-void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) {
+void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
}
RendererSceneRender::GeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) {
- RS::InstanceType type = storage->get_base_type(p_base);
+ RS::InstanceType type = RSG::utilities->get_base_type(p_base);
ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
GeometryInstanceForwardClustered *ginstance = geometry_instance_alloc.alloc();
@@ -3281,8 +3421,7 @@ void RenderForwardClustered::_update_shader_quality_settings() {
_base_uniforms_changed(); //also need this
}
-RenderForwardClustered::RenderForwardClustered(RendererStorageRD *p_storage) :
- RendererSceneRenderRD(p_storage) {
+RenderForwardClustered::RenderForwardClustered() {
singleton = this;
/* SCENE SHADER */
@@ -3314,15 +3453,22 @@ RenderForwardClustered::RenderForwardClustered(RendererStorageRD *p_storage) :
defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n";
}
- scene_shader.init(p_storage, defines);
+ scene_shader.init(defines);
}
render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances");
_update_shader_quality_settings();
+
+ resolve_effects = memnew(RendererRD::Resolve());
}
RenderForwardClustered::~RenderForwardClustered() {
+ if (resolve_effects != nullptr) {
+ memdelete(resolve_effects);
+ resolve_effects = nullptr;
+ }
+
directional_shadow_atlas_set_size(0);
{
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
index 97f39164a4..9e1f1b9954 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -32,11 +32,12 @@
#define RENDERING_SERVER_SCENE_RENDER_FORWARD_CLUSTERED_H
#include "core/templates/paged_allocator.h"
+#include "servers/rendering/renderer_rd/effects/resolve.h"
#include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h"
+#include "servers/rendering/renderer_rd/storage_rd/utilities.h"
namespace RendererSceneRenderImplementation {
@@ -72,7 +73,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RENDER_LIST_ALPHA, //used for transparent objects
RENDER_LIST_SECONDARY, //used for shadows and other objects
RENDER_LIST_MAX
-
};
/* Scene Shader */
@@ -99,7 +99,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID depth_msaa;
RID specular_msaa;
RID normal_roughness_buffer_msaa;
- RID roughness_buffer_msaa;
RID voxelgi_buffer_msaa;
RID velocity_buffer_msaa;
@@ -110,7 +109,17 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID specular_only_fb;
int width, height;
HashMap<uint32_t, RID> color_framebuffers;
+
+ // for multiview
uint32_t view_count;
+ RID color_views[RendererSceneRender::MAX_RENDER_VIEWS]; // we should rewrite this so we get access to the existing views in our renderer, something we can address when we reorg this
+ RID depth_views[RendererSceneRender::MAX_RENDER_VIEWS]; // we should rewrite this so we get access to the existing views in our renderer, something we can address when we reorg this
+ RID color_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID depth_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID normal_roughness_views[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID normal_roughness_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID voxelgi_views[RendererSceneRender::MAX_RENDER_VIEWS];
+ RID voxelgi_msaa_views[RendererSceneRender::MAX_RENDER_VIEWS];
RID render_sdfgi_uniform_set;
void ensure_specular();
@@ -527,12 +536,12 @@ class RenderForwardClustered : public RendererSceneRenderRD {
AABB aabb;
bool use_dynamic_gi = false;
- bool use_baked_light = false;
+ bool use_baked_light = true;
bool cast_double_sided_shadows = false;
bool mirror = false;
bool dirty_dependencies = false;
- RendererStorage::DependencyTracker dependency_tracker;
+ DependencyTracker dependency_tracker;
};
Data *data = nullptr;
@@ -541,8 +550,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
dirty_list_element(this) {}
};
- static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
- static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker);
SelfList<GeometryInstanceForwardClustered>::List geometry_instance_dirty_list;
@@ -619,6 +628,8 @@ class RenderForwardClustered : public RendererSceneRenderRD {
virtual void _update_shader_quality_settings() override;
+ RendererRD::Resolve *resolve_effects = nullptr;
+
protected:
virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override;
@@ -672,7 +683,7 @@ public:
virtual bool free(RID p_rid) override;
- RenderForwardClustered(RendererStorageRD *p_storage);
+ RenderForwardClustered();
~RenderForwardClustered();
};
} // namespace RendererSceneRenderImplementation
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index cfb30ef2f3..1951bfe915 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -282,6 +282,8 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
SHADER_VERSION_DEPTH_PASS_WITH_SDF,
SHADER_VERSION_DEPTH_PASS_MULTIVIEW,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW,
SHADER_VERSION_COLOR_PASS,
};
@@ -349,9 +351,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_DP || k == PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW) {
//none, leave empty
- } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
+ } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS || k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW) {
blend_state = blend_state_depth_normal_roughness;
- } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI) {
+ } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI || k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW) {
blend_state = blend_state_depth_normal_roughness_giprobe;
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL) {
blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
@@ -518,19 +520,20 @@ SceneShaderForwardClustered::~SceneShaderForwardClustered() {
material_storage->material_free(default_material);
}
-void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const String p_defines) {
+void SceneShaderForwardClustered::init(const String p_defines) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- storage = p_storage;
{
Vector<String> shader_versions;
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_DEPTH_PASS
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n"); // SHADER_VERSION_DEPTH_PASS_DP
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n"); // SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL
shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_SDF\n"); // SHADER_VERSION_DEPTH_PASS_WITH_SDF
shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_DEPTH_PASS_MULTIVIEW
+ shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW
+ shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_VOXEL_GI\n"); // SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW
Vector<String> color_pass_flags = {
"\n#define MODE_SEPARATE_SPECULAR\n", // SHADER_COLOR_PASS_FLAG_SEPARATE_SPECULAR
@@ -553,6 +556,8 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
if (!RendererCompositorRD::singleton->is_xr_enabled()) {
shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_MULTIVIEW, false);
+ shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW, false);
+ shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW, false);
// TODO Add a way to enable/disable color pass flags
}
}
@@ -621,7 +626,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
//builtins
- actions.renames["TIME"] = "scene_data_block.data.time";
+ actions.renames["TIME"] = "global_time";
actions.renames["PI"] = _MKSTR(Math_PI);
actions.renames["TAU"] = _MKSTR(Math_TAU);
actions.renames["E"] = _MKSTR(Math_E);
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
index 79ccf10090..1cfe723174 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
@@ -32,7 +32,6 @@
#define RSSR_SCENE_SHADER_FC_H
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h"
namespace RendererSceneRenderImplementation {
@@ -42,8 +41,6 @@ private:
static SceneShaderForwardClustered *singleton;
public:
- RendererStorageRD *storage = nullptr;
-
enum ShaderVersion {
SHADER_VERSION_DEPTH_PASS,
SHADER_VERSION_DEPTH_PASS_DP,
@@ -52,6 +49,8 @@ public:
SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
SHADER_VERSION_DEPTH_PASS_WITH_SDF,
SHADER_VERSION_DEPTH_PASS_MULTIVIEW,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW,
SHADER_VERSION_COLOR_PASS,
SHADER_VERSION_MAX
};
@@ -72,6 +71,8 @@ public:
PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL,
PIPELINE_VERSION_DEPTH_PASS_WITH_SDF,
PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW,
+ PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_MULTIVIEW,
+ PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI_MULTIVIEW,
PIPELINE_VERSION_COLOR_PASS,
PIPELINE_VERSION_MAX
};
@@ -245,7 +246,7 @@ public:
SceneShaderForwardClustered();
~SceneShaderForwardClustered();
- void init(RendererStorageRD *p_storage, const String p_defines);
+ void init(const String p_defines);
void set_default_specialization_constants(const Vector<RD::PipelineSpecializationConstant> &p_constants);
};
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index eae5685dd1..e1855ddb36 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -465,7 +465,7 @@ void RenderForwardMobile::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, c
Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
to_lm = to_lm.inverse().transposed(); //will transform normals
- RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
+ RendererRD::MaterialStorage::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
scene_state.lightmap_ids[i] = p_lightmaps[i];
scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap);
@@ -675,7 +675,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
}
- _pre_opaque_render(p_render_data, false, false, false, RID(), RID());
+ RID null_rids[2];
+ _pre_opaque_render(p_render_data, false, false, false, null_rids, RID());
uint32_t spec_constant_base_flags = 0;
@@ -1533,15 +1534,15 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
CameraMatrix projection = correction * p_render_data->cam_projection;
//store camera into ubo
- RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix);
- RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
- RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
- RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix);
+ RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix);
+ RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform, scene_state.ubo.inv_view_matrix);
+ RendererRD::MaterialStorage::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.view_matrix);
for (uint32_t v = 0; v < p_render_data->view_count; v++) {
projection = correction * p_render_data->view_projection[v];
- RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
- RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
+ RendererRD::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
scene_state.ubo.eye_offset[v][0] = p_render_data->view_eye_offset[v].x;
scene_state.ubo.eye_offset[v][1] = p_render_data->view_eye_offset[v].y;
@@ -1554,10 +1555,10 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
scene_state.ubo.pancake_shadows = p_pancake_shadows;
- RendererStorageRD::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
- RendererStorageRD::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_penumbra_shadow_kernel_get(), scene_state.ubo.directional_penumbra_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(directional_soft_shadow_kernel_get(), scene_state.ubo.directional_soft_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(penumbra_shadow_kernel_get(), scene_state.ubo.penumbra_shadow_kernel);
+ RendererRD::MaterialStorage::store_soft_shadow_kernel(soft_shadow_kernel_get(), scene_state.ubo.soft_shadow_kernel);
Size2 screen_pixel_size = Vector2(1.0, 1.0) / Size2(p_screen_size);
scene_state.ubo.screen_pixel_size[0] = screen_pixel_size.x;
@@ -1647,7 +1648,7 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
Basis sky_transform = environment_get_sky_orientation(p_render_data->environment);
sky_transform = sky_transform.inverse() * p_render_data->cam_transform.basis;
- RendererStorageRD::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
+ RendererRD::MaterialStorage::store_transform_3x3(sky_transform, scene_state.ubo.radiance_inverse_xform);
scene_state.ubo.use_ambient_cubemap = (ambient_src == RS::ENV_AMBIENT_SOURCE_BG && env_bg == RS::ENV_BG_SKY) || ambient_src == RS::ENV_AMBIENT_SOURCE_SKY;
scene_state.ubo.use_ambient_light = scene_state.ubo.use_ambient_cubemap || ambient_src == RS::ENV_AMBIENT_SOURCE_COLOR;
@@ -1865,9 +1866,9 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
GeometryInstanceForwardMobile::PushConstant push_constant;
if (inst->store_transform_cache) {
- RendererStorageRD::store_transform(inst->transform, push_constant.transform);
+ RendererRD::MaterialStorage::store_transform(inst->transform, push_constant.transform);
} else {
- RendererStorageRD::store_transform(Transform3D(), push_constant.transform);
+ RendererRD::MaterialStorage::store_transform(Transform3D(), push_constant.transform);
}
push_constant.flags = inst->flags_cache;
@@ -2031,7 +2032,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
/* Geometry instance */
RendererSceneRender::GeometryInstance *RenderForwardMobile::geometry_instance_create(RID p_base) {
- RS::InstanceType type = storage->get_base_type(p_base);
+ RS::InstanceType type = RSG::utilities->get_base_type(p_base);
ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
GeometryInstanceForwardMobile *ginstance = geometry_instance_alloc.alloc();
@@ -2372,7 +2373,7 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI
sdcache->surface_index = p_surface;
if (ginstance->data->dirty_dependencies) {
- storage->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
+ RSG::utilities->base_update_dependency(p_mesh, &ginstance->data->dependency_tracker);
}
//shadow
@@ -2608,16 +2609,16 @@ void RenderForwardMobile::_update_dirty_geometry_instances() {
}
}
-void RenderForwardMobile::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) {
+void RenderForwardMobile::_geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker) {
switch (p_notification) {
- case RendererStorage::DEPENDENCY_CHANGED_MATERIAL:
- case RendererStorage::DEPENDENCY_CHANGED_MESH:
- case RendererStorage::DEPENDENCY_CHANGED_PARTICLES:
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
- case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: {
+ case Dependency::DEPENDENCY_CHANGED_MATERIAL:
+ case Dependency::DEPENDENCY_CHANGED_MESH:
+ case Dependency::DEPENDENCY_CHANGED_PARTICLES:
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
+ case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA: {
static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
GeometryInstanceForwardMobile *ginstance = static_cast<GeometryInstanceForwardMobile *>(p_tracker->userdata);
if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
ginstance->instance_count = RendererRD::MeshStorage::get_singleton()->multimesh_get_instances_to_draw(ginstance->data->base);
@@ -2628,7 +2629,7 @@ void RenderForwardMobile::_geometry_instance_dependency_changed(RendererStorage:
} break;
}
}
-void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) {
+void RenderForwardMobile::_geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker) {
static_cast<RenderForwardMobile *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
}
@@ -2694,8 +2695,7 @@ void RenderForwardMobile::_update_shader_quality_settings() {
_base_uniforms_changed(); //also need this
}
-RenderForwardMobile::RenderForwardMobile(RendererStorageRD *p_storage) :
- RendererSceneRenderRD(p_storage) {
+RenderForwardMobile::RenderForwardMobile() {
singleton = this;
sky.set_texture_format(_render_buffers_get_color_format());
@@ -2727,7 +2727,7 @@ RenderForwardMobile::RenderForwardMobile(RendererStorageRD *p_storage) :
defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n";
}
- scene_shader.init(p_storage, defines);
+ scene_shader.init(defines);
// !BAS! maybe we need a mobile version of this setting?
render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances");
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
index 1b2df0ab9f..473a58045c 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h
@@ -35,7 +35,7 @@
#include "servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/storage_rd/utilities.h"
namespace RendererSceneRenderImplementation {
@@ -591,13 +591,13 @@ protected:
RID material_overlay;
AABB aabb;
- bool use_baked_light = false;
+ bool use_baked_light = true;
bool cast_double_sided_shadows = false;
// bool mirror = false; // !BAS! Does not seem used, we already have this in the main struct
bool dirty_dependencies = false;
- RendererStorage::DependencyTracker dependency_tracker;
+ DependencyTracker dependency_tracker;
};
Data *data = nullptr;
@@ -613,8 +613,8 @@ protected:
public:
virtual RID reflection_probe_create_framebuffer(RID p_color, RID p_depth) override;
- static void _geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker);
- static void _geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *p_tracker);
+ static void _geometry_instance_dependency_deleted(const RID &p_dependency, DependencyTracker *p_tracker);
SelfList<GeometryInstanceForwardMobile>::List geometry_instance_dirty_list;
@@ -668,7 +668,7 @@ public:
virtual bool is_volumetric_supported() const override;
virtual uint32_t get_max_elements() const override;
- RenderForwardMobile(RendererStorageRD *p_storage);
+ RenderForwardMobile();
~RenderForwardMobile();
};
} // namespace RendererSceneRenderImplementation
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index f66ad529de..dd00dc2bf9 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -466,8 +466,7 @@ SceneShaderForwardMobile::SceneShaderForwardMobile() {
singleton = this;
}
-void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p_defines) {
- storage = p_storage;
+void SceneShaderForwardMobile::init(const String p_defines) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
/* SCENE SHADER */
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
index f325d5c0a5..88c2143b09 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h
@@ -32,7 +32,6 @@
#define RSSR_SCENE_SHADER_FM_H
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl.gen.h"
namespace RendererSceneRenderImplementation {
@@ -40,7 +39,6 @@ namespace RendererSceneRenderImplementation {
class SceneShaderForwardMobile {
private:
static SceneShaderForwardMobile *singleton;
- RendererStorageRD *storage = nullptr;
public:
enum ShaderVersion {
@@ -207,7 +205,7 @@ public:
Vector<RD::PipelineSpecializationConstant> default_specialization_constants;
- void init(RendererStorageRD *p_storage, const String p_defines);
+ void init(const String p_defines);
void set_default_specialization_constants(const Vector<RD::PipelineSpecializationConstant> &p_constants);
};
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index 3c2f3f8a42..b87b189d53 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -2270,10 +2270,9 @@ void RendererCanvasRenderRD::set_time(double p_time) {
void RendererCanvasRenderRD::update() {
}
-RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
+RendererCanvasRenderRD::RendererCanvasRenderRD() {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- storage = p_storage;
{ //create default samplers
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
index 04881ce7e6..2ab5a7c831 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.h
@@ -34,15 +34,13 @@
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_compositor.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/canvas.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/canvas_occlusion.glsl.gen.h"
+#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/shader_compiler.h"
class RendererCanvasRenderRD : public RendererCanvasRender {
- RendererStorageRD *storage = nullptr;
-
enum {
BASE_UNIFORM_SET = 0,
MATERIAL_UNIFORM_SET = 1,
@@ -462,7 +460,7 @@ public:
void set_time(double p_time);
void update();
bool free(RID p_rid);
- RendererCanvasRenderRD(RendererStorageRD *p_storage);
+ RendererCanvasRenderRD();
~RendererCanvasRenderRD();
};
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index 759b8690eb..a61172c8f5 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -154,12 +154,14 @@ uint64_t RendererCompositorRD::frame = 1;
void RendererCompositorRD::finalize() {
memdelete(scene);
memdelete(canvas);
- memdelete(storage);
+ memdelete(effects);
+ memdelete(fog);
memdelete(particles_storage);
memdelete(light_storage);
memdelete(mesh_storage);
memdelete(material_storage);
memdelete(texture_storage);
+ memdelete(utilities);
//only need to erase these, the rest are erased by cascade
blit.shader.version_free(blit.shader_version);
@@ -287,28 +289,29 @@ RendererCompositorRD::RendererCompositorRD() {
singleton = this;
+ utilities = memnew(RendererRD::Utilities);
texture_storage = memnew(RendererRD::TextureStorage);
material_storage = memnew(RendererRD::MaterialStorage);
mesh_storage = memnew(RendererRD::MeshStorage);
light_storage = memnew(RendererRD::LightStorage);
particles_storage = memnew(RendererRD::ParticlesStorage);
- storage = memnew(RendererStorageRD);
- canvas = memnew(RendererCanvasRenderRD(storage));
+ fog = memnew(RendererRD::Fog);
+ canvas = memnew(RendererCanvasRenderRD());
back_end = (bool)(int)GLOBAL_GET("rendering/vulkan/rendering/back_end");
uint64_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
if (back_end || textures_per_stage < 48) {
- scene = memnew(RendererSceneRenderImplementation::RenderForwardMobile(storage));
+ scene = memnew(RendererSceneRenderImplementation::RenderForwardMobile());
} else { // back_end == false
// default to our high end renderer
- scene = memnew(RendererSceneRenderImplementation::RenderForwardClustered(storage));
+ scene = memnew(RendererSceneRenderImplementation::RenderForwardClustered());
}
scene->init();
// now we're ready to create our effects,
- storage->init_effects(!scene->_render_buffers_can_be_storage());
+ effects = memnew(EffectsRD(!scene->_render_buffers_can_be_storage()));
}
RendererCompositorRD::~RendererCompositorRD() {
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h
index aefc189f68..2be55743fb 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.h
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h
@@ -34,28 +34,32 @@
#include "core/os/os.h"
#include "core/templates/thread_work_pool.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"
#include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/blit.glsl.gen.h"
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
+#include "servers/rendering/renderer_rd/storage_rd/utilities.h"
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
class RendererCompositorRD : public RendererCompositor {
protected:
UniformSetCacheRD *uniform_set_cache = nullptr;
RendererCanvasRenderRD *canvas = nullptr;
+ RendererRD::Utilities *utilities = nullptr;
RendererRD::LightStorage *light_storage = nullptr;
RendererRD::MaterialStorage *material_storage = nullptr;
RendererRD::MeshStorage *mesh_storage = nullptr;
RendererRD::ParticlesStorage *particles_storage = nullptr;
RendererRD::TextureStorage *texture_storage = nullptr;
- RendererStorageRD *storage = nullptr;
+ RendererRD::Fog *fog = nullptr;
+ EffectsRD *effects = nullptr;
RendererSceneRenderRD *scene = nullptr;
enum BlitMode {
@@ -98,12 +102,18 @@ protected:
static uint64_t frame;
public:
- RendererLightStorage *get_light_storage() { return light_storage; };
- RendererMaterialStorage *get_material_storage() { return material_storage; };
- RendererMeshStorage *get_mesh_storage() { return mesh_storage; };
- RendererParticlesStorage *get_particles_storage() { return particles_storage; };
- RendererTextureStorage *get_texture_storage() { return texture_storage; };
- RendererStorage *get_storage() { return storage; }
+ RendererUtilities *get_utilities() { return utilities; };
+ RendererLightStorage *get_light_storage() { return light_storage; }
+ RendererMaterialStorage *get_material_storage() { return material_storage; }
+ RendererMeshStorage *get_mesh_storage() { return mesh_storage; }
+ RendererParticlesStorage *get_particles_storage() { return particles_storage; }
+ RendererTextureStorage *get_texture_storage() { return texture_storage; }
+ RendererGI *get_gi() {
+ ERR_FAIL_NULL_V(scene, nullptr);
+ return scene->get_gi();
+ }
+ RendererFog *get_fog() { return fog; }
+ EffectsRD *get_effects() { return effects; }
RendererCanvasRender *get_canvas() { return canvas; }
RendererSceneRender *get_scene() { return scene; }
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index a50a05d905..5185d537ec 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -33,6 +33,7 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
#include "renderer_compositor_rd.h"
+#include "servers/rendering/renderer_rd/environment/fog.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
@@ -74,7 +75,7 @@ void RendererSceneRenderRD::sdfgi_update(RID p_render_buffers, RID p_environment
rb->sdfgi = nullptr;
}
- RendererSceneGIRD::SDFGI *sdfgi = rb->sdfgi;
+ RendererRD::GI::SDFGI *sdfgi = rb->sdfgi;
if (sdfgi == nullptr) {
// re-create
rb->sdfgi = gi.create_sdfgi(env, p_world_position, requested_history_size);
@@ -95,9 +96,9 @@ int RendererSceneRenderRD::sdfgi_get_pending_region_count(RID p_render_buffers)
int dirty_count = 0;
for (uint32_t i = 0; i < rb->sdfgi->cascades.size(); i++) {
- const RendererSceneGIRD::SDFGI::Cascade &c = rb->sdfgi->cascades[i];
+ const RendererRD::GI::SDFGI::Cascade &c = rb->sdfgi->cascades[i];
- if (c.dirty_regions == RendererSceneGIRD::SDFGI::Cascade::DIRTY_ALL) {
+ if (c.dirty_regions == RendererRD::GI::SDFGI::Cascade::DIRTY_ALL) {
dirty_count++;
} else {
for (int j = 0; j < 3; j++) {
@@ -534,7 +535,7 @@ Ref<Image> RendererSceneRenderRD::environment_bake_panorama(RID p_env, bool p_ba
return panorama;
} else {
const float bg_energy = env->bg_energy;
- Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? storage->get_default_clear_color() : env->bg_color);
+ Color panorama_color = ((environment_background == RS::ENV_BG_CLEAR_COLOR) ? RSG::texture_storage->get_default_clear_color() : env->bg_color);
panorama_color = panorama_color.srgb_to_linear();
panorama_color.r *= bg_energy;
panorama_color.g *= bg_energy;
@@ -759,7 +760,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_begin_render(RID p_instanc
}
atlas->reflections.resize(atlas->count);
for (int i = 0; i < atlas->count; i++) {
- atlas->reflections.write[i].data.update_reflection_data(storage, atlas->size, mipmaps, false, atlas->reflection, i * 6, RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, sky.roughness_layers, _render_buffers_get_color_format());
+ atlas->reflections.write[i].data.update_reflection_data(atlas->size, mipmaps, false, atlas->reflection, i * 6, RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS, sky.roughness_layers, _render_buffers_get_color_format());
for (int j = 0; j < 6; j++) {
atlas->reflections.write[i].fbs[j] = reflection_probe_create_framebuffer(atlas->reflections.write[i].data.layers[0].mipmaps[0].views[j], atlas->depth_buffer);
}
@@ -829,7 +830,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins
if (RSG::light_storage->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS) {
// Using real time reflections, all roughness is done in one step
- atlas->reflections.write[rpi->atlas_index].data.create_reflection_fast_filter(storage, false);
+ atlas->reflections.write[rpi->atlas_index].data.create_reflection_fast_filter(false);
rpi->rendering = false;
rpi->processing_side = 0;
rpi->processing_layer = 1;
@@ -837,7 +838,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins
}
if (rpi->processing_layer > 1) {
- atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(storage, false, 10, rpi->processing_layer, sky.sky_ggx_samples_quality);
+ atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(false, 10, rpi->processing_layer, sky.sky_ggx_samples_quality);
rpi->processing_layer++;
if (rpi->processing_layer == atlas->reflections[rpi->atlas_index].data.layers[0].mipmaps.size()) {
rpi->rendering = false;
@@ -848,7 +849,7 @@ bool RendererSceneRenderRD::reflection_probe_instance_postprocess_step(RID p_ins
return false;
} else {
- atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(storage, false, rpi->processing_side, rpi->processing_layer, sky.sky_ggx_samples_quality);
+ atlas->reflections.write[rpi->atlas_index].data.create_reflection_importance_sample(false, rpi->processing_side, rpi->processing_layer, sky.sky_ggx_samples_quality);
}
rpi->processing_side++;
@@ -1533,7 +1534,7 @@ void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_ins
gi.voxel_gi_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects, this);
}
-void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform) {
+void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) {
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND(!rb);
@@ -1541,7 +1542,7 @@ void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RD::DrawLi
return; //nothing to debug
}
- rb->sdfgi->debug_probes(p_draw_list, p_framebuffer, p_camera_with_transform);
+ rb->sdfgi->debug_probes(p_framebuffer, p_view_count, p_camera_with_transforms, p_will_continue_color, p_will_continue_depth);
}
////////////////////////////////
@@ -1950,17 +1951,7 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) {
rb->taa.prev_velocity = RID();
}
- if (rb->ambient_buffer.is_valid()) {
- RD::get_singleton()->free(rb->ambient_buffer);
- RD::get_singleton()->free(rb->reflection_buffer);
- rb->ambient_buffer = RID();
- rb->reflection_buffer = RID();
- }
-
- if (rb->gi.voxel_gi_buffer.is_valid()) {
- RD::get_singleton()->free(rb->gi.voxel_gi_buffer);
- rb->gi.voxel_gi_buffer = RID();
- }
+ rb->rbgi.free();
}
void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) {
@@ -1978,7 +1969,7 @@ void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatri
_allocate_blur_textures(rb);
}
- storage->get_effects()->sub_surface_scattering(rb->internal_texture, rb->sss_texture, rb->depth_texture, p_camera, Size2i(rb->internal_width, rb->internal_height), sss_scale, sss_depth_scale, sss_quality);
+ RendererCompositorRD::singleton->get_effects()->sub_surface_scattering(rb->internal_texture, rb->sss_texture, rb->depth_texture, p_camera, Size2i(rb->internal_width, rb->internal_height), sss_scale, sss_depth_scale, sss_quality);
}
void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, RID p_normal_buffer, RID p_specular_buffer, RID p_metallic, const Color &p_metallic_mask, RID p_environment, const CameraMatrix &p_projection, bool p_use_additive) {
@@ -1989,7 +1980,7 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb
if (!can_use_effects) {
//just copy
- storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, RID());
+ RendererCompositorRD::singleton->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, RID());
return;
}
@@ -2029,8 +2020,8 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb
_allocate_blur_textures(rb);
}
- storage->get_effects()->screen_space_reflection(rb->internal_texture, p_normal_buffer, ssr_roughness_quality, rb->ssr.blur_radius[0], rb->ssr.blur_radius[1], p_metallic, p_metallic_mask, rb->depth_texture, rb->ssr.depth_scaled, rb->ssr.normal_scaled, rb->blur[0].layers[0].mipmaps[1].texture, rb->blur[1].layers[0].mipmaps[0].texture, Size2i(rb->internal_width / 2, rb->internal_height / 2), env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, p_projection);
- storage->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->blur[0].layers[0].mipmaps[1].texture);
+ RendererCompositorRD::singleton->get_effects()->screen_space_reflection(rb->internal_texture, p_normal_buffer, ssr_roughness_quality, rb->ssr.blur_radius[0], rb->ssr.blur_radius[1], p_metallic, p_metallic_mask, rb->depth_texture, rb->ssr.depth_scaled, rb->ssr.normal_scaled, rb->blur[0].layers[0].mipmaps[1].texture, rb->blur[1].layers[0].mipmaps[0].texture, Size2i(rb->internal_width / 2, rb->internal_height / 2), env->ssr_max_steps, env->ssr_fade_in, env->ssr_fade_out, env->ssr_depth_tolerance, p_projection);
+ RendererCompositorRD::singleton->get_effects()->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->blur[0].layers[0].mipmaps[1].texture);
}
void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) {
@@ -2155,7 +2146,7 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen
settings.half_screen_size = Size2i(buffer_width, buffer_height);
settings.quarter_screen_size = Size2i(half_width, half_height);
- storage->get_effects()->generate_ssao(p_normal_buffer, rb->ss_effects.ssao.depth_texture_view, rb->ss_effects.ssao.ao_deinterleaved, rb->ss_effects.ssao.ao_deinterleaved_slices, rb->ss_effects.ssao.ao_pong, rb->ss_effects.ssao.ao_pong_slices, rb->ss_effects.ssao.ao_final, rb->ss_effects.ssao.importance_map[0], rb->ss_effects.ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssao.gather_uniform_set, rb->ss_effects.ssao.importance_map_uniform_set);
+ RendererCompositorRD::singleton->get_effects()->generate_ssao(p_normal_buffer, rb->ss_effects.ssao.depth_texture_view, rb->ss_effects.ssao.ao_deinterleaved, rb->ss_effects.ssao.ao_deinterleaved_slices, rb->ss_effects.ssao.ao_pong, rb->ss_effects.ssao.ao_pong_slices, rb->ss_effects.ssao.ao_final, rb->ss_effects.ssao.importance_map[0], rb->ss_effects.ssao.importance_map[1], p_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssao.gather_uniform_set, rb->ss_effects.ssao.importance_map_uniform_set);
}
void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform) {
@@ -2316,7 +2307,7 @@ void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environmen
transform.set_origin(Vector3(0.0, 0.0, 0.0));
CameraMatrix last_frame_projection = rb->ss_effects.last_frame_projection * CameraMatrix(rb->ss_effects.last_frame_transform.affine_inverse()) * CameraMatrix(transform) * projection.inverse();
- storage->get_effects()->screen_space_indirect_lighting(rb->ss_effects.last_frame, rb->ss_effects.ssil.ssil_final, p_normal_buffer, rb->ss_effects.ssil.depth_texture_view, rb->ss_effects.ssil.deinterleaved, rb->ss_effects.ssil.deinterleaved_slices, rb->ss_effects.ssil.pong, rb->ss_effects.ssil.pong_slices, rb->ss_effects.ssil.importance_map[0], rb->ss_effects.ssil.importance_map[1], rb->ss_effects.ssil.edges, rb->ss_effects.ssil.edges_slices, p_projection, last_frame_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssil.gather_uniform_set, rb->ss_effects.ssil.importance_map_uniform_set, rb->ss_effects.ssil.projection_uniform_set);
+ RendererCompositorRD::singleton->get_effects()->screen_space_indirect_lighting(rb->ss_effects.last_frame, rb->ss_effects.ssil.ssil_final, p_normal_buffer, rb->ss_effects.ssil.depth_texture_view, rb->ss_effects.ssil.deinterleaved, rb->ss_effects.ssil.deinterleaved_slices, rb->ss_effects.ssil.pong, rb->ss_effects.ssil.pong_slices, rb->ss_effects.ssil.importance_map[0], rb->ss_effects.ssil.importance_map[1], rb->ss_effects.ssil.edges, rb->ss_effects.ssil.edges_slices, p_projection, last_frame_projection, settings, uniform_sets_are_invalid, rb->ss_effects.ssil.gather_uniform_set, rb->ss_effects.ssil.importance_map_uniform_set, rb->ss_effects.ssil.projection_uniform_set);
rb->ss_effects.last_frame_projection = projection;
rb->ss_effects.last_frame_transform = transform;
}
@@ -2364,7 +2355,7 @@ void RendererSceneRenderRD::_process_taa(RID p_render_buffers, RID p_velocity_bu
RD::get_singleton()->draw_command_begin_label("TAA");
if (!just_allocated) {
- storage->get_effects()->taa_resolve(rb->internal_texture, rb->taa.temp, rb->depth_texture, p_velocity_buffer, rb->taa.prev_velocity, rb->taa.history, Size2(rb->internal_width, rb->internal_height), p_z_near, p_z_far);
+ RendererCompositorRD::singleton->get_effects()->taa_resolve(rb->internal_texture, rb->taa.temp, rb->depth_texture, p_velocity_buffer, rb->taa.prev_velocity, rb->taa.history, Size2(rb->internal_width, rb->internal_height), p_z_near, p_z_far);
copy_effects->copy_to_rect(rb->taa.temp, rb->internal_texture, Rect2(0, 0, rb->internal_width, rb->internal_height));
}
@@ -2502,9 +2493,9 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
double step = env->auto_exp_speed * time_step;
if (can_use_storage) {
- storage->get_effects()->luminance_reduction(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate);
+ RendererCompositorRD::singleton->get_effects()->luminance_reduction(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate);
} else {
- storage->get_effects()->luminance_reduction_raster(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate);
+ RendererCompositorRD::singleton->get_effects()->luminance_reduction_raster(rb->internal_texture, Size2i(rb->internal_width, rb->internal_height), rb->luminance.reduce, rb->luminance.fb, rb->luminance.current, env->min_luminance, env->max_luminance, step, set_immediate);
}
// Swap final reduce with prev luminance.
SWAP(rb->luminance.current, rb->luminance.reduce.write[rb->luminance.reduce.size() - 1]);
@@ -2649,7 +2640,7 @@ void RendererSceneRenderRD::_render_buffers_post_process_and_tonemap(const Rende
if (can_use_effects && can_use_storage && (rb->internal_width != rb->width || rb->internal_height != rb->height)) {
RD::get_singleton()->draw_command_begin_label("FSR 1.0 Upscale");
- storage->get_effects()->fsr_upscale(rb->internal_texture, rb->upscale_texture, rb->texture, Size2i(rb->internal_width, rb->internal_height), Size2i(rb->width, rb->height), rb->fsr_sharpness);
+ RendererCompositorRD::singleton->get_effects()->fsr_upscale(rb->internal_texture, rb->upscale_texture, rb->texture, Size2i(rb->internal_width, rb->internal_height), Size2i(rb->width, rb->height), rb->fsr_sharpness);
RD::get_singleton()->draw_command_end_label();
}
@@ -2796,11 +2787,11 @@ void RendererSceneRenderRD::_render_buffers_debug_draw(RID p_render_buffers, RID
copy_effects->copy_to_fb_rect(_render_buffers_get_normal_texture(p_render_buffers), texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false);
}
- if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->ambient_buffer.is_valid()) {
+ if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_GI_BUFFER && rb->rbgi.ambient_buffer.is_valid()) {
Size2 rtsize = texture_storage->render_target_get_size(rb->render_target);
- RID ambient_texture = rb->ambient_buffer;
- RID reflection_texture = rb->reflection_buffer;
- copy_effects->copy_to_fb_rect(ambient_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture);
+ RID ambient_texture = rb->rbgi.ambient_buffer;
+ RID reflection_texture = rb->rbgi.reflection_buffer;
+ copy_effects->copy_to_fb_rect(ambient_texture, texture_storage->render_target_get_rd_framebuffer(rb->render_target), Rect2(Vector2(), rtsize), false, false, false, true, reflection_texture, rb->view_count > 1);
}
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_OCCLUDERS) {
@@ -2869,10 +2860,10 @@ RID RendererSceneRenderRD::render_buffers_get_ssil_texture(RID p_render_buffers)
RID RendererSceneRenderRD::render_buffers_get_voxel_gi_buffer(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
- if (rb->gi.voxel_gi_buffer.is_null()) {
- rb->gi.voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererSceneGIRD::VoxelGIData) * RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES);
+ if (rb->rbgi.voxel_gi_buffer.is_null()) {
+ rb->rbgi.voxel_gi_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(RendererRD::GI::VoxelGIData) * RendererRD::GI::MAX_VOXEL_GI_INSTANCES);
}
- return rb->gi.voxel_gi_buffer;
+ return rb->rbgi.voxel_gi_buffer;
}
RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() {
@@ -2882,12 +2873,13 @@ RID RendererSceneRenderRD::render_buffers_get_default_voxel_gi_buffer() {
RID RendererSceneRenderRD::render_buffers_get_gi_ambient_texture(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
- return rb->ambient_buffer;
+
+ return rb->rbgi.ambient_buffer;
}
RID RendererSceneRenderRD::render_buffers_get_gi_reflection_texture(RID p_render_buffers) {
RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers);
ERR_FAIL_COND_V(!rb, RID());
- return rb->reflection_buffer;
+ return rb->rbgi.reflection_buffer;
}
uint32_t RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_count(RID p_render_buffers) const {
@@ -2925,7 +2917,7 @@ Vector3i RendererSceneRenderRD::render_buffers_get_sdfgi_cascade_probe_offset(RI
ERR_FAIL_COND_V(!rb, Vector3i());
ERR_FAIL_COND_V(!rb->sdfgi, Vector3i());
ERR_FAIL_UNSIGNED_INDEX_V(p_cascade, rb->sdfgi->cascades.size(), Vector3i());
- int32_t probe_divisor = rb->sdfgi->cascade_size / RendererSceneGIRD::SDFGI::PROBE_DIVISOR;
+ int32_t probe_divisor = rb->sdfgi->cascade_size / RendererRD::GI::SDFGI::PROBE_DIVISOR;
return rb->sdfgi->cascades[p_cascade].position / probe_divisor;
}
@@ -3106,7 +3098,7 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
}
if (rb->msaa == RS::VIEWPORT_MSAA_DISABLED) {
- tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
+ tf.format = RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_D24_UNORM_S8_UINT, (RD::TEXTURE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT)) ? RD::DATA_FORMAT_D24_UNORM_S8_UINT : RD::DATA_FORMAT_D32_SFLOAT_S8_UINT;
} else {
tf.format = RD::DATA_FORMAT_R32_SFLOAT;
}
@@ -3138,14 +3130,14 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
if (rb->view_count == 1) {
// copy as a convenience
RenderBuffers::View view;
- view.view_texture = rb->internal_texture;
+ view.view_texture = rb->texture;
view.view_depth = rb->depth_texture;
view.view_fb = rb->texture_fb;
rb->views.push_back(view);
} else {
for (uint32_t i = 0; i < rb->view_count; i++) {
RenderBuffers::View view;
- view.view_texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->internal_texture, i, 0);
+ view.view_texture = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->texture, i, 0);
view.view_depth = RD::get_singleton()->texture_create_shared_from_slice(RD::TextureView(), rb->depth_texture, i, 0);
if (!_render_buffers_can_be_storage()) {
@@ -3373,7 +3365,7 @@ void RendererSceneRenderRD::_setup_reflections(const PagedArray<RID> &p_reflecti
Transform3D transform = rpi->transform;
Transform3D proj = (p_camera_inverse_transform * transform).inverse();
- RendererStorageRD::store_transform(proj, reflection_ubo.local_matrix);
+ RendererRD::MaterialStorage::store_transform(proj, reflection_ubo.local_matrix);
if (current_cluster_builder != nullptr) {
current_cluster_builder->add_box(ClusterBuilderRD::BOX_TYPE_REFLECTION_PROBE, transform, extents);
@@ -3491,7 +3483,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
light_data.shadow_transmittance_bias[j] = light_storage->light_get_transmittance_bias(base) * bias_scale;
light_data.shadow_z_range[j] = li->shadow_transform[j].farplane;
light_data.shadow_range_begin[j] = li->shadow_transform[j].range_begin;
- RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
+ RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrices[j]);
Vector2 uv_scale = li->shadow_transform[j].uv_scale;
uv_scale *= atlas_rect.size; //adapt to atlas size
@@ -3736,7 +3728,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
if (type == RS::LIGHT_OMNI) {
Transform3D proj = (inverse_transform * light_transform).inverse();
- RendererStorageRD::store_transform(proj, light_data.shadow_matrix);
+ RendererRD::MaterialStorage::store_transform(proj, light_data.shadow_matrix);
if (size > 0.0 && light_data.soft_shadow_scale > 0.0) {
// Only enable PCSS-like soft shadows if blurring is enabled.
@@ -3755,7 +3747,7 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const
bias.set_light_bias();
CameraMatrix shadow_mtx = bias * li->shadow_transform[0].camera * modelview;
- RendererStorageRD::store_camera(shadow_mtx, light_data.shadow_matrix);
+ RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrix);
if (size > 0.0 && light_data.soft_shadow_scale > 0.0) {
// Only enable PCSS-like soft shadows if blurring is enabled.
@@ -3874,7 +3866,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
Transform3D scale_xform;
scale_xform.basis.scale(decal_extents);
Transform3D to_decal_xform = (p_camera_inverse_xform * di->transform * scale_xform * uv_xform).affine_inverse();
- RendererStorageRD::store_transform(to_decal_xform, dd.xform);
+ RendererRD::MaterialStorage::store_transform(to_decal_xform, dd.xform);
Vector3 normal = xform.basis.get_column(Vector3::AXIS_Y).normalized();
normal = p_camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine
@@ -3912,7 +3904,7 @@ void RendererSceneRenderRD::_setup_decals(const PagedArray<RID> &p_decals, const
dd.normal_rect[3] = rect.size.y;
Basis normal_xform = p_camera_inverse_xform.basis * xform.basis.orthonormalized();
- RendererStorageRD::store_basis_3x4(normal_xform, dd.normal_xform);
+ RendererRD::MaterialStorage::store_basis_3x4(normal_xform, dd.normal_xform);
} else {
dd.normal_rect[0] = 0;
dd.normal_rect[1] = 0;
@@ -4159,6 +4151,9 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
if (rb->volumetric_fog->fog_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->fog_uniform_set)) {
RD::get_singleton()->free(rb->volumetric_fog->fog_uniform_set);
}
+ if (rb->volumetric_fog->process_uniform_set_density.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) {
+ RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set_density);
+ }
if (rb->volumetric_fog->process_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) {
RD::get_singleton()->free(rb->volumetric_fog->process_uniform_set);
}
@@ -4332,8 +4327,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount;
Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;
- storage->store_transform(to_prev_cam_view, params.to_prev_view);
- storage->store_transform(p_cam_transform, params.transform);
+ RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);
+ RendererRD::MaterialStorage::store_transform(p_cam_transform, params.transform);
RD::get_singleton()->buffer_update(volumetric_fog.volume_ubo, 0, sizeof(VolumetricFogShader::VolumeUBO), &params, RD::BARRIER_MASK_COMPUTE);
@@ -4395,7 +4390,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
ERR_FAIL_COND(!fog_volume_instance);
RID fog_volume = fog_volume_instance->volume;
- RID fog_material = storage->fog_volume_get_material(fog_volume);
+ RID fog_material = RendererRD::Fog::get_singleton()->fog_volume_get_material(fog_volume);
FogMaterialData *material = nullptr;
@@ -4424,8 +4419,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
Vector3i kernel_size = Vector3i();
Vector3 position = fog_volume_instance->transform.get_origin();
- RS::FogVolumeShape volume_type = storage->fog_volume_get_shape(fog_volume);
- Vector3 extents = storage->fog_volume_get_extents(fog_volume);
+ RS::FogVolumeShape volume_type = RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume);
+ Vector3 extents = RendererRD::Fog::get_singleton()->fog_volume_get_extents(fog_volume);
if (volume_type != RS::FOG_VOLUME_SHAPE_WORLD) {
// Local fog volume.
@@ -4468,8 +4463,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
volumetric_fog.push_constant.corner[0] = min.x;
volumetric_fog.push_constant.corner[1] = min.y;
volumetric_fog.push_constant.corner[2] = min.z;
- volumetric_fog.push_constant.shape = uint32_t(storage->fog_volume_get_shape(fog_volume));
- storage->store_transform(fog_volume_instance->transform.affine_inverse(), volumetric_fog.push_constant.transform);
+ volumetric_fog.push_constant.shape = uint32_t(RendererRD::Fog::get_singleton()->fog_volume_get_shape(fog_volume));
+ RendererRD::MaterialStorage::store_transform(fog_volume_instance->transform.affine_inverse(), volumetric_fog.push_constant.transform);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, shader_data->pipeline);
@@ -4491,7 +4486,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::get_singleton()->compute_list_end();
}
- if (rb->volumetric_fog->process_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set)) {
+ if (rb->volumetric_fog->process_uniform_set_density.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->process_uniform_set_density)) {
//re create uniform set if needed
Vector<RD::Uniform> uniforms;
Vector<RD::Uniform> copy_uniforms;
@@ -4615,8 +4610,8 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 12;
- for (int i = 0; i < RendererSceneGIRD::MAX_VOXEL_GI_INSTANCES; i++) {
- u.append_id(rb->gi.voxel_gi_textures[i]);
+ for (int i = 0; i < RendererRD::GI::MAX_VOXEL_GI_INSTANCES; i++) {
+ u.append_id(rb->rbgi.voxel_gi_textures[i]);
}
uniforms.push_back(u);
copy_uniforms.push_back(u);
@@ -4691,7 +4686,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
rb->volumetric_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);
- rb->volumetric_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_DENSITY), 0);
+ rb->volumetric_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);
RID aux7 = uniforms.write[7].get_id(0);
RID aux8 = uniforms.write[8].get_id(0);
@@ -4699,7 +4694,11 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
uniforms.write[7].set_id(0, aux8);
uniforms.write[8].set_id(0, aux7);
- rb->volumetric_fog->process_uniform_set2 = RD::get_singleton()->uniform_set_create(uniforms, volumetric_fog.process_shader.version_get_shader(volumetric_fog.process_shader_version, 0), 0);
+ rb->volumetric_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);
+
+ uniforms.remove_at(8);
+ uniforms.write[7].set_id(0, aux7);
+ rb->volumetric_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);
}
bool using_sdfgi = env->volumetric_fog_gi_inject > 0.0001 && env->sdfgi_enabled && (rb->sdfgi != nullptr);
@@ -4810,7 +4809,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
params.temporal_frame = RSG::rasterizer->get_frame_number() % VolumetricFog::MAX_TEMPORAL_FRAMES;
Transform3D to_prev_cam_view = p_prev_cam_inv_transform * p_cam_transform;
- storage->store_transform(to_prev_cam_view, params.to_prev_view);
+ RendererRD::MaterialStorage::store_transform(to_prev_cam_view, params.to_prev_view);
params.use_temporal_reprojection = env->volumetric_fog_temporal_reprojection;
params.temporal_blend = env->volumetric_fog_temporal_reprojection_amount;
@@ -4831,7 +4830,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
Basis sky_transform = env->sky_orientation;
sky_transform = sky_transform.inverse() * p_cam_transform.basis;
- RendererStorageRD::store_transform_3x3(sky_transform, params.radiance_inverse_xform);
+ RendererRD::MaterialStorage::store_transform_3x3(sky_transform, params.radiance_inverse_xform);
RD::get_singleton()->draw_command_begin_label("Render Volumetric Fog");
@@ -4842,7 +4841,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
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, rb->volumetric_fog->process_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->process_uniform_set_density, 0);
if (using_sdfgi) {
RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->volumetric_fog->sdfgi_uniform_set, 1);
@@ -4930,7 +4929,7 @@ void RendererSceneRenderRD::_pre_resolve_render(RenderDataRD *p_render_data, boo
}
}
-void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer) {
+void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID *p_normal_roughness_views, RID p_voxel_gi_buffer) {
// Render shadows while GI is rendering, due to how barriers are handled, this should happen at the same time
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
@@ -5005,7 +5004,7 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
//start GI
if (render_gi) {
- gi.process_gi(p_render_data->render_buffers, p_normal_roughness_buffer, p_voxel_gi_buffer, p_render_data->environment, p_render_data->cam_projection, p_render_data->cam_transform, *p_render_data->voxel_gi_instances, this);
+ gi.process_gi(p_render_data->render_buffers, p_normal_roughness_views, p_voxel_gi_buffer, p_render_data->environment, p_render_data->view_count, p_render_data->view_projection, p_render_data->view_eye_offset, p_render_data->cam_transform, *p_render_data->voxel_gi_instances, this);
}
//Do shadow rendering (in parallel with GI)
@@ -5042,15 +5041,17 @@ void RendererSceneRenderRD::_pre_opaque_render(RenderDataRD *p_render_data, bool
invalidate_uniform_set = true;
}
- storage->get_effects()->downsample_depth(rb->depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, Size2i(rb->width, rb->height), p_render_data->cam_projection);
+ RendererCompositorRD::singleton->get_effects()->downsample_depth(rb->depth_texture, rb->ss_effects.linear_depth_slices, ssao_quality, ssil_quality, invalidate_uniform_set, ssao_half_size, ssil_half_size, Size2i(rb->width, rb->height), p_render_data->cam_projection);
}
if (p_use_ssao) {
- _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_buffer, p_render_data->cam_projection);
+ // TODO make these proper stereo and thus use p_normal_roughness_views correctly
+ _process_ssao(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_views[0], p_render_data->cam_projection);
}
if (p_use_ssil) {
- _process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_buffer, p_render_data->cam_projection, p_render_data->cam_transform);
+ // TODO make these proper stereo and thus use p_normal_roughness_views correctly
+ _process_ssil(p_render_data->render_buffers, p_render_data->environment, p_normal_roughness_views[0], p_render_data->cam_projection, p_render_data->cam_transform);
}
}
@@ -5189,13 +5190,13 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData
if (p_render_buffers.is_valid()) {
clear_color = texture_storage->render_target_get_clear_request_color(rb->render_target);
} else {
- clear_color = storage->get_default_clear_color();
+ clear_color = RSG::texture_storage->get_default_clear_color();
}
//assign render indices to voxel_gi_instances
if (is_dynamic_gi_supported()) {
for (uint32_t i = 0; i < (uint32_t)p_voxel_gi_instances.size(); i++) {
- RendererSceneGIRD::VoxelGIInstance *voxel_gi_inst = gi.voxel_gi_instance_owner.get_or_null(p_voxel_gi_instances[i]);
+ RendererRD::GI::VoxelGIInstance *voxel_gi_inst = gi.voxel_gi_instance_owner.get_or_null(p_voxel_gi_instances[i]);
if (voxel_gi_inst) {
voxel_gi_inst->render_index = i;
}
@@ -5249,7 +5250,13 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const CameraData
_render_buffers_debug_draw(p_render_buffers, p_shadow_atlas, p_occluder_debug_tex);
if (debug_draw == RS::VIEWPORT_DEBUG_DRAW_SDFGI && rb != nullptr && rb->sdfgi != nullptr) {
- rb->sdfgi->debug_draw(render_data.cam_projection, render_data.cam_transform, rb->width, rb->height, rb->render_target, rb->texture);
+ Vector<RID> view_rids;
+
+ for (int v = 0; v < rb->views.size(); v++) {
+ view_rids.push_back(rb->views[v].view_texture);
+ }
+
+ rb->sdfgi->debug_draw(render_data.view_count, render_data.view_projection, render_data.cam_transform, rb->width, rb->height, rb->render_target, rb->texture, view_rids);
}
}
}
@@ -5439,9 +5446,9 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
Rect2 atlas_rect_norm = atlas_rect;
atlas_rect_norm.position /= float(atlas_size);
atlas_rect_norm.size /= float(atlas_size);
- storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), false);
+ copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), false);
atlas_rect_norm.position += Vector2(dual_paraboloid_offset) * atlas_rect_norm.size;
- storage->get_effects()->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true);
+ copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true);
//restore transform so it can be properly used
light_instance_set_shadow_transform(p_light, CameraMatrix(), light_instance->transform, zfar, 0, 0, 0);
@@ -5518,7 +5525,7 @@ bool RendererSceneRenderRD::free(RID p_rid) {
} else if (lightmap_instance_owner.owns(p_rid)) {
lightmap_instance_owner.free(p_rid);
} else if (gi.voxel_gi_instance_owner.owns(p_rid)) {
- RendererSceneGIRD::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.get_or_null(p_rid);
+ RendererRD::GI::VoxelGIInstance *voxel_gi = gi.voxel_gi_instance_owner.get_or_null(p_rid);
if (voxel_gi->texture.is_valid()) {
RD::get_singleton()->free(voxel_gi->texture);
RD::get_singleton()->free(voxel_gi->write_buffer);
@@ -5748,8 +5755,7 @@ uint32_t RendererSceneRenderRD::get_max_elements() const {
return GLOBAL_GET("rendering/limits/cluster_builder/max_clustered_elements");
}
-RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
- storage = p_storage;
+RendererSceneRenderRD::RendererSceneRenderRD() {
singleton = this;
}
@@ -5763,12 +5769,12 @@ void RendererSceneRenderRD::init() {
/* SKY SHADER */
- sky.init(storage);
+ sky.init();
/* GI */
if (is_dynamic_gi_supported()) {
- gi.init(storage, &sky);
+ gi.init(&sky);
}
{ //decals
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index a90c165d83..e8296882c9 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -38,10 +38,9 @@
#include "servers/rendering/renderer_rd/effects/bokeh_dof.h"
#include "servers/rendering/renderer_rd/effects/copy_effects.h"
#include "servers/rendering/renderer_rd/effects/tone_mapper.h"
+#include "servers/rendering/renderer_rd/environment/gi.h"
#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
-#include "servers/rendering/renderer_rd/renderer_scene_gi_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_sky_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/volumetric_fog.glsl.gen.h"
#include "servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl.gen.h"
#include "servers/rendering/renderer_scene.h"
@@ -99,10 +98,9 @@ struct RenderDataRD {
class RendererSceneRenderRD : public RendererSceneRender {
friend RendererSceneSkyRD;
- friend RendererSceneGIRD;
+ friend RendererRD::GI;
protected:
- RendererStorageRD *storage = nullptr;
RendererRD::BokehDOF *bokeh_dof = nullptr;
RendererRD::CopyEffects *copy_effects = nullptr;
RendererRD::ToneMapper *tone_mapper = nullptr;
@@ -131,7 +129,7 @@ protected:
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0;
- void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
+ void _debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth);
void _debug_draw_cluster(RID p_render_buffers);
RenderBufferData *render_buffers_get_data(RID p_render_buffers);
@@ -151,7 +149,7 @@ protected:
void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi);
- void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID p_normal_roughness_buffer, RID p_voxel_gi_buffer);
+ void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, RID *p_normal_roughness_views, RID p_voxel_gi_buffer);
void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
@@ -163,7 +161,7 @@ protected:
PagedArrayPool<GeometryInstance *> cull_argument_pool;
PagedArray<GeometryInstance *> cull_argument; //need this to exist
- RendererSceneGIRD gi;
+ RendererRD::GI gi;
RendererSceneSkyRD sky;
RendererSceneEnvironmentRD *get_environment(RID p_environment) {
@@ -503,9 +501,9 @@ private:
};
Vector<View> views;
- RendererSceneGIRD::SDFGI *sdfgi = nullptr;
+ RendererRD::GI::SDFGI *sdfgi = nullptr;
VolumetricFog *volumetric_fog = nullptr;
- RendererSceneGIRD::RenderBuffersGI gi;
+ RendererRD::GI::RenderBuffersGI rbgi;
ClusterBuilderRD *cluster_builder = nullptr;
@@ -606,9 +604,6 @@ private:
RID temp;
RID prev_velocity; // Last frame velocity buffer
} taa;
-
- RID ambient_buffer;
- RID reflection_buffer;
};
/* GI */
@@ -802,6 +797,7 @@ private:
RID fog_uniform_set;
RID copy_uniform_set;
+ RID process_uniform_set_density;
RID process_uniform_set;
RID process_uniform_set2;
RID sdfgi_uniform_set;
@@ -997,6 +993,10 @@ public:
virtual Transform3D geometry_instance_get_transform(GeometryInstance *p_instance) = 0;
virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0;
+ /* GI */
+
+ RendererRD::GI *get_gi() { return &gi; }
+
/* SHADOW ATLAS API */
virtual RID shadow_atlas_create() override;
@@ -1510,7 +1510,7 @@ public:
void init();
- RendererSceneRenderRD(RendererStorageRD *p_storage);
+ RendererSceneRenderRD();
~RendererSceneRenderRD();
};
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index 3a237dbd8c..73175d3cf3 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -37,6 +37,7 @@
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/rendering_server_default.h"
+#include "servers/rendering/rendering_server_globals.h"
////////////////////////////////////////////////////////////////////////////////
// SKY SHADER
@@ -329,13 +330,13 @@ void RendererSceneSkyRD::ReflectionData::clear_reflection_data() {
coefficient_buffer = RID();
}
-void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageRD *p_storage, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) {
+void RendererSceneSkyRD::ReflectionData::update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format) {
//recreate radiance and all data
int mipmaps = p_mipmaps;
uint32_t w = p_size, h = p_size;
- EffectsRD *effects = p_storage->get_effects();
+ EffectsRD *effects = RendererCompositorRD::singleton->get_effects();
ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised");
bool prefer_raster_effects = effects->get_prefer_raster_effects();
@@ -437,20 +438,20 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_data(RendererStorageR
}
}
-void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererStorageRD *p_storage, bool p_use_arrays) {
- EffectsRD *effects = p_storage->get_effects();
- ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised");
- bool prefer_raster_effects = effects->get_prefer_raster_effects();
+void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(bool p_use_arrays) {
+ RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
+ ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
+ bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
if (prefer_raster_effects) {
RD::get_singleton()->draw_command_begin_label("Downsample radiance map");
for (int k = 0; k < 6; k++) {
- effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size);
+ copy_effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size);
}
for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) {
for (int k = 0; k < 6; k++) {
- effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size);
+ copy_effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size);
}
}
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
@@ -459,24 +460,24 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererS
RD::get_singleton()->draw_command_begin_label("filter radiance map into array heads");
for (int i = 0; i < layers.size(); i++) {
for (int k = 0; k < 6; k++) {
- effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[i].mipmaps[0].framebuffers[k], k, i);
+ copy_effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[i].mipmaps[0].framebuffers[k], k, i);
}
}
} else {
RD::get_singleton()->draw_command_begin_label("filter radiance map into mipmaps directly");
for (int j = 0; j < layers[0].mipmaps.size(); j++) {
for (int k = 0; k < 6; k++) {
- effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[0].mipmaps[j].framebuffers[k], k, j);
+ copy_effects->cubemap_filter_raster(downsampled_radiance_cubemap, layers[0].mipmaps[j].framebuffers[k], k, j);
}
}
}
RD::get_singleton()->draw_command_end_label(); // Filter radiance
} else {
RD::get_singleton()->draw_command_begin_label("Downsample radiance map");
- effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size);
+ copy_effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size);
for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) {
- effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size);
+ copy_effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size);
}
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
Vector<RID> views;
@@ -490,26 +491,26 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_fast_filter(RendererS
}
}
RD::get_singleton()->draw_command_begin_label("Fast filter radiance");
- effects->cubemap_filter(downsampled_radiance_cubemap, views, p_use_arrays);
+ copy_effects->cubemap_filter(downsampled_radiance_cubemap, views, p_use_arrays);
RD::get_singleton()->draw_command_end_label(); // Filter radiance
}
}
-void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(RendererStorageRD *p_storage, bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) {
- EffectsRD *effects = p_storage->get_effects();
- ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised");
- bool prefer_raster_effects = effects->get_prefer_raster_effects();
+void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality) {
+ RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
+ ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
+ bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
if (prefer_raster_effects) {
if (p_base_layer == 1) {
RD::get_singleton()->draw_command_begin_label("Downsample radiance map");
for (int k = 0; k < 6; k++) {
- effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size);
+ copy_effects->cubemap_downsample_raster(radiance_base_cubemap, downsampled_layer.mipmaps[0].framebuffers[k], k, downsampled_layer.mipmaps[0].size);
}
for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) {
for (int k = 0; k < 6; k++) {
- effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size);
+ copy_effects->cubemap_downsample_raster(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].framebuffers[k], k, downsampled_layer.mipmaps[i].size);
}
}
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
@@ -518,7 +519,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren
RD::get_singleton()->draw_command_begin_label("High Quality filter radiance");
if (p_use_arrays) {
for (int k = 0; k < 6; k++) {
- effects->cubemap_roughness_raster(
+ copy_effects->cubemap_roughness_raster(
downsampled_radiance_cubemap,
layers[p_base_layer].mipmaps[0].framebuffers[k],
k,
@@ -528,7 +529,7 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren
}
} else {
for (int k = 0; k < 6; k++) {
- effects->cubemap_roughness_raster(
+ copy_effects->cubemap_roughness_raster(
downsampled_radiance_cubemap,
layers[0].mipmaps[p_base_layer].framebuffers[k],
k,
@@ -540,19 +541,19 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren
} else {
if (p_base_layer == 1) {
RD::get_singleton()->draw_command_begin_label("Downsample radiance map");
- effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size);
+ copy_effects->cubemap_downsample(radiance_base_cubemap, downsampled_layer.mipmaps[0].view, downsampled_layer.mipmaps[0].size);
for (int i = 1; i < downsampled_layer.mipmaps.size(); i++) {
- effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size);
+ copy_effects->cubemap_downsample(downsampled_layer.mipmaps[i - 1].view, downsampled_layer.mipmaps[i].view, downsampled_layer.mipmaps[i].size);
}
RD::get_singleton()->draw_command_end_label(); // Downsample Radiance
}
RD::get_singleton()->draw_command_begin_label("High Quality filter radiance");
if (p_use_arrays) {
- effects->cubemap_roughness(downsampled_radiance_cubemap, layers[p_base_layer].views[0], p_cube_side, p_sky_ggx_samples_quality, float(p_base_layer) / (layers.size() - 1.0), layers[p_base_layer].mipmaps[0].size.x);
+ copy_effects->cubemap_roughness(downsampled_radiance_cubemap, layers[p_base_layer].views[0], p_cube_side, p_sky_ggx_samples_quality, float(p_base_layer) / (layers.size() - 1.0), layers[p_base_layer].mipmaps[0].size.x);
} else {
- effects->cubemap_roughness(
+ copy_effects->cubemap_roughness(
downsampled_radiance_cubemap,
layers[0].views[p_base_layer],
p_cube_side,
@@ -564,10 +565,10 @@ void RendererSceneSkyRD::ReflectionData::create_reflection_importance_sample(Ren
RD::get_singleton()->draw_command_end_label(); // Filter radiance
}
-void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end) {
- EffectsRD *effects = p_storage->get_effects();
- ERR_FAIL_NULL_MSG(effects, "Effects haven't been initialised");
- bool prefer_raster_effects = effects->get_prefer_raster_effects();
+void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(int p_start, int p_end) {
+ RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
+ ERR_FAIL_NULL_MSG(copy_effects, "Effects haven't been initialised");
+ bool prefer_raster_effects = copy_effects->get_prefer_raster_effects();
RD::get_singleton()->draw_command_begin_label("Update Radiance Cubemap Array Mipmaps");
for (int i = p_start; i < p_end; i++) {
@@ -577,11 +578,11 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStora
if (prefer_raster_effects) {
for (int k = 0; k < 6; k++) {
RID framebuffer = layers[i].mipmaps[j + 1].framebuffers[k];
- effects->cubemap_downsample_raster(view, framebuffer, k, size);
+ copy_effects->cubemap_downsample_raster(view, framebuffer, k, size);
}
} else {
RID texture = layers[i].views[j + 1];
- effects->cubemap_downsample(view, texture, size);
+ copy_effects->cubemap_downsample(view, texture, size);
}
}
}
@@ -591,7 +592,7 @@ void RendererSceneSkyRD::ReflectionData::update_reflection_mipmaps(RendererStora
////////////////////////////////////////////////////////////////////////////////
// RendererSceneSkyRD::Sky
-void RendererSceneSkyRD::Sky::free(RendererStorageRD *p_storage) {
+void RendererSceneSkyRD::Sky::free() {
if (radiance.is_valid()) {
RD::get_singleton()->free(radiance);
radiance = RID();
@@ -614,12 +615,12 @@ void RendererSceneSkyRD::Sky::free(RendererStorageRD *p_storage) {
}
if (material.is_valid()) {
- p_storage->free(material);
+ RSG::material_storage->material_free(material);
material = RID();
}
}
-RID RendererSceneSkyRD::Sky::get_textures(RendererStorageRD *p_storage, SkyTextureSetVersion p_version, RID p_default_shader_rd) {
+RID RendererSceneSkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) {
@@ -795,10 +796,9 @@ RendererSceneSkyRD::RendererSceneSkyRD() {
sky_use_cubemap_array = GLOBAL_GET("rendering/reflections/sky_reflections/texture_array_reflections");
}
-void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
+void RendererSceneSkyRD::init() {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
- storage = p_storage;
{
// Start with the directional lights for the sky
@@ -1387,7 +1387,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
for (int i = 0; i < 6; i++) {
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
@@ -1406,7 +1406,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
for (int i = 0; i < 6; i++) {
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
@@ -1421,7 +1421,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
RD::get_singleton()->draw_command_begin_label("Render Sky Cubemap");
for (int i = 0; i < 6; i++) {
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, multiplier, p_transform.origin, p_luminance_multiplier);
@@ -1430,22 +1430,22 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
RD::get_singleton()->draw_command_end_label();
if (sky_mode == RS::SKY_MODE_REALTIME) {
- sky->reflection.create_reflection_fast_filter(storage, sky_use_cubemap_array);
+ sky->reflection.create_reflection_fast_filter(sky_use_cubemap_array);
if (sky_use_cubemap_array) {
- sky->reflection.update_reflection_mipmaps(storage, 0, sky->reflection.layers.size());
+ sky->reflection.update_reflection_mipmaps(0, sky->reflection.layers.size());
}
} else {
if (update_single_frame) {
for (int i = 1; i < max_processing_layer; i++) {
- sky->reflection.create_reflection_importance_sample(storage, sky_use_cubemap_array, 10, i, sky_ggx_samples_quality);
+ sky->reflection.create_reflection_importance_sample(sky_use_cubemap_array, 10, i, sky_ggx_samples_quality);
}
if (sky_use_cubemap_array) {
- sky->reflection.update_reflection_mipmaps(storage, 0, sky->reflection.layers.size());
+ sky->reflection.update_reflection_mipmaps(0, sky->reflection.layers.size());
}
} else {
if (sky_use_cubemap_array) {
// Multi-Frame so just update the first array level
- sky->reflection.update_reflection_mipmaps(storage, 0, 1);
+ sky->reflection.update_reflection_mipmaps(0, 1);
}
}
sky->processing_layer = 1;
@@ -1455,10 +1455,10 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM
} else {
if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) {
- sky->reflection.create_reflection_importance_sample(storage, sky_use_cubemap_array, 10, sky->processing_layer, sky_ggx_samples_quality);
+ sky->reflection.create_reflection_importance_sample(sky_use_cubemap_array, 10, sky->processing_layer, sky_ggx_samples_quality);
if (sky_use_cubemap_array) {
- sky->reflection.update_reflection_mipmaps(storage, sky->processing_layer, sky->processing_layer + 1);
+ sky->reflection.update_reflection_mipmaps(sky->processing_layer, sky->processing_layer + 1);
}
sky->processing_layer++;
@@ -1536,7 +1536,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
if (shader_data->uses_quarter_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
@@ -1549,7 +1549,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
if (shader_data->uses_half_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES];
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
@@ -1563,7 +1563,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont
RID texture_uniform_set;
if (sky) {
- texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
+ texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
} else {
texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
}
@@ -1634,7 +1634,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u
if (shader_data->uses_quarter_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
@@ -1647,7 +1647,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u
if (shader_data->uses_half_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES];
- RID texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
+ RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
@@ -1729,7 +1729,7 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme
RID texture_uniform_set;
if (sky) {
- texture_uniform_set = sky->get_textures(storage, SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
+ texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
} else {
texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
}
@@ -1777,7 +1777,7 @@ void RendererSceneSkyRD::update_dirty_skys() {
sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
- sky->reflection.update_reflection_data(storage, sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
+ sky->reflection.update_reflection_data(sky->radiance_size, mipmaps, true, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
} else {
//regular cubemap, lower quality (aliasing, less memory)
@@ -1792,7 +1792,7 @@ void RendererSceneSkyRD::update_dirty_skys() {
sky->radiance = RD::get_singleton()->texture_create(tf, RD::TextureView());
- sky->reflection.update_reflection_data(storage, sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
+ sky->reflection.update_reflection_data(sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
}
texture_set_dirty = true;
}
@@ -1872,7 +1872,7 @@ void RendererSceneSkyRD::free_sky(RID p_sky) {
Sky *sky = get_sky(p_sky);
ERR_FAIL_COND(!sky);
- sky->free(storage);
+ sky->free();
sky_owner.free(p_sky);
}
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
index 83a8fe6e77..a8ee406abc 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h
@@ -33,11 +33,13 @@
#include "core/templates/rid_owner.h"
#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_environment_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/sky.glsl.gen.h"
+#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_scene_render.h"
#include "servers/rendering/rendering_device.h"
+#include "servers/rendering/shader_compiler.h"
// Forward declare RendererSceneRenderRD so we can pass it into some of our methods, these classes are pretty tightly bound
class RendererSceneRenderRD;
@@ -63,7 +65,6 @@ public:
};
private:
- RendererStorageRD *storage = nullptr;
RD::DataFormat texture_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
RID index_buffer;
@@ -211,10 +212,10 @@ public:
Vector<Layer> layers;
void clear_reflection_data();
- void update_reflection_data(RendererStorageRD *p_storage, int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format);
- void create_reflection_fast_filter(RendererStorageRD *p_storage, bool p_use_arrays);
- void create_reflection_importance_sample(RendererStorageRD *p_storage, bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality);
- void update_reflection_mipmaps(RendererStorageRD *p_storage, int p_start, int p_end);
+ void update_reflection_data(int p_size, int p_mipmaps, bool p_use_array, RID p_base_cube, int p_base_layer, bool p_low_quality, int p_roughness_layers, RD::DataFormat p_texture_format);
+ void create_reflection_fast_filter(bool p_use_arrays);
+ void create_reflection_importance_sample(bool p_use_arrays, int p_cube_side, int p_base_layer, uint32_t p_sky_ggx_samples_quality);
+ void update_reflection_mipmaps(int p_start, int p_end);
};
/* Sky shader */
@@ -267,9 +268,9 @@ public:
Vector3 prev_position;
float prev_time;
- void free(RendererStorageRD *p_storage);
+ void free();
- RID get_textures(RendererStorageRD *p_storage, SkyTextureSetVersion p_version, RID p_default_shader_rd);
+ RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd);
bool set_radiance_size(int p_radiance_size);
bool set_mode(RS::SkyMode p_mode);
bool set_material(RID p_material);
@@ -289,7 +290,7 @@ public:
static RendererRD::MaterialData *_create_sky_material_funcs(RendererRD::ShaderData *p_shader);
RendererSceneSkyRD();
- void init(RendererStorageRD *p_storage);
+ void init();
void set_texture_format(RD::DataFormat p_texture_format);
~RendererSceneSkyRD();
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
deleted file mode 100644
index d5166c6905..0000000000
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ /dev/null
@@ -1,751 +0,0 @@
-/*************************************************************************/
-/* renderer_storage_rd.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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 "renderer_storage_rd.h"
-
-#include "core/config/engine.h"
-#include "core/config/project_settings.h"
-#include "core/io/resource_loader.h"
-#include "core/math/math_defs.h"
-#include "renderer_compositor_rd.h"
-#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
-#include "servers/rendering/renderer_rd/storage_rd/mesh_storage.h"
-#include "servers/rendering/renderer_rd/storage_rd/particles_storage.h"
-#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
-#include "servers/rendering/rendering_server_globals.h"
-#include "servers/rendering/shader_language.h"
-
-/* FOG VOLUMES */
-
-RID RendererStorageRD::fog_volume_allocate() {
- return fog_volume_owner.allocate_rid();
-}
-void RendererStorageRD::fog_volume_initialize(RID p_rid) {
- fog_volume_owner.initialize_rid(p_rid, FogVolume());
-}
-
-void RendererStorageRD::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND(!fog_volume);
-
- if (p_shape == fog_volume->shape) {
- return;
- }
-
- fog_volume->shape = p_shape;
- fog_volume->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
-}
-
-void RendererStorageRD::fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND(!fog_volume);
-
- fog_volume->extents = p_extents;
- fog_volume->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
-}
-
-void RendererStorageRD::fog_volume_set_material(RID p_fog_volume, RID p_material) {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND(!fog_volume);
- fog_volume->material = p_material;
-}
-
-RID RendererStorageRD::fog_volume_get_material(RID p_fog_volume) const {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND_V(!fog_volume, RID());
-
- return fog_volume->material;
-}
-
-RS::FogVolumeShape RendererStorageRD::fog_volume_get_shape(RID p_fog_volume) const {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND_V(!fog_volume, RS::FOG_VOLUME_SHAPE_BOX);
-
- return fog_volume->shape;
-}
-
-AABB RendererStorageRD::fog_volume_get_aabb(RID p_fog_volume) const {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND_V(!fog_volume, AABB());
-
- switch (fog_volume->shape) {
- case RS::FOG_VOLUME_SHAPE_ELLIPSOID:
- case RS::FOG_VOLUME_SHAPE_CONE:
- case RS::FOG_VOLUME_SHAPE_CYLINDER:
- case RS::FOG_VOLUME_SHAPE_BOX: {
- AABB aabb;
- aabb.position = -fog_volume->extents;
- aabb.size = fog_volume->extents * 2;
- return aabb;
- }
- default: {
- // Need some size otherwise will get culled
- return AABB(Vector3(-1, -1, -1), Vector3(2, 2, 2));
- }
- }
-
- return AABB();
-}
-
-Vector3 RendererStorageRD::fog_volume_get_extents(RID p_fog_volume) const {
- const FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
- ERR_FAIL_COND_V(!fog_volume, Vector3());
- return fog_volume->extents;
-}
-
-/* VISIBILITY NOTIFIER */
-
-RID RendererStorageRD::visibility_notifier_allocate() {
- return visibility_notifier_owner.allocate_rid();
-}
-void RendererStorageRD::visibility_notifier_initialize(RID p_notifier) {
- visibility_notifier_owner.initialize_rid(p_notifier, VisibilityNotifier());
-}
-void RendererStorageRD::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) {
- VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
- ERR_FAIL_COND(!vn);
- vn->aabb = p_aabb;
- vn->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
-}
-void RendererStorageRD::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) {
- VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
- ERR_FAIL_COND(!vn);
- vn->enter_callback = p_enter_callbable;
- vn->exit_callback = p_exit_callable;
-}
-
-AABB RendererStorageRD::visibility_notifier_get_aabb(RID p_notifier) const {
- const VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
- ERR_FAIL_COND_V(!vn, AABB());
- return vn->aabb;
-}
-void RendererStorageRD::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
- VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
- ERR_FAIL_COND(!vn);
-
- if (p_enter) {
- if (!vn->enter_callback.is_null()) {
- if (p_deferred) {
- vn->enter_callback.call_deferred(nullptr, 0);
- } else {
- Variant r;
- Callable::CallError ce;
- vn->enter_callback.call(nullptr, 0, r, ce);
- }
- }
- } else {
- if (!vn->exit_callback.is_null()) {
- if (p_deferred) {
- vn->exit_callback.call_deferred(nullptr, 0);
- } else {
- Variant r;
- Callable::CallError ce;
- vn->exit_callback.call(nullptr, 0, r, ce);
- }
- }
- }
-}
-
-/* VOXEL GI */
-
-RID RendererStorageRD::voxel_gi_allocate() {
- return voxel_gi_owner.allocate_rid();
-}
-void RendererStorageRD::voxel_gi_initialize(RID p_voxel_gi) {
- voxel_gi_owner.initialize_rid(p_voxel_gi, VoxelGI());
-}
-
-void RendererStorageRD::voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND(!voxel_gi);
-
- if (voxel_gi->octree_buffer.is_valid()) {
- RD::get_singleton()->free(voxel_gi->octree_buffer);
- RD::get_singleton()->free(voxel_gi->data_buffer);
- if (voxel_gi->sdf_texture.is_valid()) {
- RD::get_singleton()->free(voxel_gi->sdf_texture);
- }
-
- voxel_gi->sdf_texture = RID();
- voxel_gi->octree_buffer = RID();
- voxel_gi->data_buffer = RID();
- voxel_gi->octree_buffer_size = 0;
- voxel_gi->data_buffer_size = 0;
- voxel_gi->cell_count = 0;
- }
-
- voxel_gi->to_cell_xform = p_to_cell_xform;
- voxel_gi->bounds = p_aabb;
- voxel_gi->octree_size = p_octree_size;
- voxel_gi->level_counts = p_level_counts;
-
- if (p_octree_cells.size()) {
- ERR_FAIL_COND(p_octree_cells.size() % 32 != 0); //cells size must be a multiple of 32
-
- uint32_t cell_count = p_octree_cells.size() / 32;
-
- ERR_FAIL_COND(p_data_cells.size() != (int)cell_count * 16); //see that data size matches
-
- voxel_gi->cell_count = cell_count;
- voxel_gi->octree_buffer = RD::get_singleton()->storage_buffer_create(p_octree_cells.size(), p_octree_cells);
- voxel_gi->octree_buffer_size = p_octree_cells.size();
- voxel_gi->data_buffer = RD::get_singleton()->storage_buffer_create(p_data_cells.size(), p_data_cells);
- voxel_gi->data_buffer_size = p_data_cells.size();
-
- if (p_distance_field.size()) {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = voxel_gi->octree_size.x;
- tf.height = voxel_gi->octree_size.y;
- tf.depth = voxel_gi->octree_size.z;
- tf.texture_type = RD::TEXTURE_TYPE_3D;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_CAN_UPDATE_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT;
- Vector<Vector<uint8_t>> s;
- s.push_back(p_distance_field);
- voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView(), s);
- }
-#if 0
- {
- RD::TextureFormat tf;
- tf.format = RD::DATA_FORMAT_R8_UNORM;
- tf.width = voxel_gi->octree_size.x;
- tf.height = voxel_gi->octree_size.y;
- tf.depth = voxel_gi->octree_size.z;
- tf.type = RD::TEXTURE_TYPE_3D;
- tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT | RD::TEXTURE_USAGE_CAN_COPY_TO_BIT;
- tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UNORM);
- tf.shareable_formats.push_back(RD::DATA_FORMAT_R8_UINT);
- voxel_gi->sdf_texture = RD::get_singleton()->texture_create(tf, RD::TextureView());
- }
- RID shared_tex;
- {
- RD::TextureView tv;
- tv.format_override = RD::DATA_FORMAT_R8_UINT;
- shared_tex = RD::get_singleton()->texture_create_shared(tv, voxel_gi->sdf_texture);
- }
- //update SDF texture
- Vector<RD::Uniform> uniforms;
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 1;
- u.append_id(voxel_gi->octree_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.binding = 2;
- u.append_id(voxel_gi->data_buffer);
- uniforms.push_back(u);
- }
- {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
- u.binding = 3;
- u.append_id(shared_tex);
- uniforms.push_back(u);
- }
-
- RID uniform_set = RD::get_singleton()->uniform_set_create(uniforms, voxel_gi_sdf_shader_version_shader, 0);
-
- {
- uint32_t push_constant[4] = { 0, 0, 0, 0 };
-
- for (int i = 0; i < voxel_gi->level_counts.size() - 1; i++) {
- push_constant[0] += voxel_gi->level_counts[i];
- }
- push_constant[1] = push_constant[0] + voxel_gi->level_counts[voxel_gi->level_counts.size() - 1];
-
- print_line("offset: " + itos(push_constant[0]));
- print_line("size: " + itos(push_constant[1]));
- //create SDF
- RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin();
- RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, voxel_gi_sdf_shader_pipeline);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, uniform_set, 0);
- RD::get_singleton()->compute_list_set_push_constant(compute_list, push_constant, sizeof(uint32_t) * 4);
- RD::get_singleton()->compute_list_dispatch(compute_list, voxel_gi->octree_size.x / 4, voxel_gi->octree_size.y / 4, voxel_gi->octree_size.z / 4);
- RD::get_singleton()->compute_list_end();
- }
-
- RD::get_singleton()->free(uniform_set);
- RD::get_singleton()->free(shared_tex);
- }
-#endif
- }
-
- voxel_gi->version++;
- voxel_gi->data_version++;
-
- voxel_gi->dependency.changed_notify(DEPENDENCY_CHANGED_AABB);
-}
-
-AABB RendererStorageRD::voxel_gi_get_bounds(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, AABB());
-
- return voxel_gi->bounds;
-}
-
-Vector3i RendererStorageRD::voxel_gi_get_octree_size(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, Vector3i());
- return voxel_gi->octree_size;
-}
-
-Vector<uint8_t> RendererStorageRD::voxel_gi_get_octree_cells(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>());
-
- if (voxel_gi->octree_buffer.is_valid()) {
- return RD::get_singleton()->buffer_get_data(voxel_gi->octree_buffer);
- }
- return Vector<uint8_t>();
-}
-
-Vector<uint8_t> RendererStorageRD::voxel_gi_get_data_cells(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>());
-
- if (voxel_gi->data_buffer.is_valid()) {
- return RD::get_singleton()->buffer_get_data(voxel_gi->data_buffer);
- }
- return Vector<uint8_t>();
-}
-
-Vector<uint8_t> RendererStorageRD::voxel_gi_get_distance_field(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, Vector<uint8_t>());
-
- if (voxel_gi->data_buffer.is_valid()) {
- return RD::get_singleton()->texture_get_data(voxel_gi->sdf_texture, 0);
- }
- return Vector<uint8_t>();
-}
-
-Vector<int> RendererStorageRD::voxel_gi_get_level_counts(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, Vector<int>());
-
- return voxel_gi->level_counts;
-}
-
-Transform3D RendererStorageRD::voxel_gi_get_to_cell_xform(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, Transform3D());
-
- return voxel_gi->to_cell_xform;
-}
-
-void RendererStorageRD::voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND(!voxel_gi);
-
- voxel_gi->dynamic_range = p_range;
- voxel_gi->version++;
-}
-
-float RendererStorageRD::voxel_gi_get_dynamic_range(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, 0);
-
- return voxel_gi->dynamic_range;
-}
-
-void RendererStorageRD::voxel_gi_set_propagation(RID p_voxel_gi, float p_range) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND(!voxel_gi);
-
- voxel_gi->propagation = p_range;
- voxel_gi->version++;
-}
-
-float RendererStorageRD::voxel_gi_get_propagation(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, 0);
- return voxel_gi->propagation;
-}
-
-void RendererStorageRD::voxel_gi_set_energy(RID p_voxel_gi, float p_energy) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND(!voxel_gi);
-
- voxel_gi->energy = p_energy;
-}
-
-float RendererStorageRD::voxel_gi_get_energy(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, 0);
- return voxel_gi->energy;
-}
-
-void RendererStorageRD::voxel_gi_set_bias(RID p_voxel_gi, float p_bias) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND(!voxel_gi);
-
- voxel_gi->bias = p_bias;
-}
-
-float RendererStorageRD::voxel_gi_get_bias(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, 0);
- return voxel_gi->bias;
-}
-
-void RendererStorageRD::voxel_gi_set_normal_bias(RID p_voxel_gi, float p_normal_bias) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND(!voxel_gi);
-
- voxel_gi->normal_bias = p_normal_bias;
-}
-
-float RendererStorageRD::voxel_gi_get_normal_bias(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, 0);
- return voxel_gi->normal_bias;
-}
-
-void RendererStorageRD::voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND(!voxel_gi);
-
- voxel_gi->anisotropy_strength = p_strength;
-}
-
-float RendererStorageRD::voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, 0);
- return voxel_gi->anisotropy_strength;
-}
-
-void RendererStorageRD::voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND(!voxel_gi);
-
- voxel_gi->interior = p_enable;
-}
-
-void RendererStorageRD::voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND(!voxel_gi);
-
- voxel_gi->use_two_bounces = p_enable;
- voxel_gi->version++;
-}
-
-bool RendererStorageRD::voxel_gi_is_using_two_bounces(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, false);
- return voxel_gi->use_two_bounces;
-}
-
-bool RendererStorageRD::voxel_gi_is_interior(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, 0);
- return voxel_gi->interior;
-}
-
-uint32_t RendererStorageRD::voxel_gi_get_version(RID p_voxel_gi) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, 0);
- return voxel_gi->version;
-}
-
-uint32_t RendererStorageRD::voxel_gi_get_data_version(RID p_voxel_gi) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, 0);
- return voxel_gi->data_version;
-}
-
-RID RendererStorageRD::voxel_gi_get_octree_buffer(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, RID());
- return voxel_gi->octree_buffer;
-}
-
-RID RendererStorageRD::voxel_gi_get_data_buffer(RID p_voxel_gi) const {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, RID());
- return voxel_gi->data_buffer;
-}
-
-RID RendererStorageRD::voxel_gi_get_sdf_texture(RID p_voxel_gi) {
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_voxel_gi);
- ERR_FAIL_COND_V(!voxel_gi, RID());
-
- return voxel_gi->sdf_texture;
-}
-
-/* misc */
-
-void RendererStorageRD::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
- if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_base)) {
- RendererRD::Mesh *mesh = RendererRD::MeshStorage::get_singleton()->get_mesh(p_base);
- p_instance->update_dependency(&mesh->dependency);
- } else if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_base)) {
- RendererRD::MultiMesh *multimesh = RendererRD::MeshStorage::get_singleton()->get_multimesh(p_base);
- p_instance->update_dependency(&multimesh->dependency);
- if (multimesh->mesh.is_valid()) {
- base_update_dependency(multimesh->mesh, p_instance);
- }
- } else if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_base)) {
- RendererRD::ReflectionProbe *rp = RendererRD::LightStorage::get_singleton()->get_reflection_probe(p_base);
- p_instance->update_dependency(&rp->dependency);
- } else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_base)) {
- RendererRD::Decal *decal = RendererRD::TextureStorage::get_singleton()->get_decal(p_base);
- p_instance->update_dependency(&decal->dependency);
- } else if (voxel_gi_owner.owns(p_base)) {
- VoxelGI *gip = voxel_gi_owner.get_or_null(p_base);
- p_instance->update_dependency(&gip->dependency);
- } else if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_base)) {
- RendererRD::Lightmap *lm = RendererRD::LightStorage::get_singleton()->get_lightmap(p_base);
- p_instance->update_dependency(&lm->dependency);
- } else if (RendererRD::LightStorage::get_singleton()->owns_light(p_base)) {
- RendererRD::Light *l = RendererRD::LightStorage::get_singleton()->get_light(p_base);
- p_instance->update_dependency(&l->dependency);
- } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_base)) {
- RendererRD::Particles *p = RendererRD::ParticlesStorage::get_singleton()->get_particles(p_base);
- p_instance->update_dependency(&p->dependency);
- } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_base)) {
- RendererRD::ParticlesCollision *pc = RendererRD::ParticlesStorage::get_singleton()->get_particles_collision(p_base);
- p_instance->update_dependency(&pc->dependency);
- } else if (fog_volume_owner.owns(p_base)) {
- FogVolume *fv = fog_volume_owner.get_or_null(p_base);
- p_instance->update_dependency(&fv->dependency);
- } else if (visibility_notifier_owner.owns(p_base)) {
- VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_base);
- p_instance->update_dependency(&vn->dependency);
- }
-}
-
-RS::InstanceType RendererStorageRD::get_base_type(RID p_rid) const {
- if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
- return RS::INSTANCE_MESH;
- }
- if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
- return RS::INSTANCE_MULTIMESH;
- }
- if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) {
- return RS::INSTANCE_REFLECTION_PROBE;
- }
- if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
- return RS::INSTANCE_DECAL;
- }
- if (voxel_gi_owner.owns(p_rid)) {
- return RS::INSTANCE_VOXEL_GI;
- }
- if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) {
- return RS::INSTANCE_LIGHT;
- }
- if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) {
- return RS::INSTANCE_LIGHTMAP;
- }
- if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_rid)) {
- return RS::INSTANCE_PARTICLES;
- }
- if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) {
- return RS::INSTANCE_PARTICLES_COLLISION;
- }
- if (fog_volume_owner.owns(p_rid)) {
- return RS::INSTANCE_FOG_VOLUME;
- }
- if (visibility_notifier_owner.owns(p_rid)) {
- return RS::INSTANCE_VISIBLITY_NOTIFIER;
- }
-
- return RS::INSTANCE_NONE;
-}
-
-void RendererStorageRD::update_dirty_resources() {
- RendererRD::MaterialStorage::get_singleton()->_update_global_variables(); //must do before materials, so it can queue them for update
- RendererRD::MaterialStorage::get_singleton()->_update_queued_materials();
- RendererRD::MeshStorage::get_singleton()->_update_dirty_multimeshes();
- RendererRD::MeshStorage::get_singleton()->_update_dirty_skeletons();
- RendererRD::TextureStorage::get_singleton()->update_decal_atlas();
-}
-
-bool RendererStorageRD::has_os_feature(const String &p_feature) const {
- if (!RD::get_singleton()) {
- return false;
- }
-
- if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
- return true;
- }
-
- if (p_feature == "s3tc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
- return true;
- }
-
- if (p_feature == "bptc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
- return true;
- }
-
- if ((p_feature == "etc" || p_feature == "etc2") && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
- return true;
- }
-
- return false;
-}
-
-bool RendererStorageRD::free(RID p_rid) {
- if (RendererRD::TextureStorage::get_singleton()->owns_texture(p_rid)) {
- RendererRD::TextureStorage::get_singleton()->texture_free(p_rid);
- } else if (RendererRD::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
- RendererRD::TextureStorage::get_singleton()->canvas_texture_free(p_rid);
- } else if (RendererRD::MaterialStorage::get_singleton()->owns_shader(p_rid)) {
- RendererRD::MaterialStorage::get_singleton()->shader_free(p_rid);
- } else if (RendererRD::MaterialStorage::get_singleton()->owns_material(p_rid)) {
- RendererRD::MaterialStorage::get_singleton()->material_free(p_rid);
- } else if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
- RendererRD::MeshStorage::get_singleton()->mesh_free(p_rid);
- } else if (RendererRD::MeshStorage::get_singleton()->owns_mesh_instance(p_rid)) {
- RendererRD::MeshStorage::get_singleton()->mesh_instance_free(p_rid);
- } else if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
- RendererRD::MeshStorage::get_singleton()->multimesh_free(p_rid);
- } else if (RendererRD::MeshStorage::get_singleton()->owns_skeleton(p_rid)) {
- RendererRD::MeshStorage::get_singleton()->skeleton_free(p_rid);
- } else if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) {
- RendererRD::LightStorage::get_singleton()->reflection_probe_free(p_rid);
- } else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
- RendererRD::TextureStorage::get_singleton()->decal_free(p_rid);
- } else if (voxel_gi_owner.owns(p_rid)) {
- voxel_gi_allocate_data(p_rid, Transform3D(), AABB(), Vector3i(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<uint8_t>(), Vector<int>()); //deallocate
- VoxelGI *voxel_gi = voxel_gi_owner.get_or_null(p_rid);
- voxel_gi->dependency.deleted_notify(p_rid);
- voxel_gi_owner.free(p_rid);
- } else if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) {
- RendererRD::LightStorage::get_singleton()->lightmap_free(p_rid);
- } else if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) {
- RendererRD::LightStorage::get_singleton()->light_free(p_rid);
- } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_rid)) {
- RendererRD::ParticlesStorage::get_singleton()->particles_free(p_rid);
- } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) {
- RendererRD::ParticlesStorage::get_singleton()->particles_collision_free(p_rid);
- } else if (visibility_notifier_owner.owns(p_rid)) {
- VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_rid);
- vn->dependency.deleted_notify(p_rid);
- visibility_notifier_owner.free(p_rid);
- } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision_instance(p_rid)) {
- RendererRD::ParticlesStorage::get_singleton()->particles_collision_instance_free(p_rid);
- } else if (fog_volume_owner.owns(p_rid)) {
- FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid);
- fog_volume->dependency.deleted_notify(p_rid);
- fog_volume_owner.free(p_rid);
- } else if (RendererRD::TextureStorage::get_singleton()->owns_render_target(p_rid)) {
- RendererRD::TextureStorage::get_singleton()->render_target_free(p_rid);
- } else {
- return false;
- }
-
- return true;
-}
-
-void RendererStorageRD::init_effects(bool p_prefer_raster_effects) {
- effects = memnew(EffectsRD(p_prefer_raster_effects));
-}
-
-EffectsRD *RendererStorageRD::get_effects() {
- ERR_FAIL_NULL_V_MSG(effects, nullptr, "Effects haven't been initialised yet.");
- return effects;
-}
-
-void RendererStorageRD::capture_timestamps_begin() {
- RD::get_singleton()->capture_timestamp("Frame Begin");
-}
-
-void RendererStorageRD::capture_timestamp(const String &p_name) {
- RD::get_singleton()->capture_timestamp(p_name);
-}
-
-uint32_t RendererStorageRD::get_captured_timestamps_count() const {
- return RD::get_singleton()->get_captured_timestamps_count();
-}
-
-uint64_t RendererStorageRD::get_captured_timestamps_frame() const {
- return RD::get_singleton()->get_captured_timestamps_frame();
-}
-
-uint64_t RendererStorageRD::get_captured_timestamp_gpu_time(uint32_t p_index) const {
- return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index);
-}
-
-uint64_t RendererStorageRD::get_captured_timestamp_cpu_time(uint32_t p_index) const {
- return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index);
-}
-
-String RendererStorageRD::get_captured_timestamp_name(uint32_t p_index) const {
- return RD::get_singleton()->get_captured_timestamp_name(p_index);
-}
-
-void RendererStorageRD::update_memory_info() {
- texture_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TEXTURES);
- buffer_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_BUFFERS);
- total_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TOTAL);
-}
-uint64_t RendererStorageRD::get_rendering_info(RS::RenderingInfo p_info) {
- if (p_info == RS::RENDERING_INFO_TEXTURE_MEM_USED) {
- return texture_mem_cache;
- } else if (p_info == RS::RENDERING_INFO_BUFFER_MEM_USED) {
- return buffer_mem_cache;
- } else if (p_info == RS::RENDERING_INFO_VIDEO_MEM_USED) {
- return total_mem_cache;
- }
- return 0;
-}
-
-String RendererStorageRD::get_video_adapter_name() const {
- return RenderingDevice::get_singleton()->get_device_name();
-}
-
-String RendererStorageRD::get_video_adapter_vendor() const {
- return RenderingDevice::get_singleton()->get_device_vendor_name();
-}
-
-RenderingDevice::DeviceType RendererStorageRD::get_video_adapter_type() const {
- return RenderingDevice::get_singleton()->get_device_type();
-}
-
-String RendererStorageRD::get_video_adapter_api_version() const {
- return RenderingDevice::get_singleton()->get_device_api_version();
-}
-
-RendererStorageRD *RendererStorageRD::base_singleton = nullptr;
-
-RendererStorageRD::RendererStorageRD() {
- base_singleton = this;
-}
-
-RendererStorageRD::~RendererStorageRD() {
- if (effects) {
- memdelete(effects);
- effects = nullptr;
- }
-}
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
deleted file mode 100644
index 07fae45a26..0000000000
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/*************************************************************************/
-/* renderer_storage_rd.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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 RENDERING_SERVER_STORAGE_RD_H
-#define RENDERING_SERVER_STORAGE_RD_H
-
-#include "core/templates/list.h"
-#include "core/templates/local_vector.h"
-#include "core/templates/rid_owner.h"
-#include "servers/rendering/renderer_compositor.h"
-#include "servers/rendering/renderer_rd/effects_rd.h"
-#include "servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl.gen.h"
-#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
-#include "servers/rendering/renderer_scene_render.h"
-#include "servers/rendering/rendering_device.h"
-#include "servers/rendering/shader_compiler.h"
-
-class RendererStorageRD : public RendererStorage {
-public:
- static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
- p_array[0] = p_mtx.basis.rows[0][0];
- p_array[1] = p_mtx.basis.rows[1][0];
- p_array[2] = p_mtx.basis.rows[2][0];
- p_array[3] = 0;
- p_array[4] = p_mtx.basis.rows[0][1];
- p_array[5] = p_mtx.basis.rows[1][1];
- p_array[6] = p_mtx.basis.rows[2][1];
- p_array[7] = 0;
- p_array[8] = p_mtx.basis.rows[0][2];
- p_array[9] = p_mtx.basis.rows[1][2];
- p_array[10] = p_mtx.basis.rows[2][2];
- p_array[11] = 0;
- p_array[12] = p_mtx.origin.x;
- p_array[13] = p_mtx.origin.y;
- p_array[14] = p_mtx.origin.z;
- p_array[15] = 1;
- }
-
- static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) {
- p_array[0] = p_mtx.rows[0][0];
- p_array[1] = p_mtx.rows[1][0];
- p_array[2] = p_mtx.rows[2][0];
- p_array[3] = 0;
- p_array[4] = p_mtx.rows[0][1];
- p_array[5] = p_mtx.rows[1][1];
- p_array[6] = p_mtx.rows[2][1];
- p_array[7] = 0;
- p_array[8] = p_mtx.rows[0][2];
- p_array[9] = p_mtx.rows[1][2];
- p_array[10] = p_mtx.rows[2][2];
- p_array[11] = 0;
- }
-
- static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) {
- p_array[0] = p_mtx.rows[0][0];
- p_array[1] = p_mtx.rows[1][0];
- p_array[2] = p_mtx.rows[2][0];
- p_array[3] = 0;
- p_array[4] = p_mtx.rows[0][1];
- p_array[5] = p_mtx.rows[1][1];
- p_array[6] = p_mtx.rows[2][1];
- p_array[7] = 0;
- p_array[8] = p_mtx.rows[0][2];
- p_array[9] = p_mtx.rows[1][2];
- p_array[10] = p_mtx.rows[2][2];
- p_array[11] = 0;
- }
-
- static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform3D &p_mtx, float *p_array) {
- p_array[0] = p_mtx.basis.rows[0][0];
- p_array[1] = p_mtx.basis.rows[0][1];
- p_array[2] = p_mtx.basis.rows[0][2];
- p_array[3] = p_mtx.origin.x;
- p_array[4] = p_mtx.basis.rows[1][0];
- p_array[5] = p_mtx.basis.rows[1][1];
- p_array[6] = p_mtx.basis.rows[1][2];
- p_array[7] = p_mtx.origin.y;
- p_array[8] = p_mtx.basis.rows[2][0];
- p_array[9] = p_mtx.basis.rows[2][1];
- p_array[10] = p_mtx.basis.rows[2][2];
- p_array[11] = p_mtx.origin.z;
- }
-
- static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- p_array[i * 4 + j] = p_mtx.matrix[i][j];
- }
- }
- }
-
- static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) {
- for (int i = 0; i < 128; i++) {
- p_array[i] = p_kernel[i];
- }
- }
-
-private:
- /* FOG VOLUMES */
-
- struct FogVolume {
- RID material;
- Vector3 extents = Vector3(1, 1, 1);
-
- RS::FogVolumeShape shape = RS::FOG_VOLUME_SHAPE_BOX;
-
- Dependency dependency;
- };
-
- mutable RID_Owner<FogVolume, true> fog_volume_owner;
-
- /* visibility_notifier */
-
- struct VisibilityNotifier {
- AABB aabb;
- Callable enter_callback;
- Callable exit_callback;
- Dependency dependency;
- };
-
- mutable RID_Owner<VisibilityNotifier> visibility_notifier_owner;
-
- /* VOXEL GI */
-
- struct VoxelGI {
- RID octree_buffer;
- RID data_buffer;
- RID sdf_texture;
-
- uint32_t octree_buffer_size = 0;
- uint32_t data_buffer_size = 0;
-
- Vector<int> level_counts;
-
- int cell_count = 0;
-
- Transform3D to_cell_xform;
- AABB bounds;
- Vector3i octree_size;
-
- float dynamic_range = 2.0;
- float energy = 1.0;
- float bias = 1.4;
- float normal_bias = 0.0;
- float propagation = 0.7;
- bool interior = false;
- bool use_two_bounces = false;
-
- float anisotropy_strength = 0.5;
-
- uint32_t version = 1;
- uint32_t data_version = 1;
-
- Dependency dependency;
- };
-
- mutable RID_Owner<VoxelGI, true> voxel_gi_owner;
-
- /* EFFECTS */
-
- EffectsRD *effects = nullptr;
-
-public:
- //internal usage
-
- void base_update_dependency(RID p_base, DependencyTracker *p_instance);
-
- /* VOXEL GI API */
-
- RID voxel_gi_allocate();
- void voxel_gi_initialize(RID p_voxel_gi);
-
- void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts);
-
- AABB voxel_gi_get_bounds(RID p_voxel_gi) const;
- Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const;
- Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const;
- Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const;
- Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const;
-
- Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const;
- Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const;
-
- void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range);
- float voxel_gi_get_dynamic_range(RID p_voxel_gi) const;
-
- void voxel_gi_set_propagation(RID p_voxel_gi, float p_range);
- float voxel_gi_get_propagation(RID p_voxel_gi) const;
-
- void voxel_gi_set_energy(RID p_voxel_gi, float p_energy);
- float voxel_gi_get_energy(RID p_voxel_gi) const;
-
- void voxel_gi_set_bias(RID p_voxel_gi, float p_bias);
- float voxel_gi_get_bias(RID p_voxel_gi) const;
-
- void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range);
- float voxel_gi_get_normal_bias(RID p_voxel_gi) const;
-
- void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable);
- bool voxel_gi_is_interior(RID p_voxel_gi) const;
-
- void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable);
- bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const;
-
- void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength);
- float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const;
-
- uint32_t voxel_gi_get_version(RID p_probe);
- uint32_t voxel_gi_get_data_version(RID p_probe);
-
- RID voxel_gi_get_octree_buffer(RID p_voxel_gi) const;
- RID voxel_gi_get_data_buffer(RID p_voxel_gi) const;
-
- RID voxel_gi_get_sdf_texture(RID p_voxel_gi);
-
- /* FOG VOLUMES */
-
- virtual RID fog_volume_allocate();
- virtual void fog_volume_initialize(RID p_rid);
-
- virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape);
- virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents);
- virtual void fog_volume_set_material(RID p_fog_volume, RID p_material);
- virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const;
- virtual RID fog_volume_get_material(RID p_fog_volume) const;
- virtual AABB fog_volume_get_aabb(RID p_fog_volume) const;
- virtual Vector3 fog_volume_get_extents(RID p_fog_volume) const;
-
- /* VISIBILITY NOTIFIER */
-
- virtual RID visibility_notifier_allocate();
- virtual void visibility_notifier_initialize(RID p_notifier);
- virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb);
- virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable);
-
- virtual AABB visibility_notifier_get_aabb(RID p_notifier) const;
- virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred);
-
- RS::InstanceType get_base_type(RID p_rid) const;
-
- bool free(RID p_rid);
-
- bool has_os_feature(const String &p_feature) const;
-
- void update_dirty_resources();
-
- void set_debug_generate_wireframes(bool p_generate) {}
-
- //keep cached since it can be called form any thread
- uint64_t texture_mem_cache = 0;
- uint64_t buffer_mem_cache = 0;
- uint64_t total_mem_cache = 0;
-
- virtual void update_memory_info();
- virtual uint64_t get_rendering_info(RS::RenderingInfo p_info);
-
- String get_video_adapter_name() const;
- String get_video_adapter_vendor() const;
- RenderingDevice::DeviceType get_video_adapter_type() const;
- String get_video_adapter_api_version() const;
-
- virtual void capture_timestamps_begin();
- virtual void capture_timestamp(const String &p_name);
- virtual uint32_t get_captured_timestamps_count() const;
- virtual uint64_t get_captured_timestamps_frame() const;
- virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const;
- virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const;
- virtual String get_captured_timestamp_name(uint32_t p_index) const;
-
- static RendererStorageRD *base_singleton;
-
- void init_effects(bool p_prefer_raster_effects);
- EffectsRD *get_effects();
-
- RendererStorageRD();
- ~RendererStorageRD();
-};
-
-#endif // RASTERIZER_STORAGE_RD_H
diff --git a/servers/rendering/renderer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub
index acb843bfb6..d352743908 100644
--- a/servers/rendering/renderer_rd/shaders/SCsub
+++ b/servers/rendering/renderer_rd/shaders/SCsub
@@ -10,10 +10,11 @@ if "RD_GLSL" in env["BUILDERS"]:
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
# make sure we recompile shaders if include files change
- env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files)
+ env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
# compile shaders
for glsl_file in glsl_files:
env.RD_GLSL(glsl_file)
SConscript("effects/SCsub")
+SConscript("environment/SCsub")
diff --git a/servers/rendering/renderer_rd/shaders/effects/SCsub b/servers/rendering/renderer_rd/shaders/effects/SCsub
index fc513d3fb9..741da8fe69 100644
--- a/servers/rendering/renderer_rd/shaders/effects/SCsub
+++ b/servers/rendering/renderer_rd/shaders/effects/SCsub
@@ -10,7 +10,7 @@ if "RD_GLSL" in env["BUILDERS"]:
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
# make sure we recompile shaders if include files change
- env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files)
+ env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
# compile shaders
for glsl_file in glsl_files:
diff --git a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl
index e77d0de719..e77d0de719 100644
--- a/servers/rendering/renderer_rd/shaders/cube_to_dp.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler.glsl
index 63f0ce690e..63f0ce690e 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_downsampler.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler.glsl
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_downsampler_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_inc.glsl
index 641e0906f5..641e0906f5 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_downsampler_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_inc.glsl
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_downsampler_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl
index 0828ffd921..0828ffd921 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_downsampler_raster.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_filter.glsl
index 2a774b0eb4..2a774b0eb4 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_filter.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_filter.glsl
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_filter_raster.glsl
index 0990dc7c2f..0990dc7c2f 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_filter_raster.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_filter_raster.glsl
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness.glsl
index 1d46f59408..1d46f59408 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_roughness.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness.glsl
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl
index 1bee428a6f..1bee428a6f 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_raster.glsl
index c29accd8a7..c29accd8a7 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_roughness_raster.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_raster.glsl
diff --git a/servers/rendering/renderer_rd/shaders/resolve.glsl b/servers/rendering/renderer_rd/shaders/effects/resolve.glsl
index 0e086331c0..0e086331c0 100644
--- a/servers/rendering/renderer_rd/shaders/resolve.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/resolve.glsl
diff --git a/servers/rendering/renderer_rd/shaders/environment/SCsub b/servers/rendering/renderer_rd/shaders/environment/SCsub
new file mode 100644
index 0000000000..741da8fe69
--- /dev/null
+++ b/servers/rendering/renderer_rd/shaders/environment/SCsub
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+Import("env")
+
+if "RD_GLSL" in env["BUILDERS"]:
+ # find all include files
+ gl_include_files = [str(f) for f in Glob("*_inc.glsl")]
+
+ # find all shader code(all glsl files excluding our include files)
+ glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
+
+ # make sure we recompile shaders if include files change
+ env.Depends([f + ".gen.h" for f in glsl_files], gl_include_files + ["#glsl_builders.py"])
+
+ # compile shaders
+ for glsl_file in glsl_files:
+ env.RD_GLSL(glsl_file)
diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/environment/gi.glsl
index 0c7f08813b..f687d50a2d 100644
--- a/servers/rendering/renderer_rd/shaders/gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/gi.glsl
@@ -86,19 +86,29 @@ voxel_gi_instances;
layout(set = 0, binding = 17) uniform texture3D voxel_gi_textures[MAX_VOXEL_GI_INSTANCES];
-layout(push_constant, std430) uniform Params {
- ivec2 screen_size;
- float z_near;
- float z_far;
+layout(set = 0, binding = 18, std140) uniform SceneData {
+ mat4x4 inv_projection[2];
+ mat4x4 cam_transform;
+ vec4 eye_offset[2];
- vec4 proj_info;
+ ivec2 screen_size;
+ float pad1;
+ float pad2;
+}
+scene_data;
+layout(push_constant, std430) uniform Params {
+ uint view_index;
uint max_voxel_gi_instances;
bool high_quality_vct;
bool orthogonal;
- uint pad;
- mat3x4 cam_rotation;
+ vec4 proj_info;
+
+ float z_near;
+ float z_far;
+ float pad1;
+ float pad2;
}
params;
@@ -130,6 +140,16 @@ vec4 blend_color(vec4 src, vec4 dst) {
}
vec3 reconstruct_position(ivec2 screen_pos) {
+#ifdef USE_MULTIVIEW
+ vec4 pos;
+ pos.xy = (2.0 * vec2(screen_pos) / vec2(scene_data.screen_size)) - 1.0;
+ pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r * 2.0 - 1.0;
+ pos.w = 1.0;
+
+ pos = scene_data.inv_projection[params.view_index] * pos;
+
+ return pos.xyz / pos.w;
+#else
vec3 pos;
pos.z = texelFetch(sampler2D(depth_buffer, linear_sampler), screen_pos, 0).r;
@@ -147,6 +167,7 @@ vec3 reconstruct_position(ivec2 screen_pos) {
}
return pos;
+#endif
}
void sdfvoxel_gi_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal, vec3 cam_specular_normal, float roughness, out vec3 diffuse_light, out vec3 specular_light) {
@@ -579,9 +600,10 @@ void process_gi(ivec2 pos, vec3 vertex, inout vec4 ambient_light, inout vec4 ref
if (normal.length() > 0.5) {
//valid normal, can do GI
float roughness = normal_roughness.w;
- vertex = mat3(params.cam_rotation) * vertex;
- normal = normalize(mat3(params.cam_rotation) * normal);
- vec3 reflection = normalize(reflect(normalize(vertex), normal));
+ vec3 view = -normalize(mat3(scene_data.cam_transform) * (vertex - scene_data.eye_offset[params.view_index].xyz));
+ vertex = mat3(scene_data.cam_transform) * vertex;
+ normal = normalize(mat3(scene_data.cam_transform) * normal);
+ vec3 reflection = normalize(reflect(-view, normal));
#ifdef USE_SDFGI
sdfgi_process(vertex, normal, reflection, roughness, ambient_light, reflection_light);
@@ -629,7 +651,7 @@ void main() {
#ifdef MODE_HALF_RES
pos <<= 1;
#endif
- if (any(greaterThanEqual(pos, params.screen_size))) { //too large, do nothing
+ if (any(greaterThanEqual(pos, scene_data.screen_size))) { //too large, do nothing
return;
}
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl
index 802a410825..af5f7d0a58 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_debug.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug.glsl
@@ -40,10 +40,13 @@ layout(push_constant, std430) uniform Params {
bool use_occlusion;
float y_mult;
- vec3 cam_extent;
int probe_axis_size;
+ float z_near;
+ float reserved1;
+ float reserved2;
mat4 cam_transform;
+ mat4 inv_projection;
}
params;
@@ -81,8 +84,9 @@ void main() {
{
ray_pos = params.cam_transform[3].xyz;
- ray_dir.xy = params.cam_extent.xy * ((vec2(screen_pos) / vec2(params.screen_size)) * 2.0 - 1.0);
- ray_dir.z = params.cam_extent.z;
+ ray_dir.xy = ((vec2(screen_pos) / vec2(params.screen_size)) * 2.0 - 1.0);
+ ray_dir.z = params.z_near;
+ ray_dir = (params.inv_projection * vec4(ray_dir, 1.0)).xyz;
ray_dir = normalize(mat3(params.cam_transform) * ray_dir);
}
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl
index e0be0bca12..75b1ad2130 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_debug_probes.glsl
@@ -2,13 +2,28 @@
#version 450
+#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview)
+#extension GL_EXT_multiview : enable
+#endif
+
+#ifdef USE_MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#define ViewIndex gl_ViewIndex
+#else // has_VK_KHR_multiview
+// !BAS! This needs to become an input once we implement our fallback!
+#define ViewIndex 0
+#endif // has_VK_KHR_multiview
+#else // USE_MULTIVIEW
+// Set to zero, not supported in non stereo
+#define ViewIndex 0
+#endif //USE_MULTIVIEW
+
#VERSION_DEFINES
#define MAX_CASCADES 8
+#define MAX_VIEWS 2
layout(push_constant, std430) uniform Params {
- mat4 projection;
-
uint band_power;
uint sections_in_band;
uint band_mask;
@@ -68,6 +83,11 @@ cascades;
layout(set = 0, binding = 4) uniform texture3D occlusion_texture;
layout(set = 0, binding = 3) uniform sampler linear_sampler;
+layout(set = 0, binding = 5, std140) uniform SceneData {
+ mat4 projection[MAX_VIEWS];
+}
+scene_data;
+
void main() {
#ifdef MODE_PROBES
probe_index = gl_InstanceIndex;
@@ -85,7 +105,7 @@ void main() {
vertex += (cascades.data[params.cascade].offset + vec3(probe_cell) * probe_cell_size) / vec3(1.0, params.y_mult, 1.0);
- gl_Position = params.projection * vec4(vertex, 1.0);
+ gl_Position = scene_data.projection[ViewIndex] * vec4(vertex, 1.0);
#endif
#ifdef MODE_VISIBILITY
@@ -144,7 +164,7 @@ void main() {
visibility = dot(texelFetch(sampler3D(occlusion_texture, linear_sampler), tex_pos, 0), layer_axis[occlusion_layer]);
- gl_Position = params.projection * vec4(vertex, 1.0);
+ gl_Position = scene_data.projection[ViewIndex] * vec4(vertex, 1.0);
#endif
}
@@ -153,16 +173,32 @@ void main() {
#version 450
+#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview)
+#extension GL_EXT_multiview : enable
+#endif
+
+#ifdef USE_MULTIVIEW
+#ifdef has_VK_KHR_multiview
+#define ViewIndex gl_ViewIndex
+#else // has_VK_KHR_multiview
+// !BAS! This needs to become an input once we implement our fallback!
+#define ViewIndex 0
+#endif // has_VK_KHR_multiview
+#else // USE_MULTIVIEW
+// Set to zero, not supported in non stereo
+#define ViewIndex 0
+#endif //USE_MULTIVIEW
+
#VERSION_DEFINES
+#define MAX_VIEWS 2
+
layout(location = 0) out vec4 frag_color;
layout(set = 0, binding = 2) uniform texture2DArray lightprobe_texture;
layout(set = 0, binding = 3) uniform sampler linear_sampler;
layout(push_constant, std430) uniform Params {
- mat4 projection;
-
uint band_power;
uint sections_in_band;
uint band_mask;
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl
index b95fad650e..b95fad650e 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl
index 9c03297f5c..9c03297f5c 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_integrate.glsl
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl
index bce98f4054..bce98f4054 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_preprocess.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl
diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl b/servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl
index 577c6d0cd0..577c6d0cd0 100644
--- a/servers/rendering/renderer_rd/shaders/voxel_gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/voxel_gi.glsl
diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl b/servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl
index fd7a2bf8ad..fd7a2bf8ad 100644
--- a/servers/rendering/renderer_rd/shaders/voxel_gi_debug.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/voxel_gi_debug.glsl
diff --git a/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl b/servers/rendering/renderer_rd/shaders/environment/voxel_gi_sdf.glsl
index 47a611a543..47a611a543 100644
--- a/servers/rendering/renderer_rd/shaders/voxel_gi_sdf.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/voxel_gi_sdf.glsl
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index b992e948c3..5947fc5351 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -96,6 +96,8 @@ layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms
} material;
#endif
+float global_time;
+
#ifdef MODE_DUAL_PARABOLOID
layout(location = 9) out float dp_clip;
@@ -386,9 +388,12 @@ void main() {
mat4 model_matrix = instances.data[instance_index].transform;
#if defined(MOTION_VECTORS)
+ global_time = scene_data_block.prev_data.time;
vertex_shader(instance_index, is_multimesh, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position);
+ global_time = scene_data_block.data.time;
vertex_shader(instance_index, is_multimesh, scene_data_block.data, model_matrix, screen_position);
#else
+ global_time = scene_data_block.data.time;
vec4 screen_position;
vertex_shader(instance_index, is_multimesh, scene_data_block.data, model_matrix, screen_position);
#endif
@@ -486,6 +491,8 @@ layout(location = 10) in flat uint instance_index_interp;
#define inv_projection_matrix scene_data.inv_projection_matrix
#endif
+#define global_time scene_data_block.data.time
+
#if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE)
//both required for transmittance to be enabled
#define LIGHT_TRANSMITTANCE_USED
@@ -1231,12 +1238,20 @@ void fragment_shader(in SceneData scene_data) {
if (scene_data.gi_upscale_for_msaa) {
vec2 base_coord = screen_uv;
vec2 closest_coord = base_coord;
+#ifdef USE_MULTIVIEW
+ float closest_ang = dot(normal, textureLod(sampler2DArray(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(base_coord, ViewIndex), 0.0).xyz * 2.0 - 1.0);
+#else // USE_MULTIVIEW
float closest_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), base_coord, 0.0).xyz * 2.0 - 1.0);
+#endif // USE_MULTIVIEW
for (int i = 0; i < 4; i++) {
const vec2 neighbours[4] = vec2[](vec2(-1, 0), vec2(1, 0), vec2(0, -1), vec2(0, 1));
vec2 neighbour_coord = base_coord + neighbours[i] * scene_data.screen_pixel_size;
+#ifdef USE_MULTIVIEW
+ float neighbour_ang = dot(normal, textureLod(sampler2DArray(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(neighbour_coord, ViewIndex), 0.0).xyz * 2.0 - 1.0);
+#else // USE_MULTIVIEW
float neighbour_ang = dot(normal, textureLod(sampler2D(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), neighbour_coord, 0.0).xyz * 2.0 - 1.0);
+#endif // USE_MULTIVIEW
if (neighbour_ang > closest_ang) {
closest_ang = neighbour_ang;
closest_coord = neighbour_coord;
@@ -1249,8 +1264,13 @@ void fragment_shader(in SceneData scene_data) {
coord = screen_uv;
}
+#ifdef USE_MULTIVIEW
+ vec4 buffer_ambient = textureLod(sampler2DArray(ambient_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(coord, ViewIndex), 0.0);
+ vec4 buffer_reflection = textureLod(sampler2DArray(reflection_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(coord, ViewIndex), 0.0);
+#else // USE_MULTIVIEW
vec4 buffer_ambient = textureLod(sampler2D(ambient_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0.0);
vec4 buffer_reflection = textureLod(sampler2D(reflection_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), coord, 0.0);
+#endif // USE_MULTIVIEW
ambient_light = mix(ambient_light, buffer_ambient.rgb, buffer_ambient.a);
specular_light = mix(specular_light, buffer_reflection.rgb, buffer_reflection.a);
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
index 32ea83397a..0c23de96c3 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
@@ -317,10 +317,16 @@ layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid;
layout(set = 1, binding = 9) uniform texture2D depth_buffer;
layout(set = 1, binding = 10) uniform texture2D color_buffer;
+#ifdef USE_MULTIVIEW
+layout(set = 1, binding = 11) uniform texture2DArray normal_roughness_buffer;
+layout(set = 1, binding = 13) uniform texture2DArray ambient_buffer;
+layout(set = 1, binding = 14) uniform texture2DArray reflection_buffer;
+#else // USE_MULTIVIEW
layout(set = 1, binding = 11) uniform texture2D normal_roughness_buffer;
-layout(set = 1, binding = 12) uniform texture2D ao_buffer;
layout(set = 1, binding = 13) uniform texture2D ambient_buffer;
layout(set = 1, binding = 14) uniform texture2D reflection_buffer;
+#endif
+layout(set = 1, binding = 12) uniform texture2D ao_buffer;
layout(set = 1, binding = 15) uniform texture2DArray sdfgi_lightprobe_texture;
layout(set = 1, binding = 16) uniform texture3D sdfgi_occlusion_cascades;
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
index cd94908c31..26d0de46c2 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
@@ -114,9 +114,9 @@ invariant gl_Position;
#GLOBALS
-void main() {
- SceneData scene_data = scene_data_block.data;
+#define scene_data scene_data_block.data
+void main() {
vec4 instance_custom = vec4(0.0);
#if defined(COLOR_USED)
color_interp = color_attrib;
@@ -576,13 +576,14 @@ vec4 fog_process(vec3 vertex) {
#endif //!MODE_RENDER DEPTH
+#define scene_data scene_data_block.data
+
void main() {
#ifdef MODE_DUAL_PARABOLOID
if (dp_clip > 0.0)
discard;
#endif
- SceneData scene_data = scene_data_block.data;
//lay out everything, whatever is unused is optimized away anyway
vec3 vertex = vertex_interp;
diff --git a/servers/rendering/renderer_rd/shaders/taa_resolve.glsl b/servers/rendering/renderer_rd/shaders/taa_resolve.glsl
index a1a77b95aa..ddd984ad83 100644
--- a/servers/rendering/renderer_rd/shaders/taa_resolve.glsl
+++ b/servers/rendering/renderer_rd/shaders/taa_resolve.glsl
@@ -29,7 +29,8 @@
#VERSION_DEFINES
-// Based on Spartan Engine's TAA implementation https://github.com/PanosK92/SpartanEngine/blob/master/Data/shaders/temporal_antialiasing.hlsl
+// Based on Spartan Engine's TAA implementation (without TAA upscale).
+// <https://github.com/PanosK92/SpartanEngine/blob/a8338d0609b85dc32f3732a5c27fb4463816a3b9/Data/shaders/temporal_antialiasing.hlsl>
#define USE_SUBGROUPS
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
index 347fd13b28..fdbd7d3e35 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog_process.glsl
@@ -53,7 +53,6 @@ layout(set = 0, binding = 7) uniform sampler linear_sampler;
#ifdef MODE_DENSITY
layout(rgba16f, set = 0, binding = 8) uniform restrict writeonly image3D density_map;
-layout(rgba16f, set = 0, binding = 9) uniform restrict readonly image3D fog_map; //unused
#endif
#ifdef MODE_FOG
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
index 56a4525b8e..e65f676785 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.cpp
@@ -156,12 +156,12 @@ void LightStorage::light_set_param(RID p_light, RS::LightParam p_param, float p_
case RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE:
case RS::LIGHT_PARAM_SHADOW_BIAS: {
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
} break;
case RS::LIGHT_PARAM_SIZE: {
if ((light->param[p_param] > CMP_EPSILON) != (p_value > CMP_EPSILON)) {
//changing from no size to size and the opposite
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
}
} break;
default: {
@@ -177,7 +177,7 @@ void LightStorage::light_set_shadow(RID p_light, bool p_enabled) {
light->shadow = p_enabled;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_projector(RID p_light, RID p_texture) {
@@ -199,7 +199,7 @@ void LightStorage::light_set_projector(RID p_light, RID p_texture) {
if (light->projector.is_valid()) {
texture_storage->texture_add_to_decal_atlas(light->projector, light->type == RS::LIGHT_OMNI);
}
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR);
}
}
@@ -217,7 +217,7 @@ void LightStorage::light_set_cull_mask(RID p_light, uint32_t p_mask) {
light->cull_mask = p_mask;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_distance_fade(RID p_light, bool p_enabled, float p_begin, float p_shadow, float p_length) {
@@ -237,7 +237,7 @@ void LightStorage::light_set_reverse_cull_face_mode(RID p_light, bool p_enabled)
light->reverse_cull = p_enabled;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mode) {
@@ -247,7 +247,7 @@ void LightStorage::light_set_bake_mode(RID p_light, RS::LightBakeMode p_bake_mod
light->bake_mode = p_bake_mode;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) {
@@ -257,7 +257,7 @@ void LightStorage::light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade)
light->max_sdfgi_cascade = p_cascade;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMode p_mode) {
@@ -267,7 +267,7 @@ void LightStorage::light_omni_set_shadow_mode(RID p_light, RS::LightOmniShadowMo
light->omni_shadow_mode = p_mode;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
RS::LightOmniShadowMode LightStorage::light_omni_get_shadow_mode(RID p_light) {
@@ -283,7 +283,7 @@ void LightStorage::light_directional_set_shadow_mode(RID p_light, RS::LightDirec
light->directional_shadow_mode = p_mode;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable) {
@@ -292,7 +292,7 @@ void LightStorage::light_directional_set_blend_splits(RID p_light, bool p_enable
light->directional_blend_splits = p_enable;
light->version++;
- light->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_LIGHT);
+ light->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_LIGHT);
}
bool LightStorage::light_directional_get_blend_splits(RID p_light) const {
@@ -387,7 +387,7 @@ void LightStorage::reflection_probe_set_update_mode(RID p_probe, RS::ReflectionP
ERR_FAIL_COND(!reflection_probe);
reflection_probe->update_mode = p_mode;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_intensity(RID p_probe, float p_intensity) {
@@ -424,7 +424,7 @@ void LightStorage::reflection_probe_set_max_distance(RID p_probe, float p_distan
reflection_probe->max_distance = p_distance;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_extents) {
@@ -435,7 +435,7 @@ void LightStorage::reflection_probe_set_extents(RID p_probe, const Vector3 &p_ex
return;
}
reflection_probe->extents = p_extents;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3 &p_offset) {
@@ -443,7 +443,7 @@ void LightStorage::reflection_probe_set_origin_offset(RID p_probe, const Vector3
ERR_FAIL_COND(!reflection_probe);
reflection_probe->origin_offset = p_offset;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable) {
@@ -451,7 +451,7 @@ void LightStorage::reflection_probe_set_as_interior(RID p_probe, bool p_enable)
ERR_FAIL_COND(!reflection_probe);
reflection_probe->interior = p_enable;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_enable_box_projection(RID p_probe, bool p_enable) {
@@ -466,7 +466,7 @@ void LightStorage::reflection_probe_set_enable_shadows(RID p_probe, bool p_enabl
ERR_FAIL_COND(!reflection_probe);
reflection_probe->enable_shadows = p_enable;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers) {
@@ -474,7 +474,7 @@ void LightStorage::reflection_probe_set_cull_mask(RID p_probe, uint32_t p_layers
ERR_FAIL_COND(!reflection_probe);
reflection_probe->cull_mask = p_layers;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
void LightStorage::reflection_probe_set_resolution(RID p_probe, int p_resolution) {
@@ -491,7 +491,7 @@ void LightStorage::reflection_probe_set_mesh_lod_threshold(RID p_probe, float p_
reflection_probe->mesh_lod_threshold = p_ratio;
- reflection_probe->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE);
+ reflection_probe->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE);
}
AABB LightStorage::reflection_probe_get_aabb(RID p_probe) const {
diff --git a/servers/rendering/renderer_rd/storage_rd/light_storage.h b/servers/rendering/renderer_rd/storage_rd/light_storage.h
index 3cc455692d..fb25e4da7e 100644
--- a/servers/rendering/renderer_rd/storage_rd/light_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/light_storage.h
@@ -35,6 +35,7 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/storage/light_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererRD {
@@ -61,7 +62,7 @@ struct Light {
RS::LightDirectionalSkyMode directional_sky_mode = RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_AND_SKY;
uint64_t version = 0;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* REFLECTION PROBE */
@@ -82,7 +83,7 @@ struct ReflectionProbe {
uint32_t cull_mask = (1 << 20) - 1;
float mesh_lod_threshold = 0.01;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* LIGHTMAP */
@@ -104,7 +105,7 @@ struct Lightmap {
int32_t over = EMPTY_LEAF, under = EMPTY_LEAF;
};
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
class LightStorage : public RendererLightStorage {
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
index 096d371b8d..fcd25852eb 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp
@@ -2346,7 +2346,7 @@ void MaterialStorage::shader_set_code(RID p_shader, const String &p_code) {
for (Material *E : shader->owners) {
Material *material = E;
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
}
@@ -2436,7 +2436,7 @@ void MaterialStorage::_material_uniform_set_erased(void *p_material) {
// if a texture is deleted, so re-create it.
MaterialStorage::get_singleton()->_material_queue_update(material, false, true);
}
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
}
}
@@ -2466,7 +2466,7 @@ void MaterialStorage::_update_queued_materials() {
if (uniforms_changed) {
//some implementations such as 3D renderer cache the matreial uniform set, so update is required
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
}
}
}
@@ -2507,7 +2507,7 @@ void MaterialStorage::material_set_shader(RID p_material, RID p_shader) {
}
if (p_shader.is_null()) {
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
material->shader_id = 0;
return;
}
@@ -2530,7 +2530,7 @@ void MaterialStorage::material_set_shader(RID p_material, RID p_shader) {
material->data->set_next_pass(material->next_pass);
material->data->set_render_priority(material->priority);
//updating happens later
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
_material_queue_update(material, true, true);
}
@@ -2576,7 +2576,7 @@ void MaterialStorage::material_set_next_pass(RID p_material, RID p_next_material
material->data->set_next_pass(p_next_material);
}
- material->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ material->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
}
void MaterialStorage::material_set_render_priority(RID p_material, int priority) {
@@ -2626,7 +2626,7 @@ void MaterialStorage::material_get_instance_shader_parameters(RID p_material, Li
}
}
-void MaterialStorage::material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) {
+void MaterialStorage::material_update_dependency(RID p_material, DependencyTracker *p_instance) {
Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_COND(!material);
p_instance->update_dependency(&material->dependency);
diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h
index f83df05355..e35d5e7669 100644
--- a/servers/rendering/renderer_rd/storage_rd/material_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h
@@ -31,12 +31,14 @@
#ifndef MATERIAL_STORAGE_RD_H
#define MATERIAL_STORAGE_RD_H
+#include "core/math/camera_matrix.h"
#include "core/templates/local_vector.h"
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/shader_compiler.h"
#include "servers/rendering/shader_language.h"
#include "servers/rendering/storage/material_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererRD {
@@ -125,7 +127,7 @@ struct Material {
RID next_pass;
SelfList<Material> update_element;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
Material() :
update_element(this) {}
@@ -232,6 +234,86 @@ public:
MaterialStorage();
virtual ~MaterialStorage();
+ /* Helpers */
+
+ static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.basis.rows[0][0];
+ p_array[1] = p_mtx.basis.rows[1][0];
+ p_array[2] = p_mtx.basis.rows[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_mtx.basis.rows[0][1];
+ p_array[5] = p_mtx.basis.rows[1][1];
+ p_array[6] = p_mtx.basis.rows[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_mtx.basis.rows[0][2];
+ p_array[9] = p_mtx.basis.rows[1][2];
+ p_array[10] = p_mtx.basis.rows[2][2];
+ p_array[11] = 0;
+ p_array[12] = p_mtx.origin.x;
+ p_array[13] = p_mtx.origin.y;
+ p_array[14] = p_mtx.origin.z;
+ p_array[15] = 1;
+ }
+
+ static _FORCE_INLINE_ void store_basis_3x4(const Basis &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.rows[0][0];
+ p_array[1] = p_mtx.rows[1][0];
+ p_array[2] = p_mtx.rows[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_mtx.rows[0][1];
+ p_array[5] = p_mtx.rows[1][1];
+ p_array[6] = p_mtx.rows[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_mtx.rows[0][2];
+ p_array[9] = p_mtx.rows[1][2];
+ p_array[10] = p_mtx.rows[2][2];
+ p_array[11] = 0;
+ }
+
+ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.rows[0][0];
+ p_array[1] = p_mtx.rows[1][0];
+ p_array[2] = p_mtx.rows[2][0];
+ p_array[3] = 0;
+ p_array[4] = p_mtx.rows[0][1];
+ p_array[5] = p_mtx.rows[1][1];
+ p_array[6] = p_mtx.rows[2][1];
+ p_array[7] = 0;
+ p_array[8] = p_mtx.rows[0][2];
+ p_array[9] = p_mtx.rows[1][2];
+ p_array[10] = p_mtx.rows[2][2];
+ p_array[11] = 0;
+ }
+
+ static _FORCE_INLINE_ void store_transform_transposed_3x4(const Transform3D &p_mtx, float *p_array) {
+ p_array[0] = p_mtx.basis.rows[0][0];
+ p_array[1] = p_mtx.basis.rows[0][1];
+ p_array[2] = p_mtx.basis.rows[0][2];
+ p_array[3] = p_mtx.origin.x;
+ p_array[4] = p_mtx.basis.rows[1][0];
+ p_array[5] = p_mtx.basis.rows[1][1];
+ p_array[6] = p_mtx.basis.rows[1][2];
+ p_array[7] = p_mtx.origin.y;
+ p_array[8] = p_mtx.basis.rows[2][0];
+ p_array[9] = p_mtx.basis.rows[2][1];
+ p_array[10] = p_mtx.basis.rows[2][2];
+ p_array[11] = p_mtx.origin.z;
+ }
+
+ static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) {
+ for (int i = 0; i < 4; i++) {
+ for (int j = 0; j < 4; j++) {
+ p_array[i * 4 + j] = p_mtx.matrix[i][j];
+ }
+ }
+ }
+
+ static _FORCE_INLINE_ void store_soft_shadow_kernel(const float *p_kernel, float *p_array) {
+ for (int i = 0; i < 128; i++) {
+ p_array[i] = p_kernel[i];
+ }
+ }
+
/* Samplers */
_FORCE_INLINE_ RID sampler_rd_get_default(RS::CanvasItemTextureFilter p_filter, RS::CanvasItemTextureRepeat p_repeat) {
@@ -317,7 +399,7 @@ public:
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override;
- virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) override;
+ virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) override;
void material_set_data_request_function(ShaderType p_shader_type, MaterialDataRequestFunction p_function);
MaterialDataRequestFunction material_get_data_request_function(ShaderType p_shader_type);
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
index 1e0d67f269..3875eb6615 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.cpp
@@ -210,6 +210,8 @@ void MeshStorage::mesh_free(RID p_rid) {
mesh_clear(p_rid);
mesh_set_shadow_mesh(p_rid, RID());
Mesh *mesh = mesh_owner.get_or_null(p_rid);
+ ERR_FAIL_COND(!mesh);
+
mesh->dependency.deleted_notify(p_rid);
if (mesh->instances.size()) {
ERR_PRINT("deleting mesh with active instances");
@@ -218,7 +220,7 @@ void MeshStorage::mesh_free(RID p_rid) {
for (Mesh *E : mesh->shadow_owners) {
Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
- shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
}
mesh_owner.free(p_rid);
@@ -429,12 +431,12 @@ void MeshStorage::mesh_add_surface(RID p_mesh, const RS::SurfaceData &p_surface)
_mesh_instance_add_surface(mi, mesh, mesh->surface_count - 1);
}
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
for (Mesh *E : mesh->shadow_owners) {
Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
- shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
mesh->material_cache.clear();
@@ -501,7 +503,7 @@ void MeshStorage::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_mat
ERR_FAIL_UNSIGNED_INDEX((uint32_t)p_surface, mesh->surface_count);
mesh->surfaces[p_surface]->material = p_material;
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MATERIAL);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MATERIAL);
mesh->material_cache.clear();
}
@@ -692,7 +694,7 @@ void MeshStorage::mesh_set_shadow_mesh(RID p_mesh, RID p_shadow_mesh) {
shadow_mesh->shadow_owners.insert(mesh);
}
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
void MeshStorage::mesh_clear(RID p_mesh) {
@@ -740,12 +742,12 @@ void MeshStorage::mesh_clear(RID p_mesh) {
_mesh_instance_clear(mi);
}
mesh->has_bone_weights = false;
- mesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ mesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
for (Mesh *E : mesh->shadow_owners) {
Mesh *shadow_owner = E;
shadow_owner->shadow_mesh = RID();
- shadow_owner->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ shadow_owner->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
}
@@ -1209,7 +1211,7 @@ void MeshStorage::multimesh_allocate_data(RID p_multimesh, int p_instances, RS::
multimesh->buffer = RD::get_singleton()->storage_buffer_create(multimesh->instances * multimesh->stride_cache * 4);
}
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MULTIMESH);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH);
}
int MeshStorage::multimesh_get_instance_count(RID p_multimesh) const {
@@ -1243,7 +1245,7 @@ void MeshStorage::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
}
}
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MESH);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MESH);
}
#define MULTIMESH_DIRTY_REGION_SIZE 512
@@ -1602,7 +1604,7 @@ void MeshStorage::multimesh_set_buffer(RID p_multimesh, const Vector<float> &p_b
const float *data = p_buffer.ptr();
_multimesh_re_create_aabb(multimesh, data, multimesh->instances);
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
}
@@ -1644,7 +1646,7 @@ void MeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible
multimesh->visible_instances = p_visible;
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES);
}
int MeshStorage::multimesh_get_visible_instances(RID p_multimesh) const {
@@ -1703,7 +1705,7 @@ void MeshStorage::_update_dirty_multimeshes() {
//aabb is dirty..
_multimesh_re_create_aabb(multimesh, data, visible_instances);
multimesh->aabb_dirty = false;
- multimesh->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ multimesh->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
}
@@ -1781,7 +1783,7 @@ void MeshStorage::skeleton_allocate_data(RID p_skeleton, int p_bones, bool p_2d_
}
}
- skeleton->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA);
+ skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_DATA);
}
int MeshStorage::skeleton_get_bone_count(RID p_skeleton) const {
@@ -1902,7 +1904,7 @@ void MeshStorage::_update_dirty_skeletons() {
skeleton_dirty_list = skeleton->dirty_list;
- skeleton->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_SKELETON_BONES);
+ skeleton->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_SKELETON_BONES);
skeleton->version++;
@@ -1913,7 +1915,7 @@ void MeshStorage::_update_dirty_skeletons() {
skeleton_dirty_list = nullptr;
}
-void MeshStorage::skeleton_update_dependency(RID p_skeleton, RendererStorage::DependencyTracker *p_instance) {
+void MeshStorage::skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) {
Skeleton *skeleton = skeleton_owner.get_or_null(p_skeleton);
ERR_FAIL_COND(!skeleton);
diff --git a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
index 7ce019cf98..9cdda6bfca 100644
--- a/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/mesh_storage.h
@@ -35,8 +35,8 @@
#include "core/templates/rid_owner.h"
#include "core/templates/self_list.h"
#include "servers/rendering/renderer_rd/shaders/skeleton.glsl.gen.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/storage/mesh_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererRD {
@@ -143,7 +143,7 @@ struct Mesh {
RID shadow_mesh;
HashSet<Mesh *> shadow_owners;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* Mesh Instance */
@@ -199,7 +199,7 @@ struct MultiMesh {
bool dirty = false;
MultiMesh *dirty_list = nullptr;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
/* Skeleton */
@@ -256,7 +256,7 @@ struct Skeleton {
uint64_t version = 1;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
class MeshStorage : public RendererMeshStorage {
@@ -672,7 +672,7 @@ public:
virtual void skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) override;
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const override;
- virtual void skeleton_update_dependency(RID p_skeleton, RendererStorage::DependencyTracker *p_instance) override;
+ virtual void skeleton_update_dependency(RID p_skeleton, DependencyTracker *p_instance) override;
void _update_dirty_skeletons();
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
index 58a96ed1f9..5200e0d318 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.cpp
@@ -30,7 +30,6 @@
#include "particles_storage.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/rendering_server_globals.h"
#include "texture_storage.h"
@@ -321,7 +320,7 @@ void ParticlesStorage::particles_set_amount(RID p_particles, int p_amount) {
particles->prev_phase = 0;
particles->clear = true;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
}
void ParticlesStorage::particles_set_lifetime(RID p_particles, double p_lifetime) {
@@ -356,7 +355,7 @@ void ParticlesStorage::particles_set_custom_aabb(RID p_particles, const AABB &p_
Particles *particles = particles_owner.get_or_null(p_particles);
ERR_FAIL_COND(!particles);
particles->custom_aabb = p_aabb;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void ParticlesStorage::particles_set_speed_scale(RID p_particles, double p_scale) {
@@ -370,7 +369,7 @@ void ParticlesStorage::particles_set_use_local_coordinates(RID p_particles, bool
ERR_FAIL_COND(!particles);
particles->use_local_coords = p_enable;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
}
void ParticlesStorage::particles_set_fixed_fps(RID p_particles, int p_fps) {
@@ -386,7 +385,7 @@ void ParticlesStorage::particles_set_fixed_fps(RID p_particles, int p_fps) {
particles->prev_phase = 0;
particles->clear = true;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
}
void ParticlesStorage::particles_set_interpolate(RID p_particles, bool p_enable) {
@@ -419,7 +418,7 @@ void ParticlesStorage::particles_set_trails(RID p_particles, bool p_enable, doub
particles->prev_phase = 0;
particles->clear = true;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
}
void ParticlesStorage::particles_set_trail_bind_poses(RID p_particles, const Vector<Transform3D> &p_bind_poses) {
@@ -436,7 +435,7 @@ void ParticlesStorage::particles_set_trail_bind_poses(RID p_particles, const Vec
particles->trail_bind_poses = p_bind_poses;
particles->trail_bind_poses_dirty = true;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES);
}
void ParticlesStorage::particles_set_collision_base_size(RID p_particles, real_t p_size) {
@@ -458,7 +457,7 @@ void ParticlesStorage::particles_set_process_material(RID p_particles, RID p_mat
ERR_FAIL_COND(!particles);
particles->process_material = p_material;
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_PARTICLES); //the instance buffer may have changed
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_PARTICLES); //the instance buffer may have changed
}
RID ParticlesStorage::particles_get_process_material(RID p_particles) const {
@@ -545,7 +544,7 @@ void ParticlesStorage::particles_emit(RID p_particles, const Transform3D &p_tran
int32_t idx = particles->emission_buffer->particle_count;
if (idx < particles->emission_buffer->particle_max) {
- RendererStorageRD::store_transform(p_transform, particles->emission_buffer->data[idx].xform);
+ RendererRD::MaterialStorage::store_transform(p_transform, particles->emission_buffer->data[idx].xform);
particles->emission_buffer->data[idx].velocity[0] = p_velocity.x;
particles->emission_buffer->data[idx].velocity[1] = p_velocity.y;
@@ -766,9 +765,9 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
frame_params.randomness = p_particles->randomness;
if (p_particles->use_local_coords) {
- RendererStorageRD::store_transform(Transform3D(), frame_params.emission_transform);
+ RendererRD::MaterialStorage::store_transform(Transform3D(), frame_params.emission_transform);
} else {
- RendererStorageRD::store_transform(p_particles->emission_transform, frame_params.emission_transform);
+ RendererRD::MaterialStorage::store_transform(p_particles->emission_transform, frame_params.emission_transform);
}
frame_params.cycle = p_particles->cycle_number;
@@ -858,7 +857,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
ParticlesFrameParams::Attractor &attr = frame_params.attractors[frame_params.attractor_count];
- RendererStorageRD::store_transform(to_collider, attr.transform);
+ RendererRD::MaterialStorage::store_transform(to_collider, attr.transform);
attr.strength = pc->attractor_strength;
attr.attenuation = pc->attractor_attenuation;
attr.directionality = pc->attractor_directionality;
@@ -906,7 +905,7 @@ void ParticlesStorage::_particles_process(Particles *p_particles, double p_delta
ParticlesFrameParams::Collider &col = frame_params.colliders[frame_params.collider_count];
- RendererStorageRD::store_transform(to_collider, col.transform);
+ RendererRD::MaterialStorage::store_transform(to_collider, col.transform);
switch (pc->type) {
case RS::PARTICLES_COLLISION_TYPE_SPHERE_COLLIDE: {
col.type = ParticlesFrameParams::COLLISION_TYPE_SPHERE;
@@ -1203,7 +1202,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();
- RendererStorageRD::base_singleton->get_effects()->sort_buffer(particles->particles_sort_uniform_set, particles->amount);
+ RendererCompositorRD::singleton->get_effects()->sort_buffer(particles->particles_sort_uniform_set, particles->amount);
}
copy_push_constant.total_particles *= copy_push_constant.total_particles;
@@ -1383,7 +1382,7 @@ void ParticlesStorage::update_particles() {
}
for (int i = 0; i < particles->trail_bind_poses.size(); i++) {
- RendererStorageRD::store_transform(particles->trail_bind_poses[i], &particles_shader.pose_update_buffer[i * 16]);
+ RendererRD::MaterialStorage::store_transform(particles->trail_bind_poses[i], &particles_shader.pose_update_buffer[i * 16]);
}
RD::get_singleton()->buffer_update(particles->trail_bind_pose_buffer, 0, particles->trail_bind_poses.size() * 16 * sizeof(float), particles_shader.pose_update_buffer.ptr());
@@ -1457,14 +1456,14 @@ void ParticlesStorage::update_particles() {
// In local mode, particle positions are calculated locally (relative to the node position)
// and they're also drawn locally.
// It works as expected, so we just pass an identity transform.
- RendererStorageRD::store_transform(Transform3D(), copy_push_constant.inv_emission_transform);
+ RendererRD::MaterialStorage::store_transform(Transform3D(), copy_push_constant.inv_emission_transform);
} else {
// In global mode, particle positions are calculated globally (relative to the canvas origin)
// but they're drawn locally.
// So, we need to pass the inverse of the emission transform to bring the
// particles to local coordinates before drawing.
Transform3D inv = particles->emission_transform.affine_inverse();
- RendererStorageRD::store_transform(inv, copy_push_constant.inv_emission_transform);
+ RendererRD::MaterialStorage::store_transform(inv, copy_push_constant.inv_emission_transform);
}
copy_push_constant.total_particles = total_amount;
@@ -1500,7 +1499,7 @@ void ParticlesStorage::update_particles() {
RD::get_singleton()->compute_list_end();
}
- particles->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
}
@@ -1756,7 +1755,7 @@ void ParticlesStorage::particles_collision_set_collision_type(RID p_particles_co
particles_collision->heightfield_texture = RID();
}
particles_collision->type = p_type;
- particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void ParticlesStorage::particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) {
@@ -1770,7 +1769,7 @@ void ParticlesStorage::particles_collision_set_sphere_radius(RID p_particles_col
ERR_FAIL_COND(!particles_collision);
particles_collision->radius = p_radius;
- particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void ParticlesStorage::particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) {
@@ -1778,7 +1777,7 @@ void ParticlesStorage::particles_collision_set_box_extents(RID p_particles_colli
ERR_FAIL_COND(!particles_collision);
particles_collision->extents = p_extents;
- particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void ParticlesStorage::particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) {
@@ -1812,7 +1811,7 @@ void ParticlesStorage::particles_collision_set_field_texture(RID p_particles_col
void ParticlesStorage::particles_collision_height_field_update(RID p_particles_collision) {
ParticlesCollision *particles_collision = particles_collision_owner.get_or_null(p_particles_collision);
ERR_FAIL_COND(!particles_collision);
- particles_collision->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ particles_collision->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void ParticlesStorage::particles_collision_set_height_field_resolution(RID p_particles_collision, RS::ParticlesCollisionHeightfieldResolution p_resolution) {
diff --git a/servers/rendering/renderer_rd/storage_rd/particles_storage.h b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
index 115633d17a..70ac6f0349 100644
--- a/servers/rendering/renderer_rd/storage_rd/particles_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/particles_storage.h
@@ -37,9 +37,9 @@
#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"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/shader_compiler.h"
#include "servers/rendering/storage/particles_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererRD {
@@ -226,7 +226,7 @@ struct Particles {
HashSet<RID> collisions;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
double trail_length = 1.0;
bool trails_enabled = false;
@@ -254,7 +254,7 @@ struct ParticlesCollision {
RS::ParticlesCollisionHeightfieldResolution heightfield_resolution = RS::PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
struct ParticlesCollisionInstance {
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
index 329c23bad0..1109357a74 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp
@@ -1712,7 +1712,7 @@ void TextureStorage::decal_set_extents(RID p_decal, const Vector3 &p_extents) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->extents = p_extents;
- decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID p_texture) {
@@ -1736,7 +1736,7 @@ void TextureStorage::decal_set_texture(RID p_decal, RS::DecalTexture p_type, RID
texture_add_to_decal_atlas(decal->textures[p_type]);
}
- decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_DECAL);
+ decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_DECAL);
}
void TextureStorage::decal_set_emission_energy(RID p_decal, float p_energy) {
@@ -1761,7 +1761,7 @@ void TextureStorage::decal_set_cull_mask(RID p_decal, uint32_t p_layers) {
Decal *decal = decal_owner.get_or_null(p_decal);
ERR_FAIL_COND(!decal);
decal->cull_mask = p_layers;
- decal->dependency.changed_notify(RendererStorage::DEPENDENCY_CHANGED_AABB);
+ decal->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
}
void TextureStorage::decal_set_distance_fade(RID p_decal, bool p_enabled, float p_begin, float p_length) {
diff --git a/servers/rendering/renderer_rd/storage_rd/texture_storage.h b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
index 901f764085..7a96e6c6ed 100644
--- a/servers/rendering/renderer_rd/storage_rd/texture_storage.h
+++ b/servers/rendering/renderer_rd/storage_rd/texture_storage.h
@@ -33,8 +33,8 @@
#include "core/templates/rid_owner.h"
#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/storage/texture_storage.h"
+#include "servers/rendering/storage/utilities.h"
namespace RendererRD {
@@ -193,7 +193,7 @@ struct Decal {
float distance_fade_length = 1;
float normal_fade = 0.0;
- RendererStorage::Dependency dependency;
+ Dependency dependency;
};
struct RenderTarget {
diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.cpp b/servers/rendering/renderer_rd/storage_rd/utilities.cpp
new file mode 100644
index 0000000000..a1f62c16c7
--- /dev/null
+++ b/servers/rendering/renderer_rd/storage_rd/utilities.cpp
@@ -0,0 +1,337 @@
+/*************************************************************************/
+/* utilities.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 "utilities.h"
+#include "../environment/fog.h"
+#include "../environment/gi.h"
+#include "light_storage.h"
+#include "mesh_storage.h"
+#include "particles_storage.h"
+#include "texture_storage.h"
+
+using namespace RendererRD;
+
+Utilities *Utilities::singleton = nullptr;
+
+Utilities::Utilities() {
+ singleton = this;
+}
+
+Utilities::~Utilities() {
+ singleton = nullptr;
+}
+
+/* INSTANCES */
+
+RS::InstanceType Utilities::get_base_type(RID p_rid) const {
+ if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
+ return RS::INSTANCE_MESH;
+ }
+ if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
+ return RS::INSTANCE_MULTIMESH;
+ }
+ if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) {
+ return RS::INSTANCE_REFLECTION_PROBE;
+ }
+ if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
+ return RS::INSTANCE_DECAL;
+ }
+ if (RendererRD::GI::get_singleton()->owns_voxel_gi(p_rid)) {
+ return RS::INSTANCE_VOXEL_GI;
+ }
+ if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) {
+ return RS::INSTANCE_LIGHT;
+ }
+ if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) {
+ return RS::INSTANCE_LIGHTMAP;
+ }
+ if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_rid)) {
+ return RS::INSTANCE_PARTICLES;
+ }
+ if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) {
+ return RS::INSTANCE_PARTICLES_COLLISION;
+ }
+ if (RendererRD::Fog::get_singleton()->owns_fog_volume(p_rid)) {
+ return RS::INSTANCE_FOG_VOLUME;
+ }
+ if (owns_visibility_notifier(p_rid)) {
+ return RS::INSTANCE_VISIBLITY_NOTIFIER;
+ }
+
+ return RS::INSTANCE_NONE;
+}
+
+bool Utilities::free(RID p_rid) {
+ if (RendererRD::TextureStorage::get_singleton()->owns_texture(p_rid)) {
+ RendererRD::TextureStorage::get_singleton()->texture_free(p_rid);
+ } else if (RendererRD::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
+ RendererRD::TextureStorage::get_singleton()->canvas_texture_free(p_rid);
+ } else if (RendererRD::MaterialStorage::get_singleton()->owns_shader(p_rid)) {
+ RendererRD::MaterialStorage::get_singleton()->shader_free(p_rid);
+ } else if (RendererRD::MaterialStorage::get_singleton()->owns_material(p_rid)) {
+ RendererRD::MaterialStorage::get_singleton()->material_free(p_rid);
+ } else if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
+ RendererRD::MeshStorage::get_singleton()->mesh_free(p_rid);
+ } else if (RendererRD::MeshStorage::get_singleton()->owns_mesh_instance(p_rid)) {
+ RendererRD::MeshStorage::get_singleton()->mesh_instance_free(p_rid);
+ } else if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
+ RendererRD::MeshStorage::get_singleton()->multimesh_free(p_rid);
+ } else if (RendererRD::MeshStorage::get_singleton()->owns_skeleton(p_rid)) {
+ RendererRD::MeshStorage::get_singleton()->skeleton_free(p_rid);
+ } else if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) {
+ RendererRD::LightStorage::get_singleton()->reflection_probe_free(p_rid);
+ } else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
+ RendererRD::TextureStorage::get_singleton()->decal_free(p_rid);
+ } else if (RendererRD::GI::get_singleton()->owns_voxel_gi(p_rid)) {
+ RendererRD::GI::get_singleton()->voxel_gi_free(p_rid);
+ } else if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) {
+ RendererRD::LightStorage::get_singleton()->lightmap_free(p_rid);
+ } else if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) {
+ RendererRD::LightStorage::get_singleton()->light_free(p_rid);
+ } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_rid)) {
+ RendererRD::ParticlesStorage::get_singleton()->particles_free(p_rid);
+ } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) {
+ RendererRD::ParticlesStorage::get_singleton()->particles_collision_free(p_rid);
+ } else if (owns_visibility_notifier(p_rid)) {
+ visibility_notifier_free(p_rid);
+ } else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision_instance(p_rid)) {
+ RendererRD::ParticlesStorage::get_singleton()->particles_collision_instance_free(p_rid);
+ } else if (RendererRD::Fog::get_singleton()->owns_fog_volume(p_rid)) {
+ RendererRD::Fog::get_singleton()->fog_free(p_rid);
+ } else if (RendererRD::TextureStorage::get_singleton()->owns_render_target(p_rid)) {
+ RendererRD::TextureStorage::get_singleton()->render_target_free(p_rid);
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+/* DEPENDENCIES */
+
+void Utilities::base_update_dependency(RID p_base, DependencyTracker *p_instance) {
+ if (MeshStorage::get_singleton()->owns_mesh(p_base)) {
+ Mesh *mesh = MeshStorage::get_singleton()->get_mesh(p_base);
+ p_instance->update_dependency(&mesh->dependency);
+ } else if (MeshStorage::get_singleton()->owns_multimesh(p_base)) {
+ MultiMesh *multimesh = MeshStorage::get_singleton()->get_multimesh(p_base);
+ p_instance->update_dependency(&multimesh->dependency);
+ if (multimesh->mesh.is_valid()) {
+ base_update_dependency(multimesh->mesh, p_instance);
+ }
+ } else if (LightStorage::get_singleton()->owns_reflection_probe(p_base)) {
+ ReflectionProbe *rp = LightStorage::get_singleton()->get_reflection_probe(p_base);
+ p_instance->update_dependency(&rp->dependency);
+ } else if (TextureStorage::get_singleton()->owns_decal(p_base)) {
+ Decal *decal = TextureStorage::get_singleton()->get_decal(p_base);
+ p_instance->update_dependency(&decal->dependency);
+ } else if (GI::get_singleton()->owns_voxel_gi(p_base)) {
+ GI::VoxelGI *gip = GI::get_singleton()->get_voxel_gi(p_base);
+ p_instance->update_dependency(&gip->dependency);
+ } else if (LightStorage::get_singleton()->owns_lightmap(p_base)) {
+ Lightmap *lm = LightStorage::get_singleton()->get_lightmap(p_base);
+ p_instance->update_dependency(&lm->dependency);
+ } else if (LightStorage::get_singleton()->owns_light(p_base)) {
+ Light *l = LightStorage::get_singleton()->get_light(p_base);
+ p_instance->update_dependency(&l->dependency);
+ } else if (ParticlesStorage::get_singleton()->owns_particles(p_base)) {
+ Particles *p = ParticlesStorage::get_singleton()->get_particles(p_base);
+ p_instance->update_dependency(&p->dependency);
+ } else if (ParticlesStorage::get_singleton()->owns_particles_collision(p_base)) {
+ ParticlesCollision *pc = ParticlesStorage::get_singleton()->get_particles_collision(p_base);
+ p_instance->update_dependency(&pc->dependency);
+ } else if (Fog::get_singleton()->owns_fog_volume(p_base)) {
+ Fog::FogVolume *fv = Fog::get_singleton()->get_fog_volume(p_base);
+ p_instance->update_dependency(&fv->dependency);
+ } else if (owns_visibility_notifier(p_base)) {
+ VisibilityNotifier *vn = get_visibility_notifier(p_base);
+ p_instance->update_dependency(&vn->dependency);
+ }
+}
+
+/* VISIBILITY NOTIFIER */
+
+RID Utilities::visibility_notifier_allocate() {
+ return visibility_notifier_owner.allocate_rid();
+}
+
+void Utilities::visibility_notifier_initialize(RID p_notifier) {
+ visibility_notifier_owner.initialize_rid(p_notifier, VisibilityNotifier());
+}
+
+void Utilities::visibility_notifier_free(RID p_notifier) {
+ VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
+ vn->dependency.deleted_notify(p_notifier);
+ visibility_notifier_owner.free(p_notifier);
+}
+
+void Utilities::visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) {
+ VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
+ ERR_FAIL_COND(!vn);
+ vn->aabb = p_aabb;
+ vn->dependency.changed_notify(Dependency::DEPENDENCY_CHANGED_AABB);
+}
+
+void Utilities::visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) {
+ VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
+ ERR_FAIL_COND(!vn);
+ vn->enter_callback = p_enter_callbable;
+ vn->exit_callback = p_exit_callable;
+}
+
+AABB Utilities::visibility_notifier_get_aabb(RID p_notifier) const {
+ const VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
+ ERR_FAIL_COND_V(!vn, AABB());
+ return vn->aabb;
+}
+
+void Utilities::visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) {
+ VisibilityNotifier *vn = visibility_notifier_owner.get_or_null(p_notifier);
+ ERR_FAIL_COND(!vn);
+
+ if (p_enter) {
+ if (!vn->enter_callback.is_null()) {
+ if (p_deferred) {
+ vn->enter_callback.call_deferred(nullptr, 0);
+ } else {
+ Variant r;
+ Callable::CallError ce;
+ vn->enter_callback.call(nullptr, 0, r, ce);
+ }
+ }
+ } else {
+ if (!vn->exit_callback.is_null()) {
+ if (p_deferred) {
+ vn->exit_callback.call_deferred(nullptr, 0);
+ } else {
+ Variant r;
+ Callable::CallError ce;
+ vn->exit_callback.call(nullptr, 0, r, ce);
+ }
+ }
+ }
+}
+
+/* TIMING */
+
+void Utilities::capture_timestamps_begin() {
+ RD::get_singleton()->capture_timestamp("Frame Begin");
+}
+
+void Utilities::capture_timestamp(const String &p_name) {
+ RD::get_singleton()->capture_timestamp(p_name);
+}
+
+uint32_t Utilities::get_captured_timestamps_count() const {
+ return RD::get_singleton()->get_captured_timestamps_count();
+}
+
+uint64_t Utilities::get_captured_timestamps_frame() const {
+ return RD::get_singleton()->get_captured_timestamps_frame();
+}
+
+uint64_t Utilities::get_captured_timestamp_gpu_time(uint32_t p_index) const {
+ return RD::get_singleton()->get_captured_timestamp_gpu_time(p_index);
+}
+
+uint64_t Utilities::get_captured_timestamp_cpu_time(uint32_t p_index) const {
+ return RD::get_singleton()->get_captured_timestamp_cpu_time(p_index);
+}
+
+String Utilities::get_captured_timestamp_name(uint32_t p_index) const {
+ return RD::get_singleton()->get_captured_timestamp_name(p_index);
+}
+
+/* MISC */
+
+void Utilities::update_dirty_resources() {
+ MaterialStorage::get_singleton()->_update_global_variables(); //must do before materials, so it can queue them for update
+ MaterialStorage::get_singleton()->_update_queued_materials();
+ MeshStorage::get_singleton()->_update_dirty_multimeshes();
+ MeshStorage::get_singleton()->_update_dirty_skeletons();
+ TextureStorage::get_singleton()->update_decal_atlas();
+}
+
+bool Utilities::has_os_feature(const String &p_feature) const {
+ if (!RD::get_singleton()) {
+ return false;
+ }
+
+ if (p_feature == "rgtc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC5_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ if (p_feature == "s3tc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC1_RGB_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ if (p_feature == "bptc" && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_BC7_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ if ((p_feature == "etc" || p_feature == "etc2") && RD::get_singleton()->texture_is_format_supported_for_usage(RD::DATA_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, RD::TEXTURE_USAGE_SAMPLING_BIT)) {
+ return true;
+ }
+
+ return false;
+}
+
+void Utilities::update_memory_info() {
+ texture_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TEXTURES);
+ buffer_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_BUFFERS);
+ total_mem_cache = RenderingDevice::get_singleton()->get_memory_usage(RenderingDevice::MEMORY_TOTAL);
+}
+
+uint64_t Utilities::get_rendering_info(RS::RenderingInfo p_info) {
+ if (p_info == RS::RENDERING_INFO_TEXTURE_MEM_USED) {
+ return texture_mem_cache;
+ } else if (p_info == RS::RENDERING_INFO_BUFFER_MEM_USED) {
+ return buffer_mem_cache;
+ } else if (p_info == RS::RENDERING_INFO_VIDEO_MEM_USED) {
+ return total_mem_cache;
+ }
+ return 0;
+}
+
+String Utilities::get_video_adapter_name() const {
+ return RenderingDevice::get_singleton()->get_device_name();
+}
+
+String Utilities::get_video_adapter_vendor() const {
+ return RenderingDevice::get_singleton()->get_device_vendor_name();
+}
+
+RenderingDevice::DeviceType Utilities::get_video_adapter_type() const {
+ return RenderingDevice::get_singleton()->get_device_type();
+}
+
+String Utilities::get_video_adapter_api_version() const {
+ return RenderingDevice::get_singleton()->get_device_api_version();
+}
diff --git a/servers/rendering/renderer_rd/storage_rd/utilities.h b/servers/rendering/renderer_rd/storage_rd/utilities.h
new file mode 100644
index 0000000000..979e984546
--- /dev/null
+++ b/servers/rendering/renderer_rd/storage_rd/utilities.h
@@ -0,0 +1,122 @@
+/*************************************************************************/
+/* utilities.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 UTILITIES_RD_H
+#define UTILITIES_RD_H
+
+#include "core/templates/rid_owner.h"
+#include "servers/rendering/storage/utilities.h"
+
+namespace RendererRD {
+
+/* VISIBILITY NOTIFIER */
+
+struct VisibilityNotifier {
+ AABB aabb;
+ Callable enter_callback;
+ Callable exit_callback;
+ Dependency dependency;
+};
+
+class Utilities : public RendererUtilities {
+private:
+ static Utilities *singleton;
+
+ /* VISIBILITY NOTIFIER */
+
+ mutable RID_Owner<VisibilityNotifier> visibility_notifier_owner;
+
+ /* MISC */
+
+ //keep cached since it can be called form any thread
+ uint64_t texture_mem_cache = 0;
+ uint64_t buffer_mem_cache = 0;
+ uint64_t total_mem_cache = 0;
+
+public:
+ static Utilities *get_singleton() { return singleton; }
+
+ Utilities();
+ virtual ~Utilities() override;
+
+ /* INSTANCES */
+
+ virtual RS::InstanceType get_base_type(RID p_rid) const override;
+ virtual bool free(RID p_rid) override;
+
+ /* DEPENDENCIES */
+
+ virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) override;
+
+ /* VISIBILITY NOTIFIER */
+
+ VisibilityNotifier *get_visibility_notifier(RID p_rid) { return visibility_notifier_owner.get_or_null(p_rid); };
+ bool owns_visibility_notifier(RID p_rid) const { return visibility_notifier_owner.owns(p_rid); };
+
+ virtual RID visibility_notifier_allocate() override;
+ virtual void visibility_notifier_initialize(RID p_notifier) override;
+ virtual void visibility_notifier_free(RID p_notifier) override;
+
+ virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) override;
+ virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) override;
+
+ virtual AABB visibility_notifier_get_aabb(RID p_notifier) const override;
+ virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) override;
+
+ /* TIMING */
+
+ virtual void capture_timestamps_begin() override;
+ virtual void capture_timestamp(const String &p_name) override;
+ virtual uint32_t get_captured_timestamps_count() const override;
+ virtual uint64_t get_captured_timestamps_frame() const override;
+ virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const override;
+ virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const override;
+ virtual String get_captured_timestamp_name(uint32_t p_index) const override;
+
+ /* MISC */
+
+ virtual void update_dirty_resources() override;
+ virtual void set_debug_generate_wireframes(bool p_generate) override {}
+
+ virtual bool has_os_feature(const String &p_feature) const override;
+
+ virtual void update_memory_info() override;
+
+ virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) override;
+
+ virtual String get_video_adapter_name() const override;
+ virtual String get_video_adapter_vendor() const override;
+ virtual RenderingDevice::DeviceType get_video_adapter_type() const override;
+ virtual String get_video_adapter_api_version() const override;
+};
+
+} // namespace RendererRD
+
+#endif // !UTILITIES_RD_H
diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp
index 6f427272b5..aaf7ab8efd 100644
--- a/servers/rendering/renderer_scene_cull.cpp
+++ b/servers/rendering/renderer_scene_cull.cpp
@@ -470,7 +470,7 @@ void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) {
p_instance->mesh_instance = RSG::mesh_storage->mesh_instance_create(p_instance->base);
} else {
- RSG::storage->free(p_instance->mesh_instance);
+ RSG::mesh_storage->mesh_free(p_instance->mesh_instance);
p_instance->mesh_instance = RID();
}
@@ -506,7 +506,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
}
if (instance->mesh_instance.is_valid()) {
- RSG::storage->free(instance->mesh_instance);
+ RSG::mesh_storage->mesh_free(instance->mesh_instance);
instance->mesh_instance = RID();
// no need to set instance data flag here, as it was freed above
}
@@ -538,7 +538,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
} break;
case RS::INSTANCE_PARTICLES_COLLISION: {
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
- RSG::storage->free(collision->instance);
+ RSG::utilities->free(collision->instance);
} break;
case RS::INSTANCE_FOG_VOLUME: {
InstanceFogVolumeData *volume = static_cast<InstanceFogVolumeData *>(instance->base_data);
@@ -607,7 +607,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
instance->base = RID();
if (p_base.is_valid()) {
- instance->base_type = RSG::storage->get_base_type(p_base);
+ instance->base_type = RSG::utilities->get_base_type(p_base);
// fix up a specific malfunctioning case before the switch, so it can be handled
if (instance->base_type == RS::INSTANCE_NONE && RendererSceneOcclusionCull::get_singleton()->is_occluder(p_base)) {
@@ -724,7 +724,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
}
//forcefully update the dependency now, so if for some reason it gets removed, we can immediately clear it
- RSG::storage->base_update_dependency(p_base, &instance->dependency_tracker);
+ RSG::utilities->base_update_dependency(p_base, &instance->dependency_tracker);
}
_instance_queue_update(instance, true, true);
@@ -1876,10 +1876,10 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
} break;
case RenderingServer::INSTANCE_FOG_VOLUME: {
- new_aabb = RSG::storage->fog_volume_get_aabb(p_instance->base);
+ new_aabb = RSG::fog->fog_volume_get_aabb(p_instance->base);
} break;
case RenderingServer::INSTANCE_VISIBLITY_NOTIFIER: {
- new_aabb = RSG::storage->visibility_notifier_get_aabb(p_instance->base);
+ new_aabb = RSG::utilities->visibility_notifier_get_aabb(p_instance->base);
} break;
case RenderingServer::INSTANCE_LIGHT: {
new_aabb = RSG::light_storage->light_get_aabb(p_instance->base);
@@ -1894,7 +1894,7 @@ void RendererSceneCull::_update_instance_aabb(Instance *p_instance) {
} break;
case RenderingServer::INSTANCE_VOXEL_GI: {
- new_aabb = RSG::storage->voxel_gi_get_bounds(p_instance->base);
+ new_aabb = RSG::gi->voxel_gi_get_bounds(p_instance->base);
} break;
case RenderingServer::INSTANCE_LIGHTMAP: {
@@ -3282,7 +3282,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario,
RendererSceneRender::CameraData camera_data;
camera_data.set_camera(Transform3D(), CameraMatrix(), true, false);
- scene_render->render_scene(p_render_buffers, &camera_data, nullptr, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
+ scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr);
#endif
}
@@ -3677,7 +3677,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
p_instance->dependency_tracker.update_begin();
if (p_instance->base.is_valid()) {
- RSG::storage->base_update_dependency(p_instance->base, &p_instance->dependency_tracker);
+ RSG::utilities->base_update_dependency(p_instance->base, &p_instance->dependency_tracker);
}
if (p_instance->material_override.is_valid()) {
@@ -3785,7 +3785,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
can_cast_shadows = false;
}
- RSG::storage->base_update_dependency(mesh, &p_instance->dependency_tracker);
+ RSG::utilities->base_update_dependency(mesh, &p_instance->dependency_tracker);
}
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
bool cast_shadows = false;
@@ -3885,7 +3885,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
}
void RendererSceneCull::update_dirty_instances() {
- RSG::storage->update_dirty_resources();
+ RSG::utilities->update_dirty_resources();
while (_instance_update_list.first()) {
_update_dirty_instance(_instance_update_list.first()->self());
@@ -3978,12 +3978,12 @@ void RendererSceneCull::update_visibility_notifiers() {
if (visibility_notifier->just_visible) {
visibility_notifier->just_visible = false;
- RSG::storage->visibility_notifier_call(visibility_notifier->base, true, RSG::threaded);
+ RSG::utilities->visibility_notifier_call(visibility_notifier->base, true, RSG::threaded);
} else {
if (visibility_notifier->visible_in_frame != RSG::rasterizer->get_frame_number()) {
visible_notifier_list.remove(E);
- RSG::storage->visibility_notifier_call(visibility_notifier->base, false, RSG::threaded);
+ RSG::utilities->visibility_notifier_call(visibility_notifier->base, false, RSG::threaded);
}
}
diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h
index d1d3484871..198898141e 100644
--- a/servers/rendering/renderer_scene_cull.h
+++ b/servers/rendering/renderer_scene_cull.h
@@ -42,7 +42,7 @@
#include "servers/rendering/renderer_scene.h"
#include "servers/rendering/renderer_scene_occlusion_cull.h"
#include "servers/rendering/renderer_scene_render.h"
-#include "servers/rendering/renderer_storage.h"
+#include "servers/rendering/storage/utilities.h"
#include "servers/xr/xr_interface.h"
class RendererSceneCull : public RendererScene {
@@ -470,32 +470,32 @@ public:
SelfList<InstancePair>::List pairs;
uint64_t pair_check;
- RendererStorage::DependencyTracker dependency_tracker;
+ DependencyTracker dependency_tracker;
- static void dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *tracker) {
+ static void dependency_changed(Dependency::DependencyChangedNotification p_notification, DependencyTracker *tracker) {
Instance *instance = (Instance *)tracker->userdata;
switch (p_notification) {
- case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA:
- case RendererStorage::DEPENDENCY_CHANGED_AABB: {
+ case Dependency::DEPENDENCY_CHANGED_SKELETON_DATA:
+ case Dependency::DEPENDENCY_CHANGED_AABB: {
singleton->_instance_queue_update(instance, true, false);
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MATERIAL: {
+ case Dependency::DEPENDENCY_CHANGED_MATERIAL: {
singleton->_instance_queue_update(instance, false, true);
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MESH:
- case RendererStorage::DEPENDENCY_CHANGED_PARTICLES:
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
- case RendererStorage::DEPENDENCY_CHANGED_DECAL:
- case RendererStorage::DEPENDENCY_CHANGED_LIGHT:
- case RendererStorage::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
+ case Dependency::DEPENDENCY_CHANGED_MESH:
+ case Dependency::DEPENDENCY_CHANGED_PARTICLES:
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH:
+ case Dependency::DEPENDENCY_CHANGED_DECAL:
+ case Dependency::DEPENDENCY_CHANGED_LIGHT:
+ case Dependency::DEPENDENCY_CHANGED_REFLECTION_PROBE: {
singleton->_instance_queue_update(instance, true, true);
} break;
- case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES:
- case RendererStorage::DEPENDENCY_CHANGED_SKELETON_BONES: {
+ case Dependency::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES:
+ case Dependency::DEPENDENCY_CHANGED_SKELETON_BONES: {
//ignored
} break;
- case RendererStorage::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: {
+ case Dependency::DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR: {
//requires repairing
if (instance->indexer_id.is_valid()) {
singleton->_unpair_instance(instance);
@@ -506,7 +506,7 @@ public:
}
}
- static void dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *tracker) {
+ static void dependency_deleted(const RID &p_dependency, DependencyTracker *tracker) {
Instance *instance = (Instance *)tracker->userdata;
if (p_dependency == instance->base) {
@@ -526,7 +526,7 @@ public:
receive_shadows = true;
visible = true;
layer_mask = 1;
- baked_light = false;
+ baked_light = true;
dynamic_gi = false;
redraw_if_visible = false;
lightmap_slice_index = 0;
diff --git a/servers/rendering/renderer_storage.h b/servers/rendering/renderer_storage.h
deleted file mode 100644
index bb4acab582..0000000000
--- a/servers/rendering/renderer_storage.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/*************************************************************************/
-/* renderer_storage.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* 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 RENDERINGSERVERSTORAGE_H
-#define RENDERINGSERVERSTORAGE_H
-
-#include "servers/rendering_server.h"
-
-class RendererStorage {
- Color default_clear_color;
-
-public:
- enum DependencyChangedNotification {
- DEPENDENCY_CHANGED_AABB,
- DEPENDENCY_CHANGED_MATERIAL,
- DEPENDENCY_CHANGED_MESH,
- DEPENDENCY_CHANGED_MULTIMESH,
- DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES,
- DEPENDENCY_CHANGED_PARTICLES,
- DEPENDENCY_CHANGED_DECAL,
- DEPENDENCY_CHANGED_SKELETON_DATA,
- DEPENDENCY_CHANGED_SKELETON_BONES,
- DEPENDENCY_CHANGED_LIGHT,
- DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR,
- DEPENDENCY_CHANGED_REFLECTION_PROBE,
- };
-
- struct DependencyTracker;
-
- struct Dependency {
- void changed_notify(DependencyChangedNotification p_notification);
- void deleted_notify(const RID &p_rid);
-
- ~Dependency();
-
- private:
- friend struct DependencyTracker;
- HashMap<DependencyTracker *, uint32_t> instances;
- };
-
- struct DependencyTracker {
- void *userdata = nullptr;
- typedef void (*ChangedCallback)(DependencyChangedNotification, DependencyTracker *);
- typedef void (*DeletedCallback)(const RID &, DependencyTracker *);
-
- ChangedCallback changed_callback = nullptr;
- DeletedCallback deleted_callback = nullptr;
-
- void update_begin() { // call before updating dependencies
- instance_version++;
- }
-
- void update_dependency(Dependency *p_dependency) { //called internally, can't be used directly, use update functions in Storage
- dependencies.insert(p_dependency);
- p_dependency->instances[this] = instance_version;
- }
-
- void update_end() { //call after updating dependencies
- List<Pair<Dependency *, DependencyTracker *>> to_clean_up;
-
- for (Dependency *E : dependencies) {
- Dependency *dep = E;
- HashMap<DependencyTracker *, uint32_t>::Iterator F = dep->instances.find(this);
- ERR_CONTINUE(!F);
- if (F->value != instance_version) {
- Pair<Dependency *, DependencyTracker *> p;
- p.first = dep;
- p.second = F->key;
- to_clean_up.push_back(p);
- }
- }
-
- while (to_clean_up.size()) {
- to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second);
- dependencies.erase(to_clean_up.front()->get().first);
- to_clean_up.pop_front();
- }
- }
-
- void clear() { // clear all dependencies
- for (Dependency *E : dependencies) {
- Dependency *dep = E;
- dep->instances.erase(this);
- }
- dependencies.clear();
- }
-
- ~DependencyTracker() { clear(); }
-
- private:
- friend struct Dependency;
- uint32_t instance_version = 0;
- HashSet<Dependency *> dependencies;
- };
-
- virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
-
- /* VOXEL GI API */
-
- virtual RID voxel_gi_allocate() = 0;
- virtual void voxel_gi_initialize(RID p_rid) = 0;
-
- virtual void voxel_gi_allocate_data(RID p_voxel_gi, const Transform3D &p_to_cell_xform, const AABB &p_aabb, const Vector3i &p_octree_size, const Vector<uint8_t> &p_octree_cells, const Vector<uint8_t> &p_data_cells, const Vector<uint8_t> &p_distance_field, const Vector<int> &p_level_counts) = 0;
-
- virtual AABB voxel_gi_get_bounds(RID p_voxel_gi) const = 0;
- virtual Vector3i voxel_gi_get_octree_size(RID p_voxel_gi) const = 0;
- virtual Vector<uint8_t> voxel_gi_get_octree_cells(RID p_voxel_gi) const = 0;
- virtual Vector<uint8_t> voxel_gi_get_data_cells(RID p_voxel_gi) const = 0;
- virtual Vector<uint8_t> voxel_gi_get_distance_field(RID p_voxel_gi) const = 0;
-
- virtual Vector<int> voxel_gi_get_level_counts(RID p_voxel_gi) const = 0;
- virtual Transform3D voxel_gi_get_to_cell_xform(RID p_voxel_gi) const = 0;
-
- virtual void voxel_gi_set_dynamic_range(RID p_voxel_gi, float p_range) = 0;
- virtual float voxel_gi_get_dynamic_range(RID p_voxel_gi) const = 0;
-
- virtual void voxel_gi_set_propagation(RID p_voxel_gi, float p_range) = 0;
- virtual float voxel_gi_get_propagation(RID p_voxel_gi) const = 0;
-
- virtual void voxel_gi_set_energy(RID p_voxel_gi, float p_energy) = 0;
- virtual float voxel_gi_get_energy(RID p_voxel_gi) const = 0;
-
- virtual void voxel_gi_set_bias(RID p_voxel_gi, float p_bias) = 0;
- virtual float voxel_gi_get_bias(RID p_voxel_gi) const = 0;
-
- virtual void voxel_gi_set_normal_bias(RID p_voxel_gi, float p_range) = 0;
- virtual float voxel_gi_get_normal_bias(RID p_voxel_gi) const = 0;
-
- virtual void voxel_gi_set_interior(RID p_voxel_gi, bool p_enable) = 0;
- virtual bool voxel_gi_is_interior(RID p_voxel_gi) const = 0;
-
- virtual void voxel_gi_set_use_two_bounces(RID p_voxel_gi, bool p_enable) = 0;
- virtual bool voxel_gi_is_using_two_bounces(RID p_voxel_gi) const = 0;
-
- virtual void voxel_gi_set_anisotropy_strength(RID p_voxel_gi, float p_strength) = 0;
- virtual float voxel_gi_get_anisotropy_strength(RID p_voxel_gi) const = 0;
-
- virtual uint32_t voxel_gi_get_version(RID p_probe) = 0;
-
- /* FOG VOLUMES */
-
- virtual RID fog_volume_allocate() = 0;
- virtual void fog_volume_initialize(RID p_rid) = 0;
-
- virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) = 0;
- virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) = 0;
- virtual void fog_volume_set_material(RID p_fog_volume, RID p_material) = 0;
- virtual AABB fog_volume_get_aabb(RID p_fog_volume) const = 0;
- virtual RS::FogVolumeShape fog_volume_get_shape(RID p_fog_volume) const = 0;
-
- /* VISIBILITY NOTIFIER */
-
- virtual RID visibility_notifier_allocate() = 0;
- virtual void visibility_notifier_initialize(RID p_notifier) = 0;
- virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) = 0;
- virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) = 0;
-
- virtual AABB visibility_notifier_get_aabb(RID p_notifier) const = 0;
- virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) = 0;
-
- virtual RS::InstanceType get_base_type(RID p_rid) const = 0;
- virtual bool free(RID p_rid) = 0;
-
- virtual bool has_os_feature(const String &p_feature) const = 0;
-
- virtual void update_dirty_resources() = 0;
-
- virtual void set_debug_generate_wireframes(bool p_generate) = 0;
-
- virtual void update_memory_info() = 0;
-
- virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) = 0;
- virtual String get_video_adapter_name() const = 0;
- virtual String get_video_adapter_vendor() const = 0;
- virtual RenderingDevice::DeviceType get_video_adapter_type() const = 0;
- virtual String get_video_adapter_api_version() const = 0;
-
- static RendererStorage *base_singleton;
-
- void set_default_clear_color(const Color &p_color) {
- default_clear_color = p_color;
- }
-
- Color get_default_clear_color() const {
- return default_clear_color;
- }
-#define TIMESTAMP_BEGIN() \
- { \
- if (RSG::storage->capturing_timestamps) \
- RSG::storage->capture_timestamps_begin(); \
- }
-
-#define RENDER_TIMESTAMP(m_text) \
- { \
- if (RSG::storage->capturing_timestamps) \
- RSG::storage->capture_timestamp(m_text); \
- }
-
- bool capturing_timestamps = false;
-
- virtual void capture_timestamps_begin() = 0;
- virtual void capture_timestamp(const String &p_name) = 0;
- virtual uint32_t get_captured_timestamps_count() const = 0;
- virtual uint64_t get_captured_timestamps_frame() const = 0;
- virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const = 0;
- virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const = 0;
- virtual String get_captured_timestamp_name(uint32_t p_index) const = 0;
-
- RendererStorage();
- virtual ~RendererStorage() {}
-};
-
-#endif // RENDERINGSERVERSTORAGE_H
diff --git a/servers/rendering/renderer_viewport.cpp b/servers/rendering/renderer_viewport.cpp
index 2e0c4e0f79..2fccb1fd38 100644
--- a/servers/rendering/renderer_viewport.cpp
+++ b/servers/rendering/renderer_viewport.cpp
@@ -175,7 +175,7 @@ void RendererViewport::_draw_3d(Viewport *p_viewport) {
void RendererViewport::_draw_viewport(Viewport *p_viewport) {
if (p_viewport->measure_render_time) {
String rt_id = "vp_begin_" + itos(p_viewport->self.get_id());
- RSG::storage->capture_timestamp(rt_id);
+ RSG::utilities->capture_timestamp(rt_id);
timestamp_vp_map[rt_id] = p_viewport->self;
}
@@ -212,7 +212,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
_configure_3d_render_buffers(p_viewport);
}
- Color bgcolor = p_viewport->transparent_bg ? Color(0, 0, 0, 0) : RSG::storage->get_default_clear_color();
+ Color bgcolor = p_viewport->transparent_bg ? Color(0, 0, 0, 0) : RSG::texture_storage->get_default_clear_color();
if (p_viewport->clear_mode != RS::VIEWPORT_CLEAR_NEVER) {
RSG::texture_storage->render_target_request_clear(p_viewport->render_target, bgcolor);
@@ -521,7 +521,7 @@ void RendererViewport::_draw_viewport(Viewport *p_viewport) {
if (p_viewport->measure_render_time) {
String rt_id = "vp_end_" + itos(p_viewport->self.get_id());
- RSG::storage->capture_timestamp(rt_id);
+ RSG::utilities->capture_timestamp(rt_id);
timestamp_vp_map[rt_id] = p_viewport->self;
}
}
@@ -1193,6 +1193,20 @@ void RendererViewport::viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::V
RSG::texture_storage->render_target_set_sdf_size_and_scale(viewport->render_target, p_size, p_scale);
}
+RID RendererViewport::viewport_find_from_screen_attachment(DisplayServer::WindowID p_id) const {
+ RID *rids = nullptr;
+ uint32_t rid_count = viewport_owner.get_rid_count();
+ rids = (RID *)alloca(sizeof(RID *) * rid_count);
+ viewport_owner.fill_owned_buffer(rids);
+ for (uint32_t i = 0; i < rid_count; i++) {
+ Viewport *viewport = viewport_owner.get_or_null(rids[i]);
+ if (viewport->viewport_to_screen == p_id) {
+ return rids[i];
+ }
+ }
+ return RID();
+}
+
bool RendererViewport::free(RID p_rid) {
if (viewport_owner.owns(p_rid)) {
Viewport *viewport = viewport_owner.get_or_null(p_rid);
@@ -1245,7 +1259,7 @@ void RendererViewport::handle_timestamp(String p_timestamp, uint64_t p_cpu_time,
}
void RendererViewport::set_default_clear_color(const Color &p_color) {
- RSG::storage->set_default_clear_color(p_color);
+ RSG::texture_storage->set_default_clear_color(p_color);
}
// Workaround for setting this on thread.
diff --git a/servers/rendering/renderer_viewport.h b/servers/rendering/renderer_viewport.h
index 18385d1613..acab8063d1 100644
--- a/servers/rendering/renderer_viewport.h
+++ b/servers/rendering/renderer_viewport.h
@@ -282,6 +282,8 @@ public:
void viewport_set_sdf_oversize_and_scale(RID p_viewport, RS::ViewportSDFOversize p_over_size, RS::ViewportSDFScale p_scale);
+ virtual RID viewport_find_from_screen_attachment(DisplayServer::WindowID p_id = DisplayServer::MAIN_WINDOW_ID) const;
+
void handle_timestamp(String p_timestamp, uint64_t p_cpu_time, uint64_t p_gpu_time);
void set_default_clear_color(const Color &p_color);
diff --git a/servers/rendering/rendering_server_default.cpp b/servers/rendering/rendering_server_default.cpp
index 718f20f80a..bcd7e6a1dd 100644
--- a/servers/rendering/rendering_server_default.cpp
+++ b/servers/rendering/rendering_server_default.cpp
@@ -48,7 +48,7 @@ void RenderingServerDefault::_free(RID p_rid) {
if (unlikely(p_rid.is_null())) {
return;
}
- if (RSG::storage->free(p_rid)) {
+ if (RSG::utilities->free(p_rid)) {
return;
}
if (RSG::canvas->free(p_rid)) {
@@ -116,35 +116,35 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
}
RS::get_singleton()->emit_signal(SNAME("frame_post_draw"));
- if (RSG::storage->get_captured_timestamps_count()) {
+ if (RSG::utilities->get_captured_timestamps_count()) {
Vector<FrameProfileArea> new_profile;
- if (RSG::storage->capturing_timestamps) {
- new_profile.resize(RSG::storage->get_captured_timestamps_count());
+ if (RSG::utilities->capturing_timestamps) {
+ new_profile.resize(RSG::utilities->get_captured_timestamps_count());
}
- uint64_t base_cpu = RSG::storage->get_captured_timestamp_cpu_time(0);
- uint64_t base_gpu = RSG::storage->get_captured_timestamp_gpu_time(0);
- for (uint32_t i = 0; i < RSG::storage->get_captured_timestamps_count(); i++) {
- uint64_t time_cpu = RSG::storage->get_captured_timestamp_cpu_time(i);
- uint64_t time_gpu = RSG::storage->get_captured_timestamp_gpu_time(i);
+ uint64_t base_cpu = RSG::utilities->get_captured_timestamp_cpu_time(0);
+ uint64_t base_gpu = RSG::utilities->get_captured_timestamp_gpu_time(0);
+ for (uint32_t i = 0; i < RSG::utilities->get_captured_timestamps_count(); i++) {
+ uint64_t time_cpu = RSG::utilities->get_captured_timestamp_cpu_time(i);
+ uint64_t time_gpu = RSG::utilities->get_captured_timestamp_gpu_time(i);
- String name = RSG::storage->get_captured_timestamp_name(i);
+ String name = RSG::utilities->get_captured_timestamp_name(i);
if (name.begins_with("vp_")) {
RSG::viewport->handle_timestamp(name, time_cpu, time_gpu);
}
- if (RSG::storage->capturing_timestamps) {
+ if (RSG::utilities->capturing_timestamps) {
new_profile.write[i].gpu_msec = double((time_gpu - base_gpu) / 1000) / 1000.0;
new_profile.write[i].cpu_msec = double(time_cpu - base_cpu) / 1000.0;
- new_profile.write[i].name = RSG::storage->get_captured_timestamp_name(i);
+ new_profile.write[i].name = RSG::utilities->get_captured_timestamp_name(i);
}
}
frame_profile = new_profile;
}
- frame_profile_frame = RSG::storage->get_captured_timestamps_frame();
+ frame_profile_frame = RSG::utilities->get_captured_timestamps_frame();
if (print_gpu_profile) {
if (print_frame_profile_ticks_from == 0) {
@@ -191,7 +191,7 @@ void RenderingServerDefault::_draw(bool p_swap_buffers, double frame_step) {
}
}
- RSG::storage->update_memory_info();
+ RSG::utilities->update_memory_info();
}
double RenderingServerDefault::get_frame_setup_time_cpu() const {
@@ -250,27 +250,27 @@ uint64_t RenderingServerDefault::get_rendering_info(RenderingInfo p_info) {
} else if (p_info == RENDERING_INFO_TOTAL_DRAW_CALLS_IN_FRAME) {
return RSG::viewport->get_total_draw_calls_used();
}
- return RSG::storage->get_rendering_info(p_info);
+ return RSG::utilities->get_rendering_info(p_info);
}
String RenderingServerDefault::get_video_adapter_name() const {
- return RSG::storage->get_video_adapter_name();
+ return RSG::utilities->get_video_adapter_name();
}
String RenderingServerDefault::get_video_adapter_vendor() const {
- return RSG::storage->get_video_adapter_vendor();
+ return RSG::utilities->get_video_adapter_vendor();
}
RenderingDevice::DeviceType RenderingServerDefault::get_video_adapter_type() const {
- return RSG::storage->get_video_adapter_type();
+ return RSG::utilities->get_video_adapter_type();
}
String RenderingServerDefault::get_video_adapter_api_version() const {
- return RSG::storage->get_video_adapter_api_version();
+ return RSG::utilities->get_video_adapter_api_version();
}
void RenderingServerDefault::set_frame_profiling_enabled(bool p_enable) {
- RSG::storage->capturing_timestamps = p_enable;
+ RSG::utilities->capturing_timestamps = p_enable;
}
uint64_t RenderingServerDefault::get_frame_profile_frame() {
@@ -301,7 +301,7 @@ void RenderingServerDefault::sdfgi_set_debug_probe_select(const Vector3 &p_posit
}
void RenderingServerDefault::set_print_gpu_profile(bool p_enable) {
- RSG::storage->capturing_timestamps = p_enable;
+ RSG::utilities->capturing_timestamps = p_enable;
print_gpu_profile = p_enable;
}
@@ -313,15 +313,15 @@ RID RenderingServerDefault::get_test_cube() {
}
bool RenderingServerDefault::has_os_feature(const String &p_feature) const {
- if (RSG::storage) {
- return RSG::storage->has_os_feature(p_feature);
+ if (RSG::utilities) {
+ return RSG::utilities->has_os_feature(p_feature);
} else {
return false;
}
}
void RenderingServerDefault::set_debug_generate_wireframes(bool p_generate) {
- RSG::storage->set_debug_generate_wireframes(p_generate);
+ RSG::utilities->set_debug_generate_wireframes(p_generate);
}
bool RenderingServerDefault::is_low_end() const {
@@ -333,13 +333,10 @@ void RenderingServerDefault::_thread_exit() {
}
void RenderingServerDefault::_thread_draw(bool p_swap_buffers, double frame_step) {
- if (!draw_pending.decrement()) {
- _draw(p_swap_buffers, frame_step);
- }
+ _draw(p_swap_buffers, frame_step);
}
void RenderingServerDefault::_thread_flush() {
- draw_pending.decrement();
}
void RenderingServerDefault::_thread_callback(void *_instance) {
@@ -370,7 +367,6 @@ void RenderingServerDefault::_thread_loop() {
void RenderingServerDefault::sync() {
if (create_thread) {
- draw_pending.increment();
command_queue.push_and_sync(this, &RenderingServerDefault::_thread_flush);
} else {
command_queue.flush_all(); //flush all pending from other threads
@@ -379,7 +375,6 @@ void RenderingServerDefault::sync() {
void RenderingServerDefault::draw(bool p_swap_buffers, double frame_step) {
if (create_thread) {
- draw_pending.increment();
command_queue.push(this, &RenderingServerDefault::_thread_draw, p_swap_buffers, frame_step);
} else {
_draw(p_swap_buffers, frame_step);
@@ -404,12 +399,14 @@ RenderingServerDefault::RenderingServerDefault(bool p_create_thread) :
RendererSceneCull *sr = memnew(RendererSceneCull);
RSG::scene = sr;
RSG::rasterizer = RendererCompositor::create();
+ RSG::utilities = RSG::rasterizer->get_utilities();
RSG::light_storage = RSG::rasterizer->get_light_storage();
RSG::material_storage = RSG::rasterizer->get_material_storage();
RSG::mesh_storage = RSG::rasterizer->get_mesh_storage();
RSG::particles_storage = RSG::rasterizer->get_particles_storage();
RSG::texture_storage = RSG::rasterizer->get_texture_storage();
- RSG::storage = RSG::rasterizer->get_storage();
+ RSG::gi = RSG::rasterizer->get_gi();
+ RSG::fog = RSG::rasterizer->get_fog();
RSG::canvas_render = RSG::rasterizer->get_canvas();
sr->set_scene_render(RSG::rasterizer->get_scene());
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 6008f2b00e..584d9a7a51 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -31,7 +31,6 @@
#ifndef RENDERING_SERVER_DEFAULT_H
#define RENDERING_SERVER_DEFAULT_H
-#include "core/math/octree.h"
#include "core/templates/command_queue_mt.h"
#include "core/templates/hash_map.h"
#include "renderer_canvas_cull.h"
@@ -84,7 +83,6 @@ class RenderingServerDefault : public RenderingServer {
SafeFlag draw_thread_up;
bool create_thread;
- SafeNumeric<uint64_t> draw_pending;
void _thread_draw(bool p_swap_buffers, double frame_step);
void _thread_flush();
@@ -436,8 +434,8 @@ public:
#undef ServerName
#undef server_name
-#define ServerName RendererStorage
-#define server_name RSG::storage
+#define ServerName RendererGI
+#define server_name RSG::gi
FUNCRIDSPLIT(voxel_gi)
@@ -525,8 +523,8 @@ public:
#undef ServerName
#undef server_name
-#define ServerName RendererStorage
-#define server_name RSG::storage
+#define ServerName RendererFog
+#define server_name RSG::fog
FUNCRIDSPLIT(fog_volume)
@@ -536,6 +534,12 @@ public:
/* VISIBILITY_NOTIFIER */
+#undef ServerName
+#undef server_name
+
+#define ServerName RendererUtilities
+#define server_name RSG::utilities
+
FUNCRIDSPLIT(visibility_notifier)
FUNC2(visibility_notifier_set_aabb, RID, const AABB &)
FUNC3(visibility_notifier_set_callbacks, RID, const Callable &, const Callable &)
@@ -629,6 +633,7 @@ public:
FUNC2(viewport_set_measure_render_time, RID, bool)
FUNC1RC(double, viewport_get_measured_render_time_cpu, RID)
FUNC1RC(double, viewport_get_measured_render_time_gpu, RID)
+ FUNC1RC(RID, viewport_find_from_screen_attachment, DisplayServer::WindowID)
FUNC2(call_set_vsync_mode, DisplayServer::VSyncMode, DisplayServer::WindowID)
diff --git a/servers/rendering/rendering_server_globals.cpp b/servers/rendering/rendering_server_globals.cpp
index 4d24dbf3b4..46fa49e683 100644
--- a/servers/rendering/rendering_server_globals.cpp
+++ b/servers/rendering/rendering_server_globals.cpp
@@ -32,12 +32,14 @@
bool RenderingServerGlobals::threaded = false;
+RendererUtilities *RenderingServerGlobals::utilities = nullptr;
RendererLightStorage *RenderingServerGlobals::light_storage = nullptr;
RendererMaterialStorage *RenderingServerGlobals::material_storage = nullptr;
RendererMeshStorage *RenderingServerGlobals::mesh_storage = nullptr;
RendererParticlesStorage *RenderingServerGlobals::particles_storage = nullptr;
RendererTextureStorage *RenderingServerGlobals::texture_storage = nullptr;
-RendererStorage *RenderingServerGlobals::storage = nullptr;
+RendererGI *RenderingServerGlobals::gi = nullptr;
+RendererFog *RenderingServerGlobals::fog = nullptr;
RendererCanvasRender *RenderingServerGlobals::canvas_render = nullptr;
RendererCompositor *RenderingServerGlobals::rasterizer = nullptr;
diff --git a/servers/rendering/rendering_server_globals.h b/servers/rendering/rendering_server_globals.h
index ce11fae9e8..87d69984f8 100644
--- a/servers/rendering/rendering_server_globals.h
+++ b/servers/rendering/rendering_server_globals.h
@@ -31,6 +31,8 @@
#ifndef RENDERING_SERVER_GLOBALS_H
#define RENDERING_SERVER_GLOBALS_H
+#include "servers/rendering/environment/renderer_fog.h"
+#include "servers/rendering/environment/renderer_gi.h"
#include "servers/rendering/renderer_canvas_cull.h"
#include "servers/rendering/renderer_canvas_render.h"
#include "servers/rendering/renderer_scene.h"
@@ -39,6 +41,7 @@
#include "servers/rendering/storage/mesh_storage.h"
#include "servers/rendering/storage/particles_storage.h"
#include "servers/rendering/storage/texture_storage.h"
+#include "servers/rendering/storage/utilities.h"
class RendererCanvasCull;
class RendererViewport;
@@ -48,12 +51,14 @@ class RenderingServerGlobals {
public:
static bool threaded;
+ static RendererUtilities *utilities;
static RendererLightStorage *light_storage;
static RendererMaterialStorage *material_storage;
static RendererMeshStorage *mesh_storage;
static RendererParticlesStorage *particles_storage;
static RendererTextureStorage *texture_storage;
- static RendererStorage *storage;
+ static RendererGI *gi;
+ static RendererFog *fog;
static RendererCanvasRender *canvas_render;
static RendererCompositor *rasterizer;
diff --git a/servers/rendering/storage/light_storage.h b/servers/rendering/storage/light_storage.h
index 0cb0f35570..f627e46e52 100644
--- a/servers/rendering/storage/light_storage.h
+++ b/servers/rendering/storage/light_storage.h
@@ -31,7 +31,6 @@
#ifndef LIGHT_STORAGE_H
#define LIGHT_STORAGE_H
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering_server.h"
class RendererLightStorage {
diff --git a/servers/rendering/storage/material_storage.h b/servers/rendering/storage/material_storage.h
index f0363f129a..00790106af 100644
--- a/servers/rendering/storage/material_storage.h
+++ b/servers/rendering/storage/material_storage.h
@@ -31,8 +31,8 @@
#ifndef MATERIAL_STORAGE_H
#define MATERIAL_STORAGE_H
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering_server.h"
+#include "utilities.h"
class RendererMaterialStorage {
public:
@@ -95,7 +95,7 @@ public:
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) = 0;
- virtual void material_update_dependency(RID p_material, RendererStorage::DependencyTracker *p_instance) = 0;
+ virtual void material_update_dependency(RID p_material, DependencyTracker *p_instance) = 0;
};
#endif // !MATERIAL_STORAGE_H
diff --git a/servers/rendering/storage/mesh_storage.h b/servers/rendering/storage/mesh_storage.h
index 1dac51319c..146f6fde40 100644
--- a/servers/rendering/storage/mesh_storage.h
+++ b/servers/rendering/storage/mesh_storage.h
@@ -31,8 +31,8 @@
#ifndef MESH_STORAGE_H
#define MESH_STORAGE_H
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering_server.h"
+#include "utilities.h"
class RendererMeshStorage {
public:
@@ -130,7 +130,7 @@ public:
virtual Transform2D skeleton_bone_get_transform_2d(RID p_skeleton, int p_bone) const = 0;
virtual void skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) = 0;
- virtual void skeleton_update_dependency(RID p_base, RendererStorage::DependencyTracker *p_instance) = 0;
+ virtual void skeleton_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
};
#endif // !MESH_STORAGE_H
diff --git a/servers/rendering/storage/particles_storage.h b/servers/rendering/storage/particles_storage.h
index 268b5473e2..eba68210a5 100644
--- a/servers/rendering/storage/particles_storage.h
+++ b/servers/rendering/storage/particles_storage.h
@@ -31,7 +31,6 @@
#ifndef PARTICLES_STORAGE_H
#define PARTICLES_STORAGE_H
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering_server.h"
class RendererParticlesStorage {
diff --git a/servers/rendering/storage/texture_storage.h b/servers/rendering/storage/texture_storage.h
index e3a969d032..e90a028713 100644
--- a/servers/rendering/storage/texture_storage.h
+++ b/servers/rendering/storage/texture_storage.h
@@ -34,7 +34,18 @@
#include "servers/rendering_server.h"
class RendererTextureStorage {
+private:
+ Color default_clear_color;
+
public:
+ void set_default_clear_color(const Color &p_color) {
+ default_clear_color = p_color;
+ }
+
+ Color get_default_clear_color() const {
+ return default_clear_color;
+ }
+
/* Canvas Texture API */
virtual RID canvas_texture_allocate() = 0;
diff --git a/servers/rendering/renderer_storage.cpp b/servers/rendering/storage/utilities.cpp
index 56409ae187..7cc6417a25 100644
--- a/servers/rendering/renderer_storage.cpp
+++ b/servers/rendering/storage/utilities.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* renderer_storage.cpp */
+/* utilities.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,11 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "renderer_storage.h"
+#include "utilities.h"
-RendererStorage *RendererStorage::base_singleton = nullptr;
-
-void RendererStorage::Dependency::changed_notify(DependencyChangedNotification p_notification) {
+void Dependency::changed_notify(DependencyChangedNotification p_notification) {
for (const KeyValue<DependencyTracker *, uint32_t> &E : instances) {
if (E.key->changed_callback) {
E.key->changed_callback(p_notification, E.key);
@@ -40,7 +38,7 @@ void RendererStorage::Dependency::changed_notify(DependencyChangedNotification p
}
}
-void RendererStorage::Dependency::deleted_notify(const RID &p_rid) {
+void Dependency::deleted_notify(const RID &p_rid) {
for (const KeyValue<DependencyTracker *, uint32_t> &E : instances) {
if (E.key->deleted_callback) {
E.key->deleted_callback(p_rid, E.key);
@@ -52,7 +50,7 @@ void RendererStorage::Dependency::deleted_notify(const RID &p_rid) {
instances.clear();
}
-RendererStorage::Dependency::~Dependency() {
+Dependency::~Dependency() {
#ifdef DEBUG_ENABLED
if (instances.size()) {
WARN_PRINT("Leaked instance dependency: Bug - did not call instance_notify_deleted when freeing.");
@@ -62,7 +60,3 @@ RendererStorage::Dependency::~Dependency() {
}
#endif
}
-
-RendererStorage::RendererStorage() {
- base_singleton = this;
-}
diff --git a/servers/rendering/storage/utilities.h b/servers/rendering/storage/utilities.h
new file mode 100644
index 0000000000..4d7c34383c
--- /dev/null
+++ b/servers/rendering/storage/utilities.h
@@ -0,0 +1,186 @@
+/*************************************************************************/
+/* utilities.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 RENDERER_UTILITIES_H
+#define RENDERER_UTILITIES_H
+
+#include "servers/rendering_server.h"
+
+class DependencyTracker;
+
+class Dependency {
+public:
+ enum DependencyChangedNotification {
+ DEPENDENCY_CHANGED_AABB,
+ DEPENDENCY_CHANGED_MATERIAL,
+ DEPENDENCY_CHANGED_MESH,
+ DEPENDENCY_CHANGED_MULTIMESH,
+ DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES,
+ DEPENDENCY_CHANGED_PARTICLES,
+ DEPENDENCY_CHANGED_DECAL,
+ DEPENDENCY_CHANGED_SKELETON_DATA,
+ DEPENDENCY_CHANGED_SKELETON_BONES,
+ DEPENDENCY_CHANGED_LIGHT,
+ DEPENDENCY_CHANGED_LIGHT_SOFT_SHADOW_AND_PROJECTOR,
+ DEPENDENCY_CHANGED_REFLECTION_PROBE,
+ };
+
+ void changed_notify(DependencyChangedNotification p_notification);
+ void deleted_notify(const RID &p_rid);
+
+ ~Dependency();
+
+private:
+ friend class DependencyTracker;
+ HashMap<DependencyTracker *, uint32_t> instances;
+};
+
+class DependencyTracker {
+public:
+ void *userdata = nullptr;
+ typedef void (*ChangedCallback)(Dependency::DependencyChangedNotification, DependencyTracker *);
+ typedef void (*DeletedCallback)(const RID &, DependencyTracker *);
+
+ ChangedCallback changed_callback = nullptr;
+ DeletedCallback deleted_callback = nullptr;
+
+ void update_begin() { // call before updating dependencies
+ instance_version++;
+ }
+
+ void update_dependency(Dependency *p_dependency) { //called internally, can't be used directly, use update functions in Storage
+ dependencies.insert(p_dependency);
+ p_dependency->instances[this] = instance_version;
+ }
+
+ void update_end() { //call after updating dependencies
+ List<Pair<Dependency *, DependencyTracker *>> to_clean_up;
+
+ for (Dependency *E : dependencies) {
+ Dependency *dep = E;
+ HashMap<DependencyTracker *, uint32_t>::Iterator F = dep->instances.find(this);
+ ERR_CONTINUE(!F);
+ if (F->value != instance_version) {
+ Pair<Dependency *, DependencyTracker *> p;
+ p.first = dep;
+ p.second = F->key;
+ to_clean_up.push_back(p);
+ }
+ }
+
+ while (to_clean_up.size()) {
+ to_clean_up.front()->get().first->instances.erase(to_clean_up.front()->get().second);
+ dependencies.erase(to_clean_up.front()->get().first);
+ to_clean_up.pop_front();
+ }
+ }
+
+ void clear() { // clear all dependencies
+ for (Dependency *E : dependencies) {
+ Dependency *dep = E;
+ dep->instances.erase(this);
+ }
+ dependencies.clear();
+ }
+
+ ~DependencyTracker() { clear(); }
+
+private:
+ friend class Dependency;
+ uint32_t instance_version = 0;
+ HashSet<Dependency *> dependencies;
+};
+
+class RendererUtilities {
+public:
+ virtual ~RendererUtilities() {}
+
+ /* INSTANCES */
+
+ virtual RS::InstanceType get_base_type(RID p_rid) const = 0;
+ virtual bool free(RID p_rid) = 0;
+
+ /* DEPENDENCIES */
+
+ virtual void base_update_dependency(RID p_base, DependencyTracker *p_instance) = 0;
+
+ /* VISIBILITY NOTIFIER */
+
+ virtual RID visibility_notifier_allocate() = 0;
+ virtual void visibility_notifier_initialize(RID p_notifier) = 0;
+ virtual void visibility_notifier_free(RID p_notifier) = 0;
+
+ virtual void visibility_notifier_set_aabb(RID p_notifier, const AABB &p_aabb) = 0;
+ virtual void visibility_notifier_set_callbacks(RID p_notifier, const Callable &p_enter_callbable, const Callable &p_exit_callable) = 0;
+
+ virtual AABB visibility_notifier_get_aabb(RID p_notifier) const = 0;
+ virtual void visibility_notifier_call(RID p_notifier, bool p_enter, bool p_deferred) = 0;
+
+ /* TIMING */
+
+ bool capturing_timestamps = false;
+
+#define TIMESTAMP_BEGIN() \
+ { \
+ if (RSG::utilities->capturing_timestamps) \
+ RSG::utilities->capture_timestamps_begin(); \
+ }
+
+#define RENDER_TIMESTAMP(m_text) \
+ { \
+ if (RSG::utilities->capturing_timestamps) \
+ RSG::utilities->capture_timestamp(m_text); \
+ }
+
+ virtual void capture_timestamps_begin() = 0;
+ virtual void capture_timestamp(const String &p_name) = 0;
+ virtual uint32_t get_captured_timestamps_count() const = 0;
+ virtual uint64_t get_captured_timestamps_frame() const = 0;
+ virtual uint64_t get_captured_timestamp_gpu_time(uint32_t p_index) const = 0;
+ virtual uint64_t get_captured_timestamp_cpu_time(uint32_t p_index) const = 0;
+ virtual String get_captured_timestamp_name(uint32_t p_index) const = 0;
+
+ /* MISC */
+
+ virtual void update_dirty_resources() = 0;
+ virtual void set_debug_generate_wireframes(bool p_generate) = 0;
+
+ virtual bool has_os_feature(const String &p_feature) const = 0;
+
+ virtual void update_memory_info() = 0;
+
+ virtual uint64_t get_rendering_info(RS::RenderingInfo p_info) = 0;
+ virtual String get_video_adapter_name() const = 0;
+ virtual String get_video_adapter_vendor() const = 0;
+ virtual RenderingDevice::DeviceType get_video_adapter_type() const = 0;
+ virtual String get_video_adapter_api_version() const = 0;
+};
+
+#endif // !RENDERER_UTILITIES_H
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 39484e532a..ccef95f5f2 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -944,6 +944,8 @@ public:
virtual double viewport_get_measured_render_time_cpu(RID p_viewport) const = 0;
virtual double viewport_get_measured_render_time_gpu(RID p_viewport) const = 0;
+ virtual RID viewport_find_from_screen_attachment(DisplayServer::WindowID p_id = DisplayServer::MAIN_WINDOW_ID) const = 0;
+
/* SKY API */
enum SkyMode {
diff --git a/servers/text/text_server_extension.cpp b/servers/text/text_server_extension.cpp
index e9a558ac5f..68959819c9 100644
--- a/servers/text/text_server_extension.cpp
+++ b/servers/text/text_server_extension.cpp
@@ -127,9 +127,6 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(font_set_scale, "font_rid", "size", "scale");
GDVIRTUAL_BIND(font_get_scale, "font_rid", "size");
- GDVIRTUAL_BIND(font_set_spacing, "font_rid", "size", "spacing", "value");
- GDVIRTUAL_BIND(font_get_spacing, "font_rid", "size", "spacing");
-
GDVIRTUAL_BIND(font_get_texture_count, "font_rid", "size");
GDVIRTUAL_BIND(font_clear_textures, "font_rid", "size");
GDVIRTUAL_BIND(font_remove_texture, "font_rid", "size", "texture_index");
@@ -230,6 +227,9 @@ void TextServerExtension::_bind_methods() {
GDVIRTUAL_BIND(shaped_text_set_preserve_control, "shaped", "enabled");
GDVIRTUAL_BIND(shaped_text_get_preserve_control, "shaped");
+ GDVIRTUAL_BIND(shaped_text_set_spacing, "shaped", "spacing", "value");
+ GDVIRTUAL_BIND(shaped_text_get_spacing, "shaped", "spacing");
+
GDVIRTUAL_BIND(shaped_text_add_string, "shaped", "text", "fonts", "size", "opentype_features", "language", "meta");
GDVIRTUAL_BIND(shaped_text_add_object, "shaped", "key", "size", "inline_align", "length");
GDVIRTUAL_BIND(shaped_text_resize_object, "shaped", "key", "size", "inline_align");
@@ -706,18 +706,6 @@ double TextServerExtension::font_get_scale(const RID &p_font_rid, int64_t p_size
return 0.0;
}
-void TextServerExtension::font_set_spacing(const RID &p_font_rid, int64_t p_size, TextServer::SpacingType p_spacing, int64_t p_value) {
- GDVIRTUAL_CALL(font_set_spacing, p_font_rid, p_size, p_spacing, p_value);
-}
-
-int64_t TextServerExtension::font_get_spacing(const RID &p_font_rid, int64_t p_size, TextServer::SpacingType p_spacing) const {
- int64_t ret;
- if (GDVIRTUAL_CALL(font_get_spacing, p_font_rid, p_size, p_spacing, ret)) {
- return ret;
- }
- return 0;
-}
-
int64_t TextServerExtension::font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const {
int64_t ret;
if (GDVIRTUAL_CALL(font_get_texture_count, p_font_rid, p_size, ret)) {
@@ -1132,6 +1120,18 @@ bool TextServerExtension::shaped_text_get_preserve_control(const RID &p_shaped)
return false;
}
+void TextServerExtension::shaped_text_set_spacing(const RID &p_shaped, TextServer::SpacingType p_spacing, int64_t p_value) {
+ GDVIRTUAL_CALL(shaped_text_set_spacing, p_shaped, p_spacing, p_value);
+}
+
+int64_t TextServerExtension::shaped_text_get_spacing(const RID &p_shaped, TextServer::SpacingType p_spacing) const {
+ int64_t ret;
+ if (GDVIRTUAL_CALL(shaped_text_get_spacing, p_shaped, p_spacing, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
bool TextServerExtension::shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features, const String &p_language, const Variant &p_meta) {
bool ret;
if (GDVIRTUAL_CALL(shaped_text_add_string, p_shaped, p_text, p_fonts, p_size, p_opentype_features, p_language, p_meta, ret)) {
diff --git a/servers/text/text_server_extension.h b/servers/text/text_server_extension.h
index 9ca0939247..d948a97c66 100644
--- a/servers/text/text_server_extension.h
+++ b/servers/text/text_server_extension.h
@@ -204,11 +204,6 @@ public:
GDVIRTUAL3(font_set_scale, RID, int64_t, double);
GDVIRTUAL2RC(double, font_get_scale, RID, int64_t);
- virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) override;
- virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const override;
- GDVIRTUAL4(font_set_spacing, RID, int64_t, SpacingType, int64_t);
- GDVIRTUAL3RC(int64_t, font_get_spacing, RID, int64_t, SpacingType);
-
virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const override;
virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) override;
virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) override;
@@ -377,6 +372,11 @@ public:
GDVIRTUAL2(shaped_text_set_preserve_control, RID, bool);
GDVIRTUAL1RC(bool, shaped_text_get_preserve_control, RID);
+ virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) override;
+ virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const override;
+ GDVIRTUAL3(shaped_text_set_spacing, RID, SpacingType, int64_t);
+ GDVIRTUAL2RC(int64_t, shaped_text_get_spacing, RID, SpacingType);
+
virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) override;
virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) override;
virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) override;
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index fe5ade88a1..c1293230d8 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -280,9 +280,6 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("font_set_scale", "font_rid", "size", "scale"), &TextServer::font_set_scale);
ClassDB::bind_method(D_METHOD("font_get_scale", "font_rid", "size"), &TextServer::font_get_scale);
- ClassDB::bind_method(D_METHOD("font_set_spacing", "font_rid", "size", "spacing", "value"), &TextServer::font_set_spacing);
- ClassDB::bind_method(D_METHOD("font_get_spacing", "font_rid", "size", "spacing"), &TextServer::font_get_spacing);
-
ClassDB::bind_method(D_METHOD("font_get_texture_count", "font_rid", "size"), &TextServer::font_get_texture_count);
ClassDB::bind_method(D_METHOD("font_clear_textures", "font_rid", "size"), &TextServer::font_clear_textures);
ClassDB::bind_method(D_METHOD("font_remove_texture", "font_rid", "size", "texture_index"), &TextServer::font_remove_texture);
@@ -383,6 +380,9 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("shaped_text_set_preserve_control", "shaped", "enabled"), &TextServer::shaped_text_set_preserve_control);
ClassDB::bind_method(D_METHOD("shaped_text_get_preserve_control", "shaped"), &TextServer::shaped_text_get_preserve_control);
+ ClassDB::bind_method(D_METHOD("shaped_text_set_spacing", "shaped", "spacing", "value"), &TextServer::shaped_text_set_spacing);
+ ClassDB::bind_method(D_METHOD("shaped_text_get_spacing", "shaped", "spacing"), &TextServer::shaped_text_get_spacing);
+
ClassDB::bind_method(D_METHOD("shaped_text_add_string", "shaped", "text", "fonts", "size", "opentype_features", "language", "meta"), &TextServer::shaped_text_add_string, DEFVAL(Dictionary()), DEFVAL(""), DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("shaped_text_add_object", "shaped", "key", "size", "inline_align", "length"), &TextServer::shaped_text_add_object, DEFVAL(INLINE_ALIGNMENT_CENTER), DEFVAL(1));
ClassDB::bind_method(D_METHOD("shaped_text_resize_object", "shaped", "key", "size", "inline_align"), &TextServer::shaped_text_resize_object, DEFVAL(INLINE_ALIGNMENT_CENTER));
diff --git a/servers/text_server.h b/servers/text_server.h
index 6339dde0ea..0fd35f2ec0 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -161,6 +161,7 @@ public:
SPACING_SPACE,
SPACING_TOP,
SPACING_BOTTOM,
+ SPACING_MAX,
};
enum FontStyle {
@@ -284,9 +285,6 @@ public:
virtual void font_set_scale(const RID &p_font_rid, int64_t p_size, double p_scale) = 0;
virtual double font_get_scale(const RID &p_font_rid, int64_t p_size) const = 0;
- virtual void font_set_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing, int64_t p_value) = 0;
- virtual int64_t font_get_spacing(const RID &p_font_rid, int64_t p_size, SpacingType p_spacing) const = 0;
-
virtual int64_t font_get_texture_count(const RID &p_font_rid, const Vector2i &p_size) const = 0;
virtual void font_clear_textures(const RID &p_font_rid, const Vector2i &p_size) = 0;
virtual void font_remove_texture(const RID &p_font_rid, const Vector2i &p_size, int64_t p_texture_index) = 0;
@@ -386,6 +384,9 @@ public:
virtual void shaped_text_set_preserve_control(const RID &p_shaped, bool p_enabled) = 0;
virtual bool shaped_text_get_preserve_control(const RID &p_shaped) const = 0;
+ virtual void shaped_text_set_spacing(const RID &p_shaped, SpacingType p_spacing, int64_t p_value) = 0;
+ virtual int64_t shaped_text_get_spacing(const RID &p_shaped, SpacingType p_spacing) const = 0;
+
virtual bool shaped_text_add_string(const RID &p_shaped, const String &p_text, const Array &p_fonts, int64_t p_size, const Dictionary &p_opentype_features = Dictionary(), const String &p_language = "", const Variant &p_meta = Variant()) = 0;
virtual bool shaped_text_add_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER, int64_t p_length = 1) = 0;
virtual bool shaped_text_resize_object(const RID &p_shaped, const Variant &p_key, const Size2 &p_size, InlineAlignment p_inline_align = INLINE_ALIGNMENT_CENTER) = 0;
diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp
index a0bec0f95b..1f3d07c357 100644
--- a/servers/xr/xr_interface_extension.cpp
+++ b/servers/xr/xr_interface_extension.cpp
@@ -29,9 +29,7 @@
/*************************************************************************/
#include "xr_interface_extension.h"
-#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
-#include "servers/rendering/renderer_storage.h"
#include "servers/rendering/rendering_server_globals.h"
void XRInterfaceExtension::_bind_methods() {