summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2020-09-08 05:00:23 +0000
committerassiduous <assiduous@diligentgraphics.com>2020-09-09 16:18:08 +0000
commit90a707ecb5d7985c261faf1903e849548c046b02 (patch)
tree0d853d782deae54ce7a41924c50b432ac7aa464a /Graphics
parentAdded DILIGENT_NO_FORMAT_VALIDATION cmake option (diff)
downloadDiligentCore-90a707ecb5d7985c261faf1903e849548c046b02.tar.gz
DiligentCore-90a707ecb5d7985c261faf1903e849548c046b02.zip
A bunch of random updates
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsAccessories/interface/GraphicsAccessories.hpp2
-rw-r--r--Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp36
-rw-r--r--Graphics/GraphicsEngine/include/PipelineStateBase.hpp17
-rw-r--r--Graphics/GraphicsEngine/include/ShaderBase.hpp1
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceCaps.h6
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h19
-rw-r--r--Graphics/GraphicsEngine/interface/GraphicsTypes.h7
-rw-r--r--Graphics/GraphicsEngine/interface/PipelineState.h16
-rw-r--r--Graphics/GraphicsEngine/interface/Shader.h29
-rw-r--r--Graphics/GraphicsEngineD3D12/CMakeLists.txt4
-rw-r--r--Graphics/GraphicsEngineD3D12/include/CommandContext.hpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/include/RenderDeviceD3D12Impl.hpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/src/CommandListManager.cpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp2
-rw-r--r--Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp4
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RootSignature.cpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp24
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp7
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/ShaderGLImpl.cpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/PipelineStateVkImpl.hpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/VulkanUtilities/VulkanCommandBuffer.hpp4
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineLayout.cpp1
-rw-r--r--Graphics/GraphicsEngineVulkan/src/PipelineStateVkImpl.cpp3
-rw-r--r--Graphics/HLSLTools/src/DXILUtils.cpp371
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