1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsCorePrerequisites.h"
6#include "Image/BsColor.h"
7#include "RenderAPI/BsBlendState.h"
8#include "RenderAPI/BsRasterizerState.h"
9#include "RenderAPI/BsDepthStencilState.h"
10#include "RenderAPI/BsGpuProgram.h"
11#include "Reflection/BsIReflectable.h"
12#include "CoreThread/BsCoreObject.h"
13#include "RenderAPI/BsGpuPipelineState.h"
14
15namespace bs
16{
17 /** @addtogroup Material
18 * @{
19 */
20
21 /** Descriptor structure used for initializing a shader pass. */
22 struct PASS_DESC
23 {
24 BLEND_STATE_DESC blendStateDesc;
25 RASTERIZER_STATE_DESC rasterizerStateDesc;
26 DEPTH_STENCIL_STATE_DESC depthStencilStateDesc;
27 UINT32 stencilRefValue;
28
29 GPU_PROGRAM_DESC vertexProgramDesc;
30 GPU_PROGRAM_DESC fragmentProgramDesc;
31 GPU_PROGRAM_DESC geometryProgramDesc;
32 GPU_PROGRAM_DESC hullProgramDesc;
33 GPU_PROGRAM_DESC domainProgramDesc;
34 GPU_PROGRAM_DESC computeProgramDesc;
35 };
36
37 /** @} */
38
39 /** @addtogroup Implementation
40 * @{
41 */
42
43 /** Contains common functionality used by both sim and core thread versions of Pass. */
44 template<bool Core>
45 class BS_CORE_EXPORT TPass
46 {
47 public:
48 using BlendStateType = CoreVariantType<BlendState, Core>;
49 using RasterizerStateType = CoreVariantType<RasterizerState, Core>;
50 using DepthStencilStateType = CoreVariantType<DepthStencilState, Core>;
51 using GpuProgramType = CoreVariantType<GpuProgram, Core>;
52 using GraphicsPipelineStateType = CoreVariantType<GraphicsPipelineState, Core>;
53 using ComputePipelineStateType = CoreVariantType<ComputePipelineState, Core>;
54 using PipelineStateDescType = typename TGpuPipelineStateTypes<Core>::StateDescType;
55
56 virtual ~TPass() = default;
57
58 /** Returns true if this pass has some element of transparency. */
59 bool hasBlending() const;
60
61 /** Returns true if the pass executes a compute program. */
62 bool isCompute() const { return !mData.computeProgramDesc.source.empty(); }
63
64 /** Gets the stencil reference value that is used when performing operations using the stencil buffer. */
65 UINT32 getStencilRefValue() const { return mData.stencilRefValue; }
66
67 /** Returns the GPU program descriptor for the specified GPU program type. */
68 const GPU_PROGRAM_DESC& getProgramDesc(bs::GpuProgramType type) const;
69
70 /**
71 * Returns the graphics pipeline state describing this pass, or null if its a compute pass.
72 * Only valid after compile() has been called.
73 */
74 const SPtr<GraphicsPipelineStateType>& getGraphicsPipelineState() const { return mGraphicsPipelineState; }
75
76 /**
77 * Returns the compute pipeline state describing this pass, or null if its a graphics pass.
78 * Only valid after compile has been called.
79 */
80 const SPtr<ComputePipelineStateType>& getComputePipelineState() const { return mComputePipelineState; }
81
82 /**
83 * @name Internal
84 * @{
85 */
86
87 /** Enumerates all the fields in the type and executes the specified processor action for each field. */
88 template<class P>
89 void rttiEnumFields(P p);
90
91 /** @} */
92 protected:
93 TPass();
94 TPass(const PASS_DESC& desc);
95
96 /** Creates either the graphics or the compute pipeline state from the stored pass data. */
97 void createPipelineState();
98
99 PASS_DESC mData;
100 SPtr<GraphicsPipelineStateType> mGraphicsPipelineState;
101 SPtr<ComputePipelineStateType> mComputePipelineState;
102 };
103
104 /** @} */
105
106 /** @addtogroup Material
107 * @{
108 */
109
110 /**
111 * Class defining a single pass of a technique (of a material). Pass may contain multiple GPU programs (vertex,
112 * fragment, geometry, etc.), and a set of pipeline states (blend, rasterizer, etc.). When initially created the pass
113 * is in its uncompiled state. It needs to be explicitly compiled by calling compile() before use.
114 *
115 * @note Sim thread.
116 */
117 class BS_CORE_EXPORT Pass : public IReflectable, public CoreObject, public TPass<false>
118 {
119 public:
120 virtual ~Pass() = default;
121
122 /** Retrieves an implementation of a pass usable only from the core thread. */
123 SPtr<ct::Pass> getCore() const;
124
125 /**
126 * Initializes the pass internals by compiling the GPU programs and creating the relevant pipeline state. This
127 * method must be called before pass pipelines can be retrieved. After initial compilation further calls do this
128 * method will perform no operation.
129 */
130 void compile();
131
132 /** Creates a new empty pass. */
133 static SPtr<Pass> create(const PASS_DESC& desc);
134
135 protected:
136 friend class Technique;
137
138 Pass() = default;
139 Pass(const PASS_DESC& desc);
140
141 /** @copydoc CoreObject::syncToCore */
142 CoreSyncData syncToCore(FrameAlloc* allocator) override;
143
144 /** @copydoc CoreObject::createCore */
145 SPtr<ct::CoreObject> createCore() const override;
146
147 /** Creates a new empty pass but doesn't initialize it. */
148 static SPtr<Pass> createEmpty();
149
150 /************************************************************************/
151 /* RTTI */
152 /************************************************************************/
153 public:
154 friend class PassRTTI;
155 static RTTITypeBase* getRTTIStatic();
156 RTTITypeBase* getRTTI() const override;
157 };
158
159 /** @} */
160
161 namespace ct
162 {
163 /** @addtogroup Material-Internal
164 * @{
165 */
166
167 /**
168 * Core thread counterpart of bs::Pass.
169 *
170 * @note Core thread.
171 */
172 class BS_CORE_EXPORT Pass : public CoreObject, public TPass<true>
173 {
174 public:
175 virtual ~Pass() = default;
176
177 /** Creates a new empty pass. */
178 static SPtr<Pass> create(const PASS_DESC& desc);
179
180 /** @copydoc bs::Pass::compile */
181 void compile();
182
183 protected:
184 friend class bs::Pass;
185 friend class Technique;
186
187 Pass() = default;
188 Pass(const PASS_DESC& desc);
189
190 /** @copydoc CoreObject::syncToCore */
191 void syncToCore(const CoreSyncData& data) override;
192 };
193
194 /** @} */
195 }
196}
197