From ea2c6f1d0b5cab38a38b986c3af1345cbd59f633 Mon Sep 17 00:00:00 2001 From: MrBBBaiXue Date: Wed, 13 Dec 2023 17:58:38 +0100 Subject: [PATCH] Add a python script to install Direct3D 12 SDK components. This makes it much faster to get started with Direct3D 12 builds, as you only need to run `python .\misc\scripts\install_d3d12_sdk_windows.py` then run `scons d3d12=yes`. This installs DirectX Shader Compiler, Mesa NIR, WinPixEventRuntime and DirectX 12 Agility SDK. - Define a default path that uses the locations from the script. - Now the default path is in "%LOCALAPPDATA%\Godot\build_deps\" - Updated CI to use this new python script. Co-Authored-By: Hugo Locurcio --- .github/workflows/windows_builds.yml | 25 +----- drivers/d3d12/SCsub | 4 +- misc/scripts/install_d3d12_sdk_windows.py | 98 +++++++++++++++++++++++ platform/windows/SCsub | 4 +- platform/windows/detect.py | 61 ++++++++++---- 5 files changed, 150 insertions(+), 42 deletions(-) create mode 100644 misc/scripts/install_d3d12_sdk_windows.py diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index 35ed1a773d8..2794c83e221 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -7,7 +7,7 @@ on: env: # Used for the cache key. Add version suffix to force clean build. GODOT_BASE_BRANCH: master - SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes d3d12=yes "dxc_path=${{github.workspace}}/dxc" "mesa_libs=${{github.workspace}}/godot-nir-static" + SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes d3d12=yes SCONS_CACHE_MSVC_CONFIG: true concurrency: @@ -49,27 +49,8 @@ jobs: - name: Setup python and scons uses: ./.github/actions/godot-deps - - name: Download pre-built DirectX Shader Compiler - uses: dsaltares/fetch-gh-release-asset@1.0.0 - with: - repo: Microsoft/DirectXShaderCompiler - version: tags/v1.7.2308 - file: dxc_2023_08_14.zip - target: dxc.zip - - - name: Extract pre-built DirectX Shader Compiler - run: 7z x dxc.zip -o${{github.workspace}}/dxc - - - name: Download pre-built Mesa-NIR - uses: dsaltares/fetch-gh-release-asset@1.0.0 - with: - repo: godotengine/godot-nir-static - version: tags/23.1.0-devel - file: godot-nir-23.1.0-1-devel.zip - target: godot-nir-static.zip - - - name: Extract pre-built Mesa-NIR - run: 7z x godot-nir-static.zip -o${{github.workspace}}/godot-nir-static + - 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/drivers/d3d12/SCsub b/drivers/d3d12/SCsub index a49d55ebc0f..6b23e1bad05 100644 --- a/drivers/d3d12/SCsub +++ b/drivers/d3d12/SCsub @@ -25,7 +25,7 @@ env_d3d12_rdd.Append(CPPPATH=["#thirdparty/d3d12ma"]) # Agility SDK. -if env["agility_sdk_path"] != "": +if env["agility_sdk_path"] != "" and os.path.exists(env["agility_sdk_path"]): env_d3d12_rdd.Append(CPPDEFINES=["AGILITY_SDK_ENABLED"]) if env["agility_sdk_multiarch"]: env_d3d12_rdd.Append(CPPDEFINES=["AGILITY_SDK_MULTIARCH_ENABLED"]) @@ -33,7 +33,7 @@ if env["agility_sdk_path"] != "": # PIX. -if env["pix_path"] != "": +if env["pix_path"] != "" and os.path.exists(env["pix_path"]): env_d3d12_rdd.Append(CPPDEFINES=["PIX_ENABLED"]) env_d3d12_rdd.Append(CPPPATH=[env["pix_path"] + "/Include"]) diff --git a/misc/scripts/install_d3d12_sdk_windows.py b/misc/scripts/install_d3d12_sdk_windows.py new file mode 100644 index 00000000000..0995aa734f7 --- /dev/null +++ b/misc/scripts/install_d3d12_sdk_windows.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python + +import os +import urllib.request +import shutil + +# Base Godot dependencies path +deps_folder = os.path.join(f"{os.getenv('LOCALAPPDATA')}", "Godot", "build_deps") +# DirectX Shader Compiler +dxc_version = "v1.7.2308" +dxc_filename = "dxc_2023_08_14.zip" +dxc_archive = os.path.join(deps_folder, dxc_filename) +dxc_folder = os.path.join(deps_folder, "dxc") +# Mesa NIR +mesa_version = "23.1.0-devel" +mesa_filename = "godot-nir-23.1.0-1-devel.zip" +mesa_archive = os.path.join(deps_folder, mesa_filename) +mesa_folder = os.path.join(deps_folder, "mesa") +# WinPixEventRuntime +pix_version = "1.0.231030001" +pix_archive = os.path.join(deps_folder, f"WinPixEventRuntime_{pix_version}.nupkg") +pix_folder = os.path.join(deps_folder, "pix") +# DirectX 12 Agility SDK +agility_sdk_version = "1.610.4" +agility_sdk_archive = os.path.join(deps_folder, f"Agility_SDK_{agility_sdk_version}.nupkg") +agility_sdk_folder = os.path.join(deps_folder, "agility_sdk") + +# Create dependencies folder +if not os.path.exists(deps_folder): + os.makedirs(deps_folder) + +# DirectX Shader Compiler +print("[1/4] DirectX Shader Compiler") +if os.path.isfile(dxc_archive): + os.remove(dxc_archive) +print(f"Downloading DirectX Shader Compiler {dxc_filename} ...") +urllib.request.urlretrieve( + f"https://github.com/microsoft/DirectXShaderCompiler/releases/download/{dxc_version}/{dxc_filename}", + dxc_archive, +) +if os.path.exists(dxc_folder): + print(f"Removing existing local DirectX Shader Compiler installation in {dxc_folder} ...") + shutil.rmtree(dxc_folder) +print(f"Extracting DirectX Shader Compiler {dxc_filename} to {dxc_folder} ...") +shutil.unpack_archive(dxc_archive, dxc_folder) +os.remove(dxc_archive) +print(f"DirectX Shader Compiler {dxc_filename} installed successfully.\n") + +# Mesa NIR +print("[2/4] Mesa NIR") +if os.path.isfile(mesa_archive): + os.remove(mesa_archive) +print(f"Downloading Mesa NIR {mesa_filename} ...") +urllib.request.urlretrieve( + f"https://github.com/godotengine/godot-nir-static/releases/download/{mesa_version}/{mesa_filename}", + mesa_archive, +) +if os.path.exists(mesa_folder): + print(f"Removing existing local Mesa NIR installation in {mesa_folder} ...") + shutil.rmtree(mesa_folder) +print(f"Extracting Mesa NIR {mesa_filename} to {mesa_folder} ...") +shutil.unpack_archive(mesa_archive, mesa_folder) +os.remove(mesa_archive) +print(f"Mesa NIR {mesa_filename} installed successfully.\n") + +# WinPixEventRuntime +print("[3/4] WinPixEventRuntime") +if os.path.isfile(pix_archive): + os.remove(pix_archive) +print(f"Downloading WinPixEventRuntime {pix_version} ...") +urllib.request.urlretrieve(f"https://www.nuget.org/api/v2/package/WinPixEventRuntime/{pix_version}", pix_archive) +if os.path.exists(pix_folder): + print(f"Removing existing local WinPixEventRuntime installation in {pix_folder} ...") + shutil.rmtree(pix_folder) +print(f"Extracting WinPixEventRuntime {pix_version} to {pix_folder} ...") +shutil.unpack_archive(pix_archive, pix_folder, "zip") +os.remove(pix_archive) +print(f"WinPixEventRuntime {pix_version} installed successfully.\n") + +# DirectX 12 Agility SDK +print("[4/4] DirectX 12 Agility SDK") +if os.path.isfile(agility_sdk_archive): + os.remove(agility_sdk_archive) +print(f"Downloading DirectX 12 Agility SDK {agility_sdk_version} ...") +urllib.request.urlretrieve( + f"https://www.nuget.org/api/v2/package/Microsoft.Direct3D.D3D12/{agility_sdk_version}", agility_sdk_archive +) +if os.path.exists(agility_sdk_folder): + print(f"Removing existing local DirectX 12 Agility SDK installation in {agility_sdk_folder} ...") + shutil.rmtree(agility_sdk_folder) +print(f"Extracting DirectX 12 Agility SDK {agility_sdk_version} to {agility_sdk_folder} ...") +shutil.unpack_archive(agility_sdk_archive, agility_sdk_folder, "zip") +os.remove(agility_sdk_archive) +print(f"DirectX 12 Agility SDK {agility_sdk_version} installed successfully.\n") + +# Complete message +print(f"All Direct3D 12 SDK components were installed to {deps_folder} successfully!") +print('You can now build Godot with Direct3D 12 support enabled by running "scons d3d12=yes".') diff --git a/platform/windows/SCsub b/platform/windows/SCsub index 1cfbc33ef86..2df644136b3 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -109,7 +109,7 @@ if env["d3d12"]: ) # Agility SDK - if env["agility_sdk_path"] != "": + if env["agility_sdk_path"] != "" and os.path.exists(env["agility_sdk_path"]): agility_dlls = ["D3D12Core.dll", "d3d12SDKLayers.dll"] # Whether these are loaded from arch-specific directory or not has to be known at build time. target_dir = arch_bin_dir if env["agility_sdk_multiarch"] else "#bin" @@ -121,7 +121,7 @@ if env["d3d12"]: ) # PIX - if env["pix_path"] != "": + if env["pix_path"] != "" and os.path.exists(env["pix_path"]): pix_dll = "WinPixEventRuntime.dll" env.Command( "#bin/" + pix_dll, diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 79698f5bd7d..7fd314c7cee 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -164,6 +164,9 @@ def get_opts(): mingw = os.getenv("MINGW_PREFIX", "") + # Direct3D 12 SDK dependencies folder + d3d12_deps_folder = os.path.join(os.getenv("LOCALAPPDATA"), "Godot", "build_deps") + return [ ("mingw_prefix", "MinGW prefix", mingw), # Targeted Windows version: 7 (and later), minimum supported version @@ -188,15 +191,31 @@ def get_opts(): BoolVariable("incremental_link", "Use MSVC incremental linking. May increase or decrease build times.", False), ("angle_libs", "Path to the ANGLE static libraries", ""), # Direct3D 12 support. - ("mesa_libs", "Path to the MESA/NIR static libraries (required for D3D12)", ""), - ("dxc_path", "Path to the DirectX Shader Compiler distribution (required for D3D12)", ""), - ("agility_sdk_path", "Path to the Agility SDK distribution (optional for D3D12)", ""), + ( + "mesa_libs", + "Path to the MESA/NIR static libraries (required for D3D12)", + os.path.join(d3d12_deps_folder, "mesa"), + ), + ( + "dxc_path", + "Path to the DirectX Shader Compiler distribution (required for D3D12)", + os.path.join(d3d12_deps_folder, "dxc"), + ), + ( + "agility_sdk_path", + "Path to the Agility SDK distribution (optional for D3D12)", + os.path.join(d3d12_deps_folder, "agility_sdk"), + ), BoolVariable( "agility_sdk_multiarch", "Whether the Agility SDK DLLs will be stored in arch-specific subdirectories", False, ), - ("pix_path", "Path to the PIX runtime distribution (optional for D3D12)", ""), + ( + "pix_path", + "Path to the PIX runtime distribution (optional for D3D12)", + os.path.join(d3d12_deps_folder, "pix"), + ), ] @@ -441,6 +460,16 @@ def configure_msvc(env, vcvars_msvc_config): LIBS += ["vulkan"] if env["d3d12"]: + # Check whether we have d3d12 dependencies installed. + if not os.path.exists(env["mesa_libs"]) or not os.path.exists(env["dxc_path"]): + print("The Direct3D 12 rendering driver requires dependencies to be installed.") + print("You can install them by running `python misc\scripts\install_d3d12_sdk_windows.py`.") + print("See the documentation for more information:") + print( + "https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_windows.html" + ) + sys.exit(255) + env.AppendUnique(CPPDEFINES=["D3D12_ENABLED", "RD_ENABLED"]) LIBS += ["d3d12", "dxgi", "dxguid"] LIBS += ["version"] # Mesa dependency. @@ -452,15 +481,10 @@ def configure_msvc(env, vcvars_msvc_config): arch_subdir = "arm64" if env["arch"] == "arm64" else "x64" # PIX - if env["pix_path"] != "": + if env["pix_path"] != "" and os.path.exists(env["pix_path"]): env.Append(LIBPATH=[env["pix_path"] + "/bin/" + arch_subdir]) LIBS += ["WinPixEventRuntime"] - # Mesa - if env["mesa_libs"] == "": - print("The Direct3D 12 rendering driver requires mesa_libs to be set.") - sys.exit(255) - env.Append(LIBPATH=[env["mesa_libs"] + "/bin"]) LIBS += ["libNIR.windows." + env["arch"]] @@ -663,16 +687,21 @@ def configure_mingw(env): arch_subdir = "arm64" if env["arch"] == "arm64" else "x64" + # Check whether we have d3d12 dependencies installed. + if not os.path.exists(env["mesa_libs"]) or not os.path.exists(env["dxc_path"]): + print("The Direct3D 12 rendering driver requires dependencies to be installed.") + print("You can install them by running `python misc\scripts\install_d3d12_sdk_windows.py`.") + print("See the documentation for more information:") + print( + "https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_windows.html" + ) + sys.exit(255) + # PIX - if env["pix_path"] != "": + if env["pix_path"] != "" and os.path.exists(env["pix_path"]): env.Append(LIBPATH=[env["pix_path"] + "/bin/" + arch_subdir]) env.Append(LIBS=["WinPixEventRuntime"]) - # Mesa - if env["mesa_libs"] == "": - print("The Direct3D 12 rendering driver requires mesa_libs to be set.") - sys.exit(255) - env.Append(LIBPATH=[env["mesa_libs"] + "/bin"]) env.Append(LIBS=["libNIR.windows." + env["arch"]]) env.Append(LIBS=["version"]) # Mesa dependency.