diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0911ff98bf22..a1d406ff92de 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -36,6 +36,7 @@ doc_classes/* @godotengine/documentation /drivers/xaudio2/ @godotengine/audio ## Rendering +/drivers/d3d12/ @godotengine/rendering /drivers/dummy/ @godotengine/rendering /drivers/gles3/ @godotengine/rendering /drivers/spirv-reflect/ @godotengine/rendering @@ -51,12 +52,14 @@ doc_classes/* @godotengine/documentation # Editor /editor/*debugger* @godotengine/debugger +/editor/gui/ @godotengine/usability @godotengine/gui-nodes /editor/icons/ @godotengine/usability /editor/import/ @godotengine/import /editor/plugins/*2d_*.* @godotengine/2d-editor /editor/plugins/*3d_*.* @godotengine/3d-editor /editor/plugins/script_*.* @godotengine/script-editor /editor/plugins/*shader*.* @godotengine/shaders +/editor/themes/ @godotengine/usability @godotengine/gui-nodes /editor/code_editor.* @godotengine/script-editor /editor/*dock*.* @godotengine/docks /editor/*shader*.* @godotengine/shaders diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 449d2159f1d2..d1fafec50d8a 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -5,19 +5,25 @@ body: - type: markdown attributes: value: | - - When reporting bugs, you'll make our life simpler (and the fix will come sooner) if you follow the guidelines in this template. + When reporting bugs, please follow the guidelines in this template. This helps identify the problem precisely and thus enables contributors to fix it faster. - Write a descriptive issue title above. - The golden rule is to **always open *one* issue for *one* bug**. If you notice several bugs and want to report them, make sure to create one new issue for each of them. - Search [open](https://github.com/godotengine/godot/issues) and [closed](https://github.com/godotengine/godot/issues?q=is%3Aissue+is%3Aclosed) issues to ensure it has not already been reported. If you don't find a relevant match or if you're unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate. - - Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/stable/about/release_policy.html). + - Verify that you are using a [supported Godot version](https://docs.godotengine.org/en/latest/about/release_policy.html). Please always check if your issue is reproducible in the latest version – it may already have been fixed! + - If you use a custom build, please test if your issue is reproducible in official builds too. Likewise if you use any C++ modules, GDExtensions, or editor plugins, you should check if the bug is reproducible in a project without these. -- type: input +- type: textarea attributes: - label: Godot version - description: > - Specify the Godot version, including the Git commit hash if using a development or non-official build. The exact Godot version (including the commit hash) can be copied by clicking the version shown in the editor (bottom bar) or in the project manager (top bar). - If you use a custom build, please test if your issue is reproducible in official builds too. - placeholder: 3.5.stable, 4.0.dev [3041becc6] + label: Tested versions + description: | + To properly fix a bug, we need to identify if the bug was recently introduced in the engine, or if it was always present. + - Please specify the Godot version you found the issue in, including the **Git commit hash** if using a development or non-official build. The exact Godot version (including the commit hash) can be copied by clicking the version shown in the editor (bottom bar) or in the project manager (top bar). + - If you can, **please test earlier Godot versions** (previous stable branch, and development snapshots of the current feature release) and, if applicable, newer versions (development snapshots for the next feature release). Mention whether the bug is reproducible or not in the versions you tested. You can find all Godot releases in our [download archive](https://godotengine.org/download/archive/). + - The aim is for us to identify whether a bug is a **regression**, i.e. an issue that didn't exist in a previous version, but was introduced later on, breaking existing functionality. For example, if a bug is reproducible in 4.2.stable but not in 4.1.stable, we would like you to test intermediate 4.2 dev and beta snapshots to find which snapshot is the first one where the issue can be reproduced. + placeholder: | + + - Reproducible in: 4.3.dev [d76c1d0e5], 4.2.stable, 4.2.dev5 and later 4.2 snapshots. + - Not reproducible in: 4.1.3.stable, 4.2.dev4 and earlier 4.2 snapshots. validations: required: true @@ -54,12 +60,12 @@ body: - type: textarea attributes: - label: Minimal reproduction project + label: Minimal reproduction project (MRP) description: | - A small Godot project which reproduces the issue, with no unnecessary files included. Be sure to not include the `.godot` folder in the archive (but keep `project.godot`). - - Required, unless the reproduction steps are trivial and don't require any project files to be followed. In this case, write "N/A" in the field. - - Drag and drop a ZIP archive to upload it. **Do not select another field until the project is done uploading.** + - Having an MRP is very important for contributors to be able to reproduce the bug in the same way that you are experiencing it. When testing a potential fix for the issue, contributors will use the MRP to validate that the fix is working as intended. + - If the reproduction steps are not project dependent (e.g. the bug is visible in a brand new project), you can write "N/A" in the field. + - Drag and drop a ZIP archive to upload it (max 10 MB). **Do not select another field until the project is done uploading.** - **Note for C# users:** If your issue is *not* C#-specific, please upload a minimal reproduction project written in GDScript. This will make it easier for contributors to reproduce the issue locally as not everyone has a .NET setup available. - - **If you've been asked by a maintainer to upload a minimal reproduction project, you *must* do so within 7 days.** Otherwise, your bug report will be closed as it'll be considered too difficult to diagnose. validations: required: true diff --git a/.github/actions/godot-build/action.yml b/.github/actions/godot-build/action.yml index 377480b12394..0a0899db7871 100644 --- a/.github/actions/godot-build/action.yml +++ b/.github/actions/godot-build/action.yml @@ -31,6 +31,18 @@ runs: SCONS_CACHE_LIMIT: ${{ inputs.scons-cache-limit }} run: | echo "Building with flags:" platform=${{ inputs.platform }} target=${{ inputs.target }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }} - if [ "${{ inputs.target }}" != "editor" ]; then rm -rf editor; fi # Ensure we don't include editor code. + + if [ "${{ inputs.target }}" != "editor" ]; then + # Ensure we don't include editor code in export template builds. + rm -rf editor + fi + + if [ "${{ github.event.number }}" != "" ]; then + # Set build identifier with pull request number if available. This is displayed throughout the editor. + export BUILD_NAME="gh-${{ github.event.number }}" + else + export BUILD_NAME="gh" + fi + scons platform=${{ inputs.platform }} target=${{ inputs.target }} tests=${{ inputs.tests }} ${{ env.SCONSFLAGS }} ls -l bin/ diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 9d1c5efc1909..b22f16a44c10 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -96,6 +96,11 @@ jobs: sudo add-apt-repository "deb https://ppa.launchpadcontent.net/kisak/turtle/ubuntu focal main" sudo apt-get install -qq mesa-vulkan-drivers + # TODO: Figure out somehow how to embed this one. + - name: wayland-scanner dependency + run: | + sudo apt-get install libwayland-bin + - name: Free disk space on runner run: | echo "Disk usage before:" && df -h diff --git a/.github/workflows/web_builds.yml b/.github/workflows/web_builds.yml index a2a5e87943f7..fc6a18a5e3d4 100644 --- a/.github/workflows/web_builds.yml +++ b/.github/workflows/web_builds.yml @@ -17,16 +17,34 @@ concurrency: jobs: web-template: runs-on: "ubuntu-22.04" - name: Template (target=template_release) + name: ${{ matrix.name }} + strategy: + fail-fast: false + matrix: + include: + - name: Template w/ threads (target=template_release, threads=yes) + cache-name: web-template + target: template_release + sconsflags: threads=yes + tests: false + artifact: true + + - name: Template w/o threads (target=template_release, threads=no) + cache-name: web-nothreads-template + target: template_release + sconsflags: threads=no + tests: false + artifact: true steps: - uses: actions/checkout@v4 - name: Set up Emscripten latest - uses: mymindstorm/setup-emsdk@v12 + uses: mymindstorm/setup-emsdk@v14 with: version: ${{env.EM_VERSION}} actions-cache-folder: ${{env.EM_CACHE_FOLDER}} + cache-key: emsdk-${{ matrix.cache-name }}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} - name: Verify Emscripten setup run: | @@ -34,6 +52,8 @@ jobs: - name: Setup Godot build cache uses: ./.github/actions/godot-cache + with: + cache-name: ${{ matrix.cache-name }} continue-on-error: true - name: Setup python and scons @@ -42,10 +62,13 @@ jobs: - name: Compilation uses: ./.github/actions/godot-build with: - sconsflags: ${{ env.SCONSFLAGS }} + sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }} platform: web - target: template_release - tests: false + target: ${{ matrix.target }} + tests: ${{ matrix.tests }} - name: Upload artifact uses: ./.github/actions/upload-artifact + if: ${{ matrix.artifact }} + with: + name: ${{ matrix.cache-name }} diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index fc03b6647d26..18ed92b57f0a 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -6,8 +6,8 @@ on: # SCONS_CACHE for windows must be set in the build environment env: # Used for the cache key. Add version suffix to force clean build. - GODOT_BASE_BRANCH: 4.2 - SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes + GODOT_BASE_BRANCH: master + SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes d3d12=yes SCONS_CACHE_MSVC_CONFIG: true concurrency: @@ -28,7 +28,7 @@ jobs: target: editor tests: true # Skip debug symbols, they're way too big with MSVC. - sconsflags: debug_symbols=no vsproj=yes windows_subsystem=console + sconsflags: debug_symbols=no vsproj=yes vsproj_gen_only=no windows_subsystem=console bin: "./bin/godot.windows.editor.x86_64.exe" - name: Template (target=template_release) @@ -49,6 +49,9 @@ jobs: - name: Setup python and scons uses: ./.github/actions/godot-deps + - name: Download Direct3D 12 SDK components + run: python ./misc/scripts/install_d3d12_sdk_windows.py + - name: Setup MSVC problem matcher uses: ammaraskar/msvc-problem-matcher@master diff --git a/.gitignore b/.gitignore index 61ea171b8b86..f43b81f286f6 100644 --- a/.gitignore +++ b/.gitignore @@ -132,6 +132,10 @@ cppcheck-cppcheck-build-dir/ *.pydevproject *.launch +# Emacs +\#*\# +.\#* + # GCOV code coverage *.gcda *.gcno @@ -153,6 +157,9 @@ gmon.out # Kdevelop *.kdev4 +# Mypy +.mypy_cache + # Qt Creator *.config *.creator @@ -364,3 +371,4 @@ $RECYCLE.BIN/ *.msm *.msp *.lnk +*.generated.props diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 91f227d40507..d2250b762551 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -194,6 +194,16 @@ Copyright: 2018, Eric Lasota 2018, Microsoft Corp. License: Expat +Files: ./thirdparty/d3d12ma/ +Comment: D3D12 Memory Allocator +Copyright: 2019-2022 Advanced Micro Devices, Inc. +License: Expat + +Files: ./thirdparty/directx_headers/ +Comment: DirectX Headers +Copyright: Microsoft Corporation +License: Expat + Files: ./thirdparty/doctest/ Comment: doctest Copyright: 2016-2023, Viktor Kirilov @@ -325,7 +335,7 @@ License: Apache-2.0 Files: ./thirdparty/meshoptimizer/ Comment: meshoptimizer -Copyright: 2016-2022, Arseny Kapoulkine +Copyright: 2016-2023, Arseny Kapoulkine License: Expat Files: ./thirdparty/mingw-std-threads/ @@ -498,7 +508,6 @@ Comment: Vulkan Headers Copyright: 2014-2023, The Khronos Group Inc. 2014-2023, Valve Corporation 2014-2023, LunarG, Inc. - 2015-2023, Google Inc. License: Apache-2.0 Files: ./thirdparty/vulkan/vk_mem_alloc.h @@ -506,6 +515,26 @@ Comment: Vulkan Memory Allocator Copyright: 2017-2021, Advanced Micro Devices, Inc. License: Expat +Files: ./thirdparty/wayland/ +Comment: Wayland core protocol +Copyright: 2008-2012, Kristian Høgsberg + 2010-2012, Intel Corporation + 2011, Benjamin Franzke + 2012, Collabora, Ltd. +License: Expat + +Files: ./thirdparty/wayland-protocols/ +Comment: Wayland protocols that add functionality not available in the core protocol +Copyright: 2008-2013, Kristian Høgsberg + 2010-2013, Intel Corporation + 2013, Rafael Antognolli + 2013, Jasper St. Pierre + 2014, Jonas Ådahl + 2014, Jason Ekstrand + 2014-2015, Collabora, Ltd. + 2015, Red Hat Inc. +License: Expat + Files: ./thirdparty/wslay/ Comment: Wslay Copyright: 2011, 2012, 2015, Tatsuhiro Tsujikawa diff --git a/SConstruct b/SConstruct index 534d5bd95d2b..f0f53ddc65ad 100644 --- a/SConstruct +++ b/SConstruct @@ -182,6 +182,8 @@ opts.Add(BoolVariable("debug_symbols", "Build with debugging symbols", False)) opts.Add(BoolVariable("separate_debug_symbols", "Extract debugging symbols to a separate file", False)) opts.Add(EnumVariable("lto", "Link-time optimization (production builds)", "none", ("none", "auto", "thin", "full"))) opts.Add(BoolVariable("production", "Set defaults to build Godot for use in production", False)) +opts.Add(BoolVariable("generate_apk", "Generate an APK/AAB after building Android library by calling Gradle", False)) +opts.Add(BoolVariable("threads", "Enable threading support", True)) # Components opts.Add(BoolVariable("deprecated", "Enable compatibility code for deprecated and removed features", True)) @@ -191,6 +193,7 @@ opts.Add(BoolVariable("brotli", "Enable Brotli for decompresson and WOFF2 fonts opts.Add(BoolVariable("xaudio2", "Enable the XAudio2 audio driver", False)) opts.Add(BoolVariable("vulkan", "Enable the vulkan rendering driver", True)) opts.Add(BoolVariable("opengl3", "Enable the OpenGL/GLES3 rendering driver", True)) +opts.Add(BoolVariable("d3d12", "Enable the Direct3D 12 rendering driver (Windows only)", False)) opts.Add(BoolVariable("openxr", "Enable the OpenXR driver", True)) opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loader dynamically", True)) opts.Add(BoolVariable("disable_exceptions", "Force disabling exception handling code", True)) @@ -210,6 +213,7 @@ opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all opts.Add("object_prefix", "Custom prefix added to the base filename of all generated object files", "") opts.Add(BoolVariable("vsproj", "Generate a Visual Studio solution", False)) opts.Add("vsproj_name", "Name of the Visual Studio solution", "godot") +opts.Add("import_env_vars", "A comma-separated list of environment variables to copy from the outer environment.", "") opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable", False)) opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False)) opts.Add("build_profile", "Path to a file containing a feature build profile", "") @@ -268,6 +272,12 @@ opts.Add("LINKFLAGS", "Custom flags for the linker") # in following code (especially platform and custom_modules). opts.Update(env_base) +# Copy custom environment variables if set. +if env_base["import_env_vars"]: + for env_var in str(env_base["import_env_vars"]).split(","): + if env_var in os.environ: + env_base["ENV"][env_var] = os.environ[env_var] + # Platform selection: validate input, and add options. selected_platform = "" @@ -299,18 +309,14 @@ else: if selected_platform != "": print("Automatically detected platform: " + selected_platform) -if selected_platform in ["macos", "osx"]: - if selected_platform == "osx": - # Deprecated alias kept for compatibility. - print('Platform "osx" has been renamed to "macos" in Godot 4. Building for platform "macos".') - # Alias for convenience. +if selected_platform == "osx": + # Deprecated alias kept for compatibility. + print('Platform "osx" has been renamed to "macos" in Godot 4. Building for platform "macos".') selected_platform = "macos" -if selected_platform in ["ios", "iphone"]: - if selected_platform == "iphone": - # Deprecated alias kept for compatibility. - print('Platform "iphone" has been renamed to "ios" in Godot 4. Building for platform "ios".') - # Alias for convenience. +if selected_platform == "iphone": + # Deprecated alias kept for compatibility. + print('Platform "iphone" has been renamed to "ios" in Godot 4. Building for platform "ios".') selected_platform = "ios" if selected_platform in ["linux", "bsd", "x11"]: @@ -320,6 +326,11 @@ if selected_platform in ["linux", "bsd", "x11"]: # Alias for convenience. selected_platform = "linuxbsd" +if selected_platform == "javascript": + # Deprecated alias kept for compatibility. + print('Platform "javascript" has been renamed to "web" in Godot 4. Building for platform "web".') + selected_platform = "web" + # Make sure to update this to the found, valid platform as it's used through the buildsystem as the reference. # It should always be re-set after calling `opts.Update()` otherwise it uses the original input value. env_base["platform"] = selected_platform @@ -822,6 +833,10 @@ if selected_platform in platform_list: suffix += ".double" suffix += "." + env["arch"] + + if not env["threads"]: + suffix += ".nothreads" + suffix += env.extra_suffix sys.path.remove(tmppath) @@ -962,6 +977,9 @@ if selected_platform in platform_list: env.Tool("compilation_db") env.Alias("compiledb", env.CompilationDatabase()) + if env["threads"]: + env.Append(CPPDEFINES=["THREADS_ENABLED"]) + Export("env") # Build subdirs, the build order is dependent on link order. @@ -982,9 +1000,6 @@ if selected_platform in platform_list: # Microsoft Visual Studio Project Generation if env["vsproj"]: - if os.name != "nt": - print("Error: The `vsproj` option is only usable on Windows with Visual Studio.") - Exit(255) env["CPPPATH"] = [Dir(path) for path in env["CPPPATH"]] methods.generate_vs_project(env, ARGUMENTS, env["vsproj_name"]) methods.generate_cpp_hint_file("cpp.hint") diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 24080c056a02..203f8c388269 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -110,7 +110,6 @@ Dictionary Engine::get_version_info() const { dict["hex"] = VERSION_HEX; dict["status"] = VERSION_STATUS; dict["build"] = VERSION_BUILD; - dict["year"] = VERSION_YEAR; String hash = String(VERSION_HASH); dict["hash"] = hash.is_empty() ? String("unknown") : hash; diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 93934f23205a..329af9068e5e 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -95,7 +95,7 @@ const PackedStringArray ProjectSettings::_get_supported_features() { features.append(VERSION_FULL_CONFIG); features.append(VERSION_FULL_BUILD); -#ifdef VULKAN_ENABLED +#ifdef RD_ENABLED features.append("Forward Plus"); features.append("Mobile"); #endif @@ -281,6 +281,11 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { if (autoloads.has(node_name)) { remove_autoload(node_name); } + } else if (p_name.operator String().begins_with("global_group/")) { + String group_name = p_name.operator String().get_slice("/", 1); + if (global_groups.has(group_name)) { + remove_global_group(group_name); + } } } else { if (p_name == CoreStringNames::get_singleton()->_custom_features) { @@ -327,6 +332,9 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { autoload.path = path; } add_autoload(autoload); + } else if (p_name.operator String().begins_with("global_group/")) { + String group_name = p_name.operator String().get_slice("/", 1); + add_global_group(group_name, p_value); } } @@ -674,6 +682,8 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bo Compression::gzip_level = GLOBAL_GET("compression/formats/gzip/compression_level"); + load_scene_groups_cache(); + project_loaded = err == OK; return err; } @@ -1241,6 +1251,73 @@ ProjectSettings::AutoloadInfo ProjectSettings::get_autoload(const StringName &p_ return autoloads[p_name]; } +const HashMap &ProjectSettings::get_global_groups_list() const { + return global_groups; +} + +void ProjectSettings::add_global_group(const StringName &p_name, const String &p_description) { + ERR_FAIL_COND_MSG(p_name == StringName(), "Trying to add global group with no name."); + global_groups[p_name] = p_description; +} + +void ProjectSettings::remove_global_group(const StringName &p_name) { + ERR_FAIL_COND_MSG(!global_groups.has(p_name), "Trying to remove non-existent global group."); + global_groups.erase(p_name); +} + +bool ProjectSettings::has_global_group(const StringName &p_name) const { + return global_groups.has(p_name); +} + +void ProjectSettings::remove_scene_groups_cache(const StringName &p_path) { + scene_groups_cache.erase(p_path); +} + +void ProjectSettings::add_scene_groups_cache(const StringName &p_path, const HashSet &p_cache) { + scene_groups_cache[p_path] = p_cache; +} + +void ProjectSettings::save_scene_groups_cache() { + Ref cf; + cf.instantiate(); + for (const KeyValue> &E : scene_groups_cache) { + if (E.value.is_empty()) { + continue; + } + Array list; + for (const StringName &group : E.value) { + list.push_back(group); + } + cf->set_value(E.key, "groups", list); + } + cf->save(get_scene_groups_cache_path()); +} + +String ProjectSettings::get_scene_groups_cache_path() const { + return get_project_data_path().path_join("scene_groups_cache.cfg"); +} + +void ProjectSettings::load_scene_groups_cache() { + Ref cf; + cf.instantiate(); + if (cf->load(get_scene_groups_cache_path()) == OK) { + List scene_paths; + cf->get_sections(&scene_paths); + for (const String &E : scene_paths) { + Array scene_groups = cf->get_value(E, "groups", Array()); + HashSet cache; + for (int i = 0; i < scene_groups.size(); ++i) { + cache.insert(scene_groups[i]); + } + add_scene_groups_cache(E, cache); + } + } +} + +const HashMap> &ProjectSettings::get_scene_groups_cache() const { + return scene_groups_cache; +} + void ProjectSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting); ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &ProjectSettings::set_setting); @@ -1316,8 +1393,8 @@ ProjectSettings::ProjectSettings() { // - Have a 16:9 aspect ratio, // - Have both dimensions divisible by 8 to better play along with video recording, // - Be displayable correctly in windowed mode on a 1366×768 display (tested on Windows 10 with default settings). - GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/viewport_width", PROPERTY_HINT_RANGE, "0,7680,1,or_greater"), 1152); // 8K resolution - GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/viewport_height", PROPERTY_HINT_RANGE, "0,4320,1,or_greater"), 648); // 8K resolution + GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/viewport_width", PROPERTY_HINT_RANGE, "1,7680,1,or_greater"), 1152); // 8K resolution + GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/viewport_height", PROPERTY_HINT_RANGE, "1,4320,1,or_greater"), 648); // 8K resolution GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "display/window/size/mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen,Exclusive Fullscreen"), 0); @@ -1385,20 +1462,28 @@ ProjectSettings::ProjectSettings() { GLOBAL_DEF("debug/settings/crash_handler/message.editor", String("Please include this when reporting the bug on: https://github.com/godotengine/godot/issues")); GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/occlusion_culling/bvh_build_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), 2); - GLOBAL_DEF(PropertyInfo(Variant::INT, "memory/limits/multithreaded_server/rid_pool_prealloc", PROPERTY_HINT_RANGE, "0,500,1"), 60); // No negative and limit to 500 due to crashes. GLOBAL_DEF_RST("internationalization/rendering/force_right_to_left_layout_direction", false); - GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "internationalization/rendering/root_node_layout_direction", PROPERTY_HINT_ENUM, "Based on Locale,Left-to-Right,Right-to-Left"), 0); + GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "internationalization/rendering/root_node_layout_direction", PROPERTY_HINT_ENUM, "Based on Application Locale,Left-to-Right,Right-to-Left,Based on System Locale"), 0); GLOBAL_DEF(PropertyInfo(Variant::INT, "gui/timers/incremental_search_max_interval_msec", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"), 2000); GLOBAL_DEF_BASIC("gui/common/snap_controls_to_pixels", true); GLOBAL_DEF_BASIC("gui/fonts/dynamic_fonts/use_oversampling", true); - GLOBAL_DEF("rendering/rendering_device/staging_buffer/block_size_kb", 256); - GLOBAL_DEF("rendering/rendering_device/staging_buffer/max_size_mb", 128); - GLOBAL_DEF("rendering/rendering_device/staging_buffer/texture_upload_region_size_px", 64); - GLOBAL_DEF("rendering/rendering_device/pipeline_cache/save_chunk_size_mb", 3.0); - GLOBAL_DEF("rendering/rendering_device/vulkan/max_descriptors_per_pool", 64); + GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/rendering_device/staging_buffer/block_size_kb", PROPERTY_HINT_RANGE, "4,2048,1,or_greater"), 256); + GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/rendering_device/staging_buffer/max_size_mb", PROPERTY_HINT_RANGE, "1,1024,1,or_greater"), 128); + GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/rendering_device/staging_buffer/texture_upload_region_size_px", PROPERTY_HINT_RANGE, "1,256,1,or_greater"), 64); + GLOBAL_DEF(PropertyInfo(Variant::FLOAT, "rendering/rendering_device/pipeline_cache/save_chunk_size_mb", PROPERTY_HINT_RANGE, "0.000001,64.0,0.001,or_greater"), 3.0); + GLOBAL_DEF(PropertyInfo(Variant::INT, "rendering/rendering_device/vulkan/max_descriptors_per_pool", PROPERTY_HINT_RANGE, "1,256,1,or_greater"), 64); + + GLOBAL_DEF_RST("rendering/rendering_device/d3d12/max_resource_descriptors_per_frame", 16384); + custom_prop_info["rendering/rendering_device/d3d12/max_resource_descriptors_per_frame"] = PropertyInfo(Variant::INT, "rendering/rendering_device/d3d12/max_resource_descriptors_per_frame", PROPERTY_HINT_RANGE, "512,262144"); + GLOBAL_DEF_RST("rendering/rendering_device/d3d12/max_sampler_descriptors_per_frame", 1024); + custom_prop_info["rendering/rendering_device/d3d12/max_sampler_descriptors_per_frame"] = PropertyInfo(Variant::INT, "rendering/rendering_device/d3d12/max_sampler_descriptors_per_frame", PROPERTY_HINT_RANGE, "256,2048"); + GLOBAL_DEF_RST("rendering/rendering_device/d3d12/max_misc_descriptors_per_frame", 512); + custom_prop_info["rendering/rendering_device/d3d12/max_misc_descriptors_per_frame"] = PropertyInfo(Variant::INT, "rendering/rendering_device/d3d12/max_misc_descriptors_per_frame", PROPERTY_HINT_RANGE, "32,4096"); + + GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/rendering_device/d3d12/agility_sdk_version"), 610); GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_filter", PROPERTY_HINT_ENUM, "Nearest,Linear,Linear Mipmap,Nearest Mipmap"), 1); GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "rendering/textures/canvas_textures/default_texture_repeat", PROPERTY_HINT_ENUM, "Disable,Enable,Mirror"), 0); diff --git a/core/config/project_settings.h b/core/config/project_settings.h index 302df7e8d061..55d5957ad152 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -106,6 +106,8 @@ class ProjectSettings : public Object { LocalVector hidden_prefixes; HashMap autoloads; + HashMap global_groups; + HashMap> scene_groups_cache; Array global_class_list; bool is_global_class_list_loaded = false; @@ -208,6 +210,18 @@ class ProjectSettings : public Object { bool has_autoload(const StringName &p_autoload) const; AutoloadInfo get_autoload(const StringName &p_name) const; + const HashMap &get_global_groups_list() const; + void add_global_group(const StringName &p_name, const String &p_description); + void remove_global_group(const StringName &p_name); + bool has_global_group(const StringName &p_name) const; + + const HashMap> &get_scene_groups_cache() const; + void add_scene_groups_cache(const StringName &p_path, const HashSet &p_cache); + void remove_scene_groups_cache(const StringName &p_path); + void save_scene_groups_cache(); + String get_scene_groups_cache_path() const; + void load_scene_groups_cache(); + ProjectSettings(); ~ProjectSettings(); }; diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 981d9b002517..e5363f9acc8d 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -662,6 +662,7 @@ void OS::_bind_methods() { BIND_ENUM_CONSTANT(RENDERING_DRIVER_VULKAN); BIND_ENUM_CONSTANT(RENDERING_DRIVER_OPENGL3); + BIND_ENUM_CONSTANT(RENDERING_DRIVER_D3D12); BIND_ENUM_CONSTANT(SYSTEM_DIR_DESKTOP); BIND_ENUM_CONSTANT(SYSTEM_DIR_DCIM); @@ -1039,6 +1040,10 @@ Vector Geometry3D::clip_polygon(const Vector &p_points, const return ::Geometry3D::clip_polygon(p_points, p_plane); } +Vector Geometry3D::tetrahedralize_delaunay(const Vector &p_points) { + return ::Geometry3D::tetrahedralize_delaunay(p_points); +} + void Geometry3D::_bind_methods() { ClassDB::bind_method(D_METHOD("compute_convex_mesh_points", "planes"), &Geometry3D::compute_convex_mesh_points); ClassDB::bind_method(D_METHOD("build_box_planes", "extents"), &Geometry3D::build_box_planes); @@ -1060,6 +1065,7 @@ void Geometry3D::_bind_methods() { ClassDB::bind_method(D_METHOD("segment_intersects_convex", "from", "to", "planes"), &Geometry3D::segment_intersects_convex); ClassDB::bind_method(D_METHOD("clip_polygon", "points", "plane"), &Geometry3D::clip_polygon); + ClassDB::bind_method(D_METHOD("tetrahedralize_delaunay", "points"), &Geometry3D::tetrahedralize_delaunay); } ////// Marshalls ////// @@ -1369,11 +1375,11 @@ Variant ClassDB::instantiate(const StringName &p_class) const { } } -bool ClassDB::class_has_signal(StringName p_class, StringName p_signal) const { +bool ClassDB::class_has_signal(const StringName &p_class, const StringName &p_signal) const { return ::ClassDB::has_signal(p_class, p_signal); } -Dictionary ClassDB::class_get_signal(StringName p_class, StringName p_signal) const { +Dictionary ClassDB::class_get_signal(const StringName &p_class, const StringName &p_signal) const { MethodInfo signal; if (::ClassDB::get_signal(p_class, p_signal, &signal)) { return signal.operator Dictionary(); @@ -1382,7 +1388,7 @@ Dictionary ClassDB::class_get_signal(StringName p_class, StringName p_signal) co } } -TypedArray ClassDB::class_get_signal_list(StringName p_class, bool p_no_inheritance) const { +TypedArray ClassDB::class_get_signal_list(const StringName &p_class, bool p_no_inheritance) const { List signals; ::ClassDB::get_signal_list(p_class, &signals, p_no_inheritance); TypedArray ret; @@ -1394,7 +1400,7 @@ TypedArray ClassDB::class_get_signal_list(StringName p_class, bool p return ret; } -TypedArray ClassDB::class_get_property_list(StringName p_class, bool p_no_inheritance) const { +TypedArray ClassDB::class_get_property_list(const StringName &p_class, bool p_no_inheritance) const { List plist; ::ClassDB::get_property_list(p_class, &plist, p_no_inheritance); TypedArray ret; @@ -1422,11 +1428,11 @@ Error ClassDB::class_set_property(Object *p_object, const StringName &p_property return OK; } -bool ClassDB::class_has_method(StringName p_class, StringName p_method, bool p_no_inheritance) const { +bool ClassDB::class_has_method(const StringName &p_class, const StringName &p_method, bool p_no_inheritance) const { return ::ClassDB::has_method(p_class, p_method, p_no_inheritance); } -TypedArray ClassDB::class_get_method_list(StringName p_class, bool p_no_inheritance) const { +TypedArray ClassDB::class_get_method_list(const StringName &p_class, bool p_no_inheritance) const { List methods; ::ClassDB::get_method_list(p_class, &methods, p_no_inheritance); TypedArray ret; @@ -1507,7 +1513,7 @@ StringName ClassDB::class_get_integer_constant_enum(const StringName &p_class, c return ::ClassDB::get_integer_constant_enum(p_class, p_name, p_no_inheritance); } -bool ClassDB::is_class_enabled(StringName p_class) const { +bool ClassDB::is_class_enabled(const StringName &p_class) const { return ::ClassDB::is_class_enabled(p_class); } @@ -1717,6 +1723,16 @@ bool Engine::is_printing_error_messages() const { return ::Engine::get_singleton()->is_printing_error_messages(); } +void Engine::get_argument_options(const StringName &p_function, int p_idx, List *r_options) const { + String pf = p_function; + if (p_idx == 0 && (pf == "has_singleton" || pf == "get_singleton" || pf == "unregister_singleton")) { + for (const String &E : get_singleton_list()) { + r_options->push_back(E.quote()); + } + } + Object::get_argument_options(p_function, p_idx, r_options); +} + void Engine::_bind_methods() { ClassDB::bind_method(D_METHOD("set_physics_ticks_per_second", "physics_ticks_per_second"), &Engine::set_physics_ticks_per_second); ClassDB::bind_method(D_METHOD("get_physics_ticks_per_second"), &Engine::get_physics_ticks_per_second); diff --git a/core/core_bind.h b/core/core_bind.h index 5f51b64eb748..94d95f2ce987 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -129,6 +129,7 @@ class OS : public Object { enum RenderingDriver { RENDERING_DRIVER_VULKAN, RENDERING_DRIVER_OPENGL3, + RENDERING_DRIVER_D3D12, }; virtual PackedStringArray get_connected_midi_inputs(); @@ -336,6 +337,7 @@ class Geometry3D : public Object { Vector segment_intersects_convex(const Vector3 &p_from, const Vector3 &p_to, const TypedArray &p_planes); Vector clip_polygon(const Vector &p_points, const Plane &p_plane); + Vector tetrahedralize_delaunay(const Vector &p_points); Geometry3D() { singleton = this; } }; @@ -433,17 +435,17 @@ class ClassDB : public Object { bool can_instantiate(const StringName &p_class) const; Variant instantiate(const StringName &p_class) const; - bool class_has_signal(StringName p_class, StringName p_signal) const; - Dictionary class_get_signal(StringName p_class, StringName p_signal) const; - TypedArray class_get_signal_list(StringName p_class, bool p_no_inheritance = false) const; + bool class_has_signal(const StringName &p_class, const StringName &p_signal) const; + Dictionary class_get_signal(const StringName &p_class, const StringName &p_signal) const; + TypedArray class_get_signal_list(const StringName &p_class, bool p_no_inheritance = false) const; - TypedArray class_get_property_list(StringName p_class, bool p_no_inheritance = false) const; + TypedArray class_get_property_list(const StringName &p_class, bool p_no_inheritance = false) const; Variant class_get_property(Object *p_object, const StringName &p_property) const; Error class_set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const; - bool class_has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false) const; + bool class_has_method(const StringName &p_class, const StringName &p_method, bool p_no_inheritance = false) const; - TypedArray class_get_method_list(StringName p_class, bool p_no_inheritance = false) const; + TypedArray class_get_method_list(const StringName &p_class, bool p_no_inheritance = false) const; PackedStringArray class_get_integer_constant_list(const StringName &p_class, bool p_no_inheritance = false) const; bool class_has_integer_constant(const StringName &p_class, const StringName &p_name) const; @@ -454,7 +456,7 @@ class ClassDB : public Object { PackedStringArray class_get_enum_constants(const StringName &p_class, const StringName &p_enum, bool p_no_inheritance = false) const; StringName class_get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false) const; - bool is_class_enabled(StringName p_class) const; + bool is_class_enabled(const StringName &p_class) const; ClassDB() {} ~ClassDB() {} @@ -526,6 +528,8 @@ class Engine : public Object { void set_print_error_messages(bool p_enabled); bool is_printing_error_messages() const; + virtual void get_argument_options(const StringName &p_function, int p_idx, List *r_options) const override; + Engine() { singleton = this; } }; diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 2f70fdf21966..aaabbabfd9e7 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -507,6 +507,10 @@ void register_global_constants() { BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, KPAD); BIND_CORE_BITFIELD_CLASS_FLAG(KeyModifierMask, KEY_MASK, GROUP_SWITCH); + BIND_CORE_ENUM_CLASS_CONSTANT(KeyLocation, KEY_LOCATION, UNSPECIFIED); + BIND_CORE_ENUM_CLASS_CONSTANT(KeyLocation, KEY_LOCATION, LEFT); + BIND_CORE_ENUM_CLASS_CONSTANT(KeyLocation, KEY_LOCATION, RIGHT); + BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, NONE); BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, LEFT); BIND_CORE_ENUM_CLASS_CONSTANT(MouseButton, MOUSE_BUTTON, RIGHT); @@ -845,7 +849,7 @@ bool CoreConstants::is_global_enum(const StringName &p_enum) { return _global_enums.has(p_enum); } -void CoreConstants::get_enum_values(StringName p_enum, HashMap *p_values) { +void CoreConstants::get_enum_values(const StringName &p_enum, HashMap *p_values) { ERR_FAIL_NULL_MSG(p_values, "Trying to get enum values with null map."); ERR_FAIL_COND_MSG(!_global_enums.has(p_enum), "Trying to get values of non-existing enum."); for (const _CoreConstant &constant : _global_enums[p_enum]) { diff --git a/core/core_constants.h b/core/core_constants.h index 51842490c883..82d626c74953 100644 --- a/core/core_constants.h +++ b/core/core_constants.h @@ -45,7 +45,7 @@ class CoreConstants { static bool is_global_constant(const StringName &p_name); static int get_global_constant_index(const StringName &p_name); static bool is_global_enum(const StringName &p_enum); - static void get_enum_values(StringName p_enum, HashMap *p_values); + static void get_enum_values(const StringName &p_enum, HashMap *p_values); }; #endif // CORE_CONSTANTS_H diff --git a/core/debugger/engine_debugger.cpp b/core/debugger/engine_debugger.cpp index 32dc060aa2b3..0cce44d02fb3 100644 --- a/core/debugger/engine_debugger.cpp +++ b/core/debugger/engine_debugger.cpp @@ -162,7 +162,7 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, Ve singleton_script_debugger->set_skip_breakpoints(p_skip_breakpoints); for (int i = 0; i < p_breakpoints.size(); i++) { - String bp = p_breakpoints[i]; + const String &bp = p_breakpoints[i]; int sp = bp.rfind(":"); ERR_CONTINUE_MSG(sp == -1, "Invalid breakpoint: '" + bp + "', expected file:line format."); diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index a817ea871d42..d3b0039e722e 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -36,6 +36,7 @@ #include "core/debugger/engine_profiler.h" #include "core/debugger/script_debugger.h" #include "core/input/input.h" +#include "core/io/resource_loader.h" #include "core/object/script_language.h" #include "core/os/os.h" @@ -435,9 +436,7 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { messages.insert(Thread::get_caller_id(), List()); } - mutex.lock(); while (is_peer_connected()) { - mutex.unlock(); flush_output(); _poll_messages(); @@ -515,8 +514,9 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { _send_stack_vars(globals, globals_vals, 2); } else if (command == "reload_scripts") { + script_paths_to_reload = data; + } else if (command == "reload_all_scripts") { reload_all_scripts = true; - } else if (command == "breakpoint") { ERR_FAIL_COND(data.size() < 3); bool set = data[2]; @@ -591,19 +591,36 @@ void RemoteDebugger::poll_events(bool p_is_idle) { } // Reload scripts during idle poll only. - if (p_is_idle && reload_all_scripts) { - for (int i = 0; i < ScriptServer::get_language_count(); i++) { - ScriptServer::get_language(i)->reload_all_scripts(); + if (p_is_idle) { + if (reload_all_scripts) { + for (int i = 0; i < ScriptServer::get_language_count(); i++) { + ScriptServer::get_language(i)->reload_all_scripts(); + } + reload_all_scripts = false; + } else if (!script_paths_to_reload.is_empty()) { + Array scripts_to_reload; + for (int i = 0; i < script_paths_to_reload.size(); ++i) { + String path = script_paths_to_reload[i]; + Error err = OK; + Ref