diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2023-09-12 11:13:11 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-11 20:13:11 -0700 |
| commit | 09854a4596019ddb3bb315b8836b5c88e718cdc7 (patch) | |
| tree | 1556ae3e00da0fac91343f159b52cee1231a7fab /tools/gfx/d3d12 | |
| parent | 87bb0b503544f1b8c6ec818e25c695b31cda24b7 (diff) | |
Add Mesh and Task shader support to GFX (#3190)
* Bump vulkan headers
Also just use vulkan-headers as a submodule
* Add drawMeshTasks to gfx graphics pipelines
* Add DispatchMesh overload with no payload, with GLSL intrinsic
* Require spirv 1.4 for mesh shaders
* Add vulkan mesh shader feature discovery
* Add mesh shader stage bits to vk-util
* Add mesh and task shader support to render-test
* Add mesh and task tests
* Preserve "payload" specifier in task shaders
* Add mesh shader pipeline support to gfx
* Add TODO
* Add numThreads attribute for amplification stage
* Add payload to task shader test
* Drop dependency on d3dx12
* Allow passing payloads from task to mesh shaders
* regenerate vs projects
* check DispatchMesh name correctly
* Add mesh shader tests to failing tests
* Detect wave-ops feature on vulkan
* Add fuse-product to expected failures
This fails because the global varaible `count` is not initialized
* Add required extension to WaveMaskMatch SPIR-V impl
* Remove meshShader member from pipeline desc
* Identify mesh shader support on d3d12
Diffstat (limited to 'tools/gfx/d3d12')
| -rw-r--r-- | tools/gfx/d3d12/d3d12-command-buffer.cpp | 7 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-command-buffer.h | 1 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-command-encoder.cpp | 8 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-command-encoder.h | 4 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-device.cpp | 12 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-pipeline-state-stream.h | 484 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-pipeline-state.cpp | 319 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-sal-defs.h | 199 |
8 files changed, 900 insertions, 134 deletions
diff --git a/tools/gfx/d3d12/d3d12-command-buffer.cpp b/tools/gfx/d3d12/d3d12-command-buffer.cpp index 3a09da037..fb979d3b9 100644 --- a/tools/gfx/d3d12/d3d12-command-buffer.cpp +++ b/tools/gfx/d3d12/d3d12-command-buffer.cpp @@ -59,6 +59,13 @@ void CommandBufferImpl::init( reinit(); + m_cmdList->QueryInterface<ID3D12GraphicsCommandList6>(m_cmdList6.writeRef()); +if (m_cmdList6) + { + m_cmdList4 = m_cmdList6; + m_cmdList1 = m_cmdList6; + return; + } #if SLANG_GFX_HAS_DXR_SUPPORT m_cmdList->QueryInterface<ID3D12GraphicsCommandList4>(m_cmdList4.writeRef()); if (m_cmdList4) diff --git a/tools/gfx/d3d12/d3d12-command-buffer.h b/tools/gfx/d3d12/d3d12-command-buffer.h index 0b24764c1..1cc6e8850 100644 --- a/tools/gfx/d3d12/d3d12-command-buffer.h +++ b/tools/gfx/d3d12/d3d12-command-buffer.h @@ -37,6 +37,7 @@ public: ComPtr<ID3D12GraphicsCommandList> m_cmdList; ComPtr<ID3D12GraphicsCommandList1> m_cmdList1; ComPtr<ID3D12GraphicsCommandList4> m_cmdList4; + ComPtr<ID3D12GraphicsCommandList6> m_cmdList6; BreakableReference<TransientResourceHeapImpl> m_transientHeap; // Weak reference is fine here since `m_transientHeap` already holds strong reference to diff --git a/tools/gfx/d3d12/d3d12-command-encoder.cpp b/tools/gfx/d3d12/d3d12-command-encoder.cpp index 167c464d6..e4d03193b 100644 --- a/tools/gfx/d3d12/d3d12-command-encoder.cpp +++ b/tools/gfx/d3d12/d3d12-command-encoder.cpp @@ -41,6 +41,7 @@ void PipelineCommandEncoder::init(CommandBufferImpl* commandBuffer) { m_commandBuffer = commandBuffer; m_d3dCmdList = m_commandBuffer->m_cmdList; + m_d3dCmdList6 = m_commandBuffer->m_cmdList6; m_renderer = commandBuffer->m_renderer; m_transientHeap = commandBuffer->m_transientHeap; m_device = commandBuffer->m_renderer->m_device; @@ -1185,6 +1186,13 @@ Result RenderCommandEncoderImpl::drawIndexedInstanced( return SLANG_OK; } +Result RenderCommandEncoderImpl::drawMeshTasks(int x, int y, int z) +{ + SLANG_RETURN_ON_FAIL(prepareDraw()); + m_d3dCmdList6->DispatchMesh(x, y, z); + return SLANG_OK; +} + void ComputeCommandEncoderImpl::endEncoding() { PipelineCommandEncoder::endEncodingImpl(); } void ComputeCommandEncoderImpl::init( diff --git a/tools/gfx/d3d12/d3d12-command-encoder.h b/tools/gfx/d3d12/d3d12-command-encoder.h index 4190e985c..0632084cf 100644 --- a/tools/gfx/d3d12/d3d12-command-encoder.h +++ b/tools/gfx/d3d12/d3d12-command-encoder.h @@ -26,6 +26,7 @@ public: DeviceImpl* m_renderer; ID3D12Device* m_device; ID3D12GraphicsCommandList* m_d3dCmdList; + ID3D12GraphicsCommandList6* m_d3dCmdList6; ID3D12GraphicsCommandList* m_preCmdList = nullptr; RefPtr<PipelineStateBase> m_currentPipeline; @@ -290,6 +291,9 @@ public: GfxIndex startIndexLocation, GfxIndex baseVertexLocation, GfxIndex startInstanceLocation) override; + + virtual SLANG_NO_THROW Result SLANG_MCALL + drawMeshTasks(int x, int y, int z) override; }; #if SLANG_GFX_HAS_DXR_SUPPORT diff --git a/tools/gfx/d3d12/d3d12-device.cpp b/tools/gfx/d3d12/d3d12-device.cpp index 3f62c2d5c..ca624b99f 100644 --- a/tools/gfx/d3d12/d3d12-device.cpp +++ b/tools/gfx/d3d12/d3d12-device.cpp @@ -783,6 +783,18 @@ Result DeviceImpl::initialize(const Desc& desc) } } } + // Check mesh shader support + { + D3D12_FEATURE_DATA_D3D12_OPTIONS7 options; + if (SLANG_SUCCEEDED(m_device->CheckFeatureSupport( + D3D12_FEATURE_D3D12_OPTIONS7, &options, sizeof(options)))) + { + if (options.MeshShaderTier >= D3D12_MESH_SHADER_TIER_1) + { + m_features.add("mesh-shader"); + } + } + } } m_desc = desc; diff --git a/tools/gfx/d3d12/d3d12-pipeline-state-stream.h b/tools/gfx/d3d12/d3d12-pipeline-state-stream.h new file mode 100644 index 000000000..9848e96f9 --- /dev/null +++ b/tools/gfx/d3d12/d3d12-pipeline-state-stream.h @@ -0,0 +1,484 @@ +#pragma once + +// +// The CD3DX12_PIPELINE_STATE_STREAM2 struct and dependencies extracted from +// `d3dx12_pipeline_state_stream.h`. Attribution Microsoft. +// + +#include <climits> +#include <d3d12.h> +#include <dxgi1_4.h> + +#include "d3d12-sal-defs.h" + +struct CD3DX12_DEFAULT {}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC +{ + CD3DX12_DEPTH_STENCIL_DESC() = default; + explicit CD3DX12_DEPTH_STENCIL_DESC( const D3D12_DEPTH_STENCIL_DESC& o ) noexcept : + D3D12_DEPTH_STENCIL_DESC( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( CD3DX12_DEFAULT ) noexcept + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + } + explicit CD3DX12_DEPTH_STENCIL_DESC( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc ) noexcept + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC1 : public D3D12_DEPTH_STENCIL_DESC1 +{ + CD3DX12_DEPTH_STENCIL_DESC1() = default; + explicit CD3DX12_DEPTH_STENCIL_DESC1( const D3D12_DEPTH_STENCIL_DESC1& o ) noexcept : + D3D12_DEPTH_STENCIL_DESC1( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC1( const D3D12_DEPTH_STENCIL_DESC& o ) noexcept + { + DepthEnable = o.DepthEnable; + DepthWriteMask = o.DepthWriteMask; + DepthFunc = o.DepthFunc; + StencilEnable = o.StencilEnable; + StencilReadMask = o.StencilReadMask; + StencilWriteMask = o.StencilWriteMask; + FrontFace.StencilFailOp = o.FrontFace.StencilFailOp; + FrontFace.StencilDepthFailOp = o.FrontFace.StencilDepthFailOp; + FrontFace.StencilPassOp = o.FrontFace.StencilPassOp; + FrontFace.StencilFunc = o.FrontFace.StencilFunc; + BackFace.StencilFailOp = o.BackFace.StencilFailOp; + BackFace.StencilDepthFailOp = o.BackFace.StencilDepthFailOp; + BackFace.StencilPassOp = o.BackFace.StencilPassOp; + BackFace.StencilFunc = o.BackFace.StencilFunc; + DepthBoundsTestEnable = FALSE; + } + explicit CD3DX12_DEPTH_STENCIL_DESC1( CD3DX12_DEFAULT ) noexcept + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + DepthBoundsTestEnable = FALSE; + } + explicit CD3DX12_DEPTH_STENCIL_DESC1( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc, + BOOL depthBoundsTestEnable ) noexcept + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + DepthBoundsTestEnable = depthBoundsTestEnable; + } + operator D3D12_DEPTH_STENCIL_DESC() const noexcept + { + D3D12_DEPTH_STENCIL_DESC D; + D.DepthEnable = DepthEnable; + D.DepthWriteMask = DepthWriteMask; + D.DepthFunc = DepthFunc; + D.StencilEnable = StencilEnable; + D.StencilReadMask = StencilReadMask; + D.StencilWriteMask = StencilWriteMask; + D.FrontFace.StencilFailOp = FrontFace.StencilFailOp; + D.FrontFace.StencilDepthFailOp = FrontFace.StencilDepthFailOp; + D.FrontFace.StencilPassOp = FrontFace.StencilPassOp; + D.FrontFace.StencilFunc = FrontFace.StencilFunc; + D.BackFace.StencilFailOp = BackFace.StencilFailOp; + D.BackFace.StencilDepthFailOp = BackFace.StencilDepthFailOp; + D.BackFace.StencilPassOp = BackFace.StencilPassOp; + D.BackFace.StencilFunc = BackFace.StencilFunc; + return D; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC +{ + CD3DX12_BLEND_DESC() = default; + explicit CD3DX12_BLEND_DESC( const D3D12_BLEND_DESC& o ) noexcept : + D3D12_BLEND_DESC( o ) + {} + explicit CD3DX12_BLEND_DESC( CD3DX12_DEFAULT ) noexcept + { + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE,FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + }; + for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + RenderTarget[ i ] = defaultRenderTargetBlendDesc; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC +{ + CD3DX12_RASTERIZER_DESC() = default; + explicit CD3DX12_RASTERIZER_DESC( const D3D12_RASTERIZER_DESC& o ) noexcept : + D3D12_RASTERIZER_DESC( o ) + {} + explicit CD3DX12_RASTERIZER_DESC( CD3DX12_DEFAULT ) noexcept + { + FillMode = D3D12_FILL_MODE_SOLID; + CullMode = D3D12_CULL_MODE_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + ForcedSampleCount = 0; + ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + explicit CD3DX12_RASTERIZER_DESC( + D3D12_FILL_MODE fillMode, + D3D12_CULL_MODE cullMode, + BOOL frontCounterClockwise, + INT depthBias, + FLOAT depthBiasClamp, + FLOAT slopeScaledDepthBias, + BOOL depthClipEnable, + BOOL multisampleEnable, + BOOL antialiasedLineEnable, + UINT forcedSampleCount, + D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) noexcept + { + FillMode = fillMode; + CullMode = cullMode; + FrontCounterClockwise = frontCounterClockwise; + DepthBias = depthBias; + DepthBiasClamp = depthBiasClamp; + SlopeScaledDepthBias = slopeScaledDepthBias; + DepthClipEnable = depthClipEnable; + MultisampleEnable = multisampleEnable; + AntialiasedLineEnable = antialiasedLineEnable; + ForcedSampleCount = forcedSampleCount; + ConservativeRaster = conservativeRaster; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_VIEW_INSTANCING_DESC : public D3D12_VIEW_INSTANCING_DESC +{ + CD3DX12_VIEW_INSTANCING_DESC() = default; + explicit CD3DX12_VIEW_INSTANCING_DESC( const D3D12_VIEW_INSTANCING_DESC& o ) noexcept : + D3D12_VIEW_INSTANCING_DESC( o ) + {} + explicit CD3DX12_VIEW_INSTANCING_DESC( CD3DX12_DEFAULT ) noexcept + { + ViewInstanceCount = 0; + pViewInstanceLocations = nullptr; + Flags = D3D12_VIEW_INSTANCING_FLAG_NONE; + } + explicit CD3DX12_VIEW_INSTANCING_DESC( + UINT InViewInstanceCount, + const D3D12_VIEW_INSTANCE_LOCATION* InViewInstanceLocations, + D3D12_VIEW_INSTANCING_FLAGS InFlags) noexcept + { + ViewInstanceCount = InViewInstanceCount; + pViewInstanceLocations = InViewInstanceLocations; + Flags = InFlags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RT_FORMAT_ARRAY : public D3D12_RT_FORMAT_ARRAY +{ + CD3DX12_RT_FORMAT_ARRAY() = default; + explicit CD3DX12_RT_FORMAT_ARRAY(const D3D12_RT_FORMAT_ARRAY& o) noexcept + : D3D12_RT_FORMAT_ARRAY(o) + {} + explicit CD3DX12_RT_FORMAT_ARRAY(_In_reads_(NumFormats) const DXGI_FORMAT* pFormats, UINT NumFormats) noexcept + { + NumRenderTargets = NumFormats; + memcpy(RTFormats, pFormats, sizeof(RTFormats)); + // assumes ARRAY_SIZE(pFormats) == ARRAY_SIZE(RTFormats) + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SHADER_BYTECODE : public D3D12_SHADER_BYTECODE +{ + CD3DX12_SHADER_BYTECODE() = default; + explicit CD3DX12_SHADER_BYTECODE(const D3D12_SHADER_BYTECODE &o) noexcept : + D3D12_SHADER_BYTECODE(o) + {} + CD3DX12_SHADER_BYTECODE( + _In_ ID3DBlob* pShaderBlob ) noexcept + { + pShaderBytecode = pShaderBlob->GetBufferPointer(); + BytecodeLength = pShaderBlob->GetBufferSize(); + } + CD3DX12_SHADER_BYTECODE( + const void* _pShaderBytecode, + SIZE_T bytecodeLength ) noexcept + { + pShaderBytecode = _pShaderBytecode; + BytecodeLength = bytecodeLength; + } +}; + +struct DefaultSampleMask { operator UINT() noexcept { return UINT_MAX; } }; +struct DefaultSampleDesc { operator DXGI_SAMPLE_DESC() noexcept { return DXGI_SAMPLE_DESC{1, 0}; } }; + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4324) +#endif +template <typename InnerStructType, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE Type, typename DefaultArg = InnerStructType> +class alignas(void*) CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT +{ +private: + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE pssType; + InnerStructType pssInner; +public: + CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT() noexcept : pssType(Type), pssInner(DefaultArg()) {} + CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT(InnerStructType const& i) noexcept : pssType(Type), pssInner(i) {} + CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT& operator=(InnerStructType const& i) noexcept { pssType = Type; pssInner = i; return *this; } + operator InnerStructType const&() const noexcept { return pssInner; } + operator InnerStructType&() noexcept { return pssInner; } + InnerStructType* operator&() noexcept { return &pssInner; } + InnerStructType const* operator&() const noexcept { return &pssInner; } +}; +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_PIPELINE_STATE_FLAGS, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS> CD3DX12_PIPELINE_STATE_STREAM_FLAGS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK> CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< ID3D12RootSignature*, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE> CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_INPUT_LAYOUT_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT> CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_INDEX_BUFFER_STRIP_CUT_VALUE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE> CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_PRIMITIVE_TOPOLOGY_TYPE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY> CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS> CD3DX12_PIPELINE_STATE_STREAM_VS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS> CD3DX12_PIPELINE_STATE_STREAM_GS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_STREAM_OUTPUT_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT> CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS> CD3DX12_PIPELINE_STATE_STREAM_HS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS> CD3DX12_PIPELINE_STATE_STREAM_DS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS> CD3DX12_PIPELINE_STATE_STREAM_PS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS> CD3DX12_PIPELINE_STATE_STREAM_AS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS> CD3DX12_PIPELINE_STATE_STREAM_MS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS> CD3DX12_PIPELINE_STATE_STREAM_CS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_BLEND_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_DEPTH_STENCIL_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_DEPTH_STENCIL_DESC1, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< DXGI_FORMAT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_RASTERIZER_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_RT_FORMAT_ARRAY, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS> CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< DXGI_SAMPLE_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC, DefaultSampleDesc> CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK, DefaultSampleMask> CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_CACHED_PIPELINE_STATE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO> CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_VIEW_INSTANCING_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_VIEW_INSTANCING; + +struct D3DX12_MESH_SHADER_PIPELINE_STATE_DESC +{ + ID3D12RootSignature* pRootSignature; + D3D12_SHADER_BYTECODE AS; + D3D12_SHADER_BYTECODE MS; + D3D12_SHADER_BYTECODE PS; + D3D12_BLEND_DESC BlendState; + UINT SampleMask; + D3D12_RASTERIZER_DESC RasterizerState; + D3D12_DEPTH_STENCIL_DESC DepthStencilState; + D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType; + UINT NumRenderTargets; + DXGI_FORMAT RTVFormats[ D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT ]; + DXGI_FORMAT DSVFormat; + DXGI_SAMPLE_DESC SampleDesc; + UINT NodeMask; + D3D12_CACHED_PIPELINE_STATE CachedPSO; + D3D12_PIPELINE_STATE_FLAGS Flags; +}; + +// CD3DX12_PIPELINE_STATE_STREAM2 Works on OS Build 19041+ (where there is a new mesh shader pipeline). +// Use CD3DX12_PIPELINE_STATE_STREAM1 for OS Build 16299+ (where there is a new view instancing subobject). +// Use CD3DX12_PIPELINE_STATE_STREAM for OS Build 15063+ support. +struct CD3DX12_PIPELINE_STATE_STREAM2 +{ + CD3DX12_PIPELINE_STATE_STREAM2() = default; + // Mesh and amplification shaders must be set manually, since they do not have representation in D3D12_GRAPHICS_PIPELINE_STATE_DESC + CD3DX12_PIPELINE_STATE_STREAM2(const D3D12_GRAPHICS_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , InputLayout(Desc.InputLayout) + , IBStripCutValue(Desc.IBStripCutValue) + , PrimitiveTopologyType(Desc.PrimitiveTopologyType) + , VS(Desc.VS) + , GS(Desc.GS) + , StreamOutput(Desc.StreamOutput) + , HS(Desc.HS) + , DS(Desc.DS) + , PS(Desc.PS) + , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) + , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) + , DSVFormat(Desc.DSVFormat) + , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) + , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) + , SampleDesc(Desc.SampleDesc) + , SampleMask(Desc.SampleMask) + , CachedPSO(Desc.CachedPSO) + , ViewInstancingDesc(CD3DX12_VIEW_INSTANCING_DESC(CD3DX12_DEFAULT())) + {} + CD3DX12_PIPELINE_STATE_STREAM2(const D3DX12_MESH_SHADER_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , PrimitiveTopologyType(Desc.PrimitiveTopologyType) + , PS(Desc.PS) + , AS(Desc.AS) + , MS(Desc.MS) + , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) + , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) + , DSVFormat(Desc.DSVFormat) + , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) + , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) + , SampleDesc(Desc.SampleDesc) + , SampleMask(Desc.SampleMask) + , CachedPSO(Desc.CachedPSO) + , ViewInstancingDesc(CD3DX12_VIEW_INSTANCING_DESC(CD3DX12_DEFAULT())) + {} + CD3DX12_PIPELINE_STATE_STREAM2(const D3D12_COMPUTE_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , CS(CD3DX12_SHADER_BYTECODE(Desc.CS)) + , CachedPSO(Desc.CachedPSO) + { + static_cast<D3D12_DEPTH_STENCIL_DESC1&>(DepthStencilState).DepthEnable = false; + } + CD3DX12_PIPELINE_STATE_STREAM_FLAGS Flags; + CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK NodeMask; + CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE pRootSignature; + CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT InputLayout; + CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE IBStripCutValue; + CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY PrimitiveTopologyType; + CD3DX12_PIPELINE_STATE_STREAM_VS VS; + CD3DX12_PIPELINE_STATE_STREAM_GS GS; + CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT StreamOutput; + CD3DX12_PIPELINE_STATE_STREAM_HS HS; + CD3DX12_PIPELINE_STATE_STREAM_DS DS; + CD3DX12_PIPELINE_STATE_STREAM_PS PS; + CD3DX12_PIPELINE_STATE_STREAM_AS AS; + CD3DX12_PIPELINE_STATE_STREAM_MS MS; + CD3DX12_PIPELINE_STATE_STREAM_CS CS; + CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC BlendState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1 DepthStencilState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT DSVFormat; + CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER RasterizerState; + CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTVFormats; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC SampleDesc; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK SampleMask; + CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO CachedPSO; + CD3DX12_PIPELINE_STATE_STREAM_VIEW_INSTANCING ViewInstancingDesc; + D3D12_GRAPHICS_PIPELINE_STATE_DESC GraphicsDescV0() const noexcept + { + D3D12_GRAPHICS_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.InputLayout = this->InputLayout; + D.IBStripCutValue = this->IBStripCutValue; + D.PrimitiveTopologyType = this->PrimitiveTopologyType; + D.VS = this->VS; + D.GS = this->GS; + D.StreamOutput = this->StreamOutput; + D.HS = this->HS; + D.DS = this->DS; + D.PS = this->PS; + D.BlendState = this->BlendState; + D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); + D.DSVFormat = this->DSVFormat; + D.RasterizerState = this->RasterizerState; + D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; + memcpy(D.RTVFormats, D3D12_RT_FORMAT_ARRAY(this->RTVFormats).RTFormats, sizeof(D.RTVFormats)); + D.SampleDesc = this->SampleDesc; + D.SampleMask = this->SampleMask; + D.CachedPSO = this->CachedPSO; + return D; + } + D3D12_COMPUTE_PIPELINE_STATE_DESC ComputeDescV0() const noexcept + { + D3D12_COMPUTE_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.CS = this->CS; + D.CachedPSO = this->CachedPSO; + return D; + } +}; diff --git a/tools/gfx/d3d12/d3d12-pipeline-state.cpp b/tools/gfx/d3d12/d3d12-pipeline-state.cpp index 754c07e5c..fc54b3884 100644 --- a/tools/gfx/d3d12/d3d12-pipeline-state.cpp +++ b/tools/gfx/d3d12/d3d12-pipeline-state.cpp @@ -10,6 +10,7 @@ #include "d3d12-framebuffer.h" #include "d3d12-shader-program.h" #include "d3d12-vertex-layout.h" +#include "d3d12-pipeline-state-stream.h" #include <climits> @@ -59,169 +60,219 @@ Result PipelineStateImpl::ensureAPIPipelineStateCreated() // Only actually create a D3D12 pipeline state if the pipeline is fully specialized. auto inputLayoutImpl = (InputLayoutImpl*)desc.graphics.inputLayout; - // Describe and create the graphics pipeline state object (PSO) - D3D12_GRAPHICS_PIPELINE_STATE_DESC psoDesc = {}; + // A helper to fill common fields between graphics and mesh pipeline descs + const auto fillCommonGraphicsState = [&](auto& psoDesc){ + psoDesc.pRootSignature = programImpl->m_rootObjectLayout->m_rootSignature; - psoDesc.pRootSignature = programImpl->m_rootObjectLayout->m_rootSignature; + psoDesc.PrimitiveTopologyType = D3DUtil::getPrimitiveType(desc.graphics.primitiveType); - for (auto& shaderBin : programImpl->m_shaders) - { - switch (shaderBin.stage) { - case SLANG_STAGE_VERTEX: - psoDesc.VS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; - break; - case SLANG_STAGE_FRAGMENT: - psoDesc.PS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; - break; - case SLANG_STAGE_DOMAIN: - psoDesc.DS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; - break; - case SLANG_STAGE_HULL: - psoDesc.HS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; - break; - case SLANG_STAGE_GEOMETRY: - psoDesc.GS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; - break; - default: - getDebugCallback()->handleMessage( - DebugMessageType::Error, - DebugMessageSource::Layer, - "Unsupported shader stage."); - return SLANG_E_NOT_AVAILABLE; - } - } - - if (inputLayoutImpl) - { - psoDesc.InputLayout = { - inputLayoutImpl->m_elements.getBuffer(), - UINT(inputLayoutImpl->m_elements.getCount()) }; - } + auto framebufferLayout = + static_cast<FramebufferLayoutImpl*>(desc.graphics.framebufferLayout); + const int numRenderTargets = int(framebufferLayout->m_renderTargets.getCount()); - psoDesc.PrimitiveTopologyType = D3DUtil::getPrimitiveType(desc.graphics.primitiveType); + if (framebufferLayout->m_hasDepthStencil) + { + psoDesc.DSVFormat = D3DUtil::getMapFormat(framebufferLayout->m_depthStencil.format); + psoDesc.SampleDesc.Count = framebufferLayout->m_depthStencil.sampleCount; + } + else + { + psoDesc.DSVFormat = DXGI_FORMAT_UNKNOWN; + if (framebufferLayout->m_renderTargets.getCount()) + { + psoDesc.SampleDesc.Count = framebufferLayout->m_renderTargets[0].sampleCount; + } + } + psoDesc.NumRenderTargets = numRenderTargets; + for (Int i = 0; i < numRenderTargets; i++) + { + psoDesc.RTVFormats[i] = + D3DUtil::getMapFormat(framebufferLayout->m_renderTargets[i].format); + } - { - auto framebufferLayout = - static_cast<FramebufferLayoutImpl*>(desc.graphics.framebufferLayout); - const int numRenderTargets = int(framebufferLayout->m_renderTargets.getCount()); + psoDesc.SampleDesc.Quality = 0; + psoDesc.SampleMask = UINT_MAX; + } - if (framebufferLayout->m_hasDepthStencil) { - psoDesc.DSVFormat = D3DUtil::getMapFormat(framebufferLayout->m_depthStencil.format); - psoDesc.SampleDesc.Count = framebufferLayout->m_depthStencil.sampleCount; + auto& rs = psoDesc.RasterizerState; + rs.FillMode = D3DUtil::getFillMode(desc.graphics.rasterizer.fillMode); + rs.CullMode = D3DUtil::getCullMode(desc.graphics.rasterizer.cullMode); + rs.FrontCounterClockwise = + desc.graphics.rasterizer.frontFace == gfx::FrontFaceMode::CounterClockwise ? TRUE + : FALSE; + rs.DepthBias = desc.graphics.rasterizer.depthBias; + rs.DepthBiasClamp = desc.graphics.rasterizer.depthBiasClamp; + rs.SlopeScaledDepthBias = desc.graphics.rasterizer.slopeScaledDepthBias; + rs.DepthClipEnable = desc.graphics.rasterizer.depthClipEnable ? TRUE : FALSE; + rs.MultisampleEnable = desc.graphics.rasterizer.multisampleEnable ? TRUE : FALSE; + rs.AntialiasedLineEnable = + desc.graphics.rasterizer.antialiasedLineEnable ? TRUE : FALSE; + rs.ForcedSampleCount = desc.graphics.rasterizer.forcedSampleCount; + rs.ConservativeRaster = desc.graphics.rasterizer.enableConservativeRasterization + ? D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON + : D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; } - else + { - psoDesc.DSVFormat = DXGI_FORMAT_UNKNOWN; - if (framebufferLayout->m_renderTargets.getCount()) + D3D12_BLEND_DESC& blend = psoDesc.BlendState; + blend.IndependentBlendEnable = FALSE; + blend.AlphaToCoverageEnable = desc.graphics.blend.alphaToCoverageEnable ? TRUE : FALSE; + blend.RenderTarget[0].RenderTargetWriteMask = (uint8_t)RenderTargetWriteMask::EnableAll; + for (GfxIndex i = 0; i < desc.graphics.blend.targetCount; i++) + { + auto& d3dDesc = blend.RenderTarget[i]; + d3dDesc.BlendEnable = desc.graphics.blend.targets[i].enableBlend ? TRUE : FALSE; + d3dDesc.BlendOp = D3DUtil::getBlendOp(desc.graphics.blend.targets[i].color.op); + d3dDesc.BlendOpAlpha = D3DUtil::getBlendOp(desc.graphics.blend.targets[i].alpha.op); + d3dDesc.DestBlend = + D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].color.dstFactor); + d3dDesc.DestBlendAlpha = + D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].alpha.dstFactor); + d3dDesc.LogicOp = D3D12_LOGIC_OP_NOOP; + d3dDesc.LogicOpEnable = FALSE; + d3dDesc.RenderTargetWriteMask = desc.graphics.blend.targets[i].writeMask; + d3dDesc.SrcBlend = + D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].color.srcFactor); + d3dDesc.SrcBlendAlpha = + D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].alpha.srcFactor); + } + for (GfxIndex i = 1; i < desc.graphics.blend.targetCount; i++) { - psoDesc.SampleDesc.Count = framebufferLayout->m_renderTargets[0].sampleCount; + if (memcmp( + &desc.graphics.blend.targets[i], + &desc.graphics.blend.targets[0], + sizeof(desc.graphics.blend.targets[0])) != 0) + { + blend.IndependentBlendEnable = TRUE; + break; + } + } + for (uint32_t i = (uint32_t)desc.graphics.blend.targetCount; + i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; + ++i) + { + blend.RenderTarget[i] = blend.RenderTarget[0]; } } - psoDesc.NumRenderTargets = numRenderTargets; - for (Int i = 0; i < numRenderTargets; i++) + { - psoDesc.RTVFormats[i] = - D3DUtil::getMapFormat(framebufferLayout->m_renderTargets[i].format); + auto& ds = psoDesc.DepthStencilState; + + ds.DepthEnable = desc.graphics.depthStencil.depthTestEnable; + ds.DepthWriteMask = desc.graphics.depthStencil.depthWriteEnable + ? D3D12_DEPTH_WRITE_MASK_ALL + : D3D12_DEPTH_WRITE_MASK_ZERO; + ds.DepthFunc = D3DUtil::getComparisonFunc(desc.graphics.depthStencil.depthFunc); + ds.StencilEnable = desc.graphics.depthStencil.stencilEnable; + ds.StencilReadMask = (UINT8)desc.graphics.depthStencil.stencilReadMask; + ds.StencilWriteMask = (UINT8)desc.graphics.depthStencil.stencilWriteMask; + ds.FrontFace = D3DUtil::translateStencilOpDesc(desc.graphics.depthStencil.frontFace); + ds.BackFace = D3DUtil::translateStencilOpDesc(desc.graphics.depthStencil.backFace); } - psoDesc.SampleDesc.Quality = 0; - psoDesc.SampleMask = UINT_MAX; - } + psoDesc.PrimitiveTopologyType = D3DUtil::getPrimitiveType(desc.graphics.primitiveType); - { - auto& rs = psoDesc.RasterizerState; - rs.FillMode = D3DUtil::getFillMode(desc.graphics.rasterizer.fillMode); - rs.CullMode = D3DUtil::getCullMode(desc.graphics.rasterizer.cullMode); - rs.FrontCounterClockwise = - desc.graphics.rasterizer.frontFace == gfx::FrontFaceMode::CounterClockwise ? TRUE - : FALSE; - rs.DepthBias = desc.graphics.rasterizer.depthBias; - rs.DepthBiasClamp = desc.graphics.rasterizer.depthBiasClamp; - rs.SlopeScaledDepthBias = desc.graphics.rasterizer.slopeScaledDepthBias; - rs.DepthClipEnable = desc.graphics.rasterizer.depthClipEnable ? TRUE : FALSE; - rs.MultisampleEnable = desc.graphics.rasterizer.multisampleEnable ? TRUE : FALSE; - rs.AntialiasedLineEnable = - desc.graphics.rasterizer.antialiasedLineEnable ? TRUE : FALSE; - rs.ForcedSampleCount = desc.graphics.rasterizer.forcedSampleCount; - rs.ConservativeRaster = desc.graphics.rasterizer.enableConservativeRasterization - ? D3D12_CONSERVATIVE_RASTERIZATION_MODE_ON - : D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; - } + }; + if(m_program->isMeshShaderProgram()) { - D3D12_BLEND_DESC& blend = psoDesc.BlendState; - blend.IndependentBlendEnable = FALSE; - blend.AlphaToCoverageEnable = desc.graphics.blend.alphaToCoverageEnable ? TRUE : FALSE; - blend.RenderTarget[0].RenderTargetWriteMask = (uint8_t)RenderTargetWriteMask::EnableAll; - for (GfxIndex i = 0; i < desc.graphics.blend.targetCount; i++) + D3DX12_MESH_SHADER_PIPELINE_STATE_DESC meshDesc = {}; + for (auto& shaderBin : programImpl->m_shaders) { - auto& d3dDesc = blend.RenderTarget[i]; - d3dDesc.BlendEnable = desc.graphics.blend.targets[i].enableBlend ? TRUE : FALSE; - d3dDesc.BlendOp = D3DUtil::getBlendOp(desc.graphics.blend.targets[i].color.op); - d3dDesc.BlendOpAlpha = D3DUtil::getBlendOp(desc.graphics.blend.targets[i].alpha.op); - d3dDesc.DestBlend = - D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].color.dstFactor); - d3dDesc.DestBlendAlpha = - D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].alpha.dstFactor); - d3dDesc.LogicOp = D3D12_LOGIC_OP_NOOP; - d3dDesc.LogicOpEnable = FALSE; - d3dDesc.RenderTargetWriteMask = desc.graphics.blend.targets[i].writeMask; - d3dDesc.SrcBlend = - D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].color.srcFactor); - d3dDesc.SrcBlendAlpha = - D3DUtil::getBlendFactor(desc.graphics.blend.targets[i].alpha.srcFactor); - } - for (GfxIndex i = 1; i < desc.graphics.blend.targetCount; i++) - { - if (memcmp( - &desc.graphics.blend.targets[i], - &desc.graphics.blend.targets[0], - sizeof(desc.graphics.blend.targets[0])) != 0) + switch (shaderBin.stage) { - blend.IndependentBlendEnable = TRUE; + case SLANG_STAGE_FRAGMENT: + meshDesc.PS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; + break; + case SLANG_STAGE_AMPLIFICATION: + meshDesc.AS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; + break; + case SLANG_STAGE_MESH: + meshDesc.MS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; break; + default: + getDebugCallback()->handleMessage( + DebugMessageType::Error, + DebugMessageSource::Layer, + "Unsupported shader stage."); + return SLANG_E_NOT_AVAILABLE; } } - for (uint32_t i = (uint32_t)desc.graphics.blend.targetCount; - i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; - ++i) + fillCommonGraphicsState(meshDesc); + if (m_device->m_pipelineCreationAPIDispatcher) { - blend.RenderTarget[i] = blend.RenderTarget[0]; + SLANG_RETURN_ON_FAIL( + m_device->m_pipelineCreationAPIDispatcher->createMeshPipelineState( + m_device, + programImpl->linkedProgram.get(), + &meshDesc, + (void**)m_pipelineState.writeRef())); } - } - - { - auto& ds = psoDesc.DepthStencilState; - - ds.DepthEnable = desc.graphics.depthStencil.depthTestEnable; - ds.DepthWriteMask = desc.graphics.depthStencil.depthWriteEnable - ? D3D12_DEPTH_WRITE_MASK_ALL - : D3D12_DEPTH_WRITE_MASK_ZERO; - ds.DepthFunc = D3DUtil::getComparisonFunc(desc.graphics.depthStencil.depthFunc); - ds.StencilEnable = desc.graphics.depthStencil.stencilEnable; - ds.StencilReadMask = (UINT8)desc.graphics.depthStencil.stencilReadMask; - ds.StencilWriteMask = (UINT8)desc.graphics.depthStencil.stencilWriteMask; - ds.FrontFace = D3DUtil::translateStencilOpDesc(desc.graphics.depthStencil.frontFace); - ds.BackFace = D3DUtil::translateStencilOpDesc(desc.graphics.depthStencil.backFace); - } - - psoDesc.PrimitiveTopologyType = D3DUtil::getPrimitiveType(desc.graphics.primitiveType); + else + { + CD3DX12_PIPELINE_STATE_STREAM2 meshStateStream{meshDesc}; + D3D12_PIPELINE_STATE_STREAM_DESC streamDesc{sizeof(meshStateStream), &meshStateStream}; - if (m_device->m_pipelineCreationAPIDispatcher) - { - SLANG_RETURN_ON_FAIL( - m_device->m_pipelineCreationAPIDispatcher->createGraphicsPipelineState( - m_device, - programImpl->linkedProgram.get(), - &psoDesc, - (void**)m_pipelineState.writeRef())); + SLANG_RETURN_ON_FAIL(m_device->m_device5->CreatePipelineState( + &streamDesc, IID_PPV_ARGS(m_pipelineState.writeRef()))); + } } else { - SLANG_RETURN_ON_FAIL(m_device->m_device->CreateGraphicsPipelineState( - &psoDesc, IID_PPV_ARGS(m_pipelineState.writeRef()))); + D3D12_GRAPHICS_PIPELINE_STATE_DESC graphicsDesc = {}; + for (auto& shaderBin : programImpl->m_shaders) + { + switch (shaderBin.stage) + { + case SLANG_STAGE_VERTEX: + graphicsDesc.VS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; + break; + case SLANG_STAGE_FRAGMENT: + graphicsDesc.PS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; + break; + case SLANG_STAGE_DOMAIN: + graphicsDesc.DS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; + break; + case SLANG_STAGE_HULL: + graphicsDesc.HS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; + break; + case SLANG_STAGE_GEOMETRY: + graphicsDesc.GS = { shaderBin.code.getBuffer(), SIZE_T(shaderBin.code.getCount()) }; + break; + default: + getDebugCallback()->handleMessage( + DebugMessageType::Error, + DebugMessageSource::Layer, + "Unsupported shader stage."); + return SLANG_E_NOT_AVAILABLE; + } + } + + if (inputLayoutImpl) + { + graphicsDesc.InputLayout = { + inputLayoutImpl->m_elements.getBuffer(), + UINT(inputLayoutImpl->m_elements.getCount()) }; + } + + fillCommonGraphicsState(graphicsDesc); + + if (m_device->m_pipelineCreationAPIDispatcher) + { + SLANG_RETURN_ON_FAIL( + m_device->m_pipelineCreationAPIDispatcher->createGraphicsPipelineState( + m_device, + programImpl->linkedProgram.get(), + &graphicsDesc, + (void**)m_pipelineState.writeRef())); + } + else + { + SLANG_RETURN_ON_FAIL(m_device->m_device->CreateGraphicsPipelineState( + &graphicsDesc, IID_PPV_ARGS(m_pipelineState.writeRef()))); + } } } else diff --git a/tools/gfx/d3d12/d3d12-sal-defs.h b/tools/gfx/d3d12/d3d12-sal-defs.h new file mode 100644 index 000000000..058fbb14c --- /dev/null +++ b/tools/gfx/d3d12/d3d12-sal-defs.h @@ -0,0 +1,199 @@ +#pragma once + +// +// The defines here are to allow compilers without support for SAL to not choke +// on any MS headers using these annotations +// + +#if !defined(_In_) +# define _In_ +#endif +#if !defined(_Out_) +# define _Out_ +#endif +#if !defined(_Inout_) +# define _Inout_ +#endif +#if !defined(_In_z_) +# define _In_z_ +#endif +#if !defined(_Inout_z_) +# define _Inout_z_ +#endif +#if !defined(_In_reads_) +# define _In_reads_(s) +#endif +#if !defined(_In_reads_z_) +# define _In_reads_z_(s) +#endif +#if !defined(_In_reads_or_z_) +# define _In_reads_or_z_(s) +#endif +#if !defined(_Out_writes_) +# define _Out_writes_(s) +#endif +#if !defined(_Out_writes_z_) +# define _Out_writes_z_(s) +#endif +#if !defined(_Inout_updates_) +# define _Inout_updates_(s) +#endif +#if !defined(_Inout_updates_z_) +# define _Inout_updates_z_(s) +#endif +#if !defined(_Out_writes_to_) +# define _Out_writes_to_(s,c) +#endif +#if !defined(_Inout_updates_to_) +# define _Inout_updates_to_(s,c) +#endif +#if !defined(_Inout_updates_all_) +# define _Inout_updates_all_(s) +#endif +#if !defined(_In_reads_to_ptr_) +# define _In_reads_to_ptr_(p) +#endif +#if !defined(_In_reads_to_ptr_z_) +# define _In_reads_to_ptr_z_(p) +#endif +#if !defined(_Out_writes_to_ptr_) +# define _Out_writes_to_ptr_(p) +#endif +#if !defined(_Out_writes_to_ptr_z_) +# define _Out_writes_to_ptr_z_(p) +#endif +#if !defined(_Outptr_) +# define _Outptr_ +#endif +#if !defined(_Outptr_opt_) +# define _Outptr_opt_ +#endif +#if !defined(_Outptr_result_maybenull_) +# define _Outptr_result_maybenull_ +#endif +#if !defined(_Outptr_opt_result_maybenull_) +# define _Outptr_opt_result_maybenull_ +#endif +#if !defined(_Outptr_result_z_) +# define _Outptr_result_z_ +#endif +#if !defined(_COM_Outptr_) +# define _COM_Outptr_ +#endif +#if !defined(_Outptr_result_buffer_) +# define _Outptr_result_buffer_(s) +#endif +#if !defined(_Outptr_result_buffer_to_) +# define _Outptr_result_buffer_to_(s, c) +#endif +#if !defined(_Result_nullonfailure_) +# define _Result_nullonfailure_ +#endif +#if !defined(_Result_zeroonfailure_) +# define _Result_zeroonfailure_ +#endif +#if !defined(_Outptr_result_nullonfailure_) +# define _Outptr_result_nullonfailure_ +#endif +#if !defined(_Outptr_opt_result_nullonfailure_) +# define _Outptr_opt_result_nullonfailure_ +#endif +#if !defined(_Outref_result_nullonfailure_) +# define _Outref_result_nullonfailure_ +#endif +#if !defined(_Outref_) +# define _Outref_ +#endif +#if !defined(_Outref_result_maybenull_) +# define _Outref_result_maybenull_ +#endif +#if !defined(_Outref_result_buffer_) +# define _Outref_result_buffer_(s) +#endif +#if !defined(_Outref_result_bytebuffer_) +# define _Outref_result_bytebuffer_(s) +#endif +#if !defined(_Outref_result_buffer_to_) +# define _Outref_result_buffer_to_(s, c) +#endif +#if !defined(_Outref_result_bytebuffer_to_) +# define _Outref_result_bytebuffer_to_(s, c) +#endif +#if !defined(_Outref_result_buffer_all_) +# define _Outref_result_buffer_all_(s) +#endif +#if !defined(_Outref_result_bytebuffer_all_) +# define _Outref_result_bytebuffer_all_(s) +#endif +#if !defined(_Outref_result_buffer_maybenull_) +# define _Outref_result_buffer_maybenull_(s) +#endif +#if !defined(_Outref_result_bytebuffer_maybenull_) +# define _Outref_result_bytebuffer_maybenull_(s) +#endif +#if !defined(_Outref_result_buffer_to_maybenull_) +# define _Outref_result_buffer_to_maybenull_(s, c) +#endif +#if !defined(_Outref_result_bytebuffer_to_maybenull_) +# define _Outref_result_bytebuffer_to_maybenull_(s,c) +#endif +#if !defined(_Outref_result_buffer_all_maybenull_) +# define _Outref_result_buffer_all_maybenull_(s) +#endif +#if !defined(_Outref_result_bytebuffer_all_maybenull_) +# define _Outref_result_bytebuffer_all_maybenull_(s) +#endif +#if !defined(_Printf_format_string_) +# define _Printf_format_string_ +#endif +#if !defined(_Scanf_format_string_) +# define _Scanf_format_string_ +#endif +#if !defined(_Scanf_s_format_string_) +# define _Scanf_s_format_string_ +#endif +#if !defined(_In_range_) +# define _In_range_(low, hi) +#endif +#if !defined(_Pre_equal_to_) +# define _Pre_equal_to_(expr) +#endif +#if !defined(_Struct_size_bytes_) +# define _Struct_size_bytes_(size) +#endif +#if !defined(_Called_from_function_class_) +# define _Called_from_function_class_(name) +#endif +#if !defined(_Check_return_) +# define _Check_return_ +#endif +#if !defined(_Function_class_) +# define _Function_class_(name) +#endif +#if !defined(_Raises_SEH_exception_) +# define _Raises_SEH_exception_ +#endif +#if !defined(_Maybe_raises_SEH_exception_) +# define _Maybe_raises_SEH_exception_ +#endif +#if !defined(_Must_inspect_result_) +# define _Must_inspect_result_ +#endif +#if !defined(_Use_decl_annotations_) +# define _Use_decl_annotations_ +#endif +#if !defined(_Always_) +# define _Always_(anno_list) +#endif +#if !defined(_On_failure_) +# define _On_failure_(anno_list) +#endif +#if !defined(_Return_type_success_) +# define _Return_type_success_(expr) +#endif +#if !defined(_Success_) +# define _Success_(expr) +#endif +#if !defined(__analysis_assume) +# define __analysis_assume(expr) +#endif |
