1 /* 2 * Copyright (C) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef DEVICE_SHADER_MANAGER_H 17 #define DEVICE_SHADER_MANAGER_H 18 19 #include <atomic> 20 #include <mutex> 21 22 #include <base/containers/array_view.h> 23 #include <base/containers/string.h> 24 #include <base/containers/string_view.h> 25 #include <base/containers/unique_ptr.h> 26 #include <base/containers/unordered_map.h> 27 #include <base/containers/vector.h> 28 #include <base/math/vector.h> 29 #include <core/namespace.h> 30 #include <render/device/gpu_resource_desc.h> 31 #include <render/device/intf_shader_manager.h> 32 #include <render/device/pipeline_layout_desc.h> 33 #include <render/device/pipeline_state_desc.h> 34 #include <render/namespace.h> 35 #include <render/resource_handle.h> 36 37 #include "device/gpu_program.h" 38 #include "device/gpu_resource_handle_util.h" // for hash<RenderHandle> 39 40 CORE_BEGIN_NAMESPACE() 41 class IFileManager; 42 CORE_END_NAMESPACE() 43 RENDER_BEGIN_NAMESPACE() 44 class Device; 45 class ShaderModule; 46 class ShaderLoader; 47 48 constexpr const uint32_t INVALID_SM_INDEX { ~0u }; 49 50 struct ComputeShaderCreateData { 51 BASE_NS::string_view path; 52 uint32_t renderSlotId { ~0u }; 53 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 54 uint32_t shaderModuleIndex { INVALID_SM_INDEX }; 55 }; 56 57 struct ShaderCreateData { 58 BASE_NS::string_view path; 59 uint32_t renderSlotId { ~0u }; 60 uint32_t vertexInputDeclarationIndex { INVALID_SM_INDEX }; 61 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 62 uint32_t graphicsStateIndex { INVALID_SM_INDEX }; 63 64 uint32_t vertShaderModuleIndex { INVALID_SM_INDEX }; 65 uint32_t fragShaderModuleIndex { INVALID_SM_INDEX }; 66 67 BASE_NS::string_view materialMetadata; 68 }; 69 70 struct ShaderReflectionData { 71 BASE_NS::array_view<const uint8_t> reflectionData; 72 73 bool IsValid() const; 74 ShaderStageFlags GetStageFlags() const; 75 PipelineLayout GetPipelineLayout() const; 76 BASE_NS::vector<ShaderSpecialization::Constant> GetSpecializationConstants() const; 77 BASE_NS::vector<VertexInputDeclaration::VertexInputAttributeDescription> GetInputDescriptions() const; 78 BASE_NS::Math::UVec3 GetLocalSize() const; 79 80 const uint8_t* GetPushConstants() const; 81 }; 82 83 struct ShaderModuleCreateInfo { 84 ShaderStageFlags shaderStageFlags; 85 BASE_NS::array_view<const uint8_t> spvData; 86 ShaderReflectionData reflectionData; 87 }; 88 89 // Ref counted shaders are really not needed 90 // For API consistency the same RenderHandleReference is used, but the counter is dummy 91 class ShaderReferenceCounter final : public IRenderReferenceCounter { 92 public: 93 ShaderReferenceCounter() = default; 94 ~ShaderReferenceCounter() override = default; 95 96 ShaderReferenceCounter(const ShaderReferenceCounter&) = delete; 97 ShaderReferenceCounter& operator=(const ShaderReferenceCounter&) = delete; 98 Ref()99 void Ref() override 100 { 101 refcnt_.fetch_add(1, std::memory_order_relaxed); 102 }; 103 Unref()104 void Unref() override 105 { 106 if (std::atomic_fetch_sub_explicit(&refcnt_, 1, std::memory_order_release) == 1) { 107 std::atomic_thread_fence(std::memory_order_acquire); 108 delete this; 109 } 110 }; 111 GetRefCount()112 int32_t GetRefCount() const override 113 { 114 // NOTE: not destroyed based on ref count 115 // the manager is always holding the reference 116 // basically plugins could hold their shader data handles and release 117 return 1; 118 }; 119 120 private: 121 std::atomic<int32_t> refcnt_ { 0 }; 122 }; 123 124 /* ShaderManager implementation. 125 Not internally synchronized. */ 126 class ShaderManager final : public IShaderManager { 127 public: 128 explicit ShaderManager(Device& device); 129 ~ShaderManager() override; 130 131 RenderHandleReference CreateComputeShader(const ComputeShaderCreateInfo& createInfo) override; 132 RenderHandleReference CreateComputeShader(const ComputeShaderCreateInfo& createInfo, 133 const BASE_NS::string_view baseShaderPath, const BASE_NS::string_view variantName) override; 134 RenderHandleReference CreateShader(const ShaderCreateInfo& createInfo) override; 135 RenderHandleReference CreateShader(const ShaderCreateInfo& createInfo, const BASE_NS::string_view baseShaderPath, 136 const BASE_NS::string_view variantName) override; 137 138 RenderHandleReference CreateVertexInputDeclaration(const VertexInputDeclarationCreateInfo& createInfo) override; 139 RenderHandleReference CreatePipelineLayout(const PipelineLayoutCreateInfo& createInfo) override; 140 RenderHandleReference CreateGraphicsState(const GraphicsStateCreateInfo& createInfo) override; 141 RenderHandleReference CreateGraphicsState( 142 const GraphicsStateCreateInfo& createInfo, const GraphicsStateVariantCreateInfo& variantCreateInfo) override; 143 144 uint32_t CreateRenderSlotId(const BASE_NS::string_view renderSlot) override; 145 void SetRenderSlotData(const uint32_t renderSlotId, const RenderHandleReference& shaderHandle, 146 const RenderHandleReference& stateHandle) override; 147 148 RenderHandleReference GetShaderHandle(const BASE_NS::string_view name) const override; 149 RenderHandleReference GetShaderHandle( 150 const BASE_NS::string_view name, const BASE_NS::string_view variantName) const override; 151 RenderHandleReference GetShaderHandle( 152 const RenderHandleReference& handle, const uint32_t renderSlotId) const override; 153 RenderHandleReference GetShaderHandle(const RenderHandle& handle, const uint32_t renderSlotId) const; 154 BASE_NS::vector<RenderHandleReference> GetShaders(const uint32_t renderSlotId) const override; 155 BASE_NS::vector<RenderHandle> GetShaderRawHandles(const uint32_t renderSlotId) const; 156 157 RenderHandleReference GetGraphicsStateHandle(const BASE_NS::string_view name) const override; 158 RenderHandleReference GetGraphicsStateHandle( 159 const BASE_NS::string_view name, const BASE_NS::string_view variantName) const override; 160 RenderHandleReference GetGraphicsStateHandle( 161 const RenderHandleReference& handle, const uint32_t renderSlotId) const override; 162 RenderHandleReference GetGraphicsStateHandle(const RenderHandle& handle, const uint32_t renderSlotId) const; 163 RenderHandleReference GetGraphicsStateHandleByHash(const uint64_t hash) const override; 164 RenderHandleReference GetGraphicsStateHandleByShaderHandle(const RenderHandleReference& handle) const override; 165 RenderHandleReference GetGraphicsStateHandleByShaderHandle(const RenderHandle& handle) const; 166 GraphicsState GetGraphicsState(const RenderHandleReference& handle) const override; 167 const GraphicsState& GetGraphicsStateRef(const RenderHandleReference& handle) const; 168 const GraphicsState& GetGraphicsStateRef(const RenderHandle& handle) const; 169 170 uint32_t GetRenderSlotId(const BASE_NS::string_view renderSlot) const override; 171 uint32_t GetRenderSlotId(const RenderHandleReference& handle) const override; 172 uint32_t GetRenderSlotId(const RenderHandle& handle) const; 173 RenderSlotData GetRenderSlotData(const uint32_t renderSlotId) const override; 174 175 RenderHandleReference GetVertexInputDeclarationHandleByShaderHandle( 176 const RenderHandleReference& handle) const override; 177 RenderHandleReference GetVertexInputDeclarationHandleByShaderHandle(const RenderHandle& handle) const; 178 RenderHandleReference GetVertexInputDeclarationHandle(const BASE_NS::string_view name) const override; 179 VertexInputDeclarationView GetVertexInputDeclarationView(const RenderHandleReference& handle) const override; 180 VertexInputDeclarationView GetVertexInputDeclarationView(const RenderHandle& handle) const; 181 182 RenderHandleReference GetPipelineLayoutHandleByShaderHandle(const RenderHandleReference& handle) const override; 183 RenderHandleReference GetPipelineLayoutHandleByShaderHandle(const RenderHandle& handle) const; 184 185 RenderHandleReference GetPipelineLayoutHandle(const BASE_NS::string_view name) const override; 186 PipelineLayout GetPipelineLayout(const RenderHandleReference& handle) const override; 187 PipelineLayout GetPipelineLayout(const RenderHandle& handle) const; 188 const PipelineLayout& GetPipelineLayoutRef(const RenderHandle& handle) const; 189 190 RenderHandleReference GetReflectionPipelineLayoutHandle(const RenderHandle& handle) const; 191 RenderHandleReference GetReflectionPipelineLayoutHandle(const RenderHandleReference& handle) const override; 192 PipelineLayout GetReflectionPipelineLayout(const RenderHandleReference& handle) const override; 193 const PipelineLayout& GetReflectionPipelineLayoutRef(const RenderHandle& handle) const; 194 ShaderSpecilizationConstantView GetReflectionSpecialization(const RenderHandleReference& handle) const override; 195 ShaderSpecilizationConstantView GetReflectionSpecialization(const RenderHandle& handle) const; 196 VertexInputDeclarationView GetReflectionVertexInputDeclaration(const RenderHandleReference& handle) const override; 197 VertexInputDeclarationView GetReflectionVertexInputDeclaration(const RenderHandle& handle) const; 198 ShaderThreadGroup GetReflectionThreadGroupSize(const RenderHandleReference& handle) const override; 199 ShaderThreadGroup GetReflectionThreadGroupSize(const RenderHandle& handle) const; 200 201 uint64_t HashGraphicsState(const GraphicsState& graphicsState) const override; 202 203 RenderHandleReference Create(const ComputeShaderCreateData& createInfo, const BASE_NS::string_view baseShaderPath, 204 const BASE_NS::string_view variantName); 205 RenderHandleReference Create(const ShaderCreateData& createInfo, const BASE_NS::string_view baseShaderPath, 206 const BASE_NS::string_view variantName); 207 // NOTE: Can be used to add additional base uri name for a shader which has variant names 208 void AddAdditionalNameForHandle(const RenderHandleReference& handle, const BASE_NS::string_view name); 209 210 const GpuComputeProgram* GetGpuComputeProgram(const RenderHandle& gpuHandle) const; 211 const GpuShaderProgram* GetGpuShaderProgram(const RenderHandle& gpuHandle) const; 212 213 void HandlePendingAllocations(); 214 215 // replaces if already found 216 uint32_t CreateShaderModule(const BASE_NS::string_view name, const ShaderModuleCreateInfo& createInfo); 217 // returns null if not found (i.e. needs to be created) 218 ShaderModule* GetShaderModule(const uint32_t index) const; 219 // returns ~0u if not found (i.e. needs to be created) 220 uint32_t GetShaderModuleIndex(const BASE_NS::string_view name) const; 221 222 bool IsComputeShader(const RenderHandleReference& handle) const override; 223 bool IsShader(const RenderHandleReference& handle) const override; 224 225 void LoadShaderFiles(const ShaderFilePathDesc& desc) override; 226 void LoadShaderFile(const BASE_NS::string_view uri) override; 227 void ReloadShaderFile(const BASE_NS::string_view uri) override; 228 void UnloadShaderFiles(const ShaderFilePathDesc& desc) override; 229 230 const CORE_NS::json::value* GetMaterialMetadata(const RenderHandleReference& handle) const override; 231 232 void Destroy(const RenderHandleReference& handle) override; 233 234 BASE_NS::vector<RenderHandleReference> GetShaders( 235 const RenderHandleReference& handle, const ShaderStageFlags shaderStageFlags) const override; 236 BASE_NS::vector<RenderHandle> GetShaders(const RenderHandle& handle, const ShaderStageFlags shaderStageFlags) const; 237 238 IdDesc GetIdDesc(const RenderHandleReference& handle) const override; 239 240 IShaderPipelineBinder::Ptr CreateShaderPipelineBinder(const RenderHandleReference& handle) const override; 241 242 CompatibilityFlags GetCompatibilityFlags(const RenderHandle& lhs, const RenderHandle& rhs) const; 243 CompatibilityFlags GetCompatibilityFlags( 244 const RenderHandleReference& lhs, const RenderHandleReference& rhs) const override; 245 246 // reload spv files (old behaviour for automatic shader monitor) 247 void ReloadSpvFiles(const BASE_NS::array_view<BASE_NS::string>& spvFiles); 248 249 // set (engine) file manager to be usable with shader loading with shader manager api 250 void SetFileManager(CORE_NS::IFileManager& fileMgr); 251 bool HasReloadedShaders() const; 252 253 struct ComputeMappings { 254 struct Data { 255 RenderHandleReference rhr; 256 RenderHandle baseShaderHandle; // provides a link to find related shaders 257 258 uint32_t renderSlotId { INVALID_SM_INDEX }; 259 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 260 uint32_t reflectionPipelineLayoutIndex { INVALID_SM_INDEX }; 261 }; 262 BASE_NS::vector<Data> clientData; 263 }; 264 struct GraphicsMappings { 265 struct Data { 266 RenderHandleReference rhr; 267 RenderHandle baseShaderHandle; // provides a link to find related shaders 268 269 uint32_t renderSlotId { INVALID_SM_INDEX }; 270 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 271 uint32_t reflectionPipelineLayoutIndex { INVALID_SM_INDEX }; 272 273 uint32_t vertexInputDeclarationIndex { INVALID_SM_INDEX }; 274 uint32_t graphicsStateIndex { INVALID_SM_INDEX }; 275 }; 276 BASE_NS::vector<Data> clientData; 277 }; 278 struct GraphicsStateData { 279 struct Indices { 280 uint64_t hash { 0 }; 281 uint32_t renderSlotId { INVALID_SM_INDEX }; 282 uint32_t baseVariantIndex { INVALID_SM_INDEX }; 283 }; 284 BASE_NS::vector<RenderHandleReference> rhr; 285 BASE_NS::vector<GraphicsState> graphicsStates; 286 BASE_NS::vector<Indices> data; 287 288 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToIndex; 289 BASE_NS::unordered_map<uint64_t, uint32_t> hashToIndex; 290 // hash based on base graphics state handle and render slot id 291 BASE_NS::unordered_map<uint64_t, uint32_t> variantHashToIndex; 292 }; 293 294 private: 295 Device& device_; 296 CORE_NS::IFileManager* fileMgr_ { nullptr }; // engine file manager to be used with shader loading from API 297 BASE_NS::unique_ptr<ShaderLoader> shaderLoader_; 298 299 // for all shaders, names are unique 300 BASE_NS::unordered_map<BASE_NS::string, RenderHandle> nameToClientHandle_; 301 // hash based on base shader handle id and render slot id 302 BASE_NS::unordered_map<uint64_t, RenderHandle> hashToShaderVariant_; 303 ComputeMappings computeShaderMappings_; 304 GraphicsMappings shaderMappings_; 305 306 struct ClientDataIndices { 307 uint32_t renderSlotIndex { INVALID_SM_INDEX }; 308 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 309 uint32_t reflectionPipelineLayoutIndex { INVALID_SM_INDEX }; 310 }; 311 RenderHandle CreateClientData( 312 const BASE_NS::string_view name, const RenderHandleType type, const ClientDataIndices& cdi); 313 314 void DestroyShader(const RenderHandle handle); 315 void DestroyGraphicsState(const RenderHandle handle); 316 void DestroyPipelineLayout(const RenderHandle handle); 317 void DestroyVertexInputDeclaration(const RenderHandle handle); 318 319 IdDesc GetShaderIdDesc(const RenderHandle handle) const; 320 321 // NOTE: ATM GpuComputeProgram and GpuShaderPrograms are currently re-created for every new shader created 322 // will be stored and re-used in the future 323 324 struct ComputeShaderData { 325 BASE_NS::unique_ptr<GpuComputeProgram> gsp; 326 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 327 uint32_t compModuleIndex { INVALID_SM_INDEX }; 328 }; 329 BASE_NS::vector<ComputeShaderData> computeShaders_; 330 331 struct ShaderData { 332 BASE_NS::unique_ptr<GpuShaderProgram> gsp; 333 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 334 uint32_t vertexInputDeclIndex { INVALID_SM_INDEX }; 335 336 uint32_t vertModuleIndex { INVALID_SM_INDEX }; 337 uint32_t fragModuleIndex { INVALID_SM_INDEX }; 338 }; 339 BASE_NS::vector<ShaderData> shaders_; 340 341 struct RenderSlotIds { 342 BASE_NS::vector<RenderSlotData> data; 343 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToId; 344 }; 345 RenderSlotIds renderSlotIds_; 346 347 struct ComputeShaderAllocs { 348 RenderHandle handle; 349 uint32_t computeModuleIndex { INVALID_SM_INDEX }; 350 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 351 }; 352 struct ShaderAllocs { 353 RenderHandle handle; 354 uint32_t vertModuleIndex { INVALID_SM_INDEX }; 355 uint32_t fragModuleIndex { INVALID_SM_INDEX }; 356 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 357 uint32_t vertexInputDeclIndex { INVALID_SM_INDEX }; 358 }; 359 struct Allocs { 360 // client handle, object 361 BASE_NS::vector<ComputeShaderAllocs> computeShaders; 362 BASE_NS::vector<ShaderAllocs> shaders; 363 BASE_NS::vector<uint32_t> recreatedComputeModuleIndices; 364 BASE_NS::vector<uint32_t> recreatedShaderModuleIndices; 365 366 BASE_NS::vector<RenderHandle> destroyHandles; 367 }; 368 Allocs pendingAllocations_; 369 // locks only pending allocations data 370 std::mutex pendingMutex_; 371 372 void HandlePendingShaders(Allocs& allocs); 373 void HandlePendingModules(Allocs& allocs); 374 375 struct DeferredDestructions { 376 struct Module { 377 uint64_t frameIndex { 0 }; 378 BASE_NS::unique_ptr<ShaderModule> shaderModule; 379 }; 380 struct ComputeProgram { 381 uint64_t frameIndex { 0 }; 382 BASE_NS::unique_ptr<GpuComputeProgram> computeProgram; 383 }; 384 struct ShaderProgram { 385 uint64_t frameIndex { 0 }; 386 BASE_NS::unique_ptr<GpuShaderProgram> shaderProgram; 387 }; 388 BASE_NS::vector<Module> shaderModules; 389 BASE_NS::vector<ComputeProgram> computePrograms; 390 BASE_NS::vector<ShaderProgram> shaderPrograms; 391 }; 392 DeferredDestructions deferredDestructions_; 393 394 struct PL { 395 BASE_NS::vector<RenderHandleReference> rhr; 396 BASE_NS::vector<PipelineLayout> data; 397 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToIndex; 398 399 BASE_NS::unordered_map<RenderHandle, uint32_t> computeShaderToIndex; 400 BASE_NS::unordered_map<RenderHandle, uint32_t> shaderToIndex; 401 }; 402 struct VID { 403 BASE_NS::vector<RenderHandleReference> rhr; 404 BASE_NS::vector<VertexInputDeclarationData> data; 405 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToIndex; 406 BASE_NS::unordered_map<RenderHandle, uint32_t> shaderToIndex; 407 }; 408 VID shaderVid_; 409 PL pl_; 410 411 GraphicsStateData graphicsStates_; 412 413 struct ShaderModules { 414 BASE_NS::vector<BASE_NS::unique_ptr<ShaderModule>> shaderModules; 415 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToIndex; 416 }; 417 ShaderModules shaderModules_; 418 419 PipelineLayout defaultPipelineLayout_; 420 ComputeShaderReflection defaultComputeShaderReflection_; 421 ShaderReflection defaultShaderReflection_; 422 GraphicsState defaultGraphicsState_; 423 ShaderSpecilizationConstantView defaultSSCV_; 424 VertexInputDeclarationView defaultVIDV_; 425 ShaderThreadGroup defaultSTG_; 426 427 struct MaterialMetadata { 428 BASE_NS::string raw; 429 CORE_NS::json::value json; 430 }; 431 BASE_NS::unordered_map<RenderHandle, MaterialMetadata> shaderToMetadata_; 432 433 bool hasReloadedShaders_ { false }; 434 }; 435 436 class RenderNodeShaderManager final : public IRenderNodeShaderManager { 437 public: 438 explicit RenderNodeShaderManager(const ShaderManager& shaderMgr); 439 ~RenderNodeShaderManager() = default; 440 441 RenderHandle GetShaderHandle(const BASE_NS::string_view name) const override; 442 RenderHandle GetShaderHandle( 443 const BASE_NS::string_view name, const BASE_NS::string_view variantName) const override; 444 RenderHandle GetShaderHandle(const RenderHandle& name, const uint32_t renderSlotId) const override; 445 BASE_NS::vector<RenderHandle> GetShaders(const uint32_t renderSlotId) const override; 446 447 RenderHandle GetGraphicsStateHandle(const BASE_NS::string_view name) const override; 448 RenderHandle GetGraphicsStateHandle( 449 const BASE_NS::string_view name, const BASE_NS::string_view variantName) const override; 450 RenderHandle GetGraphicsStateHandle(const RenderHandle& handle, const uint32_t renderSlotId) const override; 451 RenderHandle GetGraphicsStateHandleByHash(const uint64_t hash) const override; 452 RenderHandle GetGraphicsStateHandleByShaderHandle(const RenderHandle& handle) const override; 453 virtual const GraphicsState& GetGraphicsState(const RenderHandle& handle) const override; 454 455 uint32_t GetRenderSlotId(const BASE_NS::string_view renderSlot) const override; 456 uint32_t GetRenderSlotId(const RenderHandle& handle) const override; 457 IShaderManager::RenderSlotData GetRenderSlotData(const uint32_t renderSlotId) const override; 458 459 RenderHandle GetVertexInputDeclarationHandleByShaderHandle(const RenderHandle& handle) const override; 460 RenderHandle GetVertexInputDeclarationHandle(const BASE_NS::string_view name) const override; 461 VertexInputDeclarationView GetVertexInputDeclarationView(const RenderHandle& handle) const override; 462 463 RenderHandle GetPipelineLayoutHandleByShaderHandle(const RenderHandle& handle) const override; 464 const PipelineLayout& GetPipelineLayout(const RenderHandle& handle) const override; 465 RenderHandle GetPipelineLayoutHandle(const BASE_NS::string_view name) const override; 466 467 RenderHandle GetReflectionPipelineLayoutHandle(const RenderHandle& handle) const override; 468 const PipelineLayout& GetReflectionPipelineLayout(const RenderHandle& handle) const override; 469 ShaderSpecilizationConstantView GetReflectionSpecialization(const RenderHandle& handle) const override; 470 VertexInputDeclarationView GetReflectionVertexInputDeclaration(const RenderHandle& handle) const override; 471 ShaderThreadGroup GetReflectionThreadGroupSize(const RenderHandle& handle) const override; 472 473 uint64_t HashGraphicsState(const GraphicsState& graphicsState) const override; 474 475 bool IsValid(const RenderHandle& handle) const override; 476 bool IsComputeShader(const RenderHandle& handle) const override; 477 bool IsShader(const RenderHandle& handle) const override; 478 479 BASE_NS::vector<RenderHandle> GetShaders( 480 const RenderHandle& handle, const ShaderStageFlags shaderStageFlags) const override; 481 482 IShaderManager::CompatibilityFlags GetCompatibilityFlags( 483 const RenderHandle& lhs, const RenderHandle& rhs) const override; 484 485 private: 486 const ShaderManager& shaderMgr_; 487 }; 488 RENDER_END_NAMESPACE() 489 490 #endif // DEVICE_SHADER_MANAGER_H 491