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#include "Managers/BsRenderStateManager.h"
4#include "RenderAPI/BsSamplerState.h"
5#include "RenderAPI/BsDepthStencilState.h"
6#include "RenderAPI/BsRasterizerState.h"
7#include "RenderAPI/BsBlendState.h"
8
9namespace bs
10{
11 SPtr<SamplerState> RenderStateManager::createSamplerState(const SAMPLER_STATE_DESC& desc) const
12 {
13 SPtr<SamplerState> state = _createSamplerStatePtr(desc);
14 state->initialize();
15
16 return state;
17 }
18
19 SPtr<DepthStencilState> RenderStateManager::createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const
20 {
21 SPtr<DepthStencilState> state = _createDepthStencilStatePtr(desc);
22 state->initialize();
23
24 return state;
25 }
26
27 SPtr<RasterizerState> RenderStateManager::createRasterizerState(const RASTERIZER_STATE_DESC& desc) const
28 {
29 SPtr<RasterizerState> state = _createRasterizerStatePtr(desc);
30 state->initialize();
31
32 return state;
33 }
34
35 SPtr<BlendState> RenderStateManager::createBlendState(const BLEND_STATE_DESC& desc) const
36 {
37 SPtr<BlendState> state = _createBlendStatePtr(desc);
38 state->initialize();
39
40 return state;
41 }
42
43 SPtr<GraphicsPipelineState> RenderStateManager::createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc) const
44 {
45 SPtr<GraphicsPipelineState> state = _createGraphicsPipelineState(desc);
46 state->initialize();
47
48 return state;
49 }
50
51 SPtr<ComputePipelineState> RenderStateManager::createComputePipelineState(const SPtr<GpuProgram>& program) const
52 {
53 SPtr<ComputePipelineState> state = _createComputePipelineState(program);
54 state->initialize();
55
56 return state;
57 }
58
59 SPtr<SamplerState> RenderStateManager::_createSamplerStatePtr(const SAMPLER_STATE_DESC& desc) const
60 {
61 SPtr<SamplerState> samplerState = bs_core_ptr<SamplerState>(new (bs_alloc<SamplerState>()) SamplerState(desc));
62 samplerState->_setThisPtr(samplerState);
63
64 return samplerState;
65 }
66
67 SPtr<DepthStencilState> RenderStateManager::_createDepthStencilStatePtr(const DEPTH_STENCIL_STATE_DESC& desc) const
68 {
69 SPtr<DepthStencilState> depthStencilState = bs_core_ptr<DepthStencilState>(new (bs_alloc<DepthStencilState>()) DepthStencilState(desc));
70 depthStencilState->_setThisPtr(depthStencilState);
71
72 return depthStencilState;
73 }
74
75 SPtr<RasterizerState> RenderStateManager::_createRasterizerStatePtr(const RASTERIZER_STATE_DESC& desc) const
76 {
77 SPtr<RasterizerState> rasterizerState = bs_core_ptr<RasterizerState>(new (bs_alloc<RasterizerState>()) RasterizerState(desc));
78 rasterizerState->_setThisPtr(rasterizerState);
79
80 return rasterizerState;
81 }
82
83 SPtr<BlendState> RenderStateManager::_createBlendStatePtr(const BLEND_STATE_DESC& desc) const
84 {
85 SPtr<BlendState> blendState = bs_core_ptr<BlendState>(new (bs_alloc<BlendState>()) BlendState(desc));
86 blendState->_setThisPtr(blendState);
87
88 return blendState;
89 }
90
91 SPtr<GraphicsPipelineState> RenderStateManager::_createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc) const
92 {
93 SPtr<GraphicsPipelineState> pipelineState =
94 bs_core_ptr<GraphicsPipelineState>(new (bs_alloc<GraphicsPipelineState>()) GraphicsPipelineState(desc));
95 pipelineState->_setThisPtr(pipelineState);
96
97 return pipelineState;
98 }
99
100 SPtr<ComputePipelineState> RenderStateManager::_createComputePipelineState(const SPtr<GpuProgram>& program) const
101 {
102 SPtr<ComputePipelineState> pipelineState =
103 bs_core_ptr<ComputePipelineState>(new (bs_alloc<ComputePipelineState>()) ComputePipelineState(program));
104 pipelineState->_setThisPtr(pipelineState);
105
106 return pipelineState;
107 }
108
109 const SPtr<SamplerState>& RenderStateManager::getDefaultSamplerState() const
110 {
111 if(mDefaultSamplerState == nullptr)
112 mDefaultSamplerState = createSamplerState(SAMPLER_STATE_DESC());
113
114 return mDefaultSamplerState;
115 }
116
117 const SPtr<BlendState>& RenderStateManager::getDefaultBlendState() const
118 {
119 if(mDefaultBlendState == nullptr)
120 mDefaultBlendState = createBlendState(BLEND_STATE_DESC());
121
122 return mDefaultBlendState;
123 }
124
125 const SPtr<RasterizerState>& RenderStateManager::getDefaultRasterizerState() const
126 {
127 if(mDefaultRasterizerState == nullptr)
128 mDefaultRasterizerState = createRasterizerState(RASTERIZER_STATE_DESC());
129
130 return mDefaultRasterizerState;
131 }
132
133 const SPtr<DepthStencilState>& RenderStateManager::getDefaultDepthStencilState() const
134 {
135 if(mDefaultDepthStencilState == nullptr)
136 mDefaultDepthStencilState = createDepthStencilState(DEPTH_STENCIL_STATE_DESC());
137
138 return mDefaultDepthStencilState;
139 }
140
141 namespace ct
142 {
143 SPtr<SamplerState> RenderStateManager::createSamplerState(const SAMPLER_STATE_DESC& desc,
144 GpuDeviceFlags deviceMask) const
145 {
146 SPtr<SamplerState> state = findCachedState(desc);
147 if (state == nullptr)
148 {
149 state = createSamplerStateInternal(desc, deviceMask);
150 state->initialize();
151
152 notifySamplerStateCreated(desc, state);
153 }
154
155 return state;
156 }
157
158 SPtr<DepthStencilState> RenderStateManager::createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const
159 {
160 UINT32 id = 0;
161 SPtr<DepthStencilState> state = findCachedState(desc, id);
162 if (state == nullptr)
163 {
164 state = createDepthStencilStateInternal(desc, id);
165 state->initialize();
166
167 CachedDepthStencilState cachedData(id);
168 cachedData.state = state;
169
170 notifyDepthStencilStateCreated(desc, cachedData);
171 }
172
173 return state;
174 }
175
176 SPtr<RasterizerState> RenderStateManager::createRasterizerState(const RASTERIZER_STATE_DESC& desc) const
177 {
178 UINT32 id = 0;
179 SPtr<RasterizerState> state = findCachedState(desc, id);
180 if (state == nullptr)
181 {
182 state = createRasterizerStateInternal(desc, id);
183 state->initialize();
184
185 CachedRasterizerState cachedData(id);
186 cachedData.state = state;
187
188 notifyRasterizerStateCreated(desc, cachedData);
189 }
190
191 return state;
192 }
193
194 SPtr<BlendState> RenderStateManager::createBlendState(const BLEND_STATE_DESC& desc) const
195 {
196 UINT32 id = 0;
197 SPtr<BlendState> state = findCachedState(desc, id);
198 if (state == nullptr)
199 {
200 state = createBlendStateInternal(desc, id);
201 state->initialize();
202
203 CachedBlendState cachedData(id);
204 cachedData.state = state;
205
206 notifyBlendStateCreated(desc, cachedData);
207 }
208
209 return state;
210 }
211
212 SPtr<GraphicsPipelineState> RenderStateManager::createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc,
213 GpuDeviceFlags deviceMask) const
214 {
215 SPtr<GraphicsPipelineState> state = _createGraphicsPipelineState(desc, deviceMask);
216 state->initialize();
217
218 return state;
219 }
220
221 SPtr<ComputePipelineState> RenderStateManager::createComputePipelineState(const SPtr<GpuProgram>& program,
222 GpuDeviceFlags deviceMask) const
223 {
224 SPtr<ComputePipelineState> state = _createComputePipelineState(program, deviceMask);
225 state->initialize();
226
227 return state;
228 }
229
230 SPtr<GpuPipelineParamInfo> RenderStateManager::createPipelineParamInfo(
231 const GPU_PIPELINE_PARAMS_DESC& desc, GpuDeviceFlags deviceMask) const
232 {
233 SPtr<GpuPipelineParamInfo> paramInfo = _createPipelineParamInfo(desc, deviceMask);
234 paramInfo->initialize();
235
236 return paramInfo;
237 }
238
239 SPtr<SamplerState> RenderStateManager::_createSamplerState(const SAMPLER_STATE_DESC& desc,
240 GpuDeviceFlags deviceMask) const
241 {
242 SPtr<SamplerState> state = findCachedState(desc);
243 if (state == nullptr)
244 {
245 state = createSamplerStateInternal(desc, deviceMask);
246
247 notifySamplerStateCreated(desc, state);
248 }
249
250 return state;
251 }
252
253 SPtr<DepthStencilState> RenderStateManager::_createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const
254 {
255 UINT32 id = 0;
256 SPtr<DepthStencilState> state = findCachedState(desc, id);
257 if (state == nullptr)
258 {
259 state = createDepthStencilStateInternal(desc, id);
260
261 CachedDepthStencilState cachedData(id);
262 cachedData.state = state;
263
264 notifyDepthStencilStateCreated(desc, cachedData);
265 }
266
267 return state;
268 }
269
270 SPtr<RasterizerState> RenderStateManager::_createRasterizerState(const RASTERIZER_STATE_DESC& desc) const
271 {
272 UINT32 id = 0;
273 SPtr<RasterizerState> state = findCachedState(desc, id);
274 if (state == nullptr)
275 {
276 state = createRasterizerStateInternal(desc, id);
277
278 CachedRasterizerState cachedData(id);
279 cachedData.state = state;
280
281 notifyRasterizerStateCreated(desc, cachedData);
282 }
283
284 return state;
285 }
286
287 SPtr<BlendState> RenderStateManager::_createBlendState(const BLEND_STATE_DESC& desc) const
288 {
289 UINT32 id = 0;
290 SPtr<BlendState> state = findCachedState(desc, id);
291 if (state == nullptr)
292 {
293 state = createBlendStateInternal(desc, id);
294
295 CachedBlendState cachedData(id);
296 cachedData.state = state;
297
298 notifyBlendStateCreated(desc, cachedData);
299 }
300
301 return state;
302 }
303
304 SPtr<GraphicsPipelineState> RenderStateManager::_createGraphicsPipelineState(const PIPELINE_STATE_DESC& desc,
305 GpuDeviceFlags deviceMask) const
306 {
307 SPtr<GraphicsPipelineState> pipelineState =
308 bs_shared_ptr<GraphicsPipelineState>(new (bs_alloc<GraphicsPipelineState>())
309 GraphicsPipelineState(desc, deviceMask));
310
311 pipelineState->_setThisPtr(pipelineState);
312
313 return pipelineState;
314 }
315
316 SPtr<ComputePipelineState> RenderStateManager::_createComputePipelineState(const SPtr<GpuProgram>& program,
317 GpuDeviceFlags deviceMask) const
318 {
319 SPtr<ComputePipelineState> pipelineState =
320 bs_shared_ptr<ComputePipelineState>(new (bs_alloc<ComputePipelineState>())
321 ComputePipelineState(program, deviceMask));
322
323 pipelineState->_setThisPtr(pipelineState);
324
325 return pipelineState;
326 }
327
328 SPtr<GpuPipelineParamInfo> RenderStateManager::_createPipelineParamInfo(
329 const GPU_PIPELINE_PARAMS_DESC& desc, GpuDeviceFlags deviceMask) const
330 {
331 SPtr<GpuPipelineParamInfo> paramInfo =
332 bs_shared_ptr<GpuPipelineParamInfo>(new (bs_alloc<GpuPipelineParamInfo>())
333 GpuPipelineParamInfo(desc, deviceMask));
334
335 paramInfo->_setThisPtr(paramInfo);
336
337 return paramInfo;
338 }
339
340 void RenderStateManager::onShutDown()
341 {
342 mDefaultBlendState = nullptr;
343 mDefaultDepthStencilState = nullptr;
344 mDefaultRasterizerState = nullptr;
345 mDefaultSamplerState = nullptr;
346 }
347
348 const SPtr<SamplerState>& RenderStateManager::getDefaultSamplerState() const
349 {
350 if (mDefaultSamplerState == nullptr)
351 mDefaultSamplerState = createSamplerState(SAMPLER_STATE_DESC());
352
353 return mDefaultSamplerState;
354 }
355
356 const SPtr<BlendState>& RenderStateManager::getDefaultBlendState() const
357 {
358 if (mDefaultBlendState == nullptr)
359 mDefaultBlendState = createBlendState(BLEND_STATE_DESC());
360
361 return mDefaultBlendState;
362 }
363
364 const SPtr<RasterizerState>& RenderStateManager::getDefaultRasterizerState() const
365 {
366 if (mDefaultRasterizerState == nullptr)
367 mDefaultRasterizerState = createRasterizerState(RASTERIZER_STATE_DESC());
368
369 return mDefaultRasterizerState;
370 }
371
372 const SPtr<DepthStencilState>& RenderStateManager::getDefaultDepthStencilState() const
373 {
374 if (mDefaultDepthStencilState == nullptr)
375 mDefaultDepthStencilState = createDepthStencilState(DEPTH_STENCIL_STATE_DESC());
376
377 return mDefaultDepthStencilState;
378 }
379
380 void RenderStateManager::notifySamplerStateCreated(const SAMPLER_STATE_DESC& desc, const SPtr<SamplerState>& state) const
381 {
382 Lock lock(mMutex);
383
384 mCachedSamplerStates[desc] = state;
385 }
386
387 void RenderStateManager::notifyBlendStateCreated(const BLEND_STATE_DESC& desc, const CachedBlendState& state) const
388 {
389 Lock lock(mMutex);
390
391 mCachedBlendStates[desc] = state;
392 }
393
394 void RenderStateManager::notifyRasterizerStateCreated(const RASTERIZER_STATE_DESC& desc, const CachedRasterizerState& state) const
395 {
396 Lock lock(mMutex);
397
398 mCachedRasterizerStates[desc] = state;
399 }
400
401 void RenderStateManager::notifyDepthStencilStateCreated(const DEPTH_STENCIL_STATE_DESC& desc, const CachedDepthStencilState& state) const
402 {
403 Lock lock(mMutex);
404
405 mCachedDepthStencilStates[desc] = state;
406 }
407
408 void RenderStateManager::notifySamplerStateDestroyed(const SAMPLER_STATE_DESC& desc) const
409 {
410 Lock lock(mMutex);
411
412 mCachedSamplerStates.erase(desc);
413 }
414
415 SPtr<SamplerState> RenderStateManager::findCachedState(const SAMPLER_STATE_DESC& desc) const
416 {
417 Lock lock(mMutex);
418
419 auto iterFind = mCachedSamplerStates.find(desc);
420 if (iterFind != mCachedSamplerStates.end())
421 return iterFind->second.lock();
422
423 return nullptr;
424 }
425
426 SPtr<BlendState> RenderStateManager::findCachedState(const BLEND_STATE_DESC& desc, UINT32& id) const
427 {
428 Lock lock(mMutex);
429
430 auto iterFind = mCachedBlendStates.find(desc);
431 if (iterFind != mCachedBlendStates.end())
432 {
433 id = iterFind->second.id;
434
435 if (!iterFind->second.state.expired())
436 return iterFind->second.state.lock();
437
438 return nullptr;
439 }
440
441 id = mNextBlendStateId++;
442 assert(id <= 0x3FF); // 10 bits maximum
443
444 return nullptr;
445 }
446
447 SPtr<RasterizerState> RenderStateManager::findCachedState(const RASTERIZER_STATE_DESC& desc, UINT32& id) const
448 {
449 Lock lock(mMutex);
450
451 auto iterFind = mCachedRasterizerStates.find(desc);
452 if (iterFind != mCachedRasterizerStates.end())
453 {
454 id = iterFind->second.id;
455
456 if (!iterFind->second.state.expired())
457 return iterFind->second.state.lock();
458
459 return nullptr;
460 }
461
462 id = mNextRasterizerStateId++;
463 assert(id <= 0x3FF); // 10 bits maximum
464
465 return nullptr;
466 }
467
468 SPtr<DepthStencilState> RenderStateManager::findCachedState(const DEPTH_STENCIL_STATE_DESC& desc, UINT32& id) const
469 {
470 Lock lock(mMutex);
471
472 auto iterFind = mCachedDepthStencilStates.find(desc);
473 if (iterFind != mCachedDepthStencilStates.end())
474 {
475 id = iterFind->second.id;
476
477 if (!iterFind->second.state.expired())
478 return iterFind->second.state.lock();
479
480 return nullptr;
481 }
482
483 id = mNextDepthStencilStateId++;
484 assert(id <= 0x3FF); // 10 bits maximum
485
486 return nullptr;
487 }
488
489 SPtr<SamplerState> RenderStateManager::createSamplerStateInternal(const SAMPLER_STATE_DESC& desc, GpuDeviceFlags deviceMask) const
490 {
491 SPtr<SamplerState> state =
492 bs_shared_ptr<SamplerState>(new (bs_alloc<SamplerState>()) SamplerState(desc, deviceMask));
493 state->_setThisPtr(state);
494
495 return state;
496 }
497
498 SPtr<DepthStencilState> RenderStateManager::createDepthStencilStateInternal(const DEPTH_STENCIL_STATE_DESC& desc, UINT32 id) const
499 {
500 SPtr<DepthStencilState> state = bs_shared_ptr<DepthStencilState>(new (bs_alloc<DepthStencilState>()) DepthStencilState(desc, id));
501 state->_setThisPtr(state);
502
503 return state;
504 }
505
506 SPtr<RasterizerState> RenderStateManager::createRasterizerStateInternal(const RASTERIZER_STATE_DESC& desc, UINT32 id) const
507 {
508 SPtr<RasterizerState> state = bs_shared_ptr<RasterizerState>(new (bs_alloc<RasterizerState>()) RasterizerState(desc, id));
509 state->_setThisPtr(state);
510
511 return state;
512 }
513
514 SPtr<BlendState> RenderStateManager::createBlendStateInternal(const BLEND_STATE_DESC& desc, UINT32 id) const
515 {
516 SPtr<BlendState> state = bs_shared_ptr<BlendState>(new (bs_alloc<BlendState>()) BlendState(desc, id));
517 state->_setThisPtr(state);
518
519 return state;
520 }
521 }
522}