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 "Utility/BsModule.h"
7#include "RenderAPI/BsBlendState.h"
8#include "RenderAPI/BsRasterizerState.h"
9#include "RenderAPI/BsDepthStencilState.h"
10#include "RenderAPI/BsSamplerState.h"
11#include "RenderAPI/BsGpuPipelineState.h"
12#include "RenderAPI/BsGpuPipelineParamInfo.h"
13
14namespace bs
15{
16 /** @addtogroup RenderAPI-Internal
17 * @{
18 */
19
20 /** Handles creation of various render states. */
21 class BS_CORE_EXPORT RenderStateManager : public Module <RenderStateManager>
22 {
23 public:
24 /**
25 * Creates and initializes a new SamplerState.
26 *
27 * @param[in] desc Object describing the sampler state to create.
28 */
29 SPtr<SamplerState> createSamplerState(const SAMPLER_STATE_DESC& desc) const;
30
31 /** Creates and initializes a new DepthStencilState. */
32 SPtr<DepthStencilState> createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const;
33
34 /** Creates and initializes a new RasterizerState. */
35 SPtr<RasterizerState> createRasterizerState(const RASTERIZER_STATE_DESC& desc) const;
36
37 /** Creates and initializes a new BlendState. */
38 SPtr<BlendState> createBlendState(const BLEND_STATE_DESC& desc) const;
39
40 /**
41 * Creates and initializes a new GraphicsPipelineState.
42 *
43 * @param[in] desc Object describing the pipeline to create.
44 */
45 SPtr<GraphicsPipelineState> createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc) const;
46
47 /**
48 * Creates and initializes a new ComputePipelineState.
49 *
50 * @param[in] program Compute GPU program to be executed by the pipeline.
51 */
52 SPtr<ComputePipelineState> createComputePipelineState(const SPtr<GpuProgram>& program) const;
53
54 /** Creates an uninitialized sampler state. Requires manual initialization after creation. */
55 SPtr<SamplerState> _createSamplerStatePtr(const SAMPLER_STATE_DESC& desc) const;
56
57 /** Creates an uninitialized depth-stencil state. Requires manual initialization after creation. */
58 SPtr<DepthStencilState> _createDepthStencilStatePtr(const DEPTH_STENCIL_STATE_DESC& desc) const;
59
60 /** Creates an uninitialized rasterizer state. Requires manual initialization after creation. */
61 SPtr<RasterizerState> _createRasterizerStatePtr(const RASTERIZER_STATE_DESC& desc) const;
62
63 /** Creates an uninitialized blend state. Requires manual initialization after creation. */
64 SPtr<BlendState> _createBlendStatePtr(const BLEND_STATE_DESC& desc) const;
65
66 /** Creates an uninitialized GraphicsPipelineState. Requires manual initialization after creation. */
67 virtual SPtr<GraphicsPipelineState> _createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc) const;
68
69 /** Creates an uninitialized ComputePipelineState. Requires manual initialization after creation. */
70 virtual SPtr<ComputePipelineState> _createComputePipelineState(const SPtr<GpuProgram>& program) const;
71
72 /** Gets a sampler state initialized with default options. */
73 const SPtr<SamplerState>& getDefaultSamplerState() const;
74
75 /** Gets a blend state initialized with default options. */
76 const SPtr<BlendState>& getDefaultBlendState() const;
77
78 /** Gets a rasterizer state initialized with default options. */
79 const SPtr<RasterizerState>& getDefaultRasterizerState() const;
80
81 /** Gets a depth stencil state initialized with default options. */
82 const SPtr<DepthStencilState>& getDefaultDepthStencilState() const;
83
84 private:
85 friend class SamplerState;
86 friend class BlendState;
87 friend class RasterizerState;
88 friend class DepthStencilState;
89
90 mutable SPtr<SamplerState> mDefaultSamplerState;
91 mutable SPtr<BlendState> mDefaultBlendState;
92 mutable SPtr<RasterizerState> mDefaultRasterizerState;
93 mutable SPtr<DepthStencilState> mDefaultDepthStencilState;
94 };
95
96 namespace ct
97 {
98 /** Handles creation of various render states. */
99 class BS_CORE_EXPORT RenderStateManager : public Module<RenderStateManager>
100 {
101 private:
102 /** Contains data about a cached blend state. */
103 struct CachedBlendState
104 {
105 CachedBlendState() = default;
106
107 CachedBlendState(UINT32 id)
108 :id(id)
109 { }
110
111 std::weak_ptr<BlendState> state;
112 UINT32 id = 0;
113 };
114
115 /** Contains data about a cached rasterizer state. */
116 struct CachedRasterizerState
117 {
118 CachedRasterizerState() = default;
119
120 CachedRasterizerState(UINT32 id)
121 :id(id)
122 { }
123
124 std::weak_ptr<RasterizerState> state;
125 UINT32 id = 0;
126 };
127
128 /** Contains data about a cached depth stencil state. */
129 struct CachedDepthStencilState
130 {
131 CachedDepthStencilState() = default;
132
133 CachedDepthStencilState(UINT32 id)
134 :id(id)
135 { }
136
137 std::weak_ptr<DepthStencilState> state;
138 UINT32 id = 0;
139 };
140
141 public:
142 RenderStateManager() = default;
143
144 /**
145 * @copydoc bs::RenderStateManager::createSamplerState
146 * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
147 */
148 SPtr<SamplerState> createSamplerState(const SAMPLER_STATE_DESC& desc,
149 GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
150
151 /** @copydoc bs::RenderStateManager::createDepthStencilState */
152 SPtr<DepthStencilState> createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const;
153
154 /** @copydoc bs::RenderStateManager::createRasterizerState */
155 SPtr<RasterizerState> createRasterizerState(const RASTERIZER_STATE_DESC& desc) const;
156
157 /** @copydoc bs::RenderStateManager::createBlendState */
158 SPtr<BlendState> createBlendState(const BLEND_STATE_DESC& desc) const;
159
160 /**
161 * @copydoc bs::RenderStateManager::createGraphicsPipelineState
162 * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
163 */
164 SPtr<GraphicsPipelineState> createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc,
165 GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
166
167 /**
168 * @copydoc bs::RenderStateManager::createComputePipelineState
169 * @param[in] deviceMask Mask that determines on which GPU devices should the object be created on.
170 */
171 SPtr<ComputePipelineState> createComputePipelineState(const SPtr<GpuProgram>& program,
172 GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
173
174 /** @copydoc GpuPipelineParamInfo::create */
175 SPtr<GpuPipelineParamInfo> createPipelineParamInfo(const GPU_PIPELINE_PARAMS_DESC& desc,
176 GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
177
178 /** Creates an uninitialized sampler state. Requires manual initialization after creation. */
179 SPtr<SamplerState> _createSamplerState(const SAMPLER_STATE_DESC& desc,
180 GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
181
182 /** Creates an uninitialized depth-stencil state. Requires manual initialization after creation. */
183 SPtr<DepthStencilState> _createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const;
184
185 /** Creates an uninitialized rasterizer state. Requires manual initialization after creation. */
186 SPtr<RasterizerState> _createRasterizerState(const RASTERIZER_STATE_DESC& desc) const;
187
188 /** Creates an uninitialized blend state. Requires manual initialization after creation. */
189 SPtr<BlendState> _createBlendState(const BLEND_STATE_DESC& desc) const;
190
191 /** Creates an uninitialized GraphicsPipelineState. Requires manual initialization after creation. */
192 virtual SPtr<GraphicsPipelineState> _createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc,
193 GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
194
195 /** Creates an uninitialized ComputePipelineState. Requires manual initialization after creation. */
196 virtual SPtr<ComputePipelineState> _createComputePipelineState(const SPtr<GpuProgram>& program,
197 GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
198
199 /** Creates an uninitialized GpuPipelineParamInfo. Requires manual initialization after creation. */
200 virtual SPtr<GpuPipelineParamInfo> _createPipelineParamInfo(const GPU_PIPELINE_PARAMS_DESC& desc,
201 GpuDeviceFlags deviceMask = GDF_DEFAULT) const;
202
203 /** Gets a sampler state initialized with default options. */
204 const SPtr<SamplerState>& getDefaultSamplerState() const;
205
206 /** Gets a blend state initialized with default options. */
207 const SPtr<BlendState>& getDefaultBlendState() const;
208
209 /** Gets a rasterizer state initialized with default options. */
210 const SPtr<RasterizerState>& getDefaultRasterizerState() const;
211
212 /** Gets a depth stencil state initialized with default options. */
213 const SPtr<DepthStencilState>& getDefaultDepthStencilState() const;
214
215 protected:
216 friend class bs::SamplerState;
217 friend class bs::BlendState;
218 friend class bs::RasterizerState;
219 friend class bs::DepthStencilState;
220 friend class SamplerState;
221 friend class BlendState;
222 friend class RasterizerState;
223 friend class DepthStencilState;
224
225 /** @copydoc Module::onShutDown */
226 void onShutDown() override;
227
228 /** @copydoc createSamplerState */
229 virtual SPtr<SamplerState> createSamplerStateInternal(const SAMPLER_STATE_DESC& desc, GpuDeviceFlags deviceMask) const;
230
231 /** @copydoc createBlendState */
232 virtual SPtr<BlendState> createBlendStateInternal(const BLEND_STATE_DESC& desc, UINT32 id) const;
233
234 /** @copydoc createRasterizerState */
235 virtual SPtr<RasterizerState> createRasterizerStateInternal(const RASTERIZER_STATE_DESC& desc, UINT32 id) const;
236
237 /** @copydoc createDepthStencilState */
238 virtual SPtr<DepthStencilState> createDepthStencilStateInternal(const DEPTH_STENCIL_STATE_DESC& desc, UINT32 id) const;
239
240 private:
241 /** Triggered when a new sampler state is created. */
242 void notifySamplerStateCreated(const SAMPLER_STATE_DESC& desc, const SPtr<SamplerState>& state) const;
243
244 /** Triggered when a new sampler state is created. */
245 void notifyBlendStateCreated(const BLEND_STATE_DESC& desc, const CachedBlendState& state) const;
246
247 /** Triggered when a new sampler state is created. */
248 void notifyRasterizerStateCreated(const RASTERIZER_STATE_DESC& desc, const CachedRasterizerState& state) const;
249
250 /** Triggered when a new sampler state is created. */
251 void notifyDepthStencilStateCreated(const DEPTH_STENCIL_STATE_DESC& desc, const CachedDepthStencilState& state) const;
252
253 /**
254 * Triggered when the last reference to a specific sampler state is destroyed, which means we must clear our cached
255 * version as well.
256 */
257 void notifySamplerStateDestroyed(const SAMPLER_STATE_DESC& desc) const;
258
259 /**
260 * Attempts to find a cached sampler state corresponding to the provided descriptor. Returns null if one doesn't
261 * exist.
262 */
263 SPtr<SamplerState> findCachedState(const SAMPLER_STATE_DESC& desc) const;
264
265 /**
266 * Attempts to find a cached blend state corresponding to the provided descriptor. Returns null if one doesn't exist.
267 */
268 SPtr<BlendState> findCachedState(const BLEND_STATE_DESC& desc, UINT32& id) const;
269
270 /**
271 * Attempts to find a cached rasterizer state corresponding to the provided descriptor. Returns null if one doesn't
272 * exist.
273 */
274 SPtr<RasterizerState> findCachedState(const RASTERIZER_STATE_DESC& desc, UINT32& id) const;
275
276 /**
277 * Attempts to find a cached depth-stencil state corresponding to the provided descriptor. Returns null if one
278 * doesn't exist.
279 */
280 SPtr<DepthStencilState> findCachedState(const DEPTH_STENCIL_STATE_DESC& desc, UINT32& id) const;
281
282 mutable SPtr<SamplerState> mDefaultSamplerState;
283 mutable SPtr<BlendState> mDefaultBlendState;
284 mutable SPtr<RasterizerState> mDefaultRasterizerState;
285 mutable SPtr<DepthStencilState> mDefaultDepthStencilState;
286
287 mutable UnorderedMap<SAMPLER_STATE_DESC, std::weak_ptr<SamplerState>> mCachedSamplerStates;
288 mutable UnorderedMap<BLEND_STATE_DESC, CachedBlendState> mCachedBlendStates;
289 mutable UnorderedMap<RASTERIZER_STATE_DESC, CachedRasterizerState> mCachedRasterizerStates;
290 mutable UnorderedMap<DEPTH_STENCIL_STATE_DESC, CachedDepthStencilState> mCachedDepthStencilStates;
291
292 mutable UINT32 mNextBlendStateId = 0;
293 mutable UINT32 mNextRasterizerStateId = 0;
294 mutable UINT32 mNextDepthStencilStateId = 0;
295
296 mutable Mutex mMutex;
297 };
298 }
299
300 /** @} */
301}