#include "BsRenderStateManager.h" #include "BsSamplerState.h" #include "BsDepthStencilState.h" #include "BsRasterizerState.h" #include "BsBlendState.h" namespace BansheeEngine { SamplerStatePtr RenderStateManager::createSamplerState(const SAMPLER_STATE_DESC& desc) const { SPtr state = _createSamplerStatePtr(desc); state->initialize(); return state; } DepthStencilStatePtr RenderStateManager::createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const { SPtr state = _createDepthStencilStatePtr(desc); state->initialize(); return state; } RasterizerStatePtr RenderStateManager::createRasterizerState(const RASTERIZER_STATE_DESC& desc) const { SPtr state = _createRasterizerStatePtr(desc); state->initialize(); return state; } BlendStatePtr RenderStateManager::createBlendState(const BLEND_STATE_DESC& desc) const { SPtr state = _createBlendStatePtr(desc); state->initialize(); return state; } SamplerStatePtr RenderStateManager::_createSamplerStatePtr(const SAMPLER_STATE_DESC& desc) const { SamplerStatePtr samplerState = bs_core_ptr(new (bs_alloc()) SamplerState(desc)); samplerState->_setThisPtr(samplerState); return samplerState; } DepthStencilStatePtr RenderStateManager::_createDepthStencilStatePtr(const DEPTH_STENCIL_STATE_DESC& desc) const { DepthStencilStatePtr depthStencilState = bs_core_ptr(new (bs_alloc()) DepthStencilState(desc)); depthStencilState->_setThisPtr(depthStencilState); return depthStencilState; } RasterizerStatePtr RenderStateManager::_createRasterizerStatePtr(const RASTERIZER_STATE_DESC& desc) const { RasterizerStatePtr rasterizerState = bs_core_ptr(new (bs_alloc()) RasterizerState(desc)); rasterizerState->_setThisPtr(rasterizerState); return rasterizerState; } BlendStatePtr RenderStateManager::_createBlendStatePtr(const BLEND_STATE_DESC& desc) const { BlendStatePtr blendState = bs_core_ptr(new (bs_alloc()) BlendState(desc)); blendState->_setThisPtr(blendState); return blendState; } const SamplerStatePtr& RenderStateManager::getDefaultSamplerState() const { if(mDefaultSamplerState == nullptr) mDefaultSamplerState = createSamplerState(SAMPLER_STATE_DESC()); return mDefaultSamplerState; } const BlendStatePtr& RenderStateManager::getDefaultBlendState() const { if(mDefaultBlendState == nullptr) mDefaultBlendState = createBlendState(BLEND_STATE_DESC()); return mDefaultBlendState; } const RasterizerStatePtr& RenderStateManager::getDefaultRasterizerState() const { if(mDefaultRasterizerState == nullptr) mDefaultRasterizerState = createRasterizerState(RASTERIZER_STATE_DESC()); return mDefaultRasterizerState; } const DepthStencilStatePtr& RenderStateManager::getDefaultDepthStencilState() const { if(mDefaultDepthStencilState == nullptr) mDefaultDepthStencilState = createDepthStencilState(DEPTH_STENCIL_STATE_DESC()); return mDefaultDepthStencilState; } RenderStateCoreManager::RenderStateCoreManager() :mNextBlendStateId(0), mNextDepthStencilStateId(0), mNextRasterizerStateId(0) { } SPtr RenderStateCoreManager::createSamplerState(const SAMPLER_STATE_DESC& desc) const { SPtr state = findCachedState(desc); if (state == nullptr) { state = createSamplerStateInternal(desc); state->initialize(); notifySamplerStateCreated(desc, state); } return state; } SPtr RenderStateCoreManager::createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const { UINT32 id = 0; SPtr state = findCachedState(desc, id); if (state == nullptr) { state = createDepthStencilStateInternal(desc, id); state->initialize(); CachedDepthStencilState cachedData(id); cachedData.state = state; notifyDepthStencilStateCreated(desc, cachedData); } return state; } SPtr RenderStateCoreManager::createRasterizerState(const RASTERIZER_STATE_DESC& desc) const { UINT32 id = 0; SPtr state = findCachedState(desc, id); if (state == nullptr) { state = createRasterizerStateInternal(desc, id); state->initialize(); CachedRasterizerState cachedData(id); cachedData.state = state; notifyRasterizerStateCreated(desc, cachedData); } return state; } SPtr RenderStateCoreManager::createBlendState(const BLEND_STATE_DESC& desc) const { UINT32 id = 0; SPtr state = findCachedState(desc, id); if (state == nullptr) { state = createBlendStateInternal(desc, id); state->initialize(); CachedBlendState cachedData(id); cachedData.state = state; notifyBlendStateCreated(desc, cachedData); } return state; } SPtr RenderStateCoreManager::_createSamplerState(const SAMPLER_STATE_DESC& desc) const { SPtr state = findCachedState(desc); if (state == nullptr) { state = createSamplerStateInternal(desc); notifySamplerStateCreated(desc, state); } return state; } SPtr RenderStateCoreManager::_createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const { UINT32 id = 0; SPtr state = findCachedState(desc, id); if (state == nullptr) { state = createDepthStencilStateInternal(desc, id); CachedDepthStencilState cachedData(id); cachedData.state = state; notifyDepthStencilStateCreated(desc, cachedData); } return state; } SPtr RenderStateCoreManager::_createRasterizerState(const RASTERIZER_STATE_DESC& desc) const { UINT32 id = 0; SPtr state = findCachedState(desc, id); if (state == nullptr) { state = createRasterizerStateInternal(desc, id); CachedRasterizerState cachedData(id); cachedData.state = state; notifyRasterizerStateCreated(desc, cachedData); } return state; } SPtr RenderStateCoreManager::_createBlendState(const BLEND_STATE_DESC& desc) const { UINT32 id = 0; SPtr state = findCachedState(desc, id); if (state == nullptr) { state = createBlendStateInternal(desc, id); CachedBlendState cachedData(id); cachedData.state = state; notifyBlendStateCreated(desc, cachedData); } return state; } void RenderStateCoreManager::onShutDown() { mDefaultBlendState = nullptr; mDefaultDepthStencilState = nullptr; mDefaultRasterizerState = nullptr; mDefaultSamplerState = nullptr; } const SPtr& RenderStateCoreManager::getDefaultSamplerState() const { if (mDefaultSamplerState == nullptr) mDefaultSamplerState = createSamplerState(SAMPLER_STATE_DESC()); return mDefaultSamplerState; } const SPtr& RenderStateCoreManager::getDefaultBlendState() const { if (mDefaultBlendState == nullptr) mDefaultBlendState = createBlendState(BLEND_STATE_DESC()); return mDefaultBlendState; } const SPtr& RenderStateCoreManager::getDefaultRasterizerState() const { if (mDefaultRasterizerState == nullptr) mDefaultRasterizerState = createRasterizerState(RASTERIZER_STATE_DESC()); return mDefaultRasterizerState; } const SPtr& RenderStateCoreManager::getDefaultDepthStencilState() const { if (mDefaultDepthStencilState == nullptr) mDefaultDepthStencilState = createDepthStencilState(DEPTH_STENCIL_STATE_DESC()); return mDefaultDepthStencilState; } void RenderStateCoreManager::notifySamplerStateCreated(const SAMPLER_STATE_DESC& desc, const SPtr& state) const { BS_LOCK_MUTEX(mMutex); mCachedSamplerStates[desc] = state; } void RenderStateCoreManager::notifyBlendStateCreated(const BLEND_STATE_DESC& desc, const CachedBlendState& state) const { BS_LOCK_MUTEX(mMutex); mCachedBlendStates[desc] = state; } void RenderStateCoreManager::notifyRasterizerStateCreated(const RASTERIZER_STATE_DESC& desc, const CachedRasterizerState& state) const { BS_LOCK_MUTEX(mMutex); mCachedRasterizerStates[desc] = state; } void RenderStateCoreManager::notifyDepthStencilStateCreated(const DEPTH_STENCIL_STATE_DESC& desc, const CachedDepthStencilState& state) const { BS_LOCK_MUTEX(mMutex); mCachedDepthStencilStates[desc] = state; } void RenderStateCoreManager::notifySamplerStateDestroyed(const SAMPLER_STATE_DESC& desc) const { BS_LOCK_MUTEX(mMutex); mCachedSamplerStates.erase(desc); } SPtr RenderStateCoreManager::findCachedState(const SAMPLER_STATE_DESC& desc) const { BS_LOCK_MUTEX(mMutex); auto iterFind = mCachedSamplerStates.find(desc); if (iterFind != mCachedSamplerStates.end()) return iterFind->second.lock(); return nullptr; } SPtr RenderStateCoreManager::findCachedState(const BLEND_STATE_DESC& desc, UINT32& id) const { BS_LOCK_MUTEX(mMutex); auto iterFind = mCachedBlendStates.find(desc); if (iterFind != mCachedBlendStates.end()) { id = iterFind->second.id; if (!iterFind->second.state.expired()) return iterFind->second.state.lock(); return nullptr; } id = mNextBlendStateId++; assert(id <= 0x3FF); // 10 bits maximum return nullptr; } SPtr RenderStateCoreManager::findCachedState(const RASTERIZER_STATE_DESC& desc, UINT32& id) const { BS_LOCK_MUTEX(mMutex); auto iterFind = mCachedRasterizerStates.find(desc); if (iterFind != mCachedRasterizerStates.end()) { id = iterFind->second.id; if (!iterFind->second.state.expired()) return iterFind->second.state.lock(); return nullptr; } id = mNextRasterizerStateId++; assert(id <= 0x3FF); // 10 bits maximum return nullptr; } SPtr RenderStateCoreManager::findCachedState(const DEPTH_STENCIL_STATE_DESC& desc, UINT32& id) const { BS_LOCK_MUTEX(mMutex); auto iterFind = mCachedDepthStencilStates.find(desc); if (iterFind != mCachedDepthStencilStates.end()) { id = iterFind->second.id; if (!iterFind->second.state.expired()) return iterFind->second.state.lock(); return nullptr; } id = mNextDepthStencilStateId++; assert(id <= 0x3FF); // 10 bits maximum return nullptr; } SPtr RenderStateCoreManager::createSamplerStateInternal(const SAMPLER_STATE_DESC& desc) const { SPtr state = bs_shared_ptr(new (bs_alloc()) SamplerStateCore(desc)); state->_setThisPtr(state); return state; } SPtr RenderStateCoreManager::createDepthStencilStateInternal(const DEPTH_STENCIL_STATE_DESC& desc, UINT32 id) const { SPtr state = bs_shared_ptr(new (bs_alloc()) DepthStencilStateCore(desc, id)); state->_setThisPtr(state); return state; } SPtr RenderStateCoreManager::createRasterizerStateInternal(const RASTERIZER_STATE_DESC& desc, UINT32 id) const { SPtr state = bs_shared_ptr(new (bs_alloc()) RasterizerStateCore(desc, id)); state->_setThisPtr(state); return state; } SPtr RenderStateCoreManager::createBlendStateInternal(const BLEND_STATE_DESC& desc, UINT32 id) const { SPtr state = bs_shared_ptr(new (bs_alloc()) BlendStateCore(desc, id)); state->_setThisPtr(state); return state; } }