summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/string/string_name.cpp16
-rw-r--r--doc/classes/EditorExportPlugin.xml1
-rw-r--r--editor/editor_export.cpp59
-rw-r--r--editor/editor_export.h16
-rw-r--r--editor/editor_node.cpp6
-rw-r--r--editor/editor_spin_slider.cpp1
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--editor/plugins/gdextension_export_plugin.h138
-rw-r--r--main/main.cpp1
-rw-r--r--misc/dist/shell/_godot.zsh-completion1
-rw-r--r--misc/dist/shell/godot.bash-completion1
-rw-r--r--misc/dist/shell/godot.fish1
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs4
-rw-r--r--platform/android/export/export_plugin.cpp14
-rw-r--r--platform/android/export/export_plugin.h2
-rw-r--r--platform/iphone/export/export_plugin.cpp2
-rw-r--r--platform/javascript/export/export_plugin.cpp2
-rw-r--r--platform/osx/export/export_plugin.cpp35
-rw-r--r--platform/osx/export/export_plugin.h2
-rw-r--r--platform/uwp/export/export_plugin.cpp2
-rw-r--r--scene/gui/popup_menu.cpp4
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp63
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h8
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp31
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h12
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl34
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl10
27 files changed, 382 insertions, 86 deletions
diff --git a/core/string/string_name.cpp b/core/string/string_name.cpp
index 11674629fc..2e941b8037 100644
--- a/core/string/string_name.cpp
+++ b/core/string/string_name.cpp
@@ -73,11 +73,23 @@ void StringName::cleanup() {
d = d->next;
}
}
- print_line("\nStringName Reference Ranking:\n");
+
+ print_line("\nStringName reference ranking (from most to least referenced):\n");
+
data.sort_custom<DebugSortReferences>();
- for (int i = 0; i < MIN(100, data.size()); i++) {
+ int unreferenced_stringnames = 0;
+ int rarely_referenced_stringnames = 0;
+ for (int i = 0; i < data.size(); i++) {
print_line(itos(i + 1) + ": " + data[i]->get_name() + " - " + itos(data[i]->debug_references));
+ if (data[i]->debug_references == 0) {
+ unreferenced_stringnames += 1;
+ } else if (data[i]->debug_references < 5) {
+ rarely_referenced_stringnames += 1;
+ }
}
+
+ print_line(vformat("\nOut of %d StringNames, %d StringNames were never referenced during this run (0 times) (%.2f%%).", data.size(), unreferenced_stringnames, unreferenced_stringnames / float(data.size()) * 100));
+ print_line(vformat("Out of %d StringNames, %d StringNames were rarely referenced during this run (1-4 times) (%.2f%%).", data.size(), rarely_referenced_stringnames, rarely_referenced_stringnames / float(data.size()) * 100));
}
#endif
int lost_strings = 0;
diff --git a/doc/classes/EditorExportPlugin.xml b/doc/classes/EditorExportPlugin.xml
index 698d3bfcce..8aa2db2cf8 100644
--- a/doc/classes/EditorExportPlugin.xml
+++ b/doc/classes/EditorExportPlugin.xml
@@ -108,6 +108,7 @@
<return type="void" />
<argument index="0" name="path" type="String" />
<argument index="1" name="tags" type="PackedStringArray" />
+ <argument index="2" name="target" type="String" />
<description>
Adds a shared object or a directory containing only shared objects with the given [code]tags[/code] and destination [code]path[/code].
[b]Note:[/b] In case of macOS exports, those shared objects will be added to [code]Frameworks[/code] directory of app bundle.
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index c3c8f40164..02495252bc 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -566,8 +566,8 @@ void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p
extra_files.push_back(ef);
}
-void EditorExportPlugin::add_shared_object(const String &p_path, const Vector<String> &tags) {
- shared_objects.push_back(SharedObject(p_path, tags));
+void EditorExportPlugin::add_shared_object(const String &p_path, const Vector<String> &p_tags, const String &p_target) {
+ shared_objects.push_back(SharedObject(p_path, p_tags, p_target));
}
void EditorExportPlugin::add_ios_framework(const String &p_path) {
@@ -660,7 +660,7 @@ void EditorExportPlugin::skip() {
}
void EditorExportPlugin::_bind_methods() {
- ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags"), &EditorExportPlugin::add_shared_object);
+ ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags", "target"), &EditorExportPlugin::add_shared_object);
ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_ios_project_static_lib);
ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file);
ClassDB::bind_method(D_METHOD("add_ios_framework", "path"), &EditorExportPlugin::add_ios_framework);
@@ -680,7 +680,7 @@ void EditorExportPlugin::_bind_methods() {
EditorExportPlugin::EditorExportPlugin() {
}
-EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_containers(const Ref<EditorExportPreset> &p_preset) {
+EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug) {
Ref<EditorExportPlatform> platform = p_preset->get_platform();
List<String> feature_list;
platform->get_platform_features(&feature_list);
@@ -692,6 +692,14 @@ EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_contai
result.features_pv.push_back(E);
}
+ if (p_debug) {
+ result.features.insert("debug");
+ result.features_pv.push_back("debug");
+ } else {
+ result.features.insert("release");
+ result.features_pv.push_back("release");
+ }
+
if (!p_preset->get_custom_features().is_empty()) {
Vector<String> tmp_custom_list = p_preset->get_custom_features().split(",");
@@ -708,7 +716,7 @@ EditorExportPlatform::FeatureContainers EditorExportPlatform::get_feature_contai
}
EditorExportPlatform::ExportNotifier::ExportNotifier(EditorExportPlatform &p_platform, const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
- FeatureContainers features = p_platform.get_feature_containers(p_preset);
+ FeatureContainers features = p_platform.get_feature_containers(p_preset, p_debug);
Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
//initial export plugin callback
for (int i = 0; i < export_plugins.size(); i++) {
@@ -730,7 +738,7 @@ EditorExportPlatform::ExportNotifier::~ExportNotifier() {
}
}
-Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) {
+Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func) {
//figure out paths of files that will be exported
Set<String> paths;
Vector<String> path_remaps;
@@ -864,7 +872,7 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
export_plugins.write[i]->_clear();
}
- FeatureContainers feature_containers = get_feature_containers(p_preset);
+ FeatureContainers feature_containers = get_feature_containers(p_preset, p_debug);
Set<String> &features = feature_containers.features;
Vector<String> &features_pv = feature_containers.features_pv;
@@ -1118,7 +1126,7 @@ Error EditorExportPlatform::_add_shared_object(void *p_userdata, const SharedObj
return OK;
}
-Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) {
+Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files, bool p_embed, int64_t *r_embedded_start, int64_t *r_embedded_size) {
EditorProgress ep("savepack", TTR("Packing"), 102, true);
// Create the temporary export directory if it doesn't exist.
@@ -1134,7 +1142,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
pd.f = ftmp;
pd.so_files = p_so_files;
- Error err = export_project_files(p_preset, _save_pack_file, &pd, _add_shared_object);
+ Error err = export_project_files(p_preset, p_debug, _save_pack_file, &pd, _add_shared_object);
memdelete(ftmp); //close tmp file
@@ -1324,7 +1332,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
return OK;
}
-Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
+Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) {
EditorProgress ep("savezip", TTR("Packing"), 102, true);
FileAccess *src_f;
@@ -1335,7 +1343,7 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co
zd.ep = &ep;
zd.zip = zip;
- Error err = export_project_files(p_preset, _save_zip_file, &zd);
+ Error err = export_project_files(p_preset, p_debug, _save_zip_file, &zd);
if (err != OK && err != ERR_SKIP) {
ERR_PRINT("Failed to export project files");
}
@@ -1347,12 +1355,12 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co
Error EditorExportPlatform::export_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
- return save_pack(p_preset, p_path);
+ return save_pack(p_preset, p_debug, p_path);
}
Error EditorExportPlatform::export_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags);
- return save_zip(p_preset, p_path);
+ return save_zip(p_preset, p_debug, p_path);
}
void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags) {
@@ -1873,7 +1881,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
int64_t embedded_pos;
int64_t embedded_size;
- err = save_pack(p_preset, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size);
+ err = save_pack(p_preset, p_debug, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size);
if (err == OK && p_preset->get("binary_format/embed_pck")) {
if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) {
EditorNode::get_singleton()->show_warning(TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."));
@@ -1887,12 +1895,27 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr
}
if (err == OK && !so_files.is_empty()) {
- //if shared object files, copy them
+ // If shared object files, copy them.
da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
for (int i = 0; i < so_files.size() && err == OK; i++) {
- err = da->copy(so_files[i].path, p_path.get_base_dir().plus_file(so_files[i].path.get_file()));
- if (err == OK) {
- err = sign_shared_object(p_preset, p_debug, p_path.get_base_dir().plus_file(so_files[i].path.get_file()));
+ String src_path = ProjectSettings::get_singleton()->globalize_path(so_files[i].path);
+ String target_path;
+ if (so_files[i].target.is_empty()) {
+ target_path = p_path.get_base_dir().plus_file(src_path.get_file());
+ } else {
+ target_path = p_path.get_base_dir().plus_file(so_files[i].target).plus_file(src_path.get_file());
+ }
+
+ if (da->dir_exists(src_path)) {
+ err = da->make_dir_recursive(target_path);
+ if (err == OK) {
+ err = da->copy_dir(src_path, target_path, -1, true);
+ }
+ } else {
+ err = da->copy(src_path, target_path);
+ if (err == OK) {
+ err = sign_shared_object(p_preset, p_debug, target_path);
+ }
}
}
}
diff --git a/editor/editor_export.h b/editor/editor_export.h
index 182312b18f..d9039f601e 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -152,10 +152,12 @@ public:
struct SharedObject {
String path;
Vector<String> tags;
+ String target;
- SharedObject(const String &p_path, const Vector<String> &p_tags) :
+ SharedObject(const String &p_path, const Vector<String> &p_tags, const String &p_target) :
path(p_path),
- tags(p_tags) {
+ tags(p_tags),
+ target(p_target) {
}
SharedObject() {}
@@ -216,7 +218,7 @@ protected:
~ExportNotifier();
};
- FeatureContainers get_feature_containers(const Ref<EditorExportPreset> &p_preset);
+ FeatureContainers get_feature_containers(const Ref<EditorExportPreset> &p_preset, bool p_debug);
bool exists_export_template(String template_file_name, String *err) const;
String find_export_template(String template_file_name, String *err = nullptr) const;
@@ -246,10 +248,10 @@ public:
virtual String get_name() const = 0;
virtual Ref<Texture2D> get_logo() const = 0;
- Error export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr);
+ Error export_project_files(const Ref<EditorExportPreset> &p_preset, bool p_debug, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = nullptr);
- Error save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr);
- Error save_zip(const Ref<EditorExportPreset> &p_preset, const String &p_path);
+ Error save_pack(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, Vector<SharedObject> *p_so_files = nullptr, bool p_embed = false, int64_t *r_embedded_start = nullptr, int64_t *r_embedded_size = nullptr);
+ Error save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path);
virtual bool poll_export() { return false; }
virtual int get_options_count() const { return 0; }
@@ -334,7 +336,7 @@ protected:
Ref<EditorExportPreset> get_export_preset() const;
void add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap);
- void add_shared_object(const String &p_path, const Vector<String> &tags);
+ void add_shared_object(const String &p_path, const Vector<String> &tags, const String &p_target = String());
void add_ios_framework(const String &p_path);
void add_ios_embedded_framework(const String &p_path);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 7251530fdc..b6a7e51807 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -146,6 +146,7 @@
#include "editor/plugins/editor_debugger_plugin.h"
#include "editor/plugins/editor_preview_plugins.h"
#include "editor/plugins/font_editor_plugin.h"
+#include "editor/plugins/gdextension_export_plugin.h"
#include "editor/plugins/gpu_particles_2d_editor_plugin.h"
#include "editor/plugins/gpu_particles_3d_editor_plugin.h"
#include "editor/plugins/gpu_particles_collision_sdf_editor_plugin.h"
@@ -7094,6 +7095,11 @@ EditorNode::EditorNode() {
EditorExport::get_singleton()->add_export_plugin(export_text_to_binary_plugin);
+ Ref<GDExtensionExportPlugin> gdextension_export_plugin;
+ gdextension_export_plugin.instantiate();
+
+ EditorExport::get_singleton()->add_export_plugin(gdextension_export_plugin);
+
Ref<PackedSceneEditorTranslationParserPlugin> packed_scene_translation_parser_plugin;
packed_scene_translation_parser_plugin.instantiate();
EditorTranslationParser::get_singleton()->add_parser(packed_scene_translation_parser_plugin, EditorTranslationParser::STANDARD);
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index ef34f13d45..2fd4f3d6e6 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -443,6 +443,7 @@ void EditorSpinSlider::_notification(int p_what) {
case NOTIFICATION_WM_WINDOW_FOCUS_IN:
case NOTIFICATION_WM_WINDOW_FOCUS_OUT:
+ case NOTIFICATION_WM_CLOSE_REQUEST:
case NOTIFICATION_EXIT_TREE: {
if (grabbing_spinner) {
grabber->hide();
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index d74499621d..d713e70251 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -2216,7 +2216,7 @@ bool CanvasItemEditor::_gui_input_select(const Ref<InputEvent> &p_event) {
Ref<InputEventKey> k = p_event;
if (drag_type == DRAG_NONE) {
- if (b.is_valid() &&
+ if (b.is_valid() && b->is_pressed() &&
((b->get_button_index() == MouseButton::RIGHT && b->is_alt_pressed() && tool == TOOL_SELECT) ||
(b->get_button_index() == MouseButton::LEFT && tool == TOOL_LIST_SELECT))) {
// Popup the selection menu list
diff --git a/editor/plugins/gdextension_export_plugin.h b/editor/plugins/gdextension_export_plugin.h
new file mode 100644
index 0000000000..8ed72b1c42
--- /dev/null
+++ b/editor/plugins/gdextension_export_plugin.h
@@ -0,0 +1,138 @@
+/*************************************************************************/
+/* gdextension_export_plugin.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 GDEXTENSION_EXPORT_PLUGIN_H
+#define GDEXTENSION_EXPORT_PLUGIN_H
+
+#include "editor/editor_export.h"
+
+class GDExtensionExportPlugin : public EditorExportPlugin {
+protected:
+ virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features);
+};
+
+void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p_type, const Set<String> &p_features) {
+ if (p_type != "NativeExtension") {
+ return;
+ }
+
+ Ref<ConfigFile> config;
+ config.instantiate();
+
+ Error err = config->load(p_path);
+
+ if (err != OK) {
+ return;
+ }
+
+ if (!config->has_section_key("configuration", "entry_symbol")) {
+ return;
+ }
+
+ String entry_symbol = config->get_value("configuration", "entry_symbol");
+
+ List<String> libraries;
+
+ config->get_section_keys("libraries", &libraries);
+
+ for (const String &E : libraries) {
+ Vector<String> tags = E.split(".");
+ bool all_tags_met = true;
+ for (int i = 0; i < tags.size(); i++) {
+ String tag = tags[i].strip_edges();
+ if (!p_features.has(tag)) {
+ all_tags_met = false;
+ break;
+ }
+ }
+
+ if (all_tags_met) {
+ String library_path = config->get_value("libraries", E);
+ if (!library_path.begins_with("res://")) {
+ print_line("Skipping export of out-of-project library " + library_path);
+ continue;
+ }
+ add_shared_object(library_path, tags);
+
+ if (p_features.has("iOS") && (library_path.ends_with(".a") || library_path.ends_with(".xcframework"))) {
+ String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n"
+ "extern void add_ios_init_callback(void (*cb)());\n"
+ "\n"
+ "extern \"C\" void $ENTRY();\n"
+ "void $ENTRY_init() {\n"
+ " if (&$ENTRY) register_dynamic_symbol((char *)\"$ENTRY\", (void *)$ENTRY);\n"
+ "}\n"
+ "struct $ENTRY_struct {\n"
+ " $ENTRY_struct() {\n"
+ " add_ios_init_callback($ENTRY_init);\n"
+ " }\n"
+ "};\n"
+ "$ENTRY_struct $ENTRY_struct_instance;\n\n";
+ additional_code = additional_code.replace("$ENTRY", entry_symbol);
+ add_ios_cpp_code(additional_code);
+
+ String linker_flags = "-Wl,-U,_" + entry_symbol;
+ add_ios_linker_flags(linker_flags);
+ }
+ break;
+ }
+ }
+
+ List<String> dependencies;
+
+ config->get_section_keys("dependencies", &dependencies);
+ for (const String &E : libraries) {
+ Vector<String> tags = E.split(".");
+ bool all_tags_met = true;
+ for (int i = 0; i < tags.size(); i++) {
+ String tag = tags[i].strip_edges();
+ if (!p_features.has(tag)) {
+ all_tags_met = false;
+ break;
+ }
+ }
+
+ if (all_tags_met) {
+ Dictionary dependency = config->get_value("dependencies", E);
+ for (const Variant *key = dependency.next(nullptr); key; key = dependency.next(key)) {
+ String library_path = *key;
+ String target_path = dependency[*key];
+ if (!library_path.begins_with("res://")) {
+ print_line("Skipping export of out-of-project library " + library_path);
+ continue;
+ }
+ add_shared_object(library_path, tags, target_path);
+ }
+ break;
+ }
+ }
+}
+
+#endif // GDEXTENSION_EXPORT_PLUGIN_H
diff --git a/main/main.cpp b/main/main.cpp
index e0331f4945..f0e74c3bb7 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -348,6 +348,7 @@ void Main::print_help(const char *p_binary) {
#if defined(DEBUG_ENABLED)
OS::get_singleton()->print(" --debug-collisions Show collision shapes when running the scene.\n");
OS::get_singleton()->print(" --debug-navigation Show navigation polygons when running the scene.\n");
+ OS::get_singleton()->print(" --debug-stringnames Print all StringName allocations to stdout when the engine quits.\n");
#endif
OS::get_singleton()->print(" --frame-delay <ms> Simulate high CPU load (delay each frame by <ms> milliseconds).\n");
OS::get_singleton()->print(" --time-scale <scale> Force time scale (higher values are faster, 1.0 is normal speed).\n");
diff --git a/misc/dist/shell/_godot.zsh-completion b/misc/dist/shell/_godot.zsh-completion
index 98ab41ac58..aaa5fe0a06 100644
--- a/misc/dist/shell/_godot.zsh-completion
+++ b/misc/dist/shell/_godot.zsh-completion
@@ -66,6 +66,7 @@ _arguments \
'--remote-debug[enable remote debugging]:remote debugger address' \
'--debug-collisions[show collision shapes when running the scene]' \
'--debug-navigation[show navigation polygons when running the scene]' \
+ '--debug-stringnames[print all StringName allocations to stdout when the engine quits]' \
'--frame-delay[simulate high CPU load (delay each frame by the given number of milliseconds)]:number of milliseconds' \
'--time-scale[force time scale (higher values are faster, 1.0 is normal speed)]:time scale' \
'--disable-render-loop[disable render loop so rendering only occurs when called explicitly from script]' \
diff --git a/misc/dist/shell/godot.bash-completion b/misc/dist/shell/godot.bash-completion
index 5784e15c6e..7927d26171 100644
--- a/misc/dist/shell/godot.bash-completion
+++ b/misc/dist/shell/godot.bash-completion
@@ -69,6 +69,7 @@ _complete_godot_options() {
--remote-debug
--debug-collisions
--debug-navigation
+--debug-stringnames
--frame-delay
--time-scale
--disable-render-loop
diff --git a/misc/dist/shell/godot.fish b/misc/dist/shell/godot.fish
index 880851dd23..c05aa74017 100644
--- a/misc/dist/shell/godot.fish
+++ b/misc/dist/shell/godot.fish
@@ -79,6 +79,7 @@ complete -c godot -l gpu-abort -d "Abort on GPU errors (usually validation layer
complete -c godot -l remote-debug -d "Enable remote debugging"
complete -c godot -l debug-collisions -d "Show collision shapes when running the scene"
complete -c godot -l debug-navigation -d "Show navigation polygons when running the scene"
+complete -c godot -l debug-stringnames -d "Print all StringName allocations to stdout when the engine quits"
complete -c godot -l frame-delay -d "Simulate high CPU load (delay each frame by the given number of milliseconds)" -x
complete -c godot -l time-scale -d "Force time scale (higher values are faster, 1.0 is normal speed)" -x
complete -c godot -l disable-render-loop -d "Disable render loop so rendering only occurs when called explicitly from script"
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
index ed758cc137..e2f4d2f5fd 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/AotBuilder.cs
@@ -107,7 +107,7 @@ namespace GodotTools.Export
ExecuteCompiler(FindCrossCompiler(compilerDirPath), compilerArgs, bclDir);
// The Godot exporter expects us to pass the abi in the tags parameter
- exporter.AddSharedObject(soFilePath, tags: new[] { abi });
+ exporter.AddSharedObject(soFilePath, tags: new[] { abi }, "");
}
}
}
@@ -134,7 +134,7 @@ namespace GodotTools.Export
if (platform == OS.Platforms.MacOS)
{
- exporter.AddSharedObject(tempOutputFilePath, tags: null);
+ exporter.AddSharedObject(tempOutputFilePath, tags: null, "");
}
else
{
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 4220c57cae..df3693ba61 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -2256,9 +2256,9 @@ String EditorExportPlatformAndroid::get_apk_expansion_fullpath(const Ref<EditorE
return fullpath;
}
-Error EditorExportPlatformAndroid::save_apk_expansion_file(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
+Error EditorExportPlatformAndroid::save_apk_expansion_file(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) {
String fullpath = get_apk_expansion_fullpath(p_preset, p_path);
- Error err = save_pack(p_preset, fullpath);
+ Error err = save_pack(p_preset, p_debug, fullpath);
return err;
}
@@ -2576,7 +2576,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
CustomExportData user_data;
user_data.assets_directory = assets_directory;
user_data.debug = p_debug;
- err = export_project_files(p_preset, rename_and_store_file_in_gradle_project, &user_data, copy_gradle_so);
+ err = export_project_files(p_preset, p_debug, rename_and_store_file_in_gradle_project, &user_data, copy_gradle_so);
if (err != OK) {
EditorNode::add_io_error(TTR("Could not export project files to gradle project\n"));
return err;
@@ -2589,7 +2589,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
}
} else {
print_verbose("Saving apk expansion file..");
- err = save_apk_expansion_file(p_preset, p_path);
+ err = save_apk_expansion_file(p_preset, p_debug, p_path);
if (err != OK) {
EditorNode::add_io_error(TTR("Could not write expansion package file!"));
return err;
@@ -2915,10 +2915,10 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
APKExportData ed;
ed.ep = &ep;
ed.apk = unaligned_apk;
- err = export_project_files(p_preset, ignore_apk_file, &ed, save_apk_so);
+ err = export_project_files(p_preset, p_debug, ignore_apk_file, &ed, save_apk_so);
} else {
if (apk_expansion) {
- err = save_apk_expansion_file(p_preset, p_path);
+ err = save_apk_expansion_file(p_preset, p_debug, p_path);
if (err != OK) {
EditorNode::add_io_error(TTR("Could not write expansion package file!"));
return err;
@@ -2927,7 +2927,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
APKExportData ed;
ed.ep = &ep;
ed.apk = unaligned_apk;
- err = export_project_files(p_preset, save_apk_file, &ed, save_apk_so);
+ err = export_project_files(p_preset, p_debug, save_apk_file, &ed, save_apk_so);
}
}
diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h
index a4eb608b19..0f267cf13a 100644
--- a/platform/android/export/export_plugin.h
+++ b/platform/android/export/export_plugin.h
@@ -210,7 +210,7 @@ public:
String get_apk_expansion_fullpath(const Ref<EditorExportPreset> &p_preset, const String &p_path);
- Error save_apk_expansion_file(const Ref<EditorExportPreset> &p_preset, const String &p_path);
+ Error save_apk_expansion_file(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path);
void get_command_line_flags(const Ref<EditorExportPreset> &p_preset, const String &p_path, int p_flags, Vector<uint8_t> &r_command_line_flags);
diff --git a/platform/iphone/export/export_plugin.cpp b/platform/iphone/export/export_plugin.cpp
index 26c5acb13e..ac5886e620 100644
--- a/platform/iphone/export/export_plugin.cpp
+++ b/platform/iphone/export/export_plugin.cpp
@@ -1440,7 +1440,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
}
String pack_path = dest_dir + binary_name + ".pck";
Vector<SharedObject> libraries;
- Error err = save_pack(p_preset, pack_path, &libraries);
+ Error err = save_pack(p_preset, p_debug, pack_path, &libraries);
if (err) {
return err;
}
diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp
index e7855acf60..4448acccc2 100644
--- a/platform/javascript/export/export_plugin.cpp
+++ b/platform/javascript/export/export_plugin.cpp
@@ -440,7 +440,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
// Export pck and shared objects
Vector<SharedObject> shared_objects;
String pck_path = base_path + ".pck";
- Error error = save_pack(p_preset, pck_path, &shared_objects);
+ Error error = save_pack(p_preset, p_debug, pck_path, &shared_objects);
if (error != OK) {
EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + pck_path);
return error;
diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp
index 0f4477d312..890e66ffd5 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/osx/export/export_plugin.cpp
@@ -458,7 +458,7 @@ Error EditorExportPlatformOSX::_notarize(const Ref<EditorExportPreset> &p_preset
return OK;
}
-Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path) {
+Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn) {
bool force_builtin_codesign = EditorSettings::get_singleton()->get("export/macos/force_builtin_codesign");
bool ad_hoc = (p_preset->get("codesign/identity") == "" || p_preset->get("codesign/identity") == "-");
@@ -467,10 +467,10 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
#ifdef MODULE_REGEX_ENABLED
#ifdef OSX_ENABLED
- if (p_preset->get("codesign/timestamp")) {
+ if (p_preset->get("codesign/timestamp") && p_warn) {
WARN_PRINT("Timestamping is not compatible with ad-hoc signature, and was disabled!");
}
- if (p_preset->get("codesign/hardened_runtime")) {
+ if (p_preset->get("codesign/hardened_runtime") && p_warn) {
WARN_PRINT("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!");
}
#endif
@@ -490,14 +490,18 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
List<String> args;
if (p_preset->get("codesign/timestamp")) {
if (ad_hoc) {
- WARN_PRINT("Timestamping is not compatible with ad-hoc signature, and was disabled!");
+ if (p_warn) {
+ WARN_PRINT("Timestamping is not compatible with ad-hoc signature, and was disabled!");
+ }
} else {
args.push_back("--timestamp");
}
}
if (p_preset->get("codesign/hardened_runtime")) {
if (ad_hoc) {
- WARN_PRINT("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!");
+ if (p_warn) {
+ WARN_PRINT("Hardened Runtime is not compatible with ad-hoc signature, and was disabled!");
+ }
} else {
args.push_back("--options");
args.push_back("runtime");
@@ -577,7 +581,7 @@ Error EditorExportPlatformOSX::_code_sign_directory(const Ref<EditorExportPreset
}
if (extensions_to_sign.find(current_file.get_extension()) > -1) {
- Error code_sign_error{ _code_sign(p_preset, current_file_path, p_ent_path) };
+ Error code_sign_error{ _code_sign(p_preset, current_file_path, p_ent_path, false) };
if (code_sign_error != OK) {
return code_sign_error;
}
@@ -621,7 +625,7 @@ Error EditorExportPlatformOSX::_copy_and_sign_files(DirAccessRef &dir_access, co
// If it is a directory, find and sign all dynamic libraries.
err = _code_sign_directory(p_preset, p_in_app_path, p_ent_path, p_should_error_on_non_code_sign);
} else {
- err = _code_sign(p_preset, p_in_app_path, p_ent_path);
+ err = _code_sign(p_preset, p_in_app_path, p_ent_path, false);
}
}
return err;
@@ -1046,7 +1050,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck";
Vector<SharedObject> shared_objects;
- err = save_pack(p_preset, pack_path, &shared_objects);
+ err = save_pack(p_preset, p_debug, pack_path, &shared_objects);
// See if we can code sign our new package.
bool sign_enabled = p_preset->get("codesign/enable");
@@ -1213,7 +1217,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
String hlp_path = helpers[i];
err = da->copy(hlp_path, tmp_app_path_name + "/Contents/Helpers/" + hlp_path.get_file());
if (err == OK && sign_enabled) {
- err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Helpers/" + hlp_path.get_file(), hlp_ent_path);
+ err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Helpers/" + hlp_path.get_file(), hlp_ent_path, false);
}
FileAccess::set_unix_permissions(tmp_app_path_name + "/Contents/Helpers/" + hlp_path.get_file(), 0755);
}
@@ -1238,8 +1242,13 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
for (int i = 0; i < shared_objects.size(); i++) {
String src_path = ProjectSettings::get_singleton()->globalize_path(shared_objects[i].path);
- String path_in_app{ tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file() };
- err = _copy_and_sign_files(da, src_path, path_in_app, sign_enabled, p_preset, ent_path, true);
+ if (shared_objects[i].target.is_empty()) {
+ String path_in_app = tmp_app_path_name + "/Contents/Frameworks/" + src_path.get_file();
+ err = _copy_and_sign_files(da, src_path, path_in_app, sign_enabled, p_preset, ent_path, true);
+ } else {
+ String path_in_app = tmp_app_path_name.plus_file(shared_objects[i].target).plus_file(src_path.get_file());
+ err = _copy_and_sign_files(da, src_path, path_in_app, sign_enabled, p_preset, ent_path, false);
+ }
if (err != OK) {
break;
}
@@ -1257,7 +1266,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (sign_enabled) {
for (int i = 0; i < dylibs_found.size(); i++) {
if (err == OK) {
- err = _code_sign(p_preset, tmp_app_path_name + "/" + dylibs_found[i], ent_path);
+ err = _code_sign(p_preset, tmp_app_path_name + "/" + dylibs_found[i], ent_path, false);
}
}
}
@@ -1282,7 +1291,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (ep.step(TTR("Code signing DMG"), 3)) {
return ERR_SKIP;
}
- err = _code_sign(p_preset, p_path, ent_path);
+ err = _code_sign(p_preset, p_path, ent_path, false);
}
} else if (export_format == "zip") {
// Create ZIP.
diff --git a/platform/osx/export/export_plugin.h b/platform/osx/export/export_plugin.h
index b85e9d662c..20cdd33f86 100644
--- a/platform/osx/export/export_plugin.h
+++ b/platform/osx/export/export_plugin.h
@@ -56,7 +56,7 @@ class EditorExportPlatformOSX : public EditorExportPlatform {
void _make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data);
Error _notarize(const Ref<EditorExportPreset> &p_preset, const String &p_path);
- Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path);
+ Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_warn = true);
Error _code_sign_directory(const Ref<EditorExportPreset> &p_preset, const String &p_path, const String &p_ent_path, bool p_should_error_on_non_code = true);
Error _copy_and_sign_files(DirAccessRef &dir_access, const String &p_src_path, const String &p_in_app_path,
bool p_sign_enabled, const Ref<EditorExportPreset> &p_preset, const String &p_ent_path,
diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp
index a76ff042b2..230e5c749c 100644
--- a/platform/uwp/export/export_plugin.cpp
+++ b/platform/uwp/export/export_plugin.cpp
@@ -416,7 +416,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p
EditorNode::progress_add_task("project_files", "Project Files", 100);
packager.set_progress_task("project_files");
- err = export_project_files(p_preset, save_appx_file, &packager);
+ err = export_project_files(p_preset, p_debug, save_appx_file, &packager);
EditorNode::progress_end_task("project_files");
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 4220066b20..9fc1fb072c 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -1003,8 +1003,12 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) {
p_idx += get_item_count();
}
ERR_FAIL_INDEX(p_idx, items.size());
+ if (items[p_idx].text == p_text) {
+ return;
+ }
items.write[p_idx].text = p_text;
items.write[p_idx].xl_text = atr(p_text);
+ items.write[p_idx].dirty = true;
_shape_item(p_idx);
control->update();
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 6b500260ef..f1bd179f44 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -187,12 +187,11 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) {
clear();
- ERR_FAIL_COND_MSG(p_view_count != 1, "Multiple views is currently not supported in this renderer, please use the mobile renderer for VR support");
-
msaa = p_msaa;
width = p_width;
height = p_height;
+ view_count = p_view_count;
color = p_color_buffer;
depth = p_depth_buffer;
@@ -203,20 +202,25 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
fb.push_back(p_color_buffer);
fb.push_back(depth);
- color_fb = RD::get_singleton()->framebuffer_create(fb);
+ color_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
}
{
Vector<RID> fb;
fb.push_back(depth);
- depth_fb = RD::get_singleton()->framebuffer_create(fb);
+ depth_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
}
} else {
RD::TextureFormat tf;
+ if (view_count > 1) {
+ tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
+ } else {
+ tf.texture_type = RD::TEXTURE_TYPE_2D;
+ }
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = p_width;
tf.height = p_height;
- tf.texture_type = RD::TEXTURE_TYPE_2D;
+ tf.array_layers = view_count; // create a layer for every view
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = {
@@ -241,13 +245,13 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
fb.push_back(color_msaa);
fb.push_back(depth_msaa);
- color_fb = RD::get_singleton()->framebuffer_create(fb);
+ color_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
}
{
Vector<RID> fb;
fb.push_back(depth_msaa);
- depth_fb = RD::get_singleton()->framebuffer_create(fb);
+ depth_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
}
}
}
@@ -417,22 +421,23 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
switch (p_pass_mode) {
case PASS_MODE_COLOR: {
if (element_info.uses_lightmap) {
- pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS;
+ pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS;
} else {
- pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_OPAQUE_PASS;
+ pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_OPAQUE_PASS;
}
} break;
case PASS_MODE_COLOR_TRANSPARENT: {
if (element_info.uses_lightmap) {
- pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS;
+ pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS;
} else {
if (element_info.uses_forward_gi) {
pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_FORWARD_GI;
}
- pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS;
+ pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS;
}
} break;
case PASS_MODE_COLOR_SPECULAR: {
+ ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for specular pass");
if (element_info.uses_lightmap) {
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR;
} else {
@@ -441,21 +446,26 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
} break;
case PASS_MODE_SHADOW:
case PASS_MODE_DEPTH: {
- pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS;
+ 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");
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;
} 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;
} 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: {
+ 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;
}
@@ -605,6 +615,12 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.camera_matrix);
RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.inv_camera_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]);
+ }
+
scene_state.ubo.z_far = p_render_data->z_far;
scene_state.ubo.z_near = p_render_data->z_near;
@@ -1200,8 +1216,6 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps
}
void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
- ERR_FAIL_COND_MSG(p_render_data->view_count != 1, "Multiview is currently not supported in the clustered renderer. Please use the mobile renderer for VR.");
-
RenderBufferDataForwardClustered *render_buffer = nullptr;
if (p_render_data->render_buffers.is_valid()) {
render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers);
@@ -1434,7 +1448,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID());
bool finish_depth = using_ssao || using_sdfgi || using_voxelgi;
- RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold);
+ RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
_render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear);
RD::get_singleton()->draw_command_end_label();
@@ -1492,7 +1506,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
}
RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer;
- RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold);
+ RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
_render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
if (will_continue_color && using_separate_specular) {
// close the specular framebuffer, as it's no longer used
@@ -1538,14 +1552,16 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (draw_sky || draw_sky_fog_only) {
RENDER_TIMESTAMP("Render Sky");
- CameraMatrix projection = p_render_data->cam_projection;
+ RD::get_singleton()->draw_command_begin_label("Draw Sky");
+
if (p_render_data->reflection_probe.is_valid()) {
CameraMatrix correction;
correction.set_depth_correction(true);
- projection = correction * p_render_data->cam_projection;
+ CameraMatrix projection = correction * p_render_data->cam_projection;
+ sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, 1, &projection, p_render_data->cam_transform, time);
+ } else {
+ sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time);
}
- RD::get_singleton()->draw_command_begin_label("Draw Sky");
- sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, 1, &projection, p_render_data->cam_transform, time);
RD::get_singleton()->draw_command_end_label();
}
@@ -1599,7 +1615,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
_setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);
{
- RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR_TRANSPARENT, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold);
+ RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR_TRANSPARENT, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
_render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
}
@@ -1649,6 +1665,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
RenderDataRD render_data;
render_data.cam_projection = p_projection;
render_data.cam_transform = p_transform;
+ render_data.view_projection[0] = p_projection;
render_data.z_far = p_zfar;
render_data.z_near = 0.0;
render_data.cluster_size = 1;
@@ -1720,7 +1737,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) {
for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
- RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
+ RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
_render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect);
}
@@ -1738,6 +1755,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con
RenderDataRD render_data;
render_data.cam_projection = p_cam_projection;
render_data.cam_transform = p_cam_transform;
+ render_data.view_projection[0] = p_cam_projection;
render_data.z_near = 0.0;
render_data.z_far = p_cam_projection.get_z_far();
render_data.cluster_size = 1;
@@ -1776,6 +1794,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform
RenderDataRD render_data;
render_data.cam_projection = p_cam_projection;
render_data.cam_transform = p_cam_transform;
+ render_data.view_projection[0] = p_cam_projection;
render_data.cluster_size = 1;
render_data.cluster_max_elements = 32;
render_data.instances = &p_instances;
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 dd5c719352..a219b98204 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -107,6 +107,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID color_specular_fb;
RID specular_only_fb;
int width, height;
+ uint32_t view_count;
RID render_sdfgi_uniform_set;
void ensure_specular();
@@ -155,6 +156,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
bool reverse_cull = false;
PassMode pass_mode = PASS_MODE_COLOR;
bool no_gi = false;
+ uint32_t view_count = 1;
RID render_pass_uniform_set;
bool force_wireframe = false;
Vector2 uv_offset;
@@ -166,13 +168,14 @@ class RenderForwardClustered : public RendererSceneRenderRD {
uint32_t barrier = RD::BARRIER_MASK_ALL;
bool use_directional_soft_shadow = false;
- RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
+ RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
elements = p_elements;
element_info = p_element_info;
element_count = p_element_count;
reverse_cull = p_reverse_cull;
pass_mode = p_pass_mode;
no_gi = p_no_gi;
+ view_count = p_view_count;
render_pass_uniform_set = p_render_pass_uniform_set;
force_wireframe = p_force_wireframe;
uv_offset = p_uv_offset;
@@ -219,6 +222,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
float camera_matrix[16];
float inv_camera_matrix[16];
+ float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
+ float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
+
float viewport_size[2];
float screen_pixel_size[2];
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 b4def4e11c..217427d515 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
@@ -32,6 +32,7 @@
#include "core/config/project_settings.h"
#include "core/math/math_defs.h"
#include "render_forward_clustered.h"
+#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
using namespace RendererSceneRenderImplementation;
@@ -149,7 +150,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
print_line(gen_code.defines[i]);
}
- Map<String, String>::Element * el = gen_code.code.front();
+ Map<String, String>::Element *el = gen_code.code.front();
while (el) {
print_line("\n**code " + el->key() + ":\n" + el->value());
@@ -282,6 +283,12 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
+
+ SHADER_VERSION_DEPTH_PASS_MULTIVIEW,
+ SHADER_VERSION_COLOR_PASS_MULTIVIEW,
+ SHADER_VERSION_COLOR_PASS_MULTIVIEW,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW,
};
shader_version = shader_version_table[k];
@@ -297,7 +304,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
RD::PipelineMultisampleState multisample_state;
- if (k == PIPELINE_VERSION_TRANSPARENT_PASS || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS) {
+ if (k == PIPELINE_VERSION_TRANSPARENT_PASS || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS || k == PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW) {
if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
multisample_state.enable_alpha_to_coverage = true;
} else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) {
@@ -310,9 +317,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
if (depth_draw == DEPTH_DRAW_OPAQUE) {
depth_stencil.enable_depth_write = false; //alpha does not draw depth
}
- } else if (k == PIPELINE_VERSION_OPAQUE_PASS || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS) {
+ } else if (k == PIPELINE_VERSION_OPAQUE_PASS || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS || k == PIPELINE_VERSION_OPAQUE_PASS_MULTIVIEW || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW) {
blend_state = blend_state_opaque;
- } else if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_DP) {
+ } else if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW || k == PIPELINE_VERSION_DEPTH_PASS_DP) {
//none, leave empty
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
blend_state = blend_state_depth_normal_roughness;
@@ -501,7 +508,18 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
shader_versions.push_back("\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS
shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR
+ // multiview versions of our shaders
+ 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"); // SHADER_VERSION_COLOR_PASS_MULTIVIEW
+ shader_versions.push_back("\n#define USE_MULTIVIEW\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW
+
shader.initialize(shader_versions, p_defines);
+
+ if (!RendererCompositorRD::singleton->is_xr_enabled()) {
+ shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_MULTIVIEW, false);
+ shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_MULTIVIEW, false);
+ shader.set_variant_enabled(SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW, false);
+ }
}
storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs);
@@ -516,7 +534,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.renames["INV_CAMERA_MATRIX"] = "scene_data.inv_camera_matrix";
actions.renames["CAMERA_MATRIX"] = "scene_data.camera_matrix";
actions.renames["PROJECTION_MATRIX"] = "projection_matrix";
- actions.renames["INV_PROJECTION_MATRIX"] = "scene_data.inv_projection_matrix";
+ actions.renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix";
actions.renames["MODELVIEW_MATRIX"] = "modelview";
actions.renames["MODELVIEW_NORMAL_MATRIX"] = "modelview_normal";
@@ -587,8 +605,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.renames["CUSTOM3"] = "custom3_attrib";
actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
- // not implemented but need these just in case code is in the shaders
- actions.renames["VIEW_INDEX"] = "0";
+ actions.renames["VIEW_INDEX"] = "ViewIndex";
actions.renames["VIEW_MONO_LEFT"] = "0";
actions.renames["VIEW_RIGHT"] = "1";
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 33049fad9c..4398517259 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
@@ -55,6 +55,11 @@ public:
SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
SHADER_VERSION_LIGHTMAP_COLOR_PASS,
SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+
+ SHADER_VERSION_DEPTH_PASS_MULTIVIEW,
+ SHADER_VERSION_COLOR_PASS_MULTIVIEW,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW,
+
SHADER_VERSION_MAX
};
@@ -71,6 +76,13 @@ public:
PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS,
PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR,
PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS,
+
+ PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW,
+ PIPELINE_VERSION_OPAQUE_PASS_MULTIVIEW,
+ PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW,
+ PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW,
+ PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW,
+
PIPELINE_VERSION_MAX
};
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index a8648fc96a..f9cee011d2 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -99,6 +99,18 @@ layout(location = 8) out float dp_clip;
layout(location = 9) out flat uint instance_index_interp;
+#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
+
invariant gl_Position;
#GLOBALS
@@ -244,7 +256,13 @@ void main() {
vec4 position;
#endif
+#ifdef USE_MULTIVIEW
+ mat4 projection_matrix = scene_data.projection_matrix_view[ViewIndex];
+ mat4 inv_projection_matrix = scene_data.inv_projection_matrix_view[ViewIndex];
+#else
mat4 projection_matrix = scene_data.projection_matrix;
+ mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
+#endif //USE_MULTIVIEW
//using world coordinates
#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
@@ -421,10 +439,26 @@ layout(location = 8) in float dp_clip;
layout(location = 9) in flat uint instance_index_interp;
+#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
+
//defines to keep compatibility with vertex
#define world_matrix instances.data[instance_index].transform
+#ifdef USE_MULTIVIEW
+#define projection_matrix scene_data.projection_matrix_view[ViewIndex]
+#else
#define projection_matrix scene_data.projection_matrix
+#endif
#if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE)
//both required for transmittance to be enabled
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 3b110aded2..2e31503669 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
@@ -2,6 +2,7 @@
#define ROUGHNESS_MAX_LOD 5
#define MAX_VOXEL_GI_INSTANCES 8
+#define MAX_VIEWS 2
#if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic)
@@ -12,6 +13,10 @@
#endif
+#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview)
+#extension GL_EXT_multiview : enable
+#endif
+
#include "cluster_data_inc.glsl"
#include "decal_data_inc.glsl"
@@ -169,10 +174,13 @@ sdfgi;
layout(set = 1, binding = 0, std140) uniform SceneData {
mat4 projection_matrix;
mat4 inv_projection_matrix;
-
mat4 camera_matrix;
mat4 inv_camera_matrix;
+ // only used for multiview
+ mat4 projection_matrix_view[MAX_VIEWS];
+ mat4 inv_projection_matrix_view[MAX_VIEWS];
+
vec2 viewport_size;
vec2 screen_pixel_size;