diff options
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; |