1 /* 2 * Copyright (c) 2024 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/fixed_string.h> 24 #include <base/containers/string.h> 25 #include <base/containers/string_view.h> 26 #include <base/containers/unique_ptr.h> 27 #include <base/containers/unordered_map.h> 28 #include <base/containers/vector.h> 29 #include <base/math/vector.h> 30 #include <core/namespace.h> 31 #include <render/device/gpu_resource_desc.h> 32 #include <render/device/intf_shader_manager.h> 33 #include <render/device/pipeline_layout_desc.h> 34 #include <render/device/pipeline_state_desc.h> 35 #include <render/namespace.h> 36 #include <render/resource_handle.h> 37 38 #include "device/gpu_program.h" 39 #include "device/gpu_resource_handle_util.h" // for hash<RenderHandle> 40 #include "device/shader_reflection_data.h" 41 42 CORE_BEGIN_NAMESPACE() 43 class IFileManager; 44 CORE_END_NAMESPACE() 45 RENDER_BEGIN_NAMESPACE() 46 class Device; 47 class ShaderModule; 48 class ShaderLoader; 49 50 constexpr const uint32_t INVALID_SM_INDEX { ~0u }; 51 52 struct ComputeShaderCreateData { 53 BASE_NS::string_view path; 54 uint32_t renderSlotId { INVALID_SM_INDEX }; 55 uint32_t categoryId { INVALID_SM_INDEX }; 56 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 57 uint32_t shaderModuleIndex { INVALID_SM_INDEX }; 58 59 BASE_NS::string_view shaderFileStr; 60 BASE_NS::string_view materialMetadata; 61 }; 62 63 struct ShaderCreateData { 64 BASE_NS::string_view path; 65 uint32_t renderSlotId { INVALID_SM_INDEX }; 66 uint32_t categoryId { INVALID_SM_INDEX }; 67 uint32_t vertexInputDeclarationIndex { INVALID_SM_INDEX }; 68 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 69 uint32_t graphicsStateIndex { INVALID_SM_INDEX }; 70 71 uint32_t vertShaderModuleIndex { INVALID_SM_INDEX }; 72 uint32_t fragShaderModuleIndex { INVALID_SM_INDEX }; 73 74 BASE_NS::string_view shaderFileStr; 75 BASE_NS::string_view materialMetadata; 76 }; 77 78 struct ShaderModuleCreateInfo { 79 ShaderStageFlags shaderStageFlags; 80 BASE_NS::array_view<const uint8_t> spvData; 81 ShaderReflectionData reflectionData; 82 }; 83 84 // Ref counted shaders are really not needed 85 // For API consistency the same RenderHandleReference is used, but the counter is dummy 86 class ShaderReferenceCounter final : public IRenderReferenceCounter { 87 public: 88 ShaderReferenceCounter() = default; 89 ~ShaderReferenceCounter() override = default; 90 91 ShaderReferenceCounter(const ShaderReferenceCounter&) = delete; 92 ShaderReferenceCounter& operator=(const ShaderReferenceCounter&) = delete; 93 Ref()94 void Ref() override 95 { 96 refcnt_.fetch_add(1, std::memory_order_relaxed); 97 }; 98 Unref()99 void Unref() override 100 { 101 if (std::atomic_fetch_sub_explicit(&refcnt_, 1, std::memory_order_release) == 1) { 102 std::atomic_thread_fence(std::memory_order_acquire); 103 delete this; 104 } 105 }; 106 GetRefCount()107 int32_t GetRefCount() const override 108 { 109 // NOTE: not destroyed based on ref count 110 // the manager is always holding the reference 111 // basically plugins could hold their shader data handles and release 112 return 1; 113 }; 114 115 private: 116 std::atomic<int32_t> refcnt_ { 0 }; 117 }; 118 119 /* ShaderManager implementation. 120 Not internally synchronized. */ 121 class ShaderManager final : public IShaderManager { 122 public: 123 static constexpr uint32_t MAX_DEFAULT_NAME_LENGTH { 128 }; 124 125 explicit ShaderManager(Device& device); 126 ~ShaderManager() override; 127 128 RenderHandleReference Get(const RenderHandle& handle) const override; 129 RenderHandleReference CreateComputeShader(const ComputeShaderCreateInfo& createInfo) override; 130 RenderHandleReference CreateComputeShader(const ComputeShaderCreateInfo& createInfo, 131 BASE_NS::string_view additionalBaseShaderPath, BASE_NS::string_view variantName) override; 132 RenderHandleReference CreateShader(const ShaderCreateInfo& createInfo) override; 133 RenderHandleReference CreateShader(const ShaderCreateInfo& createInfo, 134 BASE_NS::string_view additionalBaseShaderPath, BASE_NS::string_view variantName) override; 135 136 RenderHandleReference CreateVertexInputDeclaration(const VertexInputDeclarationCreateInfo& createInfo) override; 137 RenderHandleReference CreatePipelineLayout(const PipelineLayoutCreateInfo& createInfo) override; 138 RenderHandleReference CreateGraphicsState(const GraphicsStateCreateInfo& createInfo) override; 139 RenderHandleReference CreateGraphicsState( 140 const GraphicsStateCreateInfo& createInfo, const GraphicsStateVariantCreateInfo& variantCreateInfo) override; 141 142 uint32_t CreateRenderSlotId(BASE_NS::string_view renderSlot) override; 143 void SetRenderSlotData(const RenderSlotData& renderSlotData) override; 144 145 uint32_t CreateCategoryId(BASE_NS::string_view category); 146 147 RenderHandleReference GetShaderHandle(BASE_NS::string_view path) const override; 148 RenderHandleReference GetShaderHandle(BASE_NS::string_view path, BASE_NS::string_view variantName) const override; 149 RenderHandleReference GetShaderHandle(const RenderHandleReference& handle, uint32_t renderSlotId) const override; 150 RenderHandleReference GetShaderHandle(const RenderHandle& handle, uint32_t renderSlotId) const; 151 BASE_NS::vector<RenderHandleReference> GetShaders(uint32_t renderSlotId) const override; 152 BASE_NS::vector<RenderHandle> GetShaderRawHandles(uint32_t renderSlotId) const; 153 154 RenderHandleReference GetGraphicsStateHandle(BASE_NS::string_view path) const override; 155 RenderHandleReference GetGraphicsStateHandle( 156 BASE_NS::string_view path, BASE_NS::string_view variantName) const override; 157 RenderHandleReference GetGraphicsStateHandle( 158 const RenderHandleReference& handle, uint32_t renderSlotId) const override; 159 RenderHandleReference GetGraphicsStateHandle(const RenderHandle& handle, uint32_t renderSlotId) const; 160 RenderHandleReference GetGraphicsStateHandleByHash(uint64_t hash) const override; 161 RenderHandleReference GetGraphicsStateHandleByShaderHandle(const RenderHandleReference& handle) const override; 162 RenderHandleReference GetGraphicsStateHandleByShaderHandle(const RenderHandle& handle) const; 163 GraphicsState GetGraphicsState(const RenderHandleReference& handle) const override; 164 const GraphicsState& GetGraphicsStateRef(const RenderHandleReference& handle) const; 165 const GraphicsState& GetGraphicsStateRef(const RenderHandle& handle) const; 166 BASE_NS::vector<RenderHandleReference> GetGraphicsStates(uint32_t renderSlotId) const override; 167 168 uint32_t GetRenderSlotId(BASE_NS::string_view renderSlot) const override; 169 uint32_t GetRenderSlotId(const RenderHandleReference& handle) const override; 170 uint32_t GetRenderSlotId(const RenderHandle& handle) const; 171 RenderSlotData GetRenderSlotData(uint32_t renderSlotId) const override; 172 BASE_NS::string GetRenderSlotName(uint32_t renderSlotId) const override; 173 174 RenderHandleReference GetVertexInputDeclarationHandleByShaderHandle( 175 const RenderHandleReference& handle) const override; 176 RenderHandleReference GetVertexInputDeclarationHandleByShaderHandle(const RenderHandle& handle) const; 177 RenderHandleReference GetVertexInputDeclarationHandle(BASE_NS::string_view path) const override; 178 VertexInputDeclarationView GetVertexInputDeclarationView(const RenderHandleReference& handle) const override; 179 VertexInputDeclarationView GetVertexInputDeclarationView(const RenderHandle& handle) const; 180 181 RenderHandleReference GetPipelineLayoutHandleByShaderHandle(const RenderHandleReference& handle) const override; 182 RenderHandleReference GetPipelineLayoutHandleByShaderHandle(const RenderHandle& handle) const; 183 184 RenderHandleReference GetPipelineLayoutHandle(BASE_NS::string_view path) const override; 185 PipelineLayout GetPipelineLayout(const RenderHandleReference& handle) const override; 186 PipelineLayout GetPipelineLayout(const RenderHandle& handle) const; 187 const PipelineLayout& GetPipelineLayoutRef(const RenderHandle& handle) const; 188 189 RenderHandleReference GetReflectionPipelineLayoutHandle(const RenderHandle& handle) const; 190 RenderHandleReference GetReflectionPipelineLayoutHandle(const RenderHandleReference& handle) const override; 191 PipelineLayout GetReflectionPipelineLayout(const RenderHandleReference& handle) const override; 192 const PipelineLayout& GetReflectionPipelineLayoutRef(const RenderHandle& handle) const; 193 ShaderSpecializationConstantView GetReflectionSpecialization(const RenderHandleReference& handle) const override; 194 ShaderSpecializationConstantView GetReflectionSpecialization(const RenderHandle& handle) const; 195 VertexInputDeclarationView GetReflectionVertexInputDeclaration(const RenderHandleReference& handle) const override; 196 VertexInputDeclarationView GetReflectionVertexInputDeclaration(const RenderHandle& handle) const; 197 ShaderThreadGroup GetReflectionThreadGroupSize(const RenderHandleReference& handle) const override; 198 ShaderThreadGroup GetReflectionThreadGroupSize(const RenderHandle& handle) const; 199 200 uint64_t HashGraphicsState(const GraphicsState& graphicsState) const override; 201 202 struct ShaderPathCreateData { 203 BASE_NS::string_view variantName; 204 BASE_NS::string_view displayName; 205 }; 206 struct BaseShaderPathCreateData { 207 // variant points always at least to (own baseShader + slot) -> hash 208 BASE_NS::string_view ownBaseShaderUri; 209 // additional variant (not in own uri) 210 BASE_NS::string_view addBaseShaderUri; 211 }; 212 RenderHandleReference Create(const ComputeShaderCreateData& createInfo, const ShaderPathCreateData& pathCreateInfo, 213 const BaseShaderPathCreateData& baseShaderCreateInfo); 214 RenderHandleReference Create(const ShaderCreateData& createInfo, const ShaderPathCreateData& pathCreateInfo, 215 const BaseShaderPathCreateData& baseShaderCreateInfo); 216 // NOTE: Can be used to add additional base uri name for a shader which has variant names 217 void AddAdditionalNameForHandle(const RenderHandleReference& handle, BASE_NS::string_view path); 218 219 const GpuComputeProgram* GetGpuComputeProgram(const RenderHandle& gpuHandle) const; 220 const GpuShaderProgram* GetGpuShaderProgram(const RenderHandle& gpuHandle) const; 221 222 void HandlePendingAllocations(); 223 224 // replaces if already found 225 uint32_t CreateShaderModule(BASE_NS::string_view path, const ShaderModuleCreateInfo& createInfo); 226 // returns null if not found (i.e. needs to be created) 227 ShaderModule* GetShaderModule(uint32_t index) const; 228 // returns ~0u if not found (i.e. needs to be created) 229 uint32_t GetShaderModuleIndex(BASE_NS::string_view path) const; 230 231 bool IsComputeShader(const RenderHandleReference& handle) const override; 232 bool IsShader(const RenderHandleReference& handle) const override; 233 234 void LoadShaderFiles(const ShaderFilePathDesc& desc) override; 235 void LoadShaderFile(BASE_NS::string_view uri) override; 236 void ReloadShaderFile(BASE_NS::string_view uri) override; 237 void UnloadShaderFiles(const ShaderFilePathDesc& desc) override; 238 239 ShaderOutWriteResult SaveShaderGraphicsState(const ShaderGraphicsStateSaveInfo& saveInfo) override; 240 ShaderOutWriteResult SaveShaderVertexInputDeclaration( 241 const ShaderVertexInputDeclarationsSaveInfo& saveInfo) override; 242 ShaderOutWriteResult SaveShaderPipelineLayout(const ShaderPipelineLayoutSaveInfo& saveInfo) override; 243 ShaderOutWriteResult SaveShaderVariants(const ShaderVariantsSaveInfo& saveInfo) override; 244 245 const BASE_NS::string_view GetShaderFile(const RenderHandleReference& handle) const override; 246 const CORE_NS::json::value* GetMaterialMetadata(const RenderHandleReference& handle) const override; 247 248 void Destroy(const RenderHandleReference& handle) override; 249 250 BASE_NS::vector<RenderHandleReference> GetShaders( 251 const RenderHandleReference& handle, ShaderStageFlags shaderStageFlags) const override; 252 BASE_NS::vector<RenderHandle> GetShaders(const RenderHandle& handle, ShaderStageFlags shaderStageFlags) const; 253 254 BASE_NS::vector<RenderHandleReference> GetShaders() const override; 255 BASE_NS::vector<RenderHandleReference> GetGraphicsStates() const override; 256 BASE_NS::vector<RenderHandleReference> GetPipelineLayouts() const override; 257 BASE_NS::vector<RenderHandleReference> GetVertexInputDeclarations() const override; 258 259 IdDesc GetIdDesc(const RenderHandleReference& handle) const override; 260 uint64_t GetFrameIndex(const RenderHandleReference& handle) const override; 261 262 IShaderPipelineBinder::Ptr CreateShaderPipelineBinder(const RenderHandleReference& handle) const override; 263 IShaderPipelineBinder::Ptr CreateShaderPipelineBinder( 264 const RenderHandleReference& handle, const RenderHandleReference& plHandle) const override; 265 IShaderPipelineBinder::Ptr CreateShaderPipelineBinder( 266 const RenderHandleReference& handle, const PipelineLayout& pipelineLayout) const override; 267 268 CompatibilityFlags GetCompatibilityFlags(const RenderHandle& lhs, const RenderHandle& rhs) const; 269 CompatibilityFlags GetCompatibilityFlags( 270 const RenderHandleReference& lhs, const RenderHandleReference& rhs) const override; 271 272 GraphicsStateFlags GetForcedGraphicsStateFlags(const RenderHandle& handle) const; 273 GraphicsStateFlags GetForcedGraphicsStateFlags(const RenderHandleReference& handle) const override; 274 GraphicsStateFlags GetForcedGraphicsStateFlags(uint32_t renderSlotId) const override; 275 276 // set (engine) file manager to be usable with shader loading with shader manager api 277 void SetFileManager(CORE_NS::IFileManager& fileMgr); 278 279 struct FrameReloadedShaders { 280 uint64_t frameIndex { 0 }; 281 BASE_NS::vector<RenderHandle> shadersForBackend; 282 }; 283 uint64_t GetLastReloadedShaderFrameIndex() const; 284 BASE_NS::array_view<const FrameReloadedShaders> GetReloadedShadersForBackend() const; 285 286 struct ShaderNameData { 287 BASE_NS::fixed_string<MAX_DEFAULT_NAME_LENGTH> path; 288 BASE_NS::fixed_string<MAX_DEFAULT_NAME_LENGTH> variantName; 289 BASE_NS::fixed_string<MAX_DEFAULT_NAME_LENGTH> displayName; 290 }; 291 struct ComputeMappings { 292 struct Data { 293 RenderHandleReference rhr; 294 RenderHandle ownBaseShaderHandle; // link to own uri for all variants 295 RenderHandle addBaseShaderHandle; // link to separate base shader where it will add its variant 296 297 uint32_t renderSlotId { INVALID_SM_INDEX }; 298 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 299 uint32_t reflectionPipelineLayoutIndex { INVALID_SM_INDEX }; 300 uint32_t categoryId { INVALID_SM_INDEX }; 301 302 uint64_t frameIndex { 0 }; 303 }; 304 BASE_NS::vector<Data> clientData; 305 BASE_NS::vector<ShaderNameData> nameData; 306 }; 307 struct GraphicsMappings { 308 struct Data { 309 RenderHandleReference rhr; 310 RenderHandle ownBaseShaderHandle; // link to own uri for all variants 311 RenderHandle addBaseShaderHandle; // link to separate base shader where it will add its variant 312 313 uint32_t renderSlotId { INVALID_SM_INDEX }; 314 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 315 uint32_t reflectionPipelineLayoutIndex { INVALID_SM_INDEX }; 316 317 uint32_t vertexInputDeclarationIndex { INVALID_SM_INDEX }; 318 uint32_t graphicsStateIndex { INVALID_SM_INDEX }; 319 320 uint32_t categoryId { INVALID_SM_INDEX }; 321 322 uint64_t frameIndex { 0 }; 323 }; 324 BASE_NS::vector<Data> clientData; 325 BASE_NS::vector<ShaderNameData> nameData; 326 }; 327 struct GraphicsStateData { 328 struct Indices { 329 uint64_t hash { 0 }; 330 uint32_t renderSlotId { INVALID_SM_INDEX }; 331 uint32_t baseVariantIndex { INVALID_SM_INDEX }; 332 // forced state flags 333 GraphicsStateFlags stateFlags { 0u }; 334 }; 335 BASE_NS::vector<RenderHandleReference> rhr; 336 BASE_NS::vector<GraphicsState> graphicsStates; 337 BASE_NS::vector<Indices> data; 338 339 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToIndex; 340 BASE_NS::unordered_map<uint64_t, uint32_t> hashToIndex; 341 // hash based on base graphics state handle and render slot id 342 BASE_NS::unordered_map<uint64_t, uint32_t> variantHashToIndex; 343 }; 344 345 private: 346 Device& device_; 347 CORE_NS::IFileManager* fileMgr_ { nullptr }; // engine file manager to be used with shader loading from API 348 BASE_NS::unique_ptr<ShaderLoader> shaderLoader_; 349 350 // for all shaders, names are unique 351 BASE_NS::unordered_map<BASE_NS::string, RenderHandle> nameToClientHandle_; 352 // hash based on base shader handle id and render slot id 353 BASE_NS::unordered_map<uint64_t, RenderHandle> hashToShaderVariant_; 354 ComputeMappings computeShaderMappings_; 355 GraphicsMappings shaderMappings_; 356 357 struct ClientDataIndices { 358 uint32_t renderSlotIndex { INVALID_SM_INDEX }; 359 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 360 uint32_t reflectionPipelineLayoutIndex { INVALID_SM_INDEX }; 361 uint32_t categoryIndex { INVALID_SM_INDEX }; 362 }; 363 RenderHandle CreateClientData(BASE_NS::string_view path, RenderHandleType type, const ClientDataIndices& cdi); 364 365 RenderHandleReference CreateShaderDataImpl(const ShaderCreateData& createInfo, 366 const ShaderPathCreateData& pathCreateInfo, const BaseShaderPathCreateData& baseShaderCreateInfo, 367 RenderHandle clientHandle, uint32_t index); 368 369 void CreateBaseShaderPathsAndHashes(uint32_t renderSlotId, const ShaderPathCreateData& pathCreateInfo, 370 const BaseShaderPathCreateData& baseShaderCreateInfo, RenderHandle clientHandle, RenderHandle& ownBaseShaderUri, 371 RenderHandle& addBaseShaderUri); 372 373 void DestroyShader(RenderHandle handle); 374 void DestroyGraphicsState(RenderHandle handle); 375 void DestroyPipelineLayout(RenderHandle handle); 376 void DestroyVertexInputDeclaration(RenderHandle handle); 377 378 IdDesc GetShaderIdDesc(RenderHandle handle) const; 379 uint64_t GetShaderFrameIndex(RenderHandle handle) const; 380 381 BASE_NS::string GetCategoryName(uint32_t categoryId) const; 382 383 // NOTE: ATM GpuComputeProgram and GpuShaderPrograms are currently re-created for every new shader created 384 // will be stored and re-used in the future 385 386 struct ComputeShaderData { 387 BASE_NS::unique_ptr<GpuComputeProgram> gsp; 388 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 389 uint32_t compModuleIndex { INVALID_SM_INDEX }; 390 }; 391 BASE_NS::vector<ComputeShaderData> computeShaders_; 392 393 struct ShaderData { 394 BASE_NS::unique_ptr<GpuShaderProgram> gsp; 395 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 396 uint32_t vertexInputDeclIndex { INVALID_SM_INDEX }; 397 398 uint32_t vertModuleIndex { INVALID_SM_INDEX }; 399 uint32_t fragModuleIndex { INVALID_SM_INDEX }; 400 }; 401 BASE_NS::vector<ShaderData> shaders_; 402 403 struct RenderSlotIds { 404 BASE_NS::vector<RenderSlotData> data; 405 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToId; 406 }; 407 RenderSlotIds renderSlotIds_; 408 409 struct Category { 410 BASE_NS::vector<BASE_NS::string> data; 411 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToId; 412 }; 413 Category category_; 414 415 struct ComputeShaderAllocs { 416 RenderHandle handle; 417 uint32_t computeModuleIndex { INVALID_SM_INDEX }; 418 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 419 }; 420 struct ShaderAllocs { 421 RenderHandle handle; 422 uint32_t vertModuleIndex { INVALID_SM_INDEX }; 423 uint32_t fragModuleIndex { INVALID_SM_INDEX }; 424 uint32_t pipelineLayoutIndex { INVALID_SM_INDEX }; 425 uint32_t vertexInputDeclIndex { INVALID_SM_INDEX }; 426 }; 427 struct Allocs { 428 // client handle, object 429 BASE_NS::vector<ComputeShaderAllocs> computeShaders; 430 BASE_NS::vector<ShaderAllocs> shaders; 431 BASE_NS::vector<uint32_t> recreatedComputeModuleIndices; 432 BASE_NS::vector<uint32_t> recreatedShaderModuleIndices; 433 434 BASE_NS::vector<RenderHandle> destroyHandles; 435 }; 436 Allocs pendingAllocations_; 437 // locks only pending allocations data 438 std::mutex pendingMutex_; 439 440 void HandlePendingShaders(Allocs& allocs); 441 void HandlePendingModules(Allocs& allocs); 442 443 struct DeferredDestructions { 444 struct Module { 445 uint64_t frameIndex { 0 }; 446 BASE_NS::unique_ptr<ShaderModule> shaderModule; 447 }; 448 struct ComputeProgram { 449 uint64_t frameIndex { 0 }; 450 BASE_NS::unique_ptr<GpuComputeProgram> computeProgram; 451 }; 452 struct ShaderProgram { 453 uint64_t frameIndex { 0 }; 454 BASE_NS::unique_ptr<GpuShaderProgram> shaderProgram; 455 }; 456 BASE_NS::vector<Module> shaderModules; 457 BASE_NS::vector<ComputeProgram> computePrograms; 458 BASE_NS::vector<ShaderProgram> shaderPrograms; 459 }; 460 DeferredDestructions deferredDestructions_; 461 462 struct PL { 463 BASE_NS::vector<RenderHandleReference> rhr; 464 BASE_NS::vector<PipelineLayout> data; 465 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToIndex; 466 467 BASE_NS::unordered_map<RenderHandle, uint32_t> computeShaderToIndex; 468 BASE_NS::unordered_map<RenderHandle, uint32_t> shaderToIndex; 469 }; 470 struct VID { 471 BASE_NS::vector<RenderHandleReference> rhr; 472 BASE_NS::vector<VertexInputDeclarationData> data; 473 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToIndex; 474 BASE_NS::unordered_map<RenderHandle, uint32_t> shaderToIndex; 475 }; 476 VID shaderVid_; 477 PL pl_; 478 479 GraphicsStateData graphicsStates_; 480 481 struct ShaderModules { 482 BASE_NS::vector<BASE_NS::unique_ptr<ShaderModule>> shaderModules; 483 BASE_NS::unordered_map<BASE_NS::string, uint32_t> nameToIndex; 484 }; 485 ShaderModules shaderModules_; 486 487 PipelineLayout defaultPipelineLayout_; 488 ComputeShaderReflection defaultComputeShaderReflection_; 489 ShaderReflection defaultShaderReflection_; 490 GraphicsState defaultGraphicsState_; 491 ShaderSpecializationConstantView defaultSSCV_; 492 VertexInputDeclarationView defaultVIDV_; 493 ShaderThreadGroup defaultSTG_; 494 495 struct MaterialMetadata { 496 BASE_NS::string raw; 497 CORE_NS::json::value json; 498 }; 499 BASE_NS::unordered_map<RenderHandle, MaterialMetadata> shaderToMetadata_; 500 BASE_NS::unordered_map<RenderHandle, BASE_NS::string> handleToShaderDataFile_; 501 502 BASE_NS::vector<RenderHandle> reloadedShaders_; 503 // we need to store all shaders always, if some of node contexts are not running 504 // NOTE: this should be improved with separate pipeline cache 505 BASE_NS::vector<FrameReloadedShaders> reloadedShadersForBackend_; 506 uint64_t lastReloadedShadersFrameIndex_ { 0 }; 507 }; 508 509 class RenderNodeShaderManager final : public IRenderNodeShaderManager { 510 public: 511 explicit RenderNodeShaderManager(const ShaderManager& shaderMgr); 512 ~RenderNodeShaderManager() = default; 513 514 RenderHandle GetShaderHandle(BASE_NS::string_view path) const override; 515 RenderHandle GetShaderHandle(BASE_NS::string_view path, BASE_NS::string_view variantName) const override; 516 RenderHandle GetShaderHandle(const RenderHandle& name, uint32_t renderSlotId) const override; 517 BASE_NS::vector<RenderHandle> GetShaders(uint32_t renderSlotId) const override; 518 519 RenderHandle GetGraphicsStateHandle(BASE_NS::string_view path) const override; 520 RenderHandle GetGraphicsStateHandle(BASE_NS::string_view path, BASE_NS::string_view variantName) const override; 521 RenderHandle GetGraphicsStateHandle(const RenderHandle& handle, uint32_t renderSlotId) const override; 522 RenderHandle GetGraphicsStateHandleByHash(uint64_t hash) const override; 523 RenderHandle GetGraphicsStateHandleByShaderHandle(const RenderHandle& handle) const override; 524 virtual const GraphicsState& GetGraphicsState(const RenderHandle& handle) const override; 525 526 uint32_t GetRenderSlotId(BASE_NS::string_view renderSlot) const override; 527 uint32_t GetRenderSlotId(const RenderHandle& handle) const override; 528 IShaderManager::RenderSlotData GetRenderSlotData(uint32_t renderSlotId) const override; 529 530 RenderHandle GetVertexInputDeclarationHandleByShaderHandle(const RenderHandle& handle) const override; 531 RenderHandle GetVertexInputDeclarationHandle(BASE_NS::string_view path) const override; 532 VertexInputDeclarationView GetVertexInputDeclarationView(const RenderHandle& handle) const override; 533 534 RenderHandle GetPipelineLayoutHandleByShaderHandle(const RenderHandle& handle) const override; 535 const PipelineLayout& GetPipelineLayout(const RenderHandle& handle) const override; 536 RenderHandle GetPipelineLayoutHandle(BASE_NS::string_view path) const override; 537 538 RenderHandle GetReflectionPipelineLayoutHandle(const RenderHandle& handle) const override; 539 const PipelineLayout& GetReflectionPipelineLayout(const RenderHandle& handle) const override; 540 ShaderSpecializationConstantView GetReflectionSpecialization(const RenderHandle& handle) const override; 541 VertexInputDeclarationView GetReflectionVertexInputDeclaration(const RenderHandle& handle) const override; 542 ShaderThreadGroup GetReflectionThreadGroupSize(const RenderHandle& handle) const override; 543 544 uint64_t HashGraphicsState(const GraphicsState& graphicsState) const override; 545 546 bool IsValid(const RenderHandle& handle) const override; 547 bool IsComputeShader(const RenderHandle& handle) const override; 548 bool IsShader(const RenderHandle& handle) const override; 549 550 BASE_NS::vector<RenderHandle> GetShaders( 551 const RenderHandle& handle, ShaderStageFlags shaderStageFlags) const override; 552 553 IShaderManager::CompatibilityFlags GetCompatibilityFlags( 554 const RenderHandle& lhs, const RenderHandle& rhs) const override; 555 556 GraphicsStateFlags GetForcedGraphicsStateFlags(const RenderHandle& handle) const override; 557 GraphicsStateFlags GetForcedGraphicsStateFlags(uint32_t renderSlotId) const override; 558 559 IShaderManager::ShaderData GetShaderDataByShaderName(BASE_NS::string_view name) const override; 560 IShaderManager::ShaderData GetShaderDataByShaderHandle(RenderHandle handle) const override; 561 IShaderManager::GraphicsShaderData GetGraphicsShaderDataByShaderHandle(RenderHandle handle) const override; 562 563 IShaderManager::IdDesc GetIdDesc(const RenderHandle& handle) const override; 564 565 private: 566 const ShaderManager& shaderMgr_; 567 }; 568 RENDER_END_NAMESPACE() 569 570 #endif // DEVICE_SHADER_MANAGER_H 571