diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2020-09-08 05:00:23 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2020-09-09 16:18:08 +0000 |
| commit | 90a707ecb5d7985c261faf1903e849548c046b02 (patch) | |
| tree | 0d853d782deae54ce7a41924c50b432ac7aa464a /Graphics | |
| parent | Added DILIGENT_NO_FORMAT_VALIDATION cmake option (diff) | |
| download | DiligentCore-90a707ecb5d7985c261faf1903e849548c046b02.tar.gz DiligentCore-90a707ecb5d7985c261faf1903e849548c046b02.zip | |
A bunch of random updates
Diffstat (limited to 'Graphics')
25 files changed, 343 insertions, 236 deletions
diff --git a/Graphics/GraphicsAccessories/interface/GraphicsAccessories.hpp b/Graphics/GraphicsAccessories/interface/GraphicsAccessories.hpp index 3ebbb28e..0a7d115a 100644 --- a/Graphics/GraphicsAccessories/interface/GraphicsAccessories.hpp +++ b/Graphics/GraphicsAccessories/interface/GraphicsAccessories.hpp @@ -378,6 +378,8 @@ const char* GetQueryTypeString(QUERY_TYPE QueryType); const char* GetSurfaceTransformString(SURFACE_TRANSFORM SrfTransform); +const char* GetPipelineTypeString(PIPELINE_TYPE PipelineType); + Uint32 ComputeMipLevelsCount(Uint32 Width); Uint32 ComputeMipLevelsCount(Uint32 Width, Uint32 Height); Uint32 ComputeMipLevelsCount(Uint32 Width, Uint32 Height, Uint32 Depth); diff --git a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp index d32c263b..7979cfbb 100644 --- a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp +++ b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp @@ -474,21 +474,22 @@ const Char* GetBufferViewTypeLiteralName(BUFFER_VIEW_TYPE ViewType) const Char* GetShaderTypeLiteralName(SHADER_TYPE ShaderType) { + static_assert(SHADER_TYPE_LAST == SHADER_TYPE_MESH, "Please update the switch below to handle the new shader type"); switch (ShaderType) { // clang-format off #define RETURN_SHADER_TYPE_NAME(ShaderType)\ case ShaderType: return #ShaderType; - RETURN_SHADER_TYPE_NAME( SHADER_TYPE_UNKNOWN ) - RETURN_SHADER_TYPE_NAME( SHADER_TYPE_VERTEX ) - RETURN_SHADER_TYPE_NAME( SHADER_TYPE_PIXEL ) - RETURN_SHADER_TYPE_NAME( SHADER_TYPE_GEOMETRY ) - RETURN_SHADER_TYPE_NAME( SHADER_TYPE_HULL ) - RETURN_SHADER_TYPE_NAME( SHADER_TYPE_DOMAIN ) - RETURN_SHADER_TYPE_NAME( SHADER_TYPE_COMPUTE ) - RETURN_SHADER_TYPE_NAME( SHADER_TYPE_AMPLIFICATION) - RETURN_SHADER_TYPE_NAME( SHADER_TYPE_MESH ) + RETURN_SHADER_TYPE_NAME(SHADER_TYPE_UNKNOWN ) + RETURN_SHADER_TYPE_NAME(SHADER_TYPE_VERTEX ) + RETURN_SHADER_TYPE_NAME(SHADER_TYPE_PIXEL ) + RETURN_SHADER_TYPE_NAME(SHADER_TYPE_GEOMETRY ) + RETURN_SHADER_TYPE_NAME(SHADER_TYPE_HULL ) + RETURN_SHADER_TYPE_NAME(SHADER_TYPE_DOMAIN ) + RETURN_SHADER_TYPE_NAME(SHADER_TYPE_COMPUTE ) + RETURN_SHADER_TYPE_NAME(SHADER_TYPE_AMPLIFICATION) + RETURN_SHADER_TYPE_NAME(SHADER_TYPE_MESH ) #undef RETURN_SHADER_TYPE_NAME // clang-format on @@ -1120,6 +1121,23 @@ const char* GetSurfaceTransformString(SURFACE_TRANSFORM SrfTransform) // clang-format on } +const char* GetPipelineTypeString(PIPELINE_TYPE PipelineType) +{ + // clang-format off + switch (PipelineType) + { + case PIPELINE_TYPE_COMPUTE: return "compute"; + case PIPELINE_TYPE_GRAPHICS: return "graphics"; + case PIPELINE_TYPE_MESH: return "mesh"; + + default: + UNEXPECTED("Unexpected pipeline type"); + return "unknown"; + } + // clang-format on +} + + Uint32 ComputeMipLevelsCount(Uint32 Width) { if (Width == 0) diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp index 48aab98b..02a74f85 100644 --- a/Graphics/GraphicsEngine/include/PipelineStateBase.hpp +++ b/Graphics/GraphicsEngine/include/PipelineStateBase.hpp @@ -191,11 +191,11 @@ public: { DEV_CHECK_ERR(GraphicsPipeline.pMS, "Mesh shader must be defined"); DEV_CHECK_ERR(!GraphicsPipeline.pVS && !GraphicsPipeline.pGS && !GraphicsPipeline.pDS && !GraphicsPipeline.pHS, - "Vertex, geometry and tessellation shaders are not supported in mesh pipeline"); + "Vertex, geometry and tessellation shaders are not supported in a mesh pipeline"); DEV_CHECK_ERR(GraphicsPipeline.InputLayout.NumElements == 0, "Input layout ignored in mesh shader"); DEV_CHECK_ERR(GraphicsPipeline.PrimitiveTopology == PRIMITIVE_TOPOLOGY_TRIANGLE_LIST || GraphicsPipeline.PrimitiveTopology == PRIMITIVE_TOPOLOGY_UNDEFINED, - "Primitive topology ignored in mesh pipeline, set it to undefined or keep default value (triangle list)"); + "Primitive topology is ignored in a mesh pipeline, set it to undefined or keep default value (triangle list)"); m_pAS = GraphicsPipeline.pAS; m_pMS = GraphicsPipeline.pMS; m_pPS = GraphicsPipeline.pPS; @@ -451,18 +451,7 @@ protected: size_t m_ShaderResourceLayoutHash = 0; ///< Hash computed from the shader resource layout private: -#define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ", PipelineTypeToString(), " PSO '", this->m_Desc.Name, "' is invalid: ", ##__VA_ARGS__) - - const char* PipelineTypeToString() const - { - switch (this->m_Desc.PipelineType) - { - case PIPELINE_TYPE_COMPUTE: return "compute"; - case PIPELINE_TYPE_GRAPHICS: return "graphics"; - case PIPELINE_TYPE_MESH: return "mesh"; - } - return "unknown"; - } +#define LOG_PSO_ERROR_AND_THROW(...) LOG_ERROR_AND_THROW("Description of ", GetPipelineTypeString(this->m_Desc.PipelineType), " PSO '", this->m_Desc.Name, "' is invalid: ", ##__VA_ARGS__) void ValidateDesc() const { diff --git a/Graphics/GraphicsEngine/include/ShaderBase.hpp b/Graphics/GraphicsEngine/include/ShaderBase.hpp index f3d3f6cc..17dec618 100644 --- a/Graphics/GraphicsEngine/include/ShaderBase.hpp +++ b/Graphics/GraphicsEngine/include/ShaderBase.hpp @@ -54,6 +54,7 @@ inline Int32 GetShaderTypeIndex(SHADER_TYPE Type) Int32 ShaderIndex = PlatformMisc::GetLSB(Type); #ifdef DILIGENT_DEBUG + static_assert(SHADER_TYPE_LAST == SHADER_TYPE_MESH, "Please update the switch below to handle the new shader type"); switch (Type) { // clang-format off diff --git a/Graphics/GraphicsEngine/interface/DeviceCaps.h b/Graphics/GraphicsEngine/interface/DeviceCaps.h index 104481d3..b5bb866a 100644 --- a/Graphics/GraphicsEngine/interface/DeviceCaps.h +++ b/Graphics/GraphicsEngine/interface/DeviceCaps.h @@ -121,6 +121,9 @@ struct DeviceFeatures /// Indicates if device supports tessellation Bool Tessellation DEFAULT_INITIALIZER(False); + /// Indicates if device supports mesh and amplification shaders + Bool MeshShaders DEFAULT_INITIALIZER(False); + /// Indicates if device supports bindless resources Bool BindlessResources DEFAULT_INITIALIZER(False); @@ -167,9 +170,6 @@ struct DeviceFeatures /// Specifies whether all the extended UAV texture formats are available in shader code. Bool TextureUAVExtendedFormats DEFAULT_INITIALIZER(False); - - /// Indicates if device supports mesh and amplification shaders - Bool MeshShaders DEFAULT_INITIALIZER(False); }; typedef struct DeviceFeatures DeviceFeatures; diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index ae237638..18e53478 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -281,6 +281,7 @@ struct DrawIndexedAttribs }; typedef struct DrawIndexedAttribs DrawIndexedAttribs; + /// Defines the indirect draw command attributes. /// This structure is used by IDeviceContext::DrawIndirect(). @@ -319,6 +320,7 @@ struct DrawIndirectAttribs }; typedef struct DrawIndirectAttribs DrawIndirectAttribs; + /// Defines the indexed indirect draw command attributes. /// This structure is used by IDeviceContext::DrawIndexedIndirect(). @@ -364,12 +366,13 @@ struct DrawIndexedIndirectAttribs }; typedef struct DrawIndexedIndirectAttribs DrawIndexedIndirectAttribs; + /// Defines the mesh draw command attributes. /// This structure is used by IDeviceContext::DrawMesh(). struct DrawMeshAttribs { - ///< Number of dispatched groups + /// The number of dispatched groups Uint32 ThreadGroupCount DEFAULT_INITIALIZER(1); /// Additional flags, see Diligent::DRAW_FLAGS. @@ -389,6 +392,7 @@ struct DrawMeshAttribs }; typedef struct DrawMeshAttribs DrawMeshAttribs; + /// Defines the mesh indirect draw command attributes. /// This structure is used by IDeviceContext::DrawMeshIndirect(). @@ -426,6 +430,7 @@ struct DrawMeshIndirectAttribs }; typedef struct DrawMeshIndirectAttribs DrawMeshIndirectAttribs; + /// Defines which parts of the depth-stencil buffer to clear. /// These flags are used by IDeviceContext::ClearDepthStencil(). @@ -1060,13 +1065,13 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContext, IObject) IBuffer* pAttribsBuffer) PURE; - /// Executes an mesh draw command. + /// Executes a mesh draw command. /// \param [in] Attribs - Draw command attributes, see Diligent::DrawMeshAttribs for details. /// - /// \remarks For compatibility between Direct3D12 and Vulkan used only single work group dimension. - /// Also in shader numthreads and local_size attributes must use only single dimension, - /// example: '[numthreads(ThreadCount, 1, 1)]' or 'layout(local_size_x = ThreadCount) in'. + /// \remarks For compatibility between Direct3D12 and Vulkan, only a single work group dimension is used. + /// Also in the shader, 'numthreads' and 'local_size' attributes must define only the first dimension, + /// for example: '[numthreads(ThreadCount, 1, 1)]' or 'layout(local_size_x = ThreadCount) in'. VIRTUAL void METHOD(DrawMesh)(THIS_ const DrawMeshAttribs REF Attribs) PURE; @@ -1084,8 +1089,8 @@ DILIGENT_BEGIN_INTERFACE(IDeviceContext, IObject) /// Uint32 TaskCount; /// Uint32 FirstTask; /// - /// \remarks For compatibility between Direct3D12 and Vulkan and with direct call (DrawMesh) use only first element in structure, - /// example: Direct3D12 {TaskCount, 1, 1}, Vulkan {TaskCount, 0}. + /// \remarks For compatibility between Direct3D12 and Vulkan and with direct call (DrawMesh) use define the first element in the structure, + /// for example: Direct3D12 {TaskCount, 1, 1}, Vulkan {TaskCount, 0}. /// /// \remarks If IndirectAttribsBufferStateTransitionMode member is Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION, /// the method may transition the state of the indirect draw arguments buffer. This is not a thread safe operation, diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index c6a9eb5c..40ac9671 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -1686,8 +1686,8 @@ struct EngineD3D12CreateInfo DILIGENT_DERIVE(EngineCreateInfo) #endif ; - /// Path to DirectX Shader Compiler, which required to use Shader Module 6 features. - /// By default engine will search for "dxcompiler.dll". + /// Path to DirectX Shader Compiler, which is required to use Shader Model 6.0+ features. + /// By default, the engine will search for "dxcompiler.dll". const char* pDxCompilerPath DEFAULT_INITIALIZER(nullptr); }; typedef struct EngineD3D12CreateInfo EngineD3D12CreateInfo; @@ -1828,7 +1828,8 @@ struct EngineVkCreateInfo DILIGENT_DERIVE(EngineCreateInfo) #endif ; - /// Path to DirectX Shader Compiler, which required to use Shader Module 6 features for HLSL. + /// Path to DirectX Shader Compiler, which is required to use Shader Model 6.0+ + /// features when compiling shaders from HLSL. const char* pDxCompilerPath DEFAULT_INITIALIZER(nullptr); }; typedef struct EngineVkCreateInfo EngineVkCreateInfo; diff --git a/Graphics/GraphicsEngine/interface/PipelineState.h b/Graphics/GraphicsEngine/interface/PipelineState.h index d4361fde..7fe2fbb6 100644 --- a/Graphics/GraphicsEngine/interface/PipelineState.h +++ b/Graphics/GraphicsEngine/interface/PipelineState.h @@ -189,11 +189,11 @@ struct GraphicsPipelineDesc /// Depth-stencil state description. DepthStencilStateDesc DepthStencilDesc; - /// Input layout, ignored in mesh pipeline. + /// Input layout, ignored in a mesh pipeline. InputLayoutDesc InputLayout; //D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue; - /// Primitive topology type, ignored in mesh pipeline. + /// Primitive topology type, ignored in a mesh pipeline. PRIMITIVE_TOPOLOGY PrimitiveTopology DEFAULT_INITIALIZER(PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); /// The number of viewports used by this pipeline @@ -244,20 +244,22 @@ struct ComputePipelineDesc }; typedef struct ComputePipelineDesc ComputePipelineDesc; + /// Pipeline type DILIGENT_TYPED_ENUM(PIPELINE_TYPE, Uint8) { - /// Graphics pipeline used in IDeviceContext::Draw(), IDeviceContext::DrawIndexed(), + /// Graphics pipeline, which is used by IDeviceContext::Draw(), IDeviceContext::DrawIndexed(), /// IDeviceContext::DrawIndirect(), IDeviceContext::DrawIndexedIndirect(). PIPELINE_TYPE_GRAPHICS, - /// Compute pipeline used in IDeviceContext::DispatchCompute(), IDeviceContext::DispatchComputeIndirect(). + /// Compute pipeline, which is used by IDeviceContext::DispatchCompute(), IDeviceContext::DispatchComputeIndirect(). PIPELINE_TYPE_COMPUTE, - // Mesh pipeline used in IDeviceContext::DrawMesh(), IDeviceContext::DrawMeshIndirect(). + /// Mesh pipeline, which is used by IDeviceContext::DrawMesh(), IDeviceContext::DrawMeshIndirect(). PIPELINE_TYPE_MESH, }; + /// Pipeline state description struct PipelineStateDesc DILIGENT_DERIVE(DeviceObjectAttribs) @@ -276,10 +278,10 @@ struct PipelineStateDesc DILIGENT_DERIVE(DeviceObjectAttribs) /// Pipeline layout description PipelineResourceLayoutDesc ResourceLayout; - /// Graphics pipeline state description. This memeber is ignored if PipelineType != PIPELINE_TYPE_GRAPHICS or PIPELINE_TYPE_MESH + /// Graphics pipeline state description. This memeber is ignored if PipelineType is not PIPELINE_TYPE_GRAPHICS or PIPELINE_TYPE_MESH GraphicsPipelineDesc GraphicsPipeline; - /// Compute pipeline state description. This memeber is ignored if PipelineType != PIPELINE_TYPE_COMPUTE + /// Compute pipeline state description. This memeber is ignored if PipelineType is not PIPELINE_TYPE_COMPUTE ComputePipelineDesc ComputePipeline; #if DILIGENT_CPP_INTERFACE diff --git a/Graphics/GraphicsEngine/interface/Shader.h b/Graphics/GraphicsEngine/interface/Shader.h index a85ab726..7cffb0f1 100644 --- a/Graphics/GraphicsEngine/interface/Shader.h +++ b/Graphics/GraphicsEngine/interface/Shader.h @@ -58,7 +58,8 @@ DILIGENT_TYPED_ENUM(SHADER_TYPE, Uint32) }; DEFINE_FLAG_ENUM_OPERATORS(SHADER_TYPE); -/// Describes shader source code language + +/// Describes the shader source code language DILIGENT_TYPED_ENUM(SHADER_SOURCE_LANGUAGE, Uint32) { /// Default language (GLSL for OpenGL/OpenGLES/Vulkan devices, HLSL for Direct3D11/Direct3D12 devices) @@ -70,7 +71,7 @@ DILIGENT_TYPED_ENUM(SHADER_SOURCE_LANGUAGE, Uint32) /// The source language is GLSL SHADER_SOURCE_LANGUAGE_GLSL, - /// The source language is GLSL which should be compiled verbatim + /// The source language is GLSL that should be compiled verbatim /// By default the engine prepends GLSL shader source code with platform-specific /// definitions. For instance it adds appropriate #version directive (e.g. '#version 430 core' or @@ -80,28 +81,30 @@ DILIGENT_TYPED_ENUM(SHADER_SOURCE_LANGUAGE, Uint32) SHADER_SOURCE_LANGUAGE_GLSL_VERBATIM }; -/// Describes shader compiler + +/// Describes the shader compiler that will be used to compile the shader source code DILIGENT_TYPED_ENUM(SHADER_COMPILER, Uint32) { - /// Default compiler for specific language and API: - /// for Direct3D11 - external FXC - /// for Direct3D12 - external FXC - /// for OpenGL(ES) GLSL - native compiler - /// for OpenGL(ES) HLSL - HLSL2GLSL and native compiler - /// for Vulkan GLSL - builtin glslang - /// for Vulkan HLSL - builtin glslang (with limitted support for Shader Model 6.x) + /// Default compiler for specific language and API that is chosen as follows: + /// - Direct3D11: legacy HLSL compiler (FXC) + /// - Direct3D12: legacy HLSL compiler (FXC) + /// - OpenGL(ES) GLSL: native compiler + /// - OpenGL(ES) HLSL: HLSL2GLSL converter and native compiler + /// - Vulkan GLSL: built-in glslang + /// - Vulkan HLSL: built-in glslang (with limitted support for Shader Model 6.x) SHADER_COMPILER_DEFAULT = 0, - /// Builtin glslang compiler for GLSL and HLSL. + /// Built-in glslang compiler for GLSL and HLSL. SHADER_COMPILER_GLSLANG, - /// External HLSL compiler for Direct3D12 and Vulkan with Shader Model 6.x support. + /// Modern HLSL compiler (DXC) for Direct3D12 and Vulkan with Shader Model 6.x support. SHADER_COMPILER_DXC, - /// External HLSL compiler for Direct3D11 and Direct3D12 before Shader Model 6. + /// Legacy HLSL compiler (FXC) for Direct3D11 and Direct3D12 supporting shader models up to 5.1. SHADER_COMPILER_FXC, }; + /// Describes the flags that can be passed over to IShaderSourceInputStreamFactory::CreateInputStream2() function. DILIGENT_TYPED_ENUM(CREATE_SHADER_SOURCE_INPUT_STREAM_FLAGS, Uint32) { diff --git a/Graphics/GraphicsEngineD3D12/CMakeLists.txt b/Graphics/GraphicsEngineD3D12/CMakeLists.txt index 74e0f50d..e8a48236 100644 --- a/Graphics/GraphicsEngineD3D12/CMakeLists.txt +++ b/Graphics/GraphicsEngineD3D12/CMakeLists.txt @@ -180,8 +180,8 @@ PUBLIC target_compile_definitions(Diligent-GraphicsEngineD3D12-shared PUBLIC ENGINE_DLL=1) if(${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION} STRGREATER_EQUAL "10.0.19041.0") - set(D12_H_HAS_MESH_SHADER ON CACHE INTERNAL "" FORCE) - target_compile_definitions(Diligent-GraphicsEngineD3D12-static PRIVATE D12_H_HAS_MESH_SHADER) + set(D3D12_H_HAS_MESH_SHADER ON CACHE INTERNAL "" FORCE) + target_compile_definitions(Diligent-GraphicsEngineD3D12-static PRIVATE D3D12_H_HAS_MESH_SHADER) endif() if(${DILIGENT_HAS_D3D12_DXIL_COMPILER}) target_compile_definitions(Diligent-GraphicsEngineD3D12-static PRIVATE DILIGENT_HAS_D3D12_DXIL_COMPILER) diff --git a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp index 6fea488e..d6477b79 100644 --- a/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp +++ b/Graphics/GraphicsEngineD3D12/include/CommandContext.hpp @@ -394,7 +394,7 @@ class GraphicsContext6 : public GraphicsContext5 public: void DrawMesh(UINT ThreadGroupCountX, UINT ThreadGroupCountY, UINT ThreadGroupCountZ) { -#ifdef D12_H_HAS_MESH_SHADER +#ifdef D3D12_H_HAS_MESH_SHADER FlushResourceBarriers(); static_cast<ID3D12GraphicsCommandList6*>(m_pCommandList.p)->DispatchMesh(ThreadGroupCountX, ThreadGroupCountY, ThreadGroupCountZ); #else diff --git a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp index 627b270d..dc8d594e 100644 --- a/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp +++ b/Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp @@ -154,11 +154,11 @@ public: IDxCompilerLibrary* GetDxCompiler() const { return m_pDxCompiler.get(); } -#ifdef D12_H_HAS_MESH_SHADER +#ifdef D3D12_H_HAS_MESH_SHADER ID3D12Device2* GetD3D12Device2(); #endif - ShaderVersion GetShaderModel() const; + D3D_SHADER_MODEL GetMaxShaderModel() const; D3D_FEATURE_LEVEL GetD3DFeatureLevel() const; private: @@ -167,7 +167,7 @@ private: CComPtr<ID3D12Device> m_pd3d12Device; -#ifdef D12_H_HAS_MESH_SHADER +#ifdef D3D12_H_HAS_MESH_SHADER CComPtr<ID3D12Device2> m_pd3d12Device2; #endif diff --git a/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp b/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp index 8d3238c6..f2e8c1f0 100644 --- a/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp +++ b/Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp @@ -53,7 +53,7 @@ void CommandListManager::CreateNewCommandList(ID3D12GraphicsCommandList** List, const IID CmdListIIDs[] = { -#ifdef D12_H_HAS_MESH_SHADER +#ifdef D3D12_H_HAS_MESH_SHADER __uuidof(ID3D12GraphicsCommandList6), __uuidof(ID3D12GraphicsCommandList5), #endif diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 35539eb2..70289385 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -120,7 +120,7 @@ DeviceContextD3D12Impl::DeviceContextD3D12Impl(IReferenceCounters* pRef hr = pd3d12Device->CreateCommandSignature(&CmdSignatureDesc, nullptr, __uuidof(m_pDispatchIndirectSignature), reinterpret_cast<void**>(static_cast<ID3D12CommandSignature**>(&m_pDispatchIndirectSignature))); CHECK_D3D_RESULT_THROW(hr, "Failed to create dispatch indirect command signature"); -#ifdef D12_H_HAS_MESH_SHADER +#ifdef D3D12_H_HAS_MESH_SHADER CmdSignatureDesc.ByteStride = sizeof(UINT) * 3; IndirectArg.Type = D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH_MESH; hr = pd3d12Device->CreateCommandSignature(&CmdSignatureDesc, nullptr, __uuidof(m_pDrawMeshIndirectSignature), reinterpret_cast<void**>(static_cast<ID3D12CommandSignature**>(&m_pDrawMeshIndirectSignature))); diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index 6dc4d97a..5d33aefd 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -311,7 +311,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR break; } -#ifdef D12_H_HAS_MESH_SHADER +#ifdef D3D12_H_HAS_MESH_SHADER case PIPELINE_TYPE_MESH: { const auto& GraphicsPipeline = m_Desc.GraphicsPipeline; @@ -395,7 +395,7 @@ PipelineStateD3D12Impl::PipelineStateD3D12Impl(IReferenceCounters* pR CHECK_D3D_RESULT_THROW(device2->CreatePipelineState(&streamDesc, IID_PPV_ARGS(&m_pd3d12PSO)), "Failed to create pipeline state"); break; } -#endif // D12_H_HAS_MESH_SHADER +#endif // D3D12_H_HAS_MESH_SHADER default: LOG_ERROR_AND_THROW("Unknown shader type"); diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp index ea4d62a8..bdf596a4 100644 --- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp @@ -65,7 +65,7 @@ static CComPtr<IDXGIAdapter1> DXGIAdapterFromD3D12Device(ID3D12Device* pd3d12Dev return nullptr; } -ShaderVersion RenderDeviceD3D12Impl::GetShaderModel() const +ShaderVersion RenderDeviceD3D12Impl::GetMaxShaderModel() const { return ShaderVersion{Uint8((m_ShaderModel >> 4) & 0xF), Uint8(m_ShaderModel & 0xF)}; } @@ -89,7 +89,7 @@ D3D_FEATURE_LEVEL RenderDeviceD3D12Impl::GetD3DFeatureLevel() const return FeatureLevelsData.MaxSupportedFeatureLevel; } -#ifdef D12_H_HAS_MESH_SHADER +#ifdef D3D12_H_HAS_MESH_SHADER ID3D12Device2* RenderDeviceD3D12Impl::GetD3D12Device2() { if (!m_pd3d12Device2) @@ -230,7 +230,7 @@ RenderDeviceD3D12Impl::RenderDeviceD3D12Impl(IReferenceCounters* pRefCo } // Check if mesh shader is supported. -#ifdef D12_H_HAS_MESH_SHADER +#ifdef D3D12_H_HAS_MESH_SHADER { D3D12_FEATURE_DATA_D3D12_OPTIONS7 FeatureData = {}; bool SupportsMeshShader = SUCCEEDED(m_pd3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &FeatureData, sizeof(FeatureData))) && diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 4f080fcc..0acaa810 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -183,7 +183,7 @@ static D3D12_SHADER_VISIBILITY ShaderTypeInd2ShaderVisibilityMap[] D3D12_SHADER_VISIBILITY_HULL, // 3 D3D12_SHADER_VISIBILITY_DOMAIN, // 4 D3D12_SHADER_VISIBILITY_ALL, // 5 -#ifdef D12_H_HAS_MESH_SHADER +#ifdef D3D12_H_HAS_MESH_SHADER D3D12_SHADER_VISIBILITY_AMPLIFICATION, // 6 D3D12_SHADER_VISIBILITY_MESH // 7 #endif @@ -203,7 +203,7 @@ D3D12_SHADER_VISIBILITY GetShaderVisibility(SHADER_TYPE ShaderType) case SHADER_TYPE_HULL: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_HULL); break; case SHADER_TYPE_DOMAIN: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_DOMAIN); break; case SHADER_TYPE_COMPUTE: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_ALL); break; -# ifdef D12_H_HAS_MESH_SHADER +# ifdef D3D12_H_HAS_MESH_SHADER case SHADER_TYPE_AMPLIFICATION: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_AMPLIFICATION); break; case SHADER_TYPE_MESH: VERIFY_EXPR(ShaderVisibility == D3D12_SHADER_VISIBILITY_MESH); break; # endif @@ -242,7 +242,7 @@ SHADER_TYPE ShaderTypeFromShaderVisibility(D3D12_SHADER_VISIBILITY ShaderVisibil case D3D12_SHADER_VISIBILITY_HULL: VERIFY_EXPR(ShaderType == SHADER_TYPE_HULL); break; case D3D12_SHADER_VISIBILITY_DOMAIN: VERIFY_EXPR(ShaderType == SHADER_TYPE_DOMAIN); break; case D3D12_SHADER_VISIBILITY_ALL: VERIFY_EXPR(ShaderType == SHADER_TYPE_COMPUTE); break; -# ifdef D12_H_HAS_MESH_SHADER +# ifdef D3D12_H_HAS_MESH_SHADER case D3D12_SHADER_VISIBILITY_AMPLIFICATION: VERIFY_EXPR(ShaderType == SHADER_TYPE_AMPLIFICATION); break; case D3D12_SHADER_VISIBILITY_MESH: VERIFY_EXPR(ShaderType == SHADER_TYPE_MESH); break; # endif diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp index 0634bcf1..753fcbf8 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp @@ -38,23 +38,15 @@ namespace Diligent 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) - return MaxSM; - - return HLSLVersion.Major == MaxSM.Major ? - (HLSLVersion.Minor > MaxSM.Minor ? MaxSM : HLSLVersion) : - (HLSLVersion.Major > MaxSM.Major ? MaxSM : HLSLVersion); + { + D3D_SHADER_MODEL ver = pDevice->GetMaxShaderModel(); + return ShaderVersion{Uint8((ver >> 4) & 0xF), Uint8(ver & 0xF)}; + } + else + { + return HLSLVersion; + } } ShaderD3D12Impl::ShaderD3D12Impl(IReferenceCounters* pRefCounters, diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 748baa89..d1ef575e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -88,7 +88,7 @@ void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState) if (Desc.IsComputePipeline()) { } - else + else if (Desc.PipelineType == PIPELINE_TYPE_GRAPHICS) { const auto& GraphicsPipeline = Desc.GraphicsPipeline; // Set rasterizer state @@ -144,6 +144,11 @@ void DeviceContextGLImpl::SetPipelineState(IPipelineState* pPipelineState) } m_ContextState.InvalidateVAO(); } + else + { + LOG_ERROR_MESSAGE(GetPipelineTypeString(Desc.PipelineType), " pipeline '", Desc.Name, "' is not supported in OpenGL"); + return; + } // Note that the program may change if a shader is created after the call // (GLProgramResources needs to bind a program to load uniforms), but before diff --git a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp index 01266f1d..a352cd8d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp @@ -55,7 +55,7 @@ ShaderGLImpl::ShaderGLImpl(IReferenceCounters* pRefCounters, { DEV_CHECK_ERR(CreationAttribs.ByteCode == nullptr, "'ByteCode' must be null when shader is created from the source code or a file"); DEV_CHECK_ERR(CreationAttribs.ByteCodeSize == 0, "'ByteCodeSize' must be 0 when shader is created from the source code or a file"); - DEV_CHECK_ERR(CreationAttribs.ShaderCompiler == SHADER_COMPILER_DEFAULT, "only default compiler supported on OpenGL"); + DEV_CHECK_ERR(CreationAttribs.ShaderCompiler == SHADER_COMPILER_DEFAULT, "only default compiler is supported in OpenGL"); const auto& deviceCaps = pDeviceGL->GetDeviceCaps(); diff --git a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp index 3c0f5feb..5f00317e 100644 --- a/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp +++ b/Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp @@ -155,7 +155,7 @@ private: VulkanUtilities::PipelineWrapper m_Pipeline; PipelineLayout m_PipelineLayout; - std::array<Int8, 8> m_ResourceLayoutIndex; + std::array<Int8, 8> m_ResourceLayoutIndex = {}; bool m_HasStaticResources = false; bool m_HasNonStaticResources = false; }; diff --git a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp index 06e86c76..7d66600d 100644 --- a/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp +++ b/Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp @@ -142,7 +142,7 @@ public: { #ifdef VK_NV_mesh_shader VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawMeshTasksNV() must be called inside render pass (19.3)"); + VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawMeshTasksNV() must be called inside render pass"); VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound"); vkCmdDrawMeshTasksNV(m_VkCmdBuffer, TaskCount, FirstTask); @@ -155,7 +155,7 @@ public: { #ifdef VK_NV_mesh_shader VERIFY_EXPR(m_VkCmdBuffer != VK_NULL_HANDLE); - VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawMeshTasksNV() must be called inside render pass (19.3)"); + VERIFY(m_State.RenderPass != VK_NULL_HANDLE, "vkCmdDrawMeshTasksNV() must be called inside render pass"); VERIFY(m_State.GraphicsPipeline != VK_NULL_HANDLE, "No graphics pipeline bound"); vkCmdDrawMeshTasksIndirectNV(m_VkCmdBuffer, Buffer, Offset, DrawCount, Stride); diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp index 593cc0b3..13f2affe 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp @@ -43,6 +43,7 @@ namespace Diligent static VkShaderStageFlagBits ShaderTypeToVkShaderStageFlagBit(SHADER_TYPE ShaderType) { + static_assert(SHADER_TYPE_LAST == SHADER_TYPE_MESH, "Please update the switch below to handle the new shader type"); switch (ShaderType) { // clang-format off diff --git a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp index 65150c48..b136487f 100644 --- a/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp @@ -155,6 +155,8 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun TPipelineStateBase{pRefCounters, pDeviceVk, CreateInfo.PSODesc}, m_SRBMemAllocator{GetRawAllocator()} { + m_ResourceLayoutIndex.fill(-1); + const auto& LogicalDevice = pDeviceVk->GetLogicalDevice(); // Initialize shader resource layouts @@ -166,7 +168,6 @@ PipelineStateVkImpl::PipelineStateVkImpl(IReferenceCounters* pRefCoun m_ShaderResourceLayouts = ALLOCATE(ShaderResLayoutAllocator, "Raw memory for ShaderResourceLayoutVk", ShaderResourceLayoutVk, m_NumShaders * 2); m_StaticResCaches = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderResourceCacheVk", ShaderResourceCacheVk, m_NumShaders); m_StaticVarsMgrs = ALLOCATE(GetRawAllocator(), "Raw memory for ShaderVariableManagerVk", ShaderVariableManagerVk, m_NumShaders); - m_ResourceLayoutIndex.fill(-1); for (Uint32 s = 0; s < m_NumShaders; ++s) { diff --git a/Graphics/HLSLTools/src/DXILUtils.cpp b/Graphics/HLSLTools/src/DXILUtils.cpp index 58211993..5852d477 100644 --- a/Graphics/HLSLTools/src/DXILUtils.cpp +++ b/Graphics/HLSLTools/src/DXILUtils.cpp @@ -29,77 +29,123 @@ #include <unordered_map> #include <memory> #include <array> -#include <mutex> -// Platforms that has DXCompiler. -#if defined(PLATFORM_WIN32) || defined(PLATFORM_UNIVERSAL_WINDOWS) || defined(PLATFORM_LINUX) +#ifdef WIN32 +# include <Unknwn.h> +# include <guiddef.h> +# include <atlbase.h> +# include <atlcom.h> +#endif + +#include "dxc/dxcapi.h" +#ifdef PLATFORM_LINUX +# undef _countof +#endif -# include "DXCompilerBaseLiunx.hpp" -# include "DXCompilerBaseUWP.hpp" -# include "DXCompilerBaseWin32.hpp" +#include "DXILUtils.hpp" +#include "DataBlobImpl.hpp" +#include "RefCntAutoPtr.hpp" -# include "DataBlobImpl.hpp" -# include "RefCntAutoPtr.hpp" +// Platforms that has DXCompiler. +#if PLATFORM_WIN32 || PLATFORM_UNIVERSAL_WINDOWS || PLATFORM_LINUX namespace Diligent { + namespace { -class DXCompilerImpl final : public DXCompilerBase +# if PLATFORM_WIN32 +struct DXCompilerBase { -public: - DXCompilerImpl(DXCompilerTarget Target, const char* pLibName) : - m_Target{Target}, - m_LibName{pLibName ? pLibName : ""} - {} + HMODULE Module = nullptr; + DxcCreateInstanceProc CreateInstance = nullptr; - ShaderVersion GetMaxShaderModel() override + ~DXCompilerBase() { - Load(); - // mutex is not needed here - return m_MaxShaderModel; + if (Module) + FreeLibrary(Module); } - bool IsLoaded() override + void Load(const char* libName) { - return GetCreateInstaceProc() != nullptr; + if (Module) + FreeLibrary(Module); + + Module = LoadLibraryA(libName); + CreateInstance = Module ? reinterpret_cast<DxcCreateInstanceProc>(GetProcAddress(Module, "DxcCreateInstance")) : nullptr; } +}; + +# elif PLATFORM_UNIVERSAL_WINDOWS + +struct DXCompilerBase +{ + HMODULE Module = nullptr; + DxcCreateInstanceProc CreateInstance = nullptr; - DxcCreateInstanceProc GetCreateInstaceProc() + ~DXCompilerBase() { - Load(); - // mutex is not needed here - return m_pCreateInstance; + if (Module) + FreeLibrary(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) + { + if (Module) + FreeLibrary(Module); -private: - void Load() + 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; + } +}; + +# elif PLATFORM_LINUX + +struct DXCompilerBase +{ + void* Module = nullptr; + DxcCreateInstanceProc CreateInstance = nullptr; + + ~DXCompilerBase() { - std::unique_lock<std::mutex> lock{m_Guard}; + if (Module) + dlclose(Module); + } - if (m_IsInitialized) - return; + void Load(const char* libName) + { + if (Module) + dlclose(Module); + + Module = dlopen(libName, RTLD_LOCAL | RTLD_LAZY); + CreateInstance = Module ? reinterpret_cast<DxcCreateInstanceProc>(dlsym(Module, "DxcCreateInstance")) : nullptr; + } +}; + +# else + +# error Unexpected plaftorm + +# endif - m_IsInitialized = true; - m_pCreateInstance = DXCompilerBase::Load(m_Target, m_LibName); - if (m_pCreateInstance) +struct DXCompilerImpl : DXCompilerBase +{ + ShaderVersion MaxShaderModel{6, 0}; + + DXCompilerImpl() = default; + + void Load(const char* libName) + { + DXCompilerBase::Load(libName); + if (CreateInstance) { CComPtr<IDxcValidator> validator; - if (SUCCEEDED(m_pCreateInstance(CLSID_DxcValidator, IID_PPV_ARGS(&validator)))) + if (SUCCEEDED(CreateInstance(CLSID_DxcValidator, IID_PPV_ARGS(&validator)))) { CComPtr<IDxcVersionInfo> info; if (SUCCEEDED(validator->QueryInterface(IID_PPV_ARGS(&info)))) @@ -114,26 +160,37 @@ private: // map known DXC version to maximum SM switch (ver) { - 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 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 0x10003: - 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; + 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; } } } } } - -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* DXILCompilerLib() +{ +# if D3D12_SUPPORTED + static DXCompilerImpl inst; + return &inst; +# else + return nullptr; +# endif +} + +static DXCompilerImpl* SPIRVCompilerLib() +{ +# if VULKAN_SUPPORTED + static DXCompilerImpl inst; + return &inst; +# else + return nullptr; +# endif +} class DxcIncludeHandlerImpl final : public IDxcIncludeHandler { @@ -218,27 +275,93 @@ private: } // namespace +# if D3D12_SUPPORTED +HRESULT D3D12DxcCreateInstance( + _In_ REFCLSID rclsid, + _In_ REFIID riid, + _Out_ LPVOID* ppv) +{ + DXCompilerImpl* DxCompiler = DXILCompilerLib(); + if (DxCompiler != nullptr && DxCompiler->CreateInstance != nullptr) + return DxCompiler->CreateInstance(rclsid, riid, ppv); + else + return E_NOTIMPL; +} +# endif -IDxCompilerLibrary* CreateDXCompiler(DXCompilerTarget Target, const char* pLibraryName) +bool DxcLoadLibrary(DXCompilerTarget Target, const char* name) { - return new DXCompilerImpl{Target, pLibraryName}; + 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 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) +bool DxcGetMaxShaderModel(DXCompilerTarget Target, + ShaderVersion& Version) { - auto CreateInstance = GetCreateInstaceProc(); + DXCompilerImpl* DxCompiler = nullptr; + switch (Target) + { + case DXCompilerTarget::Direct3D12: DxCompiler = DXILCompilerLib(); break; + case DXCompilerTarget::Vulkan: DxCompiler = SPIRVCompilerLib(); break; + } - if (CreateInstance == nullptr) + if (DxCompiler == nullptr || DxCompiler->Module == nullptr) + return false; + + Version = DxCompiler->MaxShaderModel; + return true; +} + +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) +{ + DXCompilerImpl* DxCompiler = nullptr; + switch (Target) + { + case DXCompilerTarget::Direct3D12: DxCompiler = DXILCompilerLib(); break; + case DXCompilerTarget::Vulkan: DxCompiler = SPIRVCompilerLib(); break; + } + + if (DxCompiler == nullptr || DxCompiler->CreateInstance == nullptr) { LOG_ERROR("Failed to load DXCompiler"); return false; @@ -255,12 +378,12 @@ bool DXCompilerImpl::Compile(const char* Source, HRESULT hr; CComPtr<IDxcLibrary> library; - hr = CreateInstance(CLSID_DxcLibrary, IID_PPV_ARGS(&library)); + hr = DxCompiler->CreateInstance(CLSID_DxcLibrary, IID_PPV_ARGS(&library)); if (FAILED(hr)) return false; CComPtr<IDxcCompiler> compiler; - hr = CreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&compiler)); + hr = DxCompiler->CreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&compiler)); if (FAILED(hr)) return false; @@ -308,10 +431,10 @@ bool DXCompilerImpl::Compile(const char* Source, return false; // validate and sign in - if (m_Target == DXCompilerTarget::Direct3D12) + if (Target == DXCompilerTarget::Direct3D12) { CComPtr<IDxcValidator> validator; - hr = CreateInstance(CLSID_DxcValidator, IID_PPV_ARGS(&validator)); + hr = DxCompiler->CreateInstance(CLSID_DxcValidator, IID_PPV_ARGS(&validator)); if (FAILED(hr)) return false; @@ -353,45 +476,6 @@ bool DXCompilerImpl::Compile(const char* Source, return true; } -# if D3D12_SUPPORTED -# define FOURCC(a, b, c, d) (uint32_t{((d) << 24) | ((c) << 16) | ((b) << 8) | (a)}) - -bool DxcGetShaderReflection(IDxCompilerLibrary* pLibrary, - IDxcBlob* pShaderBytecode, - ID3D12ShaderReflection** ppShaderReflection) noexcept(false) -{ - HRESULT hr; - bool IsDXIL = false; - auto CreateInstance = pLibrary ? static_cast<DXCompilerImpl*>(pLibrary)->GetCreateInstaceProc() : nullptr; - - if (CreateInstance != nullptr) - { - const uint32_t DFCC_DXIL = FOURCC('D', 'X', 'I', 'L'); - CComPtr<IDxcContainerReflection> pReflection; - UINT32 shaderIdx; - - hr = CreateInstance(CLSID_DxcContainerReflection, IID_PPV_ARGS(&pReflection)); - if (FAILED(hr)) - LOG_ERROR_AND_THROW("Failed to create shader reflection instance"); - - hr = pReflection->Load(pShaderBytecode); - if (FAILED(hr)) - LOG_ERROR_AND_THROW("Failed to load shader reflection from bytecode"); - - hr = pReflection->FindFirstPartKind(DFCC_DXIL, &shaderIdx); - IsDXIL = SUCCEEDED(hr); - if (IsDXIL) - { - hr = pReflection->GetPartReflection(shaderIdx, __uuidof(*ppShaderReflection), reinterpret_cast<void**>(ppShaderReflection)); - if (FAILED(hr)) - LOG_ERROR_AND_THROW("Failed to get the shader reflection"); - } - } - return IsDXIL; -} -# endif - - # if VULKAN_SUPPORTED // Implemented in GLSLSourceBuilder.cpp const char* GetShaderTypeDefines(SHADER_TYPE Type); @@ -408,10 +492,9 @@ static const char g_HLSLDefinitions[] = } // namespace -std::vector<uint32_t> DXILtoSPIRV(IDxCompilerLibrary* pLibrary, - const ShaderCreateInfo& Attribs, +std::vector<uint32_t> DXILtoSPIRV(const ShaderCreateInfo& Attribs, const char* ExtraDefinitions, - IDataBlob** ppCompilerOutput) noexcept(false) + IDataBlob** ppCompilerOutput) { RefCntAutoPtr<IDataBlob> pFileData(MakeNewRCObj<DataBlobImpl>()(0)); @@ -464,13 +547,16 @@ std::vector<uint32_t> DXILtoSPIRV(IDxCompilerLibrary* pLibrary, // validate shader version ShaderVersion ShaderModel = Attribs.HLSLVersion; - ShaderVersion MaxSM = pLibrary->GetMaxShaderModel(); + ShaderVersion MaxSM; - if (ShaderModel.Major < 6 || ShaderModel.Major > MaxSM.Major) - ShaderModel = MaxSM; + if (DxcGetMaxShaderModel(DXCompilerTarget::Vulkan, 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) @@ -504,14 +590,15 @@ std::vector<uint32_t> DXILtoSPIRV(IDxCompilerLibrary* pLibrary, CComPtr<IDxcBlob> compiled; CComPtr<IDxcBlob> 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); + 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); const size_t CompilerMsgLen = errors ? errors->GetBufferSize() : 0; const char* CompilerMsg = CompilerMsgLen > 0 ? static_cast<const char*>(errors->GetBufferPointer()) : nullptr; @@ -553,22 +640,22 @@ std::vector<uint32_t> DXILtoSPIRV(IDxCompilerLibrary* pLibrary, #else -# include "DXILUtils.hpp" - namespace Diligent { -IDxCompilerLibrary* CreateDXCompiler(DXCompilerTarget Target, const char* pLibraryName) -{ - return nullptr; -} - -std::vector<uint32_t> DXILtoSPIRV(IDxCompilerLibrary* pLibrary, - const ShaderCreateInfo& Attribs, - const char* ExtraDefinitions, - IDataBlob** ppCompilerOutput) noexcept(false) +bool DXILCompile(DXCompilerTarget Target, + const char* Source, + 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) { - return {}; + return false; } } // namespace Diligent |
