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);
};