summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorazhirnov <zh1dron@gmail.com>2020-09-09 09:25:47 +0000
committerazhirnov <zh1dron@gmail.com>2020-09-09 15:56:51 +0000
commit381f66352dfaefcdeaeba3c71183ad558bb70cd6 (patch)
treea18b2fa0763a310317f6926677d87d91666bf4b6 /Graphics
parentMerge branch 'master' into mesh_shader (diff)
downloadDiligentCore-381f66352dfaefcdeaeba3c71183ad558bb70cd6.tar.gz
DiligentCore-381f66352dfaefcdeaeba3c71183ad558bb70cd6.zip
added IDxCompilerLibrary interface. DXCompilerBase moved to platform specific files
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp9
-rw-r--r--Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp5
-rw-r--r--Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp3
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp56
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp30
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp11
-rw-r--r--Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.hpp3
-rw-r--r--Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp55
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp5
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp3
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp3
-rw-r--r--Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp2
-rw-r--r--Graphics/HLSLTools/CMakeLists.txt3
-rw-r--r--Graphics/HLSLTools/include/DXILUtils.hpp51
-rw-r--r--Graphics/HLSLTools/src/DXCompilerBaseLiunx.hpp71
-rw-r--r--Graphics/HLSLTools/src/DXCompilerBaseUWP.hpp83
-rw-r--r--Graphics/HLSLTools/src/DXCompilerBaseWin32.hpp84
-rw-r--r--Graphics/HLSLTools/src/DXILUtils.cpp322
19 files changed, 467 insertions, 336 deletions
diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp
index b6cd4280..627b270d 100644
--- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp
@@ -40,6 +40,7 @@
#include "CommandQueueD3D12.h"
#include "GenerateMips.hpp"
#include "QueryManagerD3D12.hpp"
+#include "DXILUtils.hpp"
namespace Diligent
{
@@ -151,11 +152,13 @@ public:
const GenerateMipsHelper& GetMipsGenerator() const { return m_MipsGenerator; }
QueryManagerD3D12& GetQueryManager() { return m_QueryMgr; }
+ IDxCompilerLibrary* GetDxCompiler() const { return m_pDxCompiler.get(); }
+
#ifdef D12_H_HAS_MESH_SHADER
ID3D12Device2* GetD3D12Device2();
#endif
- D3D_SHADER_MODEL GetShaderModel() const;
+ ShaderVersion GetShaderModel() const;
D3D_FEATURE_LEVEL GetD3DFeatureLevel() const;
private:
@@ -188,6 +191,10 @@ private:
GenerateMipsHelper m_MipsGenerator;
QueryManagerD3D12 m_QueryMgr;
+
+ D3D_SHADER_MODEL m_ShaderModel = D3D_SHADER_MODEL_5_1;
+
+ std::unique_ptr<IDxCompilerLibrary> m_pDxCompiler;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp
index 23f9882b..b1c12f90 100644
--- a/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp
+++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourcesD3D12.hpp
@@ -92,7 +92,10 @@ class ShaderResourcesD3D12 final : public ShaderResources
{
public:
// Loads shader resources from the compiled shader bytecode
- ShaderResourcesD3D12(ID3DBlob* pShaderBytecode, const ShaderDesc& ShdrDesc, const char* CombinedSamplerSuffix);
+ ShaderResourcesD3D12(ID3DBlob* pShaderBytecode,
+ const ShaderDesc& ShdrDesc,
+ const char* CombinedSamplerSuffix,
+ class RenderDeviceD3D12Impl* pRenderDeviceD3D12);
// clang-format off
ShaderResourcesD3D12 (const ShaderResourcesD3D12&) = delete;
diff --git a/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp
index ac747d62..65991753 100644
--- a/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/EngineFactoryD3D12.cpp
@@ -42,7 +42,6 @@
#include "StringTools.hpp"
#include "EngineMemory.h"
#include "CommandQueueD3D12Impl.hpp"
-#include "DXILUtils.hpp"
#ifndef NOMINMAX
# define NOMINMAX
@@ -380,8 +379,6 @@ void EngineFactoryD3D12Impl::CreateDeviceAndContextsD3D12(const EngineD3D12Creat
std::array<ICommandQueueD3D12*, 1> CmdQueues = {pCmdQueueD3D12};
AttachToD3D12Device(d3d12Device, CmdQueues.size(), CmdQueues.data(), EngineCI, ppDevice, ppContexts);
-
- DxcLoadLibrary(DXCompilerTarget::Direct3D12, EngineCI.pDxCompilerPath);
}
diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
index 445458e2..ea4d62a8 100644
--- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
@@ -65,29 +65,9 @@ static CComPtr<IDXGIAdapter1> DXGIAdapterFromD3D12Device(ID3D12Device* pd3d12Dev
return nullptr;
}
-D3D_SHADER_MODEL RenderDeviceD3D12Impl::GetShaderModel() const
+ShaderVersion RenderDeviceD3D12Impl::GetShaderModel() const
{
- // Header may not have constants for D3D_SHADER_MODEL_6_5 and above.
- const D3D_SHADER_MODEL Models[] = {
- D3D_SHADER_MODEL(0x65), // for mesh shader
- D3D_SHADER_MODEL(0x64),
- D3D_SHADER_MODEL(0x63),
- D3D_SHADER_MODEL(0x62),
- D3D_SHADER_MODEL(0x61),
- D3D_SHADER_MODEL_6_0};
-
- // Get maximum supported shader model.
- D3D12_FEATURE_DATA_SHADER_MODEL ShaderModel = {};
- for (auto Model : Models)
- {
- ShaderModel.HighestShaderModel = Model;
- if (SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &ShaderModel, sizeof(ShaderModel))))
- return ShaderModel.HighestShaderModel;
- }
-
- // Direct3D12 supports shader model 5.1 on all feature levels.
- // https://docs.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels#feature-level-support
- return D3D_SHADER_MODEL_5_1;
+ return ShaderVersion{Uint8((m_ShaderModel >> 4) & 0xF), Uint8(m_ShaderModel & 0xF)};
}
D3D_FEATURE_LEVEL RenderDeviceD3D12Impl::GetD3DFeatureLevel() const
@@ -170,7 +150,8 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo
m_ContextPool (STD_ALLOCATOR_RAW_MEM(PooledCommandContext, GetRawAllocator(), "Allocator for vector<PooledCommandContext>")),
m_DynamicMemoryManager{GetRawAllocator(), *this, EngineCI.NumDynamicHeapPagesToReserve, EngineCI.DynamicHeapPageSize},
m_MipsGenerator {pd3d12Device},
- m_QueryMgr {pd3d12Device, EngineCI.QueryPoolSizes}
+ m_QueryMgr {pd3d12Device, EngineCI.QueryPoolSizes},
+ m_pDxCompiler {CreateDXCompiler(DXCompilerTarget::Direct3D12, EngineCI.pDxCompilerPath)}
// clang-format on
{
m_DeviceCaps.DevType = RENDER_DEVICE_TYPE_D3D12;
@@ -221,7 +202,32 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo
m_DeviceCaps.Features.VertexPipelineUAVWritesAndAtomics = True;
- const D3D_SHADER_MODEL ShaderModel = GetShaderModel();
+ // Detect maximum shader model.
+ {
+ // Direct3D12 supports shader model 5.1 on all feature levels.
+ // https://docs.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels#feature-level-support
+ m_ShaderModel = D3D_SHADER_MODEL_5_1;
+
+ // Header may not have constants for D3D_SHADER_MODEL_6_1 and above.
+ const D3D_SHADER_MODEL Models[] = {
+ D3D_SHADER_MODEL(0x65), // for mesh shader
+ D3D_SHADER_MODEL(0x64),
+ D3D_SHADER_MODEL(0x63),
+ D3D_SHADER_MODEL(0x62),
+ D3D_SHADER_MODEL(0x61),
+ D3D_SHADER_MODEL_6_0};
+
+ D3D12_FEATURE_DATA_SHADER_MODEL ShaderModel = {};
+ for (auto Model : Models)
+ {
+ ShaderModel.HighestShaderModel = Model;
+ if (SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &ShaderModel, sizeof(ShaderModel))))
+ {
+ m_ShaderModel = ShaderModel.HighestShaderModel;
+ break;
+ }
+ }
+ }
// Check if mesh shader is supported.
#ifdef D12_H_HAS_MESH_SHADER
@@ -230,7 +236,7 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo
bool SupportsMeshShader = SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &FeatureData, sizeof(FeatureData))) &&
FeatureData.MeshShaderTier != D3D12_MESH_SHADER_TIER_NOT_SUPPORTED;
- m_DeviceCaps.Features.MeshShaders = (ShaderModel >= D3D_SHADER_MODEL_6_5 && SupportsMeshShader);
+ m_DeviceCaps.Features.MeshShaders = (m_ShaderModel >= D3D_SHADER_MODEL_6_5 && SupportsMeshShader);
}
#endif
diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp
index d14eb122..0634bcf1 100644
--- a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp
@@ -36,17 +36,25 @@
namespace Diligent
{
-static ShaderVersion GetD3D12ShaderModel(RenderDeviceD3D12Impl* pDevice, const ShaderVersion& HLSLVersion)
+static ShaderVersion GetD3D12ShaderModel(RenderDeviceD3D12Impl* pDevice, const ShaderVersion& HLSLVersion, SHADER_COMPILER ShaderCompiler)
{
+ if (ShaderCompiler != SHADER_COMPILER_DXC)
+ return HLSLVersion.Major == 0 ? ShaderVersion{5, 1} : HLSLVersion;
+
+ ShaderVersion DeviceSM = pDevice->GetShaderModel();
+ ShaderVersion CompilerSM = pDevice->GetDxCompiler() && pDevice->GetDxCompiler()->IsLoaded() ? pDevice->GetDxCompiler()->GetMaxShaderModel() : ShaderVersion{5, 1};
+ ShaderVersion MaxSM;
+
+ MaxSM = DeviceSM.Major == CompilerSM.Major ?
+ (DeviceSM.Minor > CompilerSM.Minor ? CompilerSM : DeviceSM) :
+ (DeviceSM.Major > CompilerSM.Major ? CompilerSM : DeviceSM);
+
if (HLSLVersion.Major == 0 && HLSLVersion.Minor == 0)
- {
- D3D_SHADER_MODEL ver = pDevice->GetShaderModel();
- return ShaderVersion{Uint8((ver >> 4) & 0xF), Uint8(ver & 0xF)};
- }
- else
- {
- return HLSLVersion;
- }
+ return MaxSM;
+
+ return HLSLVersion.Major == MaxSM.Major ?
+ (HLSLVersion.Minor > MaxSM.Minor ? MaxSM : HLSLVersion) :
+ (HLSLVersion.Major > MaxSM.Major ? MaxSM : HLSLVersion);
}
ShaderD3D12Impl::ShaderD3D12Impl(IReferenceCounters* pRefCounters,
@@ -59,13 +67,13 @@ ShaderD3D12Impl::ShaderD3D12Impl(IReferenceCounters* pRefCounters,
pRenderDeviceD3D12,
ShaderCI.Desc
},
- ShaderD3DBase{ShaderCI, GetD3D12ShaderModel(pRenderDeviceD3D12, ShaderCI.HLSLVersion), true}
+ ShaderD3DBase{ShaderCI, GetD3D12ShaderModel(pRenderDeviceD3D12, ShaderCI.HLSLVersion, ShaderCI.ShaderCompiler), pRenderDeviceD3D12->GetDxCompiler()}
// clang-format on
{
// Load shader resources
auto& Allocator = GetRawAllocator();
auto* pRawMem = ALLOCATE(Allocator, "Allocator for ShaderResources", ShaderResourcesD3D12, 1);
- auto* pResources = new (pRawMem) ShaderResourcesD3D12(m_pShaderByteCode, m_Desc, ShaderCI.UseCombinedTextureSamplers ? ShaderCI.CombinedSamplerSuffix : nullptr);
+ auto* pResources = new (pRawMem) ShaderResourcesD3D12(m_pShaderByteCode, m_Desc, ShaderCI.UseCombinedTextureSamplers ? ShaderCI.CombinedSamplerSuffix : nullptr, pRenderDeviceD3D12);
m_pShaderResources.reset(pResources, STDDeleterRawMem<ShaderResourcesD3D12>(Allocator));
}
diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp
index bcb34226..01726d00 100644
--- a/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourcesD3D12.cpp
@@ -32,12 +32,16 @@
#include "ShaderD3DBase.hpp"
#include "ShaderBase.hpp"
#include "DXILUtils.hpp"
+#include "RenderDeviceD3D12Impl.hpp"
namespace Diligent
{
-ShaderResourcesD3D12::ShaderResourcesD3D12(ID3DBlob* pShaderBytecode, const ShaderDesc& ShdrDesc, const char* CombinedSamplerSuffix) :
+ShaderResourcesD3D12::ShaderResourcesD3D12(ID3DBlob* pShaderBytecode,
+ const ShaderDesc& ShdrDesc,
+ const char* CombinedSamplerSuffix,
+ RenderDeviceD3D12Impl* pRenderDeviceD3D12) :
ShaderResources{ShdrDesc.ShaderType}
{
class NewResourceHandler
@@ -54,9 +58,12 @@ ShaderResourcesD3D12::ShaderResourcesD3D12(ID3DBlob* pShaderBytecode, const Shad
};
CComPtr<ID3D12ShaderReflection> pShaderReflection;
+ auto* DxCompiler = pRenderDeviceD3D12->GetDxCompiler();
- if (!DxcGetShaderReflection(reinterpret_cast<IDxcBlob*>(pShaderBytecode), &pShaderReflection))
+ // At first try to get shader reflection with a DXC.
+ if (!DxcGetShaderReflection(DxCompiler, reinterpret_cast<IDxcBlob*>(pShaderBytecode), &pShaderReflection))
{
+ // Use FXC to get reflection.
HRESULT hr = D3DReflect(pShaderBytecode->GetBufferPointer(), pShaderBytecode->GetBufferSize(), __uuidof(pShaderReflection), reinterpret_cast<void**>(&pShaderReflection));
CHECK_D3D_RESULT_THROW(hr, "Failed to get the shader reflection");
}
diff --git a/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.hpp b/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.hpp
index 3de8b38e..61aa7976 100644
--- a/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.hpp
+++ b/Graphics/GraphicsEngineD3DBase/include/ShaderD3DBase.hpp
@@ -29,6 +29,7 @@
#include <d3dcommon.h>
#include "Shader.h"
+#include "DXILUtils.hpp"
/// \file
/// Base implementation of a D3D shader
@@ -40,7 +41,7 @@ namespace Diligent
class ShaderD3DBase
{
public:
- ShaderD3DBase(const ShaderCreateInfo& ShaderCI, ShaderVersion ShaderModel, bool IsD3D12);
+ ShaderD3DBase(const ShaderCreateInfo& ShaderCI, ShaderVersion ShaderModel, IDxCompilerLibrary* DxCompiler);
protected:
CComPtr<ID3DBlob> m_pShaderByteCode;
diff --git a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp
index 8df5330a..d9c5008b 100644
--- a/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp
+++ b/Graphics/GraphicsEngineD3DBase/src/ShaderD3DBase.cpp
@@ -33,7 +33,6 @@
#include "RefCntAutoPtr.hpp"
#include <atlcomcli.h>
#include "ShaderD3DBase.hpp"
-#include "DXILUtils.hpp"
#include "dxc/dxcapi.h"
#include <locale>
#include <cwchar>
@@ -48,7 +47,8 @@ static const Char* g_HLSLDefinitions =
#include "HLSLDefinitions_inc.fxh"
};
-static HRESULT CompileDxilShader(const char* Source,
+static HRESULT CompileDxilShader(IDxCompilerLibrary* DxCompiler,
+ const char* Source,
size_t SourceLength,
const ShaderCreateInfo& ShaderCI,
LPCSTR profile,
@@ -169,15 +169,14 @@ static HRESULT CompileDxilShader(const char* Source,
VERIFY_EXPR(__uuidof(ID3DBlob) == __uuidof(IDxcBlob));
- if (!DxcCompile(DXCompilerTarget::Direct3D12,
- Source, SourceLength,
- ToUnicode(ShaderCI.EntryPoint),
- ToUnicode(profile),
- D3DMacros.data(), D3DMacros.size(),
- pArgs, _countof(pArgs),
- ShaderCI.pShaderSourceStreamFactory,
- reinterpret_cast<IDxcBlob**>(ppBlobOut),
- reinterpret_cast<IDxcBlob**>(ppCompilerOutput)))
+ if (!DxCompiler->Compile(Source, SourceLength,
+ ToUnicode(ShaderCI.EntryPoint),
+ ToUnicode(profile),
+ D3DMacros.data(), D3DMacros.size(),
+ pArgs, _countof(pArgs),
+ ShaderCI.pShaderSourceStreamFactory,
+ reinterpret_cast<IDxcBlob**>(ppBlobOut),
+ reinterpret_cast<IDxcBlob**>(ppCompilerOutput)))
{
return E_FAIL;
}
@@ -311,7 +310,7 @@ static HRESULT CompileShader(const char* Source,
} // namespace
-ShaderD3DBase::ShaderD3DBase(const ShaderCreateInfo& ShaderCI, ShaderVersion ShaderModel, bool IsD3D12)
+ShaderD3DBase::ShaderD3DBase(const ShaderCreateInfo& ShaderCI, const ShaderVersion ShaderModel, IDxCompilerLibrary* DxCompiler)
{
if (ShaderCI.Source || ShaderCI.FilePath)
{
@@ -324,37 +323,13 @@ ShaderD3DBase::ShaderD3DBase(const ShaderCreateInfo& ShaderCI, ShaderVersion Sha
switch (ShaderCI.ShaderCompiler)
{
// clang-format off
- case SHADER_COMPILER_DEFAULT: IsDXIL = false; break;
- case SHADER_COMPILER_DXC: IsDXIL = true; break;
- case SHADER_COMPILER_FXC: IsDXIL = false; break;
+ case SHADER_COMPILER_DEFAULT: IsDXIL = false; break;
+ case SHADER_COMPILER_DXC: IsDXIL = DxCompiler != nullptr && DxCompiler->IsLoaded(); break;
+ case SHADER_COMPILER_FXC: IsDXIL = false; break;
// clang-format on
default: UNEXPECTED("Unsupported shader compiler");
}
- // validate shader model
- if (IsDXIL)
- {
- ShaderModel = (ShaderModel.Major >= 6 ? ShaderModel : ShaderVersion{6, 0});
-
- // clamp to maximum supported version
- ShaderVersion MaxSM;
- if (DxcGetMaxShaderModel(DXCompilerTarget::Direct3D12, MaxSM))
- {
- if (ShaderModel.Major > MaxSM.Major)
- ShaderModel = MaxSM;
-
- if (ShaderModel.Major == MaxSM.Major && ShaderModel.Minor > MaxSM.Minor)
- ShaderModel = MaxSM;
- }
- else
- IsDXIL = false;
- }
-
- if (!IsDXIL)
- {
- ShaderModel = (ShaderModel.Major < 6 ? ShaderModel : (IsD3D12 ? ShaderVersion{5, 1} : ShaderVersion{5, 0}));
- }
-
std::string strShaderProfile;
switch (ShaderCI.Desc.ShaderType)
{
@@ -403,7 +378,7 @@ ShaderD3DBase::ShaderD3DBase(const ShaderCreateInfo& ShaderCI, ShaderVersion Sha
HRESULT hr;
if (IsDXIL)
- hr = CompileDxilShader(ShaderSource.c_str(), ShaderSource.length(), ShaderCI, strShaderProfile.c_str(), &m_pShaderByteCode, &errors);
+ hr = CompileDxilShader(DxCompiler, ShaderSource.c_str(), ShaderSource.length(), ShaderCI, strShaderProfile.c_str(), &m_pShaderByteCode, &errors);
else
hr = CompileShader(ShaderSource.c_str(), ShaderSource.length(), ShaderCI, strShaderProfile.c_str(), &m_pShaderByteCode, &errors);
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
index 1adf71ee..9f18c99c 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.hpp
@@ -48,6 +48,7 @@
#include "FramebufferCache.hpp"
#include "RenderPassCache.hpp"
#include "CommandPoolManager.hpp"
+#include "DXILUtils.hpp"
namespace Diligent
{
@@ -176,6 +177,8 @@ public:
void FlushStaleResources(Uint32 CmdQueueIndex);
+ IDxCompilerLibrary* GetDxCompiler() const { return m_pDxCompiler.get(); }
+
private:
virtual void TestTextureFormat(TEXTURE_FORMAT TexFormat) override final;
@@ -205,6 +208,8 @@ private:
VulkanUtilities::VulkanMemoryManager m_MemoryMgr;
VulkanDynamicMemoryManager m_DynamicMemoryManager;
+
+ std::unique_ptr<IDxCompilerLibrary> m_pDxCompiler;
};
} // namespace Diligent
diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
index 760099e2..57631b91 100644
--- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
+++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanPhysicalDevice.hpp
@@ -39,9 +39,7 @@ class VulkanPhysicalDevice
public:
struct ExtensionFeatures
{
-#ifdef VK_NV_mesh_shader
- VkPhysicalDeviceMeshShaderFeaturesNV MeshShader;
-#endif
+ VkPhysicalDeviceMeshShaderFeaturesNV MeshShader = {};
};
struct ExtensionProperties
diff --git a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
index 9a17c9e2..f0dafcff 100644
--- a/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/EngineFactoryVk.cpp
@@ -39,7 +39,6 @@
#include "VulkanUtilities/VulkanInstance.hpp"
#include "VulkanUtilities/VulkanPhysicalDevice.hpp"
#include "EngineFactoryBase.hpp"
-#include "DXILUtils.hpp"
#if PLATFORM_ANDROID
# include "FileSystem.hpp"
@@ -248,8 +247,6 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk(const EngineVkCreateInfo& _E
std::array<ICommandQueueVk*, 1> CommandQueues = {{pCmdQueueVk}};
AttachToVulkanDevice(Instance, std::move(PhysicalDevice), LogicalDevice, CommandQueues.size(), CommandQueues.data(), EngineCI, ppDevice, ppContexts);
-
- DxcLoadLibrary(DXCompilerTarget::Vulkan, EngineCI.pDxCompilerPath);
}
catch (std::runtime_error&)
{
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index e9fae8e7..c619dc59 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -148,7 +148,8 @@ RenderDeviceVkImpl::RenderDeviceVkImpl(IReferenceCounters*
*this,
EngineCI.DynamicHeapSize,
~Uint64{0}
- }
+ },
+ m_pDxCompiler{CreateDXCompiler(DXCompilerTarget::Vulkan, EngineCI.pDxCompilerPath)}
// clang-format on
{
m_DeviceCaps.DevType = RENDER_DEVICE_TYPE_VULKAN;
diff --git a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp
index cafa7303..7cfa5f97 100644
--- a/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/ShaderVkImpl.cpp
@@ -67,7 +67,7 @@ ShaderVkImpl::ShaderVkImpl(IReferenceCounters* pRefCounters,
switch (CreationAttribs.ShaderCompiler)
{
case SHADER_COMPILER_DXC:
- m_SPIRV = DXILtoSPIRV(CreationAttribs, VulkanDefine, CreationAttribs.ppCompilerOutput);
+ m_SPIRV = DXILtoSPIRV(pRenderDeviceVk->GetDxCompiler(), CreationAttribs, VulkanDefine, CreationAttribs.ppCompilerOutput);
break;
case SHADER_COMPILER_DEFAULT:
diff --git a/Graphics/HLSLTools/CMakeLists.txt b/Graphics/HLSLTools/CMakeLists.txt
index 2b7c34b9..b4e33258 100644
--- a/Graphics/HLSLTools/CMakeLists.txt
+++ b/Graphics/HLSLTools/CMakeLists.txt
@@ -8,6 +8,9 @@ set(INCLUDE
set(SOURCE
src/DXILUtils.cpp
+ src/DXCompilerBaseLiunx.hpp
+ src/DXCompilerBaseUWP.hpp
+ src/DXCompilerBaseWin32.hpp
)
if(PLATFORM_LINUX)
diff --git a/Graphics/HLSLTools/include/DXILUtils.hpp b/Graphics/HLSLTools/include/DXILUtils.hpp
index 3f0b4a67..32e53b43 100644
--- a/Graphics/HLSLTools/include/DXILUtils.hpp
+++ b/Graphics/HLSLTools/include/DXILUtils.hpp
@@ -44,38 +44,49 @@ namespace Diligent
enum class DXCompilerTarget
{
- Direct3D12,
- Vulkan,
+ Direct3D12, // compiles to DXIL
+ Vulkan, // compiles to SPIRV
+};
+
+class IDxCompilerLibrary
+{
+public:
+ virtual ~IDxCompilerLibrary() {}
+
+ virtual ShaderVersion GetMaxShaderModel() = 0;
+
+ virtual bool IsLoaded() = 0;
+
+ virtual bool Compile(const char* Source,
+ size_t SourceLength,
+ const wchar_t* EntryPoint,
+ const wchar_t* Profile,
+ const DxcDefine* pDefines,
+ size_t DefinesCount,
+ const wchar_t** pArgs,
+ size_t ArgsCount,
+ IShaderSourceInputStreamFactory* pShaderSourceStreamFactory,
+ IDxcBlob** ppBlobOut,
+ IDxcBlob** ppCompilerOutput) = 0;
};
// Use this function to load specific library,
// otherwise default library will be implicitly loaded.
-bool DxcLoadLibrary(DXCompilerTarget Target, const char* name);
+IDxCompilerLibrary* CreateDXCompiler(DXCompilerTarget Target, const char* pLibraryName);
-bool DxcGetMaxShaderModel(DXCompilerTarget Target,
- ShaderVersion& Version);
-bool DxcCompile(DXCompilerTarget Target,
- const char* Source,
- size_t SourceLength,
- const wchar_t* EntryPoint,
- const wchar_t* Profile,
- const DxcDefine* pDefines,
- size_t DefinesCount,
- const wchar_t** pArgs,
- size_t ArgsCount,
- IShaderSourceInputStreamFactory* pShaderSourceStreamFactory,
- IDxcBlob** ppBlobOut,
- IDxcBlob** ppCompilerOutput);
-
-std::vector<uint32_t> DXILtoSPIRV(const ShaderCreateInfo& Attribs,
+#if VULKAN_SUPPORTED
+std::vector<uint32_t> DXILtoSPIRV(IDxCompilerLibrary* pLibrary,
+ const ShaderCreateInfo& Attribs,
const char* ExtraDefinitions,
IDataBlob** ppCompilerOutput) noexcept(false);
+#endif
#if D3D12_SUPPORTED
// Returns false if pShaderBytecode hasn't DXIL bytecode.
// Throws exception on error.
-bool DxcGetShaderReflection(IDxcBlob* pShaderBytecode,
+bool DxcGetShaderReflection(IDxCompilerLibrary* pLibrary,
+ IDxcBlob* pShaderBytecode,
ID3D12ShaderReflection** ppShaderReflection) noexcept(false);
#endif
diff --git a/Graphics/HLSLTools/src/DXCompilerBaseLiunx.hpp b/Graphics/HLSLTools/src/DXCompilerBaseLiunx.hpp
new file mode 100644
index 00000000..ff8ad75a
--- /dev/null
+++ b/Graphics/HLSLTools/src/DXCompilerBaseLiunx.hpp
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2019-2020 Diligent Graphics LLC
+ * Copyright 2015-2019 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#ifdef PLATFORM_LINUX
+
+# include "DXILUtils.hpp"
+
+# include "dxc/dxcapi.h"
+
+namespace Diligent
+{
+namespace
+{
+
+class DXCompilerBase : public IDxCompilerLibrary
+{
+public:
+ ~DXCompilerBase() override
+ {
+ if (Module)
+ dlclose(Module);
+ }
+
+protected:
+ DxcCreateInstanceProc Load(DXCompilerTarget, const String& LibName)
+ {
+ if (LibName.size())
+ Module = dlopen(LibName.c_str(), RTLD_LOCAL | RTLD_LAZY);
+
+ if (Module == nullptr)
+ Module = dlopen("libdxcompiler.so", RTLD_LOCAL | RTLD_LAZY);
+
+ // try to load from default path
+ if (Module == nullptr)
+ Module = dlopen("/usr/lib/dxc/libdxcompiler.so", RTLD_LOCAL | RTLD_LAZY);
+
+ return Module ? reinterpret_cast<DxcCreateInstanceProc>(dlsym(Module, "DxcCreateInstance")) : nullptr;
+ }
+
+private:
+ void* Module = nullptr;
+};
+
+} // namespace
+} // namespace Diligent
+
+#endif // PLATFORM_LINUX \ No newline at end of file
diff --git a/Graphics/HLSLTools/src/DXCompilerBaseUWP.hpp b/Graphics/HLSLTools/src/DXCompilerBaseUWP.hpp
new file mode 100644
index 00000000..f8b9771e
--- /dev/null
+++ b/Graphics/HLSLTools/src/DXCompilerBaseUWP.hpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2019-2020 Diligent Graphics LLC
+ * Copyright 2015-2019 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#ifdef PLATFORM_UNIVERSAL_WINDOWS
+
+# ifdef WIN32
+# include <Unknwn.h>
+# include <guiddef.h>
+# include <atlbase.h>
+# include <atlcom.h>
+# endif
+
+# include "dxc/dxcapi.h"
+
+# include "DXILUtils.hpp"
+
+# if D3D12_SUPPORTED
+# include <d3d12shader.h>
+# endif
+
+namespace Diligent
+{
+namespace
+{
+
+class DXCompilerBase : public IDxCompilerLibrary
+{
+public:
+ ~DXCompilerBase() override
+ {
+ if (Module)
+ FreeLibrary(Module);
+ }
+
+protected:
+ DxcCreateInstanceProc Load(DXCompilerTarget, const String& LibName)
+ {
+ if (LibName.size())
+ {
+ std::wstring wname{LibName.begin(), LibName.end()};
+ wname += L".dll";
+
+ Module = LoadPackagedLibrary(wname.c_str(), 0);
+ }
+
+ if (Module == nullptr)
+ Module = LoadPackagedLibrary(L"dxcompiler.dll", 0);
+
+ return Module ? reinterpret_cast<DxcCreateInstanceProc>(GetProcAddress(Module, "DxcCreateInstance")) : nullptr;
+ }
+
+private:
+ HMODULE Module = nullptr;
+};
+
+} // namespace
+} // namespace Diligent
+
+#endif // PLATFORM_UNIVERSAL_WINDOWS \ No newline at end of file
diff --git a/Graphics/HLSLTools/src/DXCompilerBaseWin32.hpp b/Graphics/HLSLTools/src/DXCompilerBaseWin32.hpp
new file mode 100644
index 00000000..b186bcf1
--- /dev/null
+++ b/Graphics/HLSLTools/src/DXCompilerBaseWin32.hpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2019-2020 Diligent Graphics LLC
+ * Copyright 2015-2019 Egor Yusov
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * In no event and under no legal theory, whether in tort (including negligence),
+ * contract, or otherwise, unless required by applicable law (such as deliberate
+ * and grossly negligent acts) or agreed to in writing, shall any Contributor be
+ * liable for any damages, including any direct, indirect, special, incidental,
+ * or consequential damages of any character arising as a result of this License or
+ * out of the use or inability to use the software (including but not limited to damages
+ * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
+ * all other commercial damages or losses), even if such Contributor has been advised
+ * of the possibility of such damages.
+ */
+
+#ifdef PLATFORM_WIN32
+
+# ifdef WIN32
+# include <Unknwn.h>
+# include <guiddef.h>
+# include <atlbase.h>
+# include <atlcom.h>
+# endif
+
+# include "dxc/dxcapi.h"
+
+# include "DXILUtils.hpp"
+
+# if D3D12_SUPPORTED
+# include <d3d12shader.h>
+# endif
+
+namespace Diligent
+{
+namespace
+{
+
+class DXCompilerBase : public IDxCompilerLibrary
+{
+public:
+ ~DXCompilerBase() override
+ {
+ if (Module)
+ FreeLibrary(Module);
+ }
+
+protected:
+ DxcCreateInstanceProc Load(DXCompilerTarget Target, const String& LibName)
+ {
+ if (LibName.size())
+ Module = LoadLibraryA(LibName.c_str());
+
+ if (Module == nullptr)
+ {
+ switch (Target)
+ {
+ case DXCompilerTarget::Direct3D12: Module = LoadLibraryA("dxcompiler.dll"); break;
+ case DXCompilerTarget::Vulkan: Module = LoadLibraryA("spv_dxcompiler.dll"); break;
+ }
+ }
+
+ return Module ? reinterpret_cast<DxcCreateInstanceProc>(GetProcAddress(Module, "DxcCreateInstance")) : nullptr;
+ }
+
+private:
+ HMODULE Module = nullptr;
+};
+
+} // namespace
+} // namespace Diligent
+
+#endif // PLATFORM_WIN32 \ No newline at end of file
diff --git a/Graphics/HLSLTools/src/DXILUtils.cpp b/Graphics/HLSLTools/src/DXILUtils.cpp
index cc343414..58211993 100644
--- a/Graphics/HLSLTools/src/DXILUtils.cpp
+++ b/Graphics/HLSLTools/src/DXILUtils.cpp
@@ -29,24 +29,14 @@
#include <unordered_map>
#include <memory>
#include <array>
-
-#ifdef WIN32
-# include <Unknwn.h>
-# include <guiddef.h>
-# include <atlbase.h>
-# include <atlcom.h>
-#endif
-
-#include "DXILUtils.hpp"
+#include <mutex>
// Platforms that has DXCompiler.
#if defined(PLATFORM_WIN32) || defined(PLATFORM_UNIVERSAL_WINDOWS) || defined(PLATFORM_LINUX)
-# if D3D12_SUPPORTED
-# include <d3d12shader.h>
-# endif
-
-# include "dxc/dxcapi.h"
+# include "DXCompilerBaseLiunx.hpp"
+# include "DXCompilerBaseUWP.hpp"
+# include "DXCompilerBaseWin32.hpp"
# include "DataBlobImpl.hpp"
# include "RefCntAutoPtr.hpp"
@@ -56,92 +46,60 @@ namespace Diligent
namespace
{
-# ifdef PLATFORM_WIN32
-struct DXCompilerBase
+class DXCompilerImpl final : public DXCompilerBase
{
- HMODULE Module = nullptr;
- DxcCreateInstanceProc CreateInstance = nullptr;
-
- ~DXCompilerBase()
- {
- if (Module)
- FreeLibrary(Module);
- }
+public:
+ DXCompilerImpl(DXCompilerTarget Target, const char* pLibName) :
+ m_Target{Target},
+ m_LibName{pLibName ? pLibName : ""}
+ {}
- void Load(const char* libName)
+ ShaderVersion GetMaxShaderModel() override
{
- if (Module)
- FreeLibrary(Module);
-
- Module = LoadLibraryA(libName);
- CreateInstance = Module ? reinterpret_cast<DxcCreateInstanceProc>(GetProcAddress(Module, "DxcCreateInstance")) : nullptr;
+ Load();
+ // mutex is not needed here
+ return m_MaxShaderModel;
}
-};
-# endif // PLATFORM_WIN32
-
-# ifdef PLATFORM_UNIVERSAL_WINDOWS
-struct DXCompilerBase
-{
- HMODULE Module = nullptr;
- DxcCreateInstanceProc CreateInstance = nullptr;
- ~DXCompilerBase()
+ bool IsLoaded() override
{
- if (Module)
- FreeLibrary(Module);
+ return GetCreateInstaceProc() != nullptr;
}
- void Load(const char* libName)
+ DxcCreateInstanceProc GetCreateInstaceProc()
{
- if (Module)
- FreeLibrary(Module);
-
- std::wstring wname{libName, libName + strlen(libName)};
- wname += L".dll";
-
- Module = LoadPackagedLibrary(wname.c_str(), 0);
- CreateInstance = Module ? reinterpret_cast<DxcCreateInstanceProc>(GetProcAddress(Module, "DxcCreateInstance")) : nullptr;
+ Load();
+ // mutex is not needed here
+ return m_pCreateInstance;
}
-};
-# endif // PLATFORM_UNIVERSAL_WINDOWS
-
-# ifdef PLATFORM_LINUX
-struct DXCompilerBase
-{
- void* Module = nullptr;
- DxcCreateInstanceProc CreateInstance = nullptr;
- ~DXCompilerBase()
- {
- if (Module)
- dlclose(Module);
- }
+ bool Compile(const char* Source,
+ size_t SourceLength,
+ const wchar_t* EntryPoint,
+ const wchar_t* Profile,
+ const DxcDefine* pDefines,
+ size_t DefinesCount,
+ const wchar_t** pArgs,
+ size_t ArgsCount,
+ IShaderSourceInputStreamFactory* pShaderSourceStreamFactory,
+ IDxcBlob** ppBlobOut,
+ IDxcBlob** ppCompilerOutput) override;
- void Load(const char* libName)
+private:
+ void Load()
{
- if (Module)
- dlclose(Module);
+ std::unique_lock<std::mutex> lock{m_Guard};
- Module = dlopen(libName, RTLD_LOCAL | RTLD_LAZY);
- CreateInstance = Module ? reinterpret_cast<DxcCreateInstanceProc>(dlsym(Module, "DxcCreateInstance")) : nullptr;
- }
-};
-# endif // PLATFORM_LINUX
-
-
-struct DXCompilerImpl : DXCompilerBase
-{
- ShaderVersion MaxShaderModel{6, 0};
+ if (m_IsInitialized)
+ return;
- DXCompilerImpl() = default;
+ m_IsInitialized = true;
+ m_pCreateInstance = DXCompilerBase::Load(m_Target, m_LibName);
- void Load(const char* libName)
- {
- DXCompilerBase::Load(libName);
- if (CreateInstance)
+ if (m_pCreateInstance)
{
CComPtr<IDxcValidator> validator;
- if (SUCCEEDED(CreateInstance(CLSID_DxcValidator, IID_PPV_ARGS(&validator))))
+ if (SUCCEEDED(m_pCreateInstance(CLSID_DxcValidator, IID_PPV_ARGS(&validator))))
{
CComPtr<IDxcVersionInfo> info;
if (SUCCEEDED(validator->QueryInterface(IID_PPV_ARGS(&info))))
@@ -156,37 +114,26 @@ struct DXCompilerImpl : DXCompilerBase
// map known DXC version to maximum SM
switch (ver)
{
- case 0x10005: MaxShaderModel = {6, 5}; break; // SM 6.5 and SM 6.6 preview
- case 0x10004: MaxShaderModel = {6, 4}; break; // SM 6.4 and SM 6.5 preview
+ case 0x10005: m_MaxShaderModel = {6, 5}; break; // SM 6.5 and SM 6.6 preview
+ case 0x10004: m_MaxShaderModel = {6, 4}; break; // SM 6.4 and SM 6.5 preview
case 0x10003:
- case 0x10002: MaxShaderModel = {6, 1}; break; // SM 6.1 and SM 6.2 preview
- default: MaxShaderModel = (ver > 0x10005 ? ShaderVersion{6, 6} : ShaderVersion{6, 0}); break;
+ case 0x10002: m_MaxShaderModel = {6, 1}; break; // SM 6.1 and SM 6.2 preview
+ default: m_MaxShaderModel = (ver > 0x10005 ? ShaderVersion{6, 6} : ShaderVersion{6, 0}); break;
}
}
}
}
}
-};
-static DXCompilerImpl* DXILCompilerLib()
-{
-# if D3D12_SUPPORTED
- static DXCompilerImpl inst;
- return &inst;
-# else
- return nullptr;
-# endif
-}
+private:
+ DxcCreateInstanceProc m_pCreateInstance = nullptr;
+ bool m_IsInitialized = false;
+ ShaderVersion m_MaxShaderModel;
+ std::mutex m_Guard;
+ const String m_LibName;
+ const DXCompilerTarget m_Target;
+};
-static DXCompilerImpl* SPIRVCompilerLib()
-{
-# if VULKAN_SUPPORTED
- static DXCompilerImpl inst;
- return &inst;
-# else
- return nullptr;
-# endif
-}
class DxcIncludeHandlerImpl final : public IDxcIncludeHandler
{
@@ -271,79 +218,27 @@ private:
} // namespace
-bool DxcLoadLibrary(DXCompilerTarget Target, const char* name)
-{
- DXCompilerImpl* DxCompiler = nullptr;
- switch (Target)
- {
- case DXCompilerTarget::Direct3D12: DxCompiler = DXILCompilerLib(); break;
- case DXCompilerTarget::Vulkan: DxCompiler = SPIRVCompilerLib(); break;
- }
- if (DxCompiler == nullptr)
- return false;
-
- if (name != nullptr)
- DxCompiler->Load(name);
-
- if (DxCompiler->CreateInstance == nullptr)
- {
- switch (Target)
- {
- case DXCompilerTarget::Direct3D12:
- name = "dxcompiler.dll";
- break;
- case DXCompilerTarget::Vulkan:
-# ifdef PLATFORM_LINUX
- name = "/usr/lib/dxc/libdxcompiler.so";
-# else
- name = "spv_dxcompiler.dll";
-# endif
- break;
- }
- DxCompiler->Load(name);
- }
-
- return DxCompiler->CreateInstance != nullptr;
-}
-bool DxcGetMaxShaderModel(DXCompilerTarget Target,
- ShaderVersion& Version)
+IDxCompilerLibrary* CreateDXCompiler(DXCompilerTarget Target, const char* pLibraryName)
{
- DXCompilerImpl* DxCompiler = nullptr;
- switch (Target)
- {
- case DXCompilerTarget::Direct3D12: DxCompiler = DXILCompilerLib(); break;
- case DXCompilerTarget::Vulkan: DxCompiler = SPIRVCompilerLib(); break;
- }
-
- if (DxCompiler == nullptr || DxCompiler->Module == nullptr)
- return false;
-
- Version = DxCompiler->MaxShaderModel;
- return true;
+ return new DXCompilerImpl{Target, pLibraryName};
}
-bool DxcCompile(DXCompilerTarget Target,
- const char* Source,
- size_t SourceLength,
- const wchar_t* EntryPoint,
- const wchar_t* Profile,
- const DxcDefine* pDefines,
- size_t DefinesCount,
- const wchar_t** pArgs,
- size_t ArgsCount,
- IShaderSourceInputStreamFactory* pShaderSourceStreamFactory,
- IDxcBlob** ppBlobOut,
- IDxcBlob** ppCompilerOutput)
+bool DXCompilerImpl::Compile(const char* Source,
+ size_t SourceLength,
+ const wchar_t* EntryPoint,
+ const wchar_t* Profile,
+ const DxcDefine* pDefines,
+ size_t DefinesCount,
+ const wchar_t** pArgs,
+ size_t ArgsCount,
+ IShaderSourceInputStreamFactory* pShaderSourceStreamFactory,
+ IDxcBlob** ppBlobOut,
+ IDxcBlob** ppCompilerOutput)
{
- DXCompilerImpl* DxCompiler = nullptr;
- switch (Target)
- {
- case DXCompilerTarget::Direct3D12: DxCompiler = DXILCompilerLib(); break;
- case DXCompilerTarget::Vulkan: DxCompiler = SPIRVCompilerLib(); break;
- }
+ auto CreateInstance = GetCreateInstaceProc();
- if (DxCompiler == nullptr || DxCompiler->CreateInstance == nullptr)
+ if (CreateInstance == nullptr)
{
LOG_ERROR("Failed to load DXCompiler");
return false;
@@ -360,12 +255,12 @@ bool DxcCompile(DXCompilerTarget Target,
HRESULT hr;
CComPtr<IDxcLibrary> library;
- hr = DxCompiler->CreateInstance(CLSID_DxcLibrary, IID_PPV_ARGS(&library));
+ hr = CreateInstance(CLSID_DxcLibrary, IID_PPV_ARGS(&library));
if (FAILED(hr))
return false;
CComPtr<IDxcCompiler> compiler;
- hr = DxCompiler->CreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&compiler));
+ hr = CreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&compiler));
if (FAILED(hr))
return false;
@@ -413,10 +308,10 @@ bool DxcCompile(DXCompilerTarget Target,
return false;
// validate and sign in
- if (Target == DXCompilerTarget::Direct3D12)
+ if (m_Target == DXCompilerTarget::Direct3D12)
{
CComPtr<IDxcValidator> validator;
- hr = DxCompiler->CreateInstance(CLSID_DxcValidator, IID_PPV_ARGS(&validator));
+ hr = CreateInstance(CLSID_DxcValidator, IID_PPV_ARGS(&validator));
if (FAILED(hr))
return false;
@@ -461,20 +356,21 @@ bool DxcCompile(DXCompilerTarget Target,
# if D3D12_SUPPORTED
# define FOURCC(a, b, c, d) (uint32_t{((d) << 24) | ((c) << 16) | ((b) << 8) | (a)})
-bool DxcGetShaderReflection(IDxcBlob* pShaderBytecode,
+bool DxcGetShaderReflection(IDxCompilerLibrary* pLibrary,
+ IDxcBlob* pShaderBytecode,
ID3D12ShaderReflection** ppShaderReflection) noexcept(false)
{
HRESULT hr;
- auto DXCompiler = DXILCompilerLib();
- bool IsDXIL = false;
+ bool IsDXIL = false;
+ auto CreateInstance = pLibrary ? static_cast<DXCompilerImpl*>(pLibrary)->GetCreateInstaceProc() : nullptr;
- if (DXCompiler != nullptr && DXCompiler->CreateInstance != nullptr)
+ if (CreateInstance != nullptr)
{
const uint32_t DFCC_DXIL = FOURCC('D', 'X', 'I', 'L');
CComPtr<IDxcContainerReflection> pReflection;
UINT32 shaderIdx;
- hr = DXCompiler->CreateInstance(CLSID_DxcContainerReflection, IID_PPV_ARGS(&pReflection));
+ hr = CreateInstance(CLSID_DxcContainerReflection, IID_PPV_ARGS(&pReflection));
if (FAILED(hr))
LOG_ERROR_AND_THROW("Failed to create shader reflection instance");
@@ -512,7 +408,8 @@ static const char g_HLSLDefinitions[] =
} // namespace
-std::vector<uint32_t> DXILtoSPIRV(const ShaderCreateInfo& Attribs,
+std::vector<uint32_t> DXILtoSPIRV(IDxCompilerLibrary* pLibrary,
+ const ShaderCreateInfo& Attribs,
const char* ExtraDefinitions,
IDataBlob** ppCompilerOutput) noexcept(false)
{
@@ -567,16 +464,13 @@ std::vector<uint32_t> DXILtoSPIRV(const ShaderCreateInfo& Attribs,
// validate shader version
ShaderVersion ShaderModel = Attribs.HLSLVersion;
- ShaderVersion MaxSM;
+ ShaderVersion MaxSM = pLibrary->GetMaxShaderModel();
- if (DxcGetMaxShaderModel(DXCompilerTarget::Vulkan, MaxSM))
- {
- if (ShaderModel.Major < 6 || ShaderModel.Major > MaxSM.Major)
- ShaderModel = MaxSM;
+ if (ShaderModel.Major < 6 || ShaderModel.Major > MaxSM.Major)
+ ShaderModel = MaxSM;
- if (ShaderModel.Major == MaxSM.Major && ShaderModel.Minor > MaxSM.Minor)
- ShaderModel = MaxSM;
- }
+ if (ShaderModel.Major == MaxSM.Major && ShaderModel.Minor > MaxSM.Minor)
+ ShaderModel = MaxSM;
std::wstring Profile;
switch (Attribs.Desc.ShaderType)
@@ -610,15 +504,14 @@ std::vector<uint32_t> DXILtoSPIRV(const ShaderCreateInfo& Attribs,
CComPtr<IDxcBlob> compiled;
CComPtr<IDxcBlob> errors;
- bool result = DxcCompile(DXCompilerTarget::Vulkan,
- Source.c_str(), Source.length(),
- std::wstring{Attribs.EntryPoint, Attribs.EntryPoint + strlen(Attribs.EntryPoint)}.c_str(),
- Profile.c_str(),
- nullptr, 0,
- pArgs, _countof(pArgs),
- Attribs.pShaderSourceStreamFactory,
- &compiled,
- &errors);
+ bool result = pLibrary->Compile(Source.c_str(), Source.length(),
+ std::wstring{Attribs.EntryPoint, Attribs.EntryPoint + strlen(Attribs.EntryPoint)}.c_str(),
+ Profile.c_str(),
+ nullptr, 0,
+ pArgs, _countof(pArgs),
+ Attribs.pShaderSourceStreamFactory,
+ &compiled,
+ &errors);
const size_t CompilerMsgLen = errors ? errors->GetBufferSize() : 0;
const char* CompilerMsg = CompilerMsgLen > 0 ? static_cast<const char*>(errors->GetBufferPointer()) : nullptr;
@@ -660,37 +553,18 @@ std::vector<uint32_t> DXILtoSPIRV(const ShaderCreateInfo& Attribs,
#else
-namespace Diligent
-{
+# include "DXILUtils.hpp"
-bool DxcLoadLibrary(DXCompilerTarget Target, const char* name)
-{
- return false;
-}
-
-bool DxcGetMaxShaderModel(DXCompilerTarget Target,
- ShaderVersion& Version)
+namespace Diligent
{
- return false;
-}
-bool DxcCompile(DXCompilerTarget Target,
- const char* Source,
- size_t SourceLength,
- const wchar_t* EntryPoint,
- const wchar_t* Profile,
- const DxcDefine* pDefines,
- size_t DefinesCount,
- const wchar_t** pArgs,
- size_t ArgsCount,
- IShaderSourceInputStreamFactory* pShaderSourceStreamFactory,
- IDxcBlob** ppBlobOut,
- IDxcBlob** ppCompilerOutput)
+IDxCompilerLibrary* CreateDXCompiler(DXCompilerTarget Target, const char* pLibraryName)
{
- return false;
+ return nullptr;
}
-std::vector<uint32_t> DXILtoSPIRV(const ShaderCreateInfo& Attribs,
+std::vector<uint32_t> DXILtoSPIRV(IDxCompilerLibrary* pLibrary,
+ const ShaderCreateInfo& Attribs,
const char* ExtraDefinitions,
IDataBlob** ppCompilerOutput) noexcept(false)
{