2020-09-24 00:43:27 -04:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
#include "DXCWrapper.h"
|
|
|
|
|
#include "HAL/PlatformProcess.h"
|
2021-02-05 15:18:17 -04:00
|
|
|
#include "HAL/FileManager.h"
|
2020-09-24 00:43:27 -04:00
|
|
|
#include "Templates/RefCounting.h"
|
|
|
|
|
#include "Misc/Paths.h"
|
2021-02-01 18:54:58 -04:00
|
|
|
#include "Hash/CityHash.h"
|
|
|
|
|
|
|
|
|
|
#if PLATFORM_WINDOWS
|
|
|
|
|
#include "Windows/WindowsHWrapper.h"
|
|
|
|
|
#endif // PLATFORM_WINDOWS
|
2020-09-24 00:43:27 -04:00
|
|
|
|
2021-02-05 10:29:11 -04:00
|
|
|
static TRefCountPtr<FDllHandle> GDxilHandle;
|
2020-09-24 00:43:27 -04:00
|
|
|
static TRefCountPtr<FDllHandle> GDxcHandle;
|
|
|
|
|
static TRefCountPtr<FDllHandle> GShaderConductorHandle;
|
|
|
|
|
|
2021-02-01 18:54:58 -04:00
|
|
|
static uint64 GetLoadedModuleVersion(const TCHAR* ModuleName)
|
|
|
|
|
{
|
|
|
|
|
#if PLATFORM_WINDOWS
|
|
|
|
|
HMODULE ModuleDll = ::GetModuleHandleW(ModuleName);
|
2021-02-05 10:29:11 -04:00
|
|
|
if (ModuleDll == nullptr)
|
2021-02-01 18:54:58 -04:00
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TCHAR DllPath[4096] = {};
|
|
|
|
|
int32 PathLen = ::GetModuleFileNameW(ModuleDll, DllPath, UE_ARRAY_COUNT(DllPath));
|
|
|
|
|
if (PathLen == 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
check(PathLen < UE_ARRAY_COUNT(DllPath));
|
|
|
|
|
|
2021-02-05 15:45:40 -04:00
|
|
|
uint64 FileVersion = 0;
|
|
|
|
|
|
|
|
|
|
TUniquePtr<FArchive> FileReader(IFileManager::Get().CreateFileReader(DllPath));
|
|
|
|
|
if (FileReader)
|
2021-02-01 18:54:58 -04:00
|
|
|
{
|
2021-02-05 15:45:40 -04:00
|
|
|
TArray<char> FileContents;
|
|
|
|
|
FileContents.SetNumUninitialized(FileReader->TotalSize());
|
|
|
|
|
FileReader->Serialize(FileContents.GetData(), FileContents.Num());
|
|
|
|
|
FileVersion = CityHash64(FileContents.GetData(), FileContents.Num());
|
2021-02-01 18:54:58 -04:00
|
|
|
}
|
2021-02-05 15:45:40 -04:00
|
|
|
|
2021-02-01 18:54:58 -04:00
|
|
|
return FileVersion;
|
|
|
|
|
#else // PLATFORM_WINDOWS
|
|
|
|
|
return 0;
|
|
|
|
|
#endif // PLATFORM_WINDOWS
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-24 00:43:27 -04:00
|
|
|
FDllHandle::FDllHandle(const TCHAR* InFilename)
|
|
|
|
|
{
|
|
|
|
|
#if PLATFORM_WINDOWS
|
|
|
|
|
check(InFilename && *InFilename);
|
|
|
|
|
FString ShaderConductorDir = FPaths::EngineDir() / TEXT("Binaries/ThirdParty/ShaderConductor/Win64");
|
|
|
|
|
FString ModulePath = ShaderConductorDir / InFilename;
|
|
|
|
|
Handle = FPlatformProcess::GetDllHandle(*ModulePath);
|
|
|
|
|
checkf(Handle, TEXT("Failed to load module: %s"), *ModulePath);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FDllHandle::~FDllHandle()
|
|
|
|
|
{
|
|
|
|
|
if (Handle)
|
|
|
|
|
{
|
|
|
|
|
FPlatformProcess::FreeDllHandle(Handle);
|
|
|
|
|
Handle = nullptr;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FDxcModuleWrapper::FDxcModuleWrapper()
|
|
|
|
|
{
|
|
|
|
|
if (GDxcHandle.GetRefCount() == 0)
|
|
|
|
|
{
|
2021-02-05 10:29:11 -04:00
|
|
|
GDxilHandle = new FDllHandle(TEXT("dxil.dll"));
|
2020-09-24 00:43:27 -04:00
|
|
|
GDxcHandle = new FDllHandle(TEXT("dxcompiler.dll"));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2021-02-05 10:29:11 -04:00
|
|
|
GDxilHandle->AddRef();
|
2020-09-24 00:43:27 -04:00
|
|
|
GDxcHandle->AddRef();
|
|
|
|
|
}
|
2021-02-01 18:54:58 -04:00
|
|
|
|
|
|
|
|
static uint64 DxcVersion = GetLoadedModuleVersion(TEXT("dxcompiler.dll"));
|
|
|
|
|
|
|
|
|
|
// If dxil.dll is present, it's automatically loaded by dxcompiler.dll and used for validation and signing.
|
|
|
|
|
// If dxil.dll is not present, shaders will silently be unsigned and will fail to load outside of development environment.
|
|
|
|
|
// This must be taken into account when computing DDC key for D3D shaders.
|
|
|
|
|
static uint64 DxilVersion = GetLoadedModuleVersion(TEXT("dxil.dll"));
|
|
|
|
|
|
|
|
|
|
ModuleVersionHash = HashCombine(GetTypeHash(DxcVersion), GetTypeHash(DxilVersion));
|
2020-09-24 00:43:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FDxcModuleWrapper::~FDxcModuleWrapper()
|
|
|
|
|
{
|
2020-10-22 19:19:16 -04:00
|
|
|
GDxcHandle.SafeRelease();
|
2021-02-05 10:29:11 -04:00
|
|
|
GDxilHandle.SafeRelease();
|
2020-09-24 00:43:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FShaderConductorModuleWrapper::FShaderConductorModuleWrapper()
|
|
|
|
|
{
|
|
|
|
|
if (GShaderConductorHandle.GetRefCount() == 0)
|
|
|
|
|
{
|
|
|
|
|
GShaderConductorHandle = new FDllHandle(TEXT("ShaderConductor.dll"));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
GShaderConductorHandle->AddRef();
|
|
|
|
|
}
|
2021-02-01 18:54:58 -04:00
|
|
|
|
|
|
|
|
static uint64 DllVersion = GetLoadedModuleVersion(TEXT("ShaderConductor.dll"));
|
|
|
|
|
|
2021-02-05 10:29:11 -04:00
|
|
|
ModuleVersionHash = HashCombine(GetTypeHash(DllVersion), FDxcModuleWrapper::GetModuleVersionHash());
|
2020-09-24 00:43:27 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FShaderConductorModuleWrapper::~FShaderConductorModuleWrapper()
|
|
|
|
|
{
|
2020-10-22 19:19:16 -04:00
|
|
|
GShaderConductorHandle.SafeRelease();
|
2020-09-24 00:43:27 -04:00
|
|
|
}
|