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 | |
14 | namespace 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 = 0; |
294 | mutable UINT32 mNextDepthStencilStateId = 0; |
295 | |
296 | mutable Mutex mMutex; |
297 | }; |
298 | } |
299 | |
300 | /** @} */ |
301 | } |