diff --git a/Source/Editor/Cooker/Platform/GDK/GDKPlatformTools.cpp b/Source/Editor/Cooker/Platform/GDK/GDKPlatformTools.cpp index f9a8f1b82..fa1ac4d0b 100644 --- a/Source/Editor/Cooker/Platform/GDK/GDKPlatformTools.cpp +++ b/Source/Editor/Cooker/Platform/GDK/GDKPlatformTools.cpp @@ -15,26 +15,32 @@ #include "Editor/ProjectInfo.h" #include "Editor/Utilities/EditorUtilities.h" -GDKPlatformTools::GDKPlatformTools() +String GetGDK() { - // Find GDK - Platform::GetEnvironmentVariable(TEXT("GameDKLatest"), _gdkPath); - if (_gdkPath.IsEmpty() || !FileSystem::DirectoryExists(_gdkPath)) + String gdk; + Platform::GetEnvironmentVariable(TEXT("GameDKLatest"), gdk); + if (gdk.IsEmpty() || !FileSystem::DirectoryExists(gdk)) { - _gdkPath.Clear(); - Platform::GetEnvironmentVariable(TEXT("GRDKLatest"), _gdkPath); - if (_gdkPath.IsEmpty() || !FileSystem::DirectoryExists(_gdkPath)) + gdk.Clear(); + Platform::GetEnvironmentVariable(TEXT("GRDKLatest"), gdk); + if (gdk.IsEmpty() || !FileSystem::DirectoryExists(gdk)) { - _gdkPath.Clear(); + gdk.Clear(); } else { - if (_gdkPath.EndsWith(TEXT("GRDK\\"))) - _gdkPath.Remove(_gdkPath.Length() - 6); - else if (_gdkPath.EndsWith(TEXT("GRDK"))) - _gdkPath.Remove(_gdkPath.Length() - 5); + if (gdk.EndsWith(TEXT("GRDK\\"))) + gdk.Remove(gdk.Length() - 6); + else if (gdk.EndsWith(TEXT("GRDK"))) + gdk.Remove(gdk.Length() - 5); } } + return gdk; +} + +GDKPlatformTools::GDKPlatformTools() +{ + _gdkPath = GetGDK(); } DotNetAOTModes GDKPlatformTools::UseAOT() const diff --git a/Source/Editor/Cooker/Steps/CookAssetsStep.cpp b/Source/Editor/Cooker/Steps/CookAssetsStep.cpp index 030c31c41..57654a6b3 100644 --- a/Source/Editor/Cooker/Steps/CookAssetsStep.cpp +++ b/Source/Editor/Cooker/Steps/CookAssetsStep.cpp @@ -526,6 +526,7 @@ bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* ass #if PLATFORM_TOOLS_XBOX_SCARLETT case BuildPlatform::XboxScarlett: { + options.Platform = PlatformType::XboxScarlett; const char* platformDefineName = "PLATFORM_XBOX_SCARLETT"; COMPILE_PROFILE(DirectX_SM6, SHADER_FILE_CHUNK_INTERNAL_D3D_SM6_CACHE); break; diff --git a/Source/Engine/ShadersCompilation/Config.h b/Source/Engine/ShadersCompilation/Config.h index 8d9730f70..65d596235 100644 --- a/Source/Engine/ShadersCompilation/Config.h +++ b/Source/Engine/ShadersCompilation/Config.h @@ -15,7 +15,6 @@ class MemoryWriteStream; struct FLAXENGINE_API ShaderCompilationOptions { public: - /// /// Name of the target object (name of the shader or material for better logging readability) /// @@ -37,12 +36,16 @@ public: uint32 SourceLength = 0; public: - /// /// Target shader profile /// ShaderProfile Profile = ShaderProfile::Unknown; + /// + /// Target platform, set to invalid value of 0 if not used (platform-independent compilation). + /// + PlatformType Platform = (PlatformType)0; + /// /// Disables shaders compiler optimizations. Can be used to debug shaders on a target platform or to speed up the shaders compilation time. /// @@ -64,7 +67,6 @@ public: Array Macros; public: - /// /// Output stream to write compiled shader cache to /// diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp index 3edad2488..01ce8faef 100644 --- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp +++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerD3D.cpp @@ -196,7 +196,7 @@ bool ShaderCompilerD3D::CompileShader(ShaderFunctionMeta& meta, WritePermutation default: return true; } - if (_profile == ShaderProfile::DirectX_SM5) + if (GetProfile() == ShaderProfile::DirectX_SM5) { profileName += "_5_0"; } diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp index 5e49da710..aa2f70ac7 100644 --- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp +++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.cpp @@ -59,7 +59,8 @@ public: *ppIncludeSource = nullptr; const char* source; int32 sourceLength; - const StringAnsi filename(pFilename); + StringAnsi filename(pFilename); + filename.Replace('\\', '/'); if (ShaderCompiler::GetIncludedFileSource(_context, "", filename.Get(), source, sourceLength)) return E_FAIL; IDxcBlobEncoding* textBlob; @@ -70,25 +71,25 @@ public: } }; -ShaderCompilerDX::ShaderCompilerDX(ShaderProfile profile) - : ShaderCompiler(profile) +ShaderCompilerDX::ShaderCompilerDX(ShaderProfile profile, PlatformType platform, void* dxcCreateInstanceProc) + : ShaderCompiler(profile, platform) { IDxcCompiler3* compiler = nullptr; IDxcLibrary* library = nullptr; IDxcContainerReflection* containerReflection = nullptr; - if (FAILED(DxcCreateInstance(CLSID_DxcCompiler, __uuidof(compiler), reinterpret_cast(&compiler))) || - FAILED(DxcCreateInstance(CLSID_DxcLibrary, __uuidof(library), reinterpret_cast(&library))) || - FAILED(DxcCreateInstance(CLSID_DxcContainerReflection, __uuidof(containerReflection), reinterpret_cast(&containerReflection)))) + DxcCreateInstanceProc createInstance = dxcCreateInstanceProc ? (DxcCreateInstanceProc)dxcCreateInstanceProc : &DxcCreateInstance; + if (FAILED(createInstance(CLSID_DxcCompiler, __uuidof(compiler), reinterpret_cast(&compiler))) || + FAILED(createInstance(CLSID_DxcLibrary, __uuidof(library), reinterpret_cast(&library))) || + FAILED(createInstance(CLSID_DxcContainerReflection, __uuidof(containerReflection), reinterpret_cast(&containerReflection)))) { LOG(Error, "DxcCreateInstance failed"); } _compiler = compiler; _library = library; _containerReflection = containerReflection; - static bool PrintVersion = true; - if (PrintVersion) + static HashSet PrintVersions; + if (PrintVersions.Add(createInstance)) { - PrintVersion = false; IDxcVersionInfo* version = nullptr; if (compiler && SUCCEEDED(compiler->QueryInterface(__uuidof(version), reinterpret_cast(&version)))) { @@ -221,6 +222,7 @@ bool ShaderCompilerDX::CompileShader(ShaderFunctionMeta& meta, WritePermutationD argsFull.Add(TEXT("-D")); argsFull.Add(*d); } + GetArgs(argsFull); // Compile ComPtr results; diff --git a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.h b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.h index 7973fe397..a3e6d7073 100644 --- a/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.h +++ b/Source/Engine/ShadersCompilation/DirectX/ShaderCompilerDX.h @@ -22,7 +22,9 @@ public: /// Initializes a new instance of the class. /// /// The profile. - ShaderCompilerDX(ShaderProfile profile); + /// The platform. + /// The custom DXC Compiler factory function. + ShaderCompilerDX(ShaderProfile profile, PlatformType platform = (PlatformType)0, void* dxcCreateInstanceProc = nullptr); /// /// Finalizes an instance of the class. @@ -30,6 +32,10 @@ public: ~ShaderCompilerDX(); protected: + virtual void GetArgs(Array> args) + { + } + // [ShaderCompiler] bool CompileShader(ShaderFunctionMeta& meta, WritePermutationData customDataWrite = nullptr) override; bool OnCompileBegin() override; diff --git a/Source/Engine/ShadersCompilation/ShaderCompiler.h b/Source/Engine/ShadersCompilation/ShaderCompiler.h index 79cdb1cae..36fd592e6 100644 --- a/Source/Engine/ShadersCompilation/ShaderCompiler.h +++ b/Source/Engine/ShadersCompilation/ShaderCompiler.h @@ -23,10 +23,11 @@ public: }; private: + ShaderProfile _profile; + PlatformType _platform; Array _funcNameDefineBuffer; protected: - ShaderProfile _profile; ShaderCompilationContext* _context = nullptr; Array _globalMacros; Array _macros; @@ -37,8 +38,10 @@ public: /// Initializes a new instance of the class. /// /// The profile. - ShaderCompiler(ShaderProfile profile) + /// The platform. + ShaderCompiler(ShaderProfile profile, PlatformType platform = (PlatformType)0) : _profile(profile) + , _platform(platform) { } @@ -51,12 +54,19 @@ public: /// /// Gets shader profile supported by this compiler. /// - /// The shader profile. FORCE_INLINE ShaderProfile GetProfile() const { return _profile; } + /// + /// Gets target platform supported by this compiler. Returns invalid value of '0' if any platform works. + /// + FORCE_INLINE PlatformType GetPlatform() const + { + return _platform; + } + /// /// Performs the shader compilation. /// diff --git a/Source/Engine/ShadersCompilation/ShadersCompilation.Build.cs b/Source/Engine/ShadersCompilation/ShadersCompilation.Build.cs index 0e203f656..03ab0a74e 100644 --- a/Source/Engine/ShadersCompilation/ShadersCompilation.Build.cs +++ b/Source/Engine/ShadersCompilation/ShadersCompilation.Build.cs @@ -63,6 +63,8 @@ public class ShadersCompilation : EngineModule options.PrivateDependencies.Add("ShaderCompilerPS4"); if (Sdk.HasValid("PS5Sdk")) options.PrivateDependencies.Add("ShaderCompilerPS5"); + if (Flax.Build.Platform.GetPlatform(TargetPlatform.XboxScarlett, true) != null) + options.PrivateDependencies.Add("ShaderCompilerXboxScarlett"); } /// diff --git a/Source/Engine/ShadersCompilation/ShadersCompilation.cpp b/Source/Engine/ShadersCompilation/ShadersCompilation.cpp index accfeaad5..f7d1367ba 100644 --- a/Source/Engine/ShadersCompilation/ShadersCompilation.cpp +++ b/Source/Engine/ShadersCompilation/ShadersCompilation.cpp @@ -48,6 +48,9 @@ #if COMPILE_WITH_PS5_SHADER_COMPILER #include "Platforms/PS5/Engine/ShaderCompilerPS5/ShaderCompilerPS5.h" #endif +#if COMPILE_WITH_XBOX_SCARLETT_SHADER_COMPILER +#include "Platforms/XboxScarlett/Engine/ShaderCompilerXboxScarlett/ShaderCompilerXboxScarlett.h" +#endif namespace ShadersCompilationImpl { @@ -165,20 +168,16 @@ bool ShadersCompilation::Compile(ShaderCompilationOptions& options) bool result; { ShaderCompilationContext context(&options, &meta); - - // Request shaders compiler - auto compiler = RequestCompiler(options.Profile); + auto compiler = RequestCompiler(options.Profile, options.Platform); if (compiler == nullptr) { LOG(Error, "Shader compiler request failed."); return true; } - ASSERT(compiler->GetProfile() == options.Profile); + ASSERT_LOW_LAYER(compiler->GetProfile() == options.Profile); // Call compilation process result = compiler->Compile(&context); - - // Dismiss compiler FreeCompiler(compiler); #if GPU_USE_SHADERS_DEBUG_LAYER @@ -210,65 +209,65 @@ bool ShadersCompilation::Compile(ShaderCompilationOptions& options) return result; } -ShaderCompiler* ShadersCompilation::CreateCompiler(ShaderProfile profile) +ShaderCompiler* ShadersCompilation::RequestCompiler(ShaderProfile profile, PlatformType platform) { - ShaderCompiler* result = nullptr; - - switch (profile) - { -#if COMPILE_WITH_D3D_SHADER_COMPILER - case ShaderProfile::DirectX_SM4: - case ShaderProfile::DirectX_SM5: - result = New(profile); - break; -#endif -#if COMPILE_WITH_DX_SHADER_COMPILER - case ShaderProfile::DirectX_SM6: - result = New(profile); - break; -#endif -#if COMPILE_WITH_VK_SHADER_COMPILER - case ShaderProfile::Vulkan_SM5: - result = New(profile); - break; -#endif -#if COMPILE_WITH_PS4_SHADER_COMPILER - case ShaderProfile::PS4: - result = New(); - break; -#endif -#if COMPILE_WITH_PS5_SHADER_COMPILER - case ShaderProfile::PS5: - result = New(); - break; -#endif - default: - break; - } - ASSERT_LOW_LAYER(result == nullptr || result->GetProfile() == profile); - - return result; -} - -ShaderCompiler* ShadersCompilation::RequestCompiler(ShaderProfile profile) -{ - ShaderCompiler* compiler; ScopeLock lock(Locker); // Try to find ready compiler + ShaderCompiler* compiler = nullptr; for (int32 i = 0; i < ReadyCompilers.Count(); i++) { - compiler = ReadyCompilers[i]; - if (compiler->GetProfile() == profile) + compiler = ReadyCompilers.Get()[i]; + if (compiler->GetProfile() == profile && + (compiler->GetPlatform() == platform || (int32)compiler->GetPlatform() == 0)) { - // Use it ReadyCompilers.RemoveAt(i); return compiler; } } // Create new compiler for a target profile - compiler = CreateCompiler(profile); + switch (profile) + { +#if COMPILE_WITH_D3D_SHADER_COMPILER + case ShaderProfile::DirectX_SM4: + case ShaderProfile::DirectX_SM5: + compiler = New(profile); + break; +#endif +#if COMPILE_WITH_DX_SHADER_COMPILER + case ShaderProfile::DirectX_SM6: + switch (platform) + { + case PlatformType::XboxScarlett: +#if COMPILE_WITH_XBOX_SCARLETT_SHADER_COMPILER + compiler = New(); +#endif + break; + default: + compiler = New(profile); + break; + } + break; +#endif +#if COMPILE_WITH_VK_SHADER_COMPILER + case ShaderProfile::Vulkan_SM5: + compiler = New(profile); + break; +#endif +#if COMPILE_WITH_PS4_SHADER_COMPILER + case ShaderProfile::PS4: + compiler = New(); + break; +#endif +#if COMPILE_WITH_PS5_SHADER_COMPILER + case ShaderProfile::PS5: + compiler = New(); + break; +#endif + default: + break; + } if (compiler == nullptr) { LOG(Error, "Cannot create Shader Compiler for profile {0}", ::ToString(profile)); @@ -414,7 +413,8 @@ String ShadersCompilation::ResolveShaderPath(StringView path) // Skip to the last root start './' but preserve the leading one for (int32 i = path.Length() - 2; i >= 2; i--) { - if (StringUtils::Compare(path.Get() + i, TEXT("./"), 2) == 0) + const Char* pos = path.Get() + i; + if (pos[0] == '.' && pos[1] == '/') { path = path.Substring(i); break; diff --git a/Source/Engine/ShadersCompilation/ShadersCompilation.h b/Source/Engine/ShadersCompilation/ShadersCompilation.h index 0c251f61e..b32c9f51a 100644 --- a/Source/Engine/ShadersCompilation/ShadersCompilation.h +++ b/Source/Engine/ShadersCompilation/ShadersCompilation.h @@ -48,9 +48,7 @@ public: static String CompactShaderPath(StringView path); private: - - static ShaderCompiler* CreateCompiler(ShaderProfile profile); - static ShaderCompiler* RequestCompiler(ShaderProfile profile); + static ShaderCompiler* RequestCompiler(ShaderProfile profile, PlatformType platform); static void FreeCompiler(ShaderCompiler* compiler); };