#pragma once #include "BsCorePrerequisites.h" #include "BsModule.h" #include "BsBlendState.h" #include "BsRasterizerState.h" #include "BsDepthStencilState.h" #include "BsSamplerState.h" namespace BansheeEngine { /** * @brief Handles creation of various render states. */ class BS_CORE_EXPORT RenderStateManager : public Module { public: /** * @brief Creates and initializes a new SamplerState. */ SamplerStatePtr createSamplerState(const SAMPLER_STATE_DESC& desc) const; /** * @brief Creates and initializes a new DepthStencilState. */ DepthStencilStatePtr createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const; /** * @brief Creates and initializes a new RasterizerState. */ RasterizerStatePtr createRasterizerState(const RASTERIZER_STATE_DESC& desc) const; /** * @brief Creates and initializes a new BlendState. */ BlendStatePtr createBlendState(const BLEND_STATE_DESC& desc) const; /** * @brief Creates an uninitialized sampler state. Requires manual initialization * after creation. * * @note Internal method. */ SamplerStatePtr _createSamplerStatePtr(const SAMPLER_STATE_DESC& desc) const; /** * @brief Creates an uninitialized depth-stencil state. Requires manual initialization * after creation. * * @note Internal method. */ DepthStencilStatePtr _createDepthStencilStatePtr(const DEPTH_STENCIL_STATE_DESC& desc) const; /** * @brief Creates an uninitialized rasterizer state. Requires manual initialization * after creation. * * @note Internal method. */ RasterizerStatePtr _createRasterizerStatePtr(const RASTERIZER_STATE_DESC& desc) const; /** * @brief Creates an uninitialized blend state. Requires manual initialization * after creation. * * @note Internal method. */ BlendStatePtr _createBlendStatePtr(const BLEND_STATE_DESC& desc) const; /** * @brief Gets a sampler state initialized with default options. */ const SamplerStatePtr& getDefaultSamplerState() const; /** * @brief Gets a blend state initialized with default options. */ const BlendStatePtr& getDefaultBlendState() const; /** * @brief Gets a rasterizer state initialized with default options. */ const RasterizerStatePtr& getDefaultRasterizerState() const; /** * @brief Gets a depth stencil state initialized with default options. */ const DepthStencilStatePtr& getDefaultDepthStencilState() const; private: friend class SamplerState; friend class BlendState; friend class RasterizerState; friend class DepthStencilState; mutable SamplerStatePtr mDefaultSamplerState; mutable BlendStatePtr mDefaultBlendState; mutable RasterizerStatePtr mDefaultRasterizerState; mutable DepthStencilStatePtr mDefaultDepthStencilState; }; /** * @brief Handles creation of various render states. */ class BS_CORE_EXPORT RenderStateCoreManager : public Module { private: /** * @brief Contains data about a cached blend state */ struct CachedBlendState { CachedBlendState() :id(0) { } CachedBlendState(UINT32 id) :id(id) { } std::weak_ptr state; UINT32 id; }; /** * @brief Contains data about a cached blend state */ struct CachedRasterizerState { CachedRasterizerState() :id(0) { } CachedRasterizerState(UINT32 id) :id(id) { } std::weak_ptr state; UINT32 id; }; /** * @brief Contains data about a cached blend state */ struct CachedDepthStencilState { CachedDepthStencilState() :id(0) { } CachedDepthStencilState(UINT32 id) :id(id) { } std::weak_ptr state; UINT32 id; }; public: RenderStateCoreManager(); /** * @copydoc RenderStateManager::createSamplerState */ SPtr createSamplerState(const SAMPLER_STATE_DESC& desc) const; /** * @copydoc RenderStateManager::createDepthStencilState */ SPtr createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const; /** * @copydoc RenderStateManager::createRasterizerState */ SPtr createRasterizerState(const RASTERIZER_STATE_DESC& desc) const; /** * @copydoc RenderStateManager::createBlendState */ SPtr createBlendState(const BLEND_STATE_DESC& desc) const; /** * @brief Creates an uninitialized sampler state. Requires manual initialization * after creation. * * @note Internal method. */ SPtr _createSamplerState(const SAMPLER_STATE_DESC& desc) const; /** * @brief Creates an uninitialized depth-stencil state. Requires manual initialization * after creation. * * @note Internal method. */ SPtr _createDepthStencilState(const DEPTH_STENCIL_STATE_DESC& desc) const; /** * @brief Creates an uninitialized rasterizer state. Requires manual initialization * after creation. * * @note Internal method. */ SPtr _createRasterizerState(const RASTERIZER_STATE_DESC& desc) const; /** * @brief Creates an uninitialized blend state. Requires manual initialization * after creation. * * @note Internal method. */ SPtr _createBlendState(const BLEND_STATE_DESC& desc) const; /** * @brief Gets a sampler state initialized with default options. */ const SPtr& getDefaultSamplerState() const; /** * @brief Gets a blend state initialized with default options. */ const SPtr& getDefaultBlendState() const; /** * @brief Gets a rasterizer state initialized with default options. */ const SPtr& getDefaultRasterizerState() const; /** * @brief Gets a depth stencil state initialized with default options. */ const SPtr& getDefaultDepthStencilState() const; protected: friend class SamplerState; friend class BlendState; friend class RasterizerState; friend class DepthStencilState; friend class SamplerStateCore; friend class BlendStateCore; friend class RasterizerStateCore; friend class DepthStencilStateCore; /** * @copydoc Module::onShutDown */ void onShutDown() override; /** * @copydoc createSamplerState */ virtual SPtr createSamplerStateInternal(const SAMPLER_STATE_DESC& desc) const; /** * @copydoc createBlendState */ virtual SPtr createBlendStateInternal(const BLEND_STATE_DESC& desc, UINT32 id) const; /** * @copydoc createRasterizerState */ virtual SPtr createRasterizerStateInternal(const RASTERIZER_STATE_DESC& desc, UINT32 id) const; /** * @copydoc createDepthStencilState */ virtual SPtr createDepthStencilStateInternal(const DEPTH_STENCIL_STATE_DESC& desc, UINT32 id) const; private: /** * @brief Triggered when a new sampler state is created. */ void notifySamplerStateCreated(const SAMPLER_STATE_DESC& desc, const SPtr& state) const; /** * @brief Triggered when a new sampler state is created. */ void notifyBlendStateCreated(const BLEND_STATE_DESC& desc, const CachedBlendState& state) const; /** * @brief Triggered when a new sampler state is created. */ void notifyRasterizerStateCreated(const RASTERIZER_STATE_DESC& desc, const CachedRasterizerState& state) const; /** * @brief Triggered when a new sampler state is created. */ void notifyDepthStencilStateCreated(const DEPTH_STENCIL_STATE_DESC& desc, const CachedDepthStencilState& state) const; /** * @brief Triggered when the last reference to a specific sampler state is destroyed, which * means we must clear our cached version as well. */ void notifySamplerStateDestroyed(const SAMPLER_STATE_DESC& desc) const; /** * @brief Attempts to find a cached sampler state corresponding to the provided descriptor. * Returns null if one doesn't exist. */ SPtr findCachedState(const SAMPLER_STATE_DESC& desc) const; /** * @brief Attempts to find a cached blend state corresponding to the provided descriptor. * Returns null if one doesn't exist. */ SPtr findCachedState(const BLEND_STATE_DESC& desc, UINT32& id) const; /** * @brief Attempts to find a cached rasterizer state corresponding to the provided descriptor. * Returns null if one doesn't exist. */ SPtr findCachedState(const RASTERIZER_STATE_DESC& desc, UINT32& id) const; /** * @brief Attempts to find a cached depth-stencil state corresponding to the provided descriptor. * Returns null if one doesn't exist. */ SPtr findCachedState(const DEPTH_STENCIL_STATE_DESC& desc, UINT32& id) const; mutable SPtr mDefaultSamplerState; mutable SPtr mDefaultBlendState; mutable SPtr mDefaultRasterizerState; mutable SPtr mDefaultDepthStencilState; mutable UnorderedMap> mCachedSamplerStates; mutable UnorderedMap mCachedBlendStates; mutable UnorderedMap mCachedRasterizerStates; mutable UnorderedMap mCachedDepthStencilStates; mutable UINT32 mNextBlendStateId; mutable UINT32 mNextRasterizerStateId; mutable UINT32 mNextDepthStencilStateId; BS_MUTEX(mMutex); }; }