Diligent Engine API Reference: D:/GitHub/DiligentEngine/DiligentCore/Graphics/GraphicsEngine/include/PipelineStateBase.h Source File

Diligent Engine API Reference

PipelineStateBase.h
1 /* Copyright 2015-2018 Egor Yusov
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
12 *
13 * In no event and under no legal theory, whether in tort (including negligence),
14 * contract, or otherwise, unless required by applicable law (such as deliberate
15 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
16 * liable for any damages, including any direct, indirect, special, incidental,
17 * or consequential damages of any character arising as a result of this License or
18 * out of the use or inability to use the software (including but not limited to damages
19 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
20 * all other commercial damages or losses), even if such Contributor has been advised
21 * of the possibility of such damages.
22 */
23
24 #pragma once
25
28
29 #include "PipelineState.h"
30 #include "DeviceObjectBase.h"
31 #include "STDAllocator.h"
32 #include "EngineMemory.h"
33 #include "GraphicsAccessories.h"
34
35 namespace Diligent
36 {
37
39
45 template<class BaseInterface, class RenderDeviceBaseInterface>
46 class PipelineStateBase : public DeviceObjectBase<BaseInterface, PipelineStateDesc>
47 {
48 public:
49 typedef DeviceObjectBase<BaseInterface, PipelineStateDesc> TDeviceObjectBase;
50 typedef RenderDeviceBase < RenderDeviceBaseInterface > TRenderDeviceBase;
51
57 PipelineStateBase( IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const PipelineStateDesc& PSODesc, bool bIsDeviceInternal = false ) :
58 TDeviceObjectBase( pRefCounters, pDevice, PSODesc, bIsDeviceInternal ),
59 m_LayoutElements( PSODesc.GraphicsPipeline.InputLayout.NumElements, LayoutElement(), STD_ALLOCATOR_RAW_MEM(LayoutElement, GetRawAllocator(), "Allocator for vector<LayoutElement>" ) ),
60 m_NumShaders(0)
61 {
62 memset(m_ppShaders, 0, sizeof(m_ppShaders));
63
64 if (this->m_Desc.IsComputePipeline)
65 {
66 const auto &ComputePipeline = PSODesc.ComputePipeline;
67 if (ComputePipeline.pCS == nullptr)
68 {
69 LOG_ERROR_AND_THROW( "Compute shader is not provided" );
70 }
71
72 #define VALIDATE_SHADER_TYPE(Shader, ExpectedType, ShaderName)\
73 if (Shader && Shader->GetDesc().ShaderType != ExpectedType) \
74 { \
75 LOG_ERROR_AND_THROW( GetShaderTypeLiteralName(Shader->GetDesc().ShaderType), " is not valid type for ", ShaderName, " shader" );\
76 }
77 VALIDATE_SHADER_TYPE(ComputePipeline.pCS, SHADER_TYPE_COMPUTE, "compute")
78
79 m_pCS = ComputePipeline.pCS;
80 m_ppShaders[0] = ComputePipeline.pCS;
81 m_NumShaders = 1;
82 }
83 else
84 {
85 const auto &GraphicsPipeline = PSODesc.GraphicsPipeline;
86
87 VALIDATE_SHADER_TYPE(GraphicsPipeline.pVS, SHADER_TYPE_VERTEX, "vertex")
88 VALIDATE_SHADER_TYPE(GraphicsPipeline.pPS, SHADER_TYPE_PIXEL, "pixel")
89 VALIDATE_SHADER_TYPE(GraphicsPipeline.pGS, SHADER_TYPE_GEOMETRY, "geometry")
90 VALIDATE_SHADER_TYPE(GraphicsPipeline.pHS, SHADER_TYPE_HULL, "hull")
91 VALIDATE_SHADER_TYPE(GraphicsPipeline.pDS, SHADER_TYPE_DOMAIN, "domain")
92 #undef VALIDATE_SHADER_TYPE
93
94 m_pVS = GraphicsPipeline.pVS;
95 m_pPS = GraphicsPipeline.pPS;
96 m_pGS = GraphicsPipeline.pGS;
97 m_pDS = GraphicsPipeline.pDS;
98 m_pHS = GraphicsPipeline.pHS;
99
100 if( GraphicsPipeline.pVS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pVS;
101 if( GraphicsPipeline.pPS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pPS;
102 if( GraphicsPipeline.pGS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pGS;
103 if( GraphicsPipeline.pHS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pHS;
104 if( GraphicsPipeline.pDS )m_ppShaders[m_NumShaders++] = GraphicsPipeline.pDS;
105 }
106
107 const auto &InputLayout = PSODesc.GraphicsPipeline.InputLayout;
108 for( size_t Elem = 0; Elem < InputLayout.NumElements; ++Elem )
109 m_LayoutElements[Elem] = InputLayout.LayoutElements[Elem];
110 this->m_Desc.GraphicsPipeline.InputLayout.LayoutElements = m_LayoutElements.data();
111
112 // Correct description and compute offsets and tight strides
113 for( auto It = m_LayoutElements.begin(); It != m_LayoutElements.end(); ++It )
114 {
115 if( It->ValueType == VT_FLOAT32 || It->ValueType == VT_FLOAT16 )
116 It->IsNormalized = false; // Floating point values cannot be normalized
117
118 auto BuffSlot = It->BufferSlot;
119 if( BuffSlot >= _countof(m_TightStrides) )
120 {
121 UNEXPECTED("Buffer slot (", BuffSlot, ") exceeds the limit (", _countof(m_TightStrides), ")");
122 continue;
123 }
124
125 auto &CurrStride = m_TightStrides[BuffSlot];
126 if( It->RelativeOffset < CurrStride )
127 {
128 if( It->RelativeOffset == 0 )
129 It->RelativeOffset = CurrStride;
130 else
131 UNEXPECTED( "Overlapping layout elements" );
132 }
133
134 CurrStride += It->NumComponents * GetValueSize( It->ValueType );
135 }
136 }
137
138 ~PipelineStateBase()
139 {
140 /*
148 auto &PipelineStateRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetBSRegistry();
149 auto &RasterizerStateRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetRSRegistry();
150 auto &DSSRegistry = static_cast<TRenderDeviceBase*>(this->GetDevice())->GetDSSRegistry();
151 // StateObjectsRegistry::ReportDeletedObject() does not lock the registry, but only
152 // atomically increments the outstanding deleted objects counter.
153 PipelineStateRegistry.ReportDeletedObject();
154 RasterizerStateRegistry.ReportDeletedObject();
155 DSSRegistry.ReportDeletedObject();
156 */
157 }
158
159 IMPLEMENT_QUERY_INTERFACE_IN_PLACE( IID_PipelineState, TDeviceObjectBase )
160
161 virtual const Uint32* GetTightStrides()const
162 {
163 return m_TightStrides;
164 }
165
166 IShader* GetVS(){return m_pVS;}
167 IShader* GetPS(){return m_pPS;}
168 IShader* GetGS(){return m_pGS;}
169 IShader* GetDS(){return m_pDS;}
170 IShader* GetHS(){return m_pHS;}
171 IShader* GetCS(){return m_pCS;}
172
173 IShader* const* GetShaders()const{return m_ppShaders;}
174 Uint32 GetNumShaders()const{return m_NumShaders;}
175
176 protected:
177 std::vector<LayoutElement, STDAllocatorRawMem<LayoutElement> > m_LayoutElements;
178
179 // The size of this array must be equal to the
180 // maximum number of buffer slots, because a layout
181 // element can refer to any input slot
182 Uint32 m_TightStrides[MaxBufferSlots] = {};
183
184 RefCntAutoPtr<IShader> m_pVS;
185 RefCntAutoPtr<IShader> m_pPS;
186 RefCntAutoPtr<IShader> m_pGS;
187 RefCntAutoPtr<IShader> m_pDS;
188 RefCntAutoPtr<IShader> m_pHS;
189 RefCntAutoPtr<IShader> m_pCS;
190 IShader *m_ppShaders[5];
191 Uint32 m_NumShaders;
192 };
193
194 }
Diligent::MaxBufferSlots
static constexpr Uint32 MaxBufferSlots
Maximum number of input buffer slots. D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT == 32...
Definition: Constants.h:33
Diligent::PipelineStateBase::m_pDS
RefCntAutoPtr< IShader > m_pDS
Strong reference to the domain shader.
Definition: PipelineStateBase.h:187
Diligent::IRenderDevice
Render device interface.
Definition: RenderDevice.h:55
Diligent::IShader
Shader interface.
Definition: Shader.h:288
Diligent::PipelineStateBase::m_pCS
RefCntAutoPtr< IShader > m_pCS
Strong reference to the compute shader.
Definition: PipelineStateBase.h:189
Diligent::PipelineStateBase
Template class implementing base functionality for a pipeline state object.
Definition: PipelineStateBase.h:46
Diligent
Namespace for the OpenGL implementation of the graphics engine.
Definition: BufferD3D11Impl.h:34
Diligent::SHADER_TYPE_PIXEL
Pixel (fragment) shader.
Definition: Shader.h:50
Diligent::PipelineStateBase::m_pVS
RefCntAutoPtr< IShader > m_pVS
Strong reference to the vertex shader.
Definition: PipelineStateBase.h:184
Diligent::GetRawAllocator
IMemoryAllocator & GetRawAllocator()
Returns raw memory allocator.
Definition: EngineMemory.cpp:46
Diligent::SHADER_TYPE_HULL
Hull (tessellation control) shader.
Definition: Shader.h:52
Diligent::SHADER_TYPE_DOMAIN
Domain (tessellation evaluation) shader.
Definition: Shader.h:53
Diligent::PipelineStateBase::PipelineStateBase
PipelineStateBase(IReferenceCounters *pRefCounters, IRenderDevice *pDevice, const PipelineStateDesc &PSODesc, bool bIsDeviceInternal=false)
Definition: PipelineStateBase.h:57
Diligent::LayoutElement
Description of a single element of the input layout.
Definition: InputLayout.h:37
Diligent::RenderDeviceBase
Base implementation of a render device.
Definition: DeviceObjectBase.h:36
Diligent::SHADER_TYPE_VERTEX
Vertex shader.
Definition: Shader.h:49
Diligent::PipelineStateBase::m_NumShaders
Uint32 m_NumShaders
Number of shaders that this PSO uses.
Definition: PipelineStateBase.h:191
Diligent::DeviceObjectBase< BaseInterface, PipelineStateDesc >::m_Desc
PipelineStateDesc m_Desc
Object description.
Definition: DeviceObjectBase.h:138
Diligent::PipelineStateBase::m_pGS
RefCntAutoPtr< IShader > m_pGS
Strong reference to the geometry shader.
Definition: PipelineStateBase.h:186
Diligent::VT_FLOAT16
Half-precision 16-bit floating point.
Definition: GraphicsTypes.h:48
Diligent::VT_FLOAT32
Full-precision 32-bit floating point.
Definition: GraphicsTypes.h:49
Diligent::PipelineStateDesc::ComputePipeline
ComputePipelineDesc ComputePipeline
Compute pipeline state description. This memeber is ignored if IsComputePipeline == False...
Definition: PipelineState.h:188
Diligent::GraphicsPipelineDesc::InputLayout
InputLayoutDesc InputLayout
Input layout.
Definition: PipelineState.h:124
Diligent::PipelineStateBase::m_ppShaders
IShader * m_ppShaders[5]
Array of pointers to shaders that this PSO uses.
Definition: PipelineStateBase.h:190
Diligent::PipelineStateBase::m_pHS
RefCntAutoPtr< IShader > m_pHS
Strong reference to the hull shader.
Definition: PipelineStateBase.h:188
Diligent::RefCntAutoPtr
Template class that implements reference counting.
Definition: RefCntAutoPtr.h:71
Diligent::PipelineStateDesc::IsComputePipeline
bool IsComputePipeline
Flag indicating if pipeline state is a compute pipeline state.
Definition: PipelineState.h:182
Diligent::PipelineStateDesc::GraphicsPipeline
GraphicsPipelineDesc GraphicsPipeline
Graphics pipeline state description. This memeber is ignored if IsComputePipeline == True...
Definition: PipelineState.h:185
Diligent::PipelineStateBase::m_pPS
RefCntAutoPtr< IShader > m_pPS
Strong reference to the pixel shader.
Definition: PipelineStateBase.h:185
Diligent::DeviceObjectBase
Template class implementing base functionality for a device object.
Definition: DeviceObjectBase.h:42
Diligent::PipelineStateDesc
Pipeline state description.
Definition: PipelineState.h:179
Diligent::SHADER_TYPE_COMPUTE
Compute shader.
Definition: Shader.h:54
Diligent::SHADER_TYPE_GEOMETRY
Geometry shader.
Definition: Shader.h:51