• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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