diff options
| author | azhirnov <zh1dron@gmail.com> | 2020-09-09 09:25:47 +0000 |
|---|---|---|
| committer | azhirnov <zh1dron@gmail.com> | 2020-09-09 15:56:51 +0000 |
| commit | 381f66352dfaefcdeaeba3c71183ad558bb70cd6 (patch) | |
| tree | a18b2fa0763a310317f6926677d87d91666bf4b6 /Graphics | |
| parent | Merge branch 'master' into mesh_shader (diff) | |
| download | DiligentCore-381f66352dfaefcdeaeba3c71183ad558bb70cd6.tar.gz DiligentCore-381f66352dfaefcdeaeba3c71183ad558bb70cd6.zip | |
added IDxCompilerLibrary interface. DXCompilerBase moved to platform specific files
Diffstat (limited to 'Graphics')
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) { |
