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 | |
9 | namespace 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 | } |