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