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