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 API_RENDER_DEVICE_ISHADER_MANAGER_H
17 #define API_RENDER_DEVICE_ISHADER_MANAGER_H
18 
19 #include <base/containers/string_view.h>
20 #include <base/containers/vector.h>
21 #include <core/json/json.h>
22 #include <core/namespace.h>
23 #include <render/device/intf_shader_pipeline_binder.h>
24 #include <render/device/pipeline_layout_desc.h>
25 #include <render/device/pipeline_state_desc.h>
26 #include <render/namespace.h>
27 #include <render/resource_handle.h>
28 
RENDER_BEGIN_NAMESPACE()29 RENDER_BEGIN_NAMESPACE()
30 
31 /** \addtogroup group_ishadermanager
32  *  @{
33  */
34 /** Shader manager interface.
35  *  Not internally synchronized.
36  *
37  *  Shaders are automatically loaded from json files with LoadShaderFiles(prefix).
38  *  One can explicitly (Re)LoadShaderFile(...) but LoadShaderFiles would be preferred method.
39  *  Beware that shader manager is not internally synchronized. Create methods should only be called before
40  *  calling RenderFrame (and not in render nodes).
41  *
42  *  Loading shader data:
43  *  By default shader data is loaded from default paths:
44  *  Shaders "<prefix>shaders://"
45  *  Shader states ""<prefix>shaderstates://";
46  *  Vertex input declarations "<prefix>vertexinputdeclarations://"
47  *  Pipeline layouts "<prefix>pipelinelayouts://"
48  *
49  *  Naming of shader resources
50  *  Shaders:                        .shader
51  *  Shader states (graphics state): .shadergs
52  *  Vertex input declaration:       .shadervid
53  *  Pipeline layout:                .shaderpl
54  *
55  *  Calling LoadShaderFiles effectively does the previous.
56  *  In application one needs to load all plugin shader assets.
57  *  This enables faster loading times when one can control if and when default shader files are needed.
58  *
59  *  LoadShaderFile(uri)
60  *  Loads a specified shader data file. Identifies the type and loads it's data.
61  *
62  *  Shaders are created with default name which is the path.
63  *
64  *  Methods that have a name as a parameter print error message if resource not found.
65  *  Methods that have a handle as a parameter return invalid handles or default data if not found.
66  *
67  *  Shader language is (vulkan):
68  *  #version 460 core
69  *  #extension GL_ARB_separate_shader_objects : enable
70  *  #extension GL_ARB_shading_language_420pack : enable
71  *
72  *  Default specilization that can be used (handled automatically):
73  *  layout(constant_id = 0) const uint CORE_BACKEND_TYPE = 0;
74  *  Vulkan: CORE_BACKEND_TYPE = 0
75  *  GL and GLES: CORE_BACKEND_TYPE = 1
76  *
77  *  NOTE: Do not set this automatically.
78  *
79  *  Specialization constant ids need to be smaller than 256.
80  *  Engine uses special low level specializations with ids 256+.
81  *  Prefer using every id from zero onwards.
82 
83  */
84 class IShaderManager {
85 public:
86     struct ShaderModulePath {
87         /* Shader module path */
88         BASE_NS::string_view path;
89         /* Shader stage flags */
90         ShaderStageFlags shaderStageFlags { 0u };
91     };
92     struct ComputeShaderCreateInfo {
93         /* Path, used as a name */
94         BASE_NS::string_view path;
95         /* Shader modules for this shader */
96         BASE_NS::array_view<const ShaderModulePath> shaderPaths;
97 
98         /* Optional pipeline layout handle */
99         RenderHandle pipelineLayout;
100         /* Optional render slot mask */
101         uint32_t renderSlotId { ~0u };
102         /* Optional category id */
103         uint32_t categoryId { ~0u };
104     };
105     struct ShaderCreateInfo {
106         /* Path, used as a name */
107         BASE_NS::string_view path;
108         /* Shader modules for this shader */
109         BASE_NS::array_view<const ShaderModulePath> shaderPaths;
110 
111         /* Optional default graphics state handle for the shader */
112         RenderHandle graphicsState;
113         /* Optional pipeline layout handle */
114         RenderHandle pipelineLayout;
115         /* Optional vertex input declaration handle */
116         RenderHandle vertexInputDeclaration;
117         /* Optional render slot mask */
118         uint32_t renderSlotId { ~0u };
119         /* Optional category id */
120         uint32_t categoryId { ~0u };
121     };
122 
123     struct PipelineLayoutCreateInfo {
124         /* Path, used as a name */
125         BASE_NS::string_view path;
126         /* Reference to pipeline layout */
127         const PipelineLayout& pipelineLayout;
128     };
129     struct GraphicsStateCreateInfo {
130         /* Path, used as a name */
131         BASE_NS::string_view path;
132         /* Reference to graphics state */
133         const GraphicsState& graphicsState;
134     };
135     struct GraphicsStateVariantCreateInfo {
136         /* Render slot for the variant */
137         BASE_NS::string_view renderSlot;
138         /* Variant name for the graphics state */
139         BASE_NS::string_view variant;
140         /* Base graphics state name */
141         BASE_NS::string_view baseShaderState;
142         /* Base graphics state variant name */
143         BASE_NS::string_view baseVariant;
144         /* Forced graphics state flags */
145         GraphicsStateFlags stateFlags { 0u };
146     };
147     struct VertexInputDeclarationCreateInfo {
148         /* Path, used as a name */
149         BASE_NS::string_view path;
150         /* Reference to vertex input declaration view */
151         const VertexInputDeclarationView& vertexInputDeclarationView;
152     };
153     /* Id Description which can be fetched for handle */
154     struct IdDesc {
155         /* Unique path */
156         BASE_NS::string path;
157         /* Variant name */
158         BASE_NS::string variant;
159         /* Display name */
160         BASE_NS::string displayName;
161         /* Category name */
162         BASE_NS::string category;
163         /* Render slot id */
164         BASE_NS::string renderSlot;
165         /* Frame index when the shader was loaded. (Can be used as a "timestamp" for caching) */
166         uint64_t frameIndex { 0 };
167     };
168     /* Render slot data. Used for default render slot data handles */
169     struct RenderSlotData {
170         /** Render slot ID */
171         uint32_t renderSlotId { ~0u };
172         /** Shader handle */
173         RENDER_NS::RenderHandleReference shader;
174         /** Graphics state handle */
175         RENDER_NS::RenderHandleReference graphicsState;
176     };
177 
178     /* Shader files loading */
179     struct ShaderFilePathDesc {
180         /* Shaders path */
181         BASE_NS::string_view shaderPath;
182         /* Shader states path */
183         BASE_NS::string_view shaderStatePath;
184         /* Pipeline layouts path */
185         BASE_NS::string_view pipelineLayoutPath;
186         /* Vertex input declarations path */
187         BASE_NS::string_view vertexInputDeclarationPath;
188     };
189 
190     /** Get render handle reference of raw handle.
191      *  @param handle Raw render handle
192      *  @return Returns A render handle reference for the handle.
193      */
194     virtual RenderHandleReference Get(const RenderHandle& handle) const = 0;
195 
196     /** Create a compute shader. Prefer loading shaders from json files.
197      *  @param createInfo A create info with valid parameters.
198      *  @return Returns compute shader gpu resource handle.
199      */
200     virtual RenderHandleReference CreateComputeShader(const ComputeShaderCreateInfo& createInfo) = 0;
201 
202     /** Create a compute shader with a variant name. Prefer loading shaders from json files.
203      *  @param createInfo A create info with valid parameters.
204      *  @param baseShaderPath A base shader path/name to which the added variant is for.
205      *  @param variantName A variant name.
206      *  @return Returns compute shader gpu resource handle.
207      */
208     virtual RenderHandleReference CreateComputeShader(const ComputeShaderCreateInfo& createInfo,
209         const BASE_NS::string_view baseShaderPath, const BASE_NS::string_view variantName) = 0;
210 
211     /** Create a shader. Prefer loading shaders from json files.
212      *  @param createInfo A create info with valid parameters.
213      *  @return Returns shader gpu resource handle.
214      */
215     virtual RenderHandleReference CreateShader(const ShaderCreateInfo& createInfo) = 0;
216 
217     /** Create a shader. Prefer loading shaders from json files.
218      *  @param createInfo A create info with valid parameters.
219      *  @param baseShaderPath A base shader path/name to which the added variant is for.
220      *  @param variantName A variant name.
221      *  @return Returns shader gpu resource handle.
222      */
223     virtual RenderHandleReference CreateShader(const ShaderCreateInfo& createInfo,
224         const BASE_NS::string_view baseShaderPath, const BASE_NS::string_view variantName) = 0;
225 
226     /** Create a pipeline layout. Prefer loading pipeline layouts from json files.
227      *  @param createInfo A pipeline layout create info.
228      *  @return Returns pipeline layout render handle.
229      */
230     virtual RenderHandleReference CreatePipelineLayout(const PipelineLayoutCreateInfo& createInfo) = 0;
231 
232     /** Create a vertex input declaration. Prefer laoding vertex input declaration from json files.
233      *  @param createInfo A vertex input declaration create info.
234      *  @return Returns vertex input declaration handle.
235      */
236     virtual RenderHandleReference CreateVertexInputDeclaration(const VertexInputDeclarationCreateInfo& createInfo) = 0;
237 
238     /** Create a graphics state. Prefer loading graphics states from json files.
239      *  @param name Unique name of the graphics state. (Optional name, can be empty string view)
240      *  @param createInfo A graphics state create info.
241      *  @return Returns graphics state render handle.
242      */
243     virtual RenderHandleReference CreateGraphicsState(const GraphicsStateCreateInfo& createInfo) = 0;
244 
245     /** Create a graphics state with additional variant info. Prefer loading graphics states from json files.
246      *  @param createInfo A graphics state create info.
247      *  @param variantCreateInfo A create info for shader graphics state variant.
248      *  @return Returns graphics state render handle.
249      */
250     virtual RenderHandleReference CreateGraphicsState(
251         const GraphicsStateCreateInfo& createInfo, const GraphicsStateVariantCreateInfo& variantCreateInfo) = 0;
252 
253     /** Create a render slot id for render slot name. If render slot already created for the name the slot id is
254      * returned.
255      *  @param name Unique name of the render slot id.
256      *  @return Returns render slot id for the name.
257      */
258     virtual uint32_t CreateRenderSlotId(const BASE_NS::string_view name) = 0;
259 
260     /** Set render slot default data.
261      *  @param renderSlotId Render slot id.
262      *  @param shaderHandle Render slot default shader handle. (Does not replace if not valid)
263      *  @param stateHandle Render slot default graphics state handle. (Does not replace if not valid)
264      */
265     virtual void SetRenderSlotData(const uint32_t renderSlotId, const RenderHandleReference& shaderHandle,
266         const RenderHandleReference& stateHandle) = 0;
267 
268     /** Get shader handle.
269      *  @param path Path/Name of the shader.
270      *  @return Returns shader handle.
271      */
272     virtual RenderHandleReference GetShaderHandle(const BASE_NS::string_view path) const = 0;
273 
274     /** Get shader variant handle. One can fetch and explicit handle to variant.
275      *  @param path Path/Name of the base shader.
276      *  @param variantName Name of variant.
277      *  @return Returns shader gpu resource handle.
278      */
279     virtual RenderHandleReference GetShaderHandle(
280         const BASE_NS::string_view path, const BASE_NS::string_view variantName) const = 0;
281 
282     /** Get shader handle. Tries to find a shader variant for provided render slot id.
283      *  @param handle Shader handle.
284      *  @param renderSlotId Render slot id.
285      *  @return Returns shader handle for given render slot id.
286      */
287     virtual RenderHandleReference GetShaderHandle(
288         const RenderHandleReference& handle, const uint32_t renderSlotId) const = 0;
289 
290     /** Get shaders
291      *  @param renderSlotId Id of render slot
292      *  @return Returns shader handles for given render slot id.
293      */
294     virtual BASE_NS::vector<RenderHandleReference> GetShaders(const uint32_t renderSlotId) const = 0;
295 
296     /** Get graphics state based on path name
297      *  @param path Path/Name of the graphics state
298      */
299     virtual RenderHandleReference GetGraphicsStateHandle(const BASE_NS::string_view path) const = 0;
300 
301     /** Get graphics state based on name and variant name
302      *  @param path Path/Name of the graphics state
303      *  @param name Variant name of the graphics state
304      */
305     virtual RenderHandleReference GetGraphicsStateHandle(
306         const BASE_NS::string_view path, const BASE_NS::string_view variantName) const = 0;
307 
308     /** Get graphics state handle. Tries to find a graphics state variant for provided render slot id.
309      *  Returns the given handle if it's own slot matches.
310      *  @param handle Graphics state handle.
311      *  @param renderSlotId Render slot id.
312      *  @return Returns shader handle for given render slot id.
313      */
314     virtual RenderHandleReference GetGraphicsStateHandle(
315         const RenderHandleReference& handle, const uint32_t renderSlotId) const = 0;
316 
317     /** Get graphics state based on graphics state hash.
318      *  @param hash A hash created with HashGraphicsState().
319      *  @return Graphics state handle.
320      */
321     virtual RenderHandleReference GetGraphicsStateHandleByHash(const uint64_t hash) const = 0;
322 
323     /** Get graphics state handle based on shader handle. The default graphics in shader json.
324      *  @param handle Valid shader handle.
325      *  @return Graphics state handle.
326      */
327     virtual RenderHandleReference GetGraphicsStateHandleByShaderHandle(const RenderHandleReference& handle) const = 0;
328 
329     /** Get graphics state.
330      *  @param handle Graphics state render handle.
331      *  @return Graphics state for the handle.
332      */
333     virtual GraphicsState GetGraphicsState(const RenderHandleReference& handle) const = 0;
334 
335     /** Get graphics states.
336      *  @param renderSlotId Id of render slot.
337      *  @return Returns all graphics state handles for the render slot id.
338      */
339     virtual BASE_NS::vector<RenderHandleReference> GetGraphicsStates(const uint32_t renderSlotId) const = 0;
340 
341     /** Get render slot ID
342      *  @param renderSlot Name of render slot
343      *  @return render slot id if found (~0u invalid)
344      */
345     virtual uint32_t GetRenderSlotId(const BASE_NS::string_view renderSlot) const = 0;
346 
347     /** Get render slot ID.
348      *  @param handle Handle of shader or graphics state.
349      *  @return render slot id if found (~0u invalid)
350      */
351     virtual uint32_t GetRenderSlotId(const RenderHandleReference& handle) const = 0;
352 
353     /** Get render slot data. Get default data of render slot.
354      *  @param renderSlotId Render slot id.
355      *  @return render slot data.
356      */
357     virtual RenderSlotData GetRenderSlotData(const uint32_t renderSlotId) const = 0;
358 
359     /** Get render slot name.
360      *  @param renderSlotId Render slot id.
361      *  @return render slot name.
362      */
363     virtual BASE_NS::string GetRenderSlotName(const uint32_t renderSlotId) const = 0;
364 
365     /** Get vertex input declaration handle by shader handle.
366      *  @param handle A handle of the shader which vertex input declaration data handle will be returned.
367      *  @return Returns a data handle for vertex input declaration.
368      */
369     virtual RenderHandleReference GetVertexInputDeclarationHandleByShaderHandle(
370         const RenderHandleReference& handle) const = 0;
371 
372     /** Get vertex input declaration handle by vertex input declaration name.
373      *  @param path Path/Name of the vertex input declaration given in data.
374      *  @return Returns a data handle for vertex input declaration.
375      */
376     virtual RenderHandleReference GetVertexInputDeclarationHandle(const BASE_NS::string_view path) const = 0;
377 
378     /** Get vertex input declaration view by vertex input declaration data handle.
379      *  The return value should not be hold into as it contains array_views to data which my change.
380      *  @param handle A handle to the vertex input declaration data.
381      *  @return Returns a view to vertex input declaration data.
382      */
383     virtual VertexInputDeclarationView GetVertexInputDeclarationView(const RenderHandleReference& handle) const = 0;
384 
385     /** Get pipeline layout handle by shader handle.
386      *  @param handle A handle of the shader which pipeline layout data handle will be returned.
387      *  @return Returns a handle to pipeline layout.
388      */
389     virtual RenderHandleReference GetPipelineLayoutHandleByShaderHandle(const RenderHandleReference& handle) const = 0;
390 
391     /** Get pipeline layout by shader or compute shader pipeline layout handle.
392      *  @param handle A handle to pipeline layout.
393      *  @return Returns a const reference to pipeline layout.
394      */
395     virtual PipelineLayout GetPipelineLayout(const RenderHandleReference& handle) const = 0;
396 
397     /** Get pipeline layout handle by pipeline layout name.
398      *  @param path Path/Name of the pipeline layout.
399      *  @return Returns a handle to pipeline layout.
400      */
401     virtual RenderHandleReference GetPipelineLayoutHandle(const BASE_NS::string_view path) const = 0;
402 
403     /** Get pipeline layout handle for reflected shader data.
404      *  @param handle A handle to a valid shader or compute shader.
405      *  @return Returns a handle to pipeline layout.
406      */
407     virtual RenderHandleReference GetReflectionPipelineLayoutHandle(const RenderHandleReference& handle) const = 0;
408 
409     /** Get pipeline layout reflected from the shader or compute shader pipeline layout handle.
410      *  @param handle A handle to a valid shader or compute shader.
411      *  @return Returns a const reference to pipeline layout.
412      */
413     virtual PipelineLayout GetReflectionPipelineLayout(const RenderHandleReference& handle) const = 0;
414 
415     /** Get specialization reflected from the given shader.
416      *  @param handle A handle to a valid shader or compute shader.
417      *  @return Returns a view to shader specialization. The struct should not be holded unto.
418      */
419     virtual ShaderSpecializationConstantView GetReflectionSpecialization(const RenderHandleReference& handle) const = 0;
420 
421     /** Get vertex input declaration reflected from the shader. (Zero values if shader does not have one)
422      *  @param handle A handle to a valid shader.
423      *  @return Returns a view to vertex input declaration view. The struct should not be holded unto.
424      */
425     virtual VertexInputDeclarationView GetReflectionVertexInputDeclaration(
426         const RenderHandleReference& handle) const = 0;
427 
428     /** Get thread group size of a given shader. (Zero values if shader does not have thread group)
429      *  @param handle A handle to a valid compute shader.
430      *  @return Returns a shader thread group size.
431      */
432     virtual ShaderThreadGroup GetReflectionThreadGroupSize(const RenderHandleReference& handle) const = 0;
433 
434     /** Hash graphics state.
435      *  @return Returns a hash for shader related graphics state.
436      */
437     virtual uint64_t HashGraphicsState(const GraphicsState& graphicsState) const = 0;
438 
439     /** Checks if resource is a compute shader */
440     virtual bool IsComputeShader(const RenderHandleReference& handle) const = 0;
441     /** Checks if resource is a shader */
442     virtual bool IsShader(const RenderHandleReference& handle) const = 0;
443 
444     /** Load shader files.
445      * Looks for json files under paths for shaders, shader states, vertex input declarations, and pipeline
446      * layouts. Creates resources based on loaded data.
447      * NOTE: does not re-create shader modules if the module with the same spv has already been done.
448      * @param desc Paths to shader files
449      */
450     virtual void LoadShaderFiles(const ShaderFilePathDesc& desc) = 0;
451 
452     /** Load shader file and create resources.
453      *  NOTE: beware that shader json files can refer to names (not uris) of other shader resources (like pipeline
454      *  layout) and they need to be loaded before hand. Prefer using LoadShaderFiles() or automatic loading of shaders.
455      *  @param uri A uri to a valid shader data json file.
456      */
457     virtual void LoadShaderFile(const BASE_NS::string_view uri) = 0;
458 
459     /** Unload shader files.
460      * Looks for json files under paths for shaders, shader states, vertex input declarations, and pipeline
461      * layouts. Unloads/Destroys the shaders.
462      * @param desc Paths to shader files
463      */
464     virtual void UnloadShaderFiles(const ShaderFilePathDesc& desc) = 0;
465 
466     /** Get json string.
467      * @param handle A handle to a valid shader.
468      * @return Returns string view of loaded shader file.
469      */
470     virtual const BASE_NS::string_view GetShaderFile(const RenderHandleReference& handle) const = 0;
471 
472     /** Get material metadata for the shader.
473      * @param handle A handle to a valid shader.
474      * @return Returns available metadata as JSON.
475      */
476     virtual const CORE_NS::json::value* GetMaterialMetadata(const RenderHandleReference& handle) const = 0;
477 
478     /** Destroy shader data handle (shaders, pipeline layouts, shader states, vertex input declarations).
479      * @param handle A handle to a valid shader (pl, state, vid).
480      */
481     virtual void Destroy(const RenderHandleReference& handle) = 0;
482 
483     /** Get shaders based on render handle (pipeline layout, vertex input declaration, graphics state).
484      * Based on ShaderStageFlags searches for valid shaders.
485      * Not fast operation and should not be queried every frame.
486      * @param handle A handle to a valid render handle (pl, vid).
487      * @param shaderStateFlags Flags for specific shaders.
488      * @return Returns All shaders that use the specific handle.
489      */
490     virtual BASE_NS::vector<RenderHandleReference> GetShaders(
491         const RenderHandleReference& handle, const ShaderStageFlags shaderStageFlags) const = 0;
492 
493     /** Get IdDesc for a RenderHandle.
494      * @param handle A handle to a valid render handle.
495      * @return Returns IdDesc for a given handle.
496      */
497     virtual IdDesc GetIdDesc(const RenderHandleReference& handle) const = 0;
498 
499     /** Get frame update index for a RenderHandle.
500      * @param handle A handle to a valid render handle.
501      * @return Returns frame index.
502      */
503     virtual uint64_t GetFrameIndex(const RenderHandleReference& handle) const = 0;
504 
505     /** Reload shader file and create resources.
506      *  NOTE: Force re-creates shader modules from spv -files in shader json.
507      *  NOTE: Do not call on perf-critical path.
508      *  NOTE: beware that shader json files can refer to names (not uris) of other shader resources (like pipeline
509      *  layout) and they need to be loaded before hand. Prefer using LoadShaderFiles() or automatic loading of shaders.
510      *  @param uri A uri to a valid shader data json file.
511      */
512     virtual void ReloadShaderFile(const BASE_NS::string_view uri) = 0;
513 
514     /** Get all shaders.
515      *  @return vector of all shaders.
516      */
517     virtual BASE_NS::vector<RenderHandleReference> GetShaders() const = 0;
518 
519     /** Get all graphics states.
520      *  @return vector of all graphics states.
521      */
522     virtual BASE_NS::vector<RenderHandleReference> GetGraphicsStates() const = 0;
523 
524     /** Get all pipeline layouts.
525      *  @return vector of all pipeline layouts.
526      */
527     virtual BASE_NS::vector<RenderHandleReference> GetPipelineLayouts() const = 0;
528 
529     /** Get all vertex input declarations.
530      *  @return vector of all vertex input declarations.
531      */
532     virtual BASE_NS::vector<RenderHandleReference> GetVertexInputDeclarations() const = 0;
533 
534     /** Create shader pipeline binder.
535      *  @param handle Shader handle.
536      *  @return Returns shader pipeline binder.
537      */
538     virtual IShaderPipelineBinder::Ptr CreateShaderPipelineBinder(const RenderHandleReference& handle) const = 0;
539 
540     /** Create shader pipeline binder.
541      *  @param handle Shader handle.
542      *  @param plHandle Enforced pipeline layout handle.
543      *  @return Returns shader pipeline binder.
544      */
545     virtual IShaderPipelineBinder::Ptr CreateShaderPipelineBinder(
546         const RenderHandleReference& handle, const RenderHandleReference& plHandle) const = 0;
547 
548     /** Create shader pipeline binder.
549      *  @param handle Shader handle.
550      *  @param pipelineLayout Enforced pipeline layout.
551      *  @return Returns shader pipeline binder.
552      */
553     virtual IShaderPipelineBinder::Ptr CreateShaderPipelineBinder(
554         const RenderHandleReference& handle, const PipelineLayout& pipelineLayout) const = 0;
555 
556     /** Compatibility flags */
557     enum CompatibilityFlagBits {
558         /** Is compatible */
559         COMPATIBLE_BIT = 0x00000001,
560         /** Exact match */
561         EXACT_BIT = 0x00000002,
562     };
563     /** Container for compatibility flag flag bits */
564     using CompatibilityFlags = uint32_t;
565 
566     /** Check compatibility of render resources.
567      *  @param lhs The base for compatibility check.
568      *  @param rhs The one which will be compared against the base.
569      *  @return Returns compatibility flags.
570      */
571     virtual CompatibilityFlags GetCompatibilityFlags(
572         const RenderHandleReference& lhs, const RenderHandleReference& rhs) const = 0;
573 
574     /** Check forced graphics states. Can be set for render slot variants.
575      *  @param handle Graphics state or shader handle. Faster to check with graphics state handle.
576      *  @return Returns forced graphics state flags.
577      */
578     virtual GraphicsStateFlags GetForcedGraphicsStateFlags(const RenderHandleReference& handle) const = 0;
579 
580     /** Check forced graphics states. Can be set for render slot variants.
581      *  @param renderSlotId Render slot id. Find the base graphics state and checks the forced flags
582      *  @return Returns forced graphics state flags.
583      */
584     virtual GraphicsStateFlags GetForcedGraphicsStateFlags(const uint32_t renderSlotId) const = 0;
585 
586 protected:
587     IShaderManager() = default;
588     virtual ~IShaderManager() = default;
589 
590     IShaderManager(const IShaderManager&) = delete;
591     IShaderManager& operator=(const IShaderManager&) = delete;
592     IShaderManager(IShaderManager&&) = delete;
593     IShaderManager& operator=(IShaderManager&&) = delete;
594 };
595 
596 /** IRenderNodeShaderManager.
597  *  Shader manager interface to be used inside render nodes.
598  *
599  *  Some methods use faster path (no locking).
600  *  Some methods are not available like creation methods
601  */
602 class IRenderNodeShaderManager {
603 public:
604     /** Get shader handle (any type).
605      *  @param path Path/Name of the shader.
606      *  @return Returns shader handle.
607      */
608     virtual RenderHandle GetShaderHandle(const BASE_NS::string_view path) const = 0;
609 
610     /** Get shader handle.
611      *  @param path Path/Name of the shader.
612      *  @param variantName Name of the variant.
613      *  @return Returns shader gpu resource handle.
614      */
615     virtual RenderHandle GetShaderHandle(
616         const BASE_NS::string_view path, const BASE_NS::string_view variantName) const = 0;
617 
618     /** Get shader handle. Tries to find variant of shader with given render slot id.
619      *  @param handle Shader handle.
620      *  @param renderSlotId Render slot id.
621      *  @return Returns shader gpu resource handle for given slot.
622      */
623     virtual RenderHandle GetShaderHandle(const RenderHandle& handle, const uint32_t renderSlotId) const = 0;
624 
625     /** Get shaders
626      *  @param renderSlotId Id of render slot
627      */
628     virtual BASE_NS::vector<RenderHandle> GetShaders(const uint32_t renderSlotId) const = 0;
629 
630     /** Get graphics state based on name
631      *  @param path Path/Name of the graphics state
632      */
633     virtual RenderHandle GetGraphicsStateHandle(const BASE_NS::string_view path) const = 0;
634 
635     /** Get graphics state based on name
636      *  @param path Path/Name of the graphics state
637      *  @param variantName Variant name of the graphics state
638      */
639     virtual RenderHandle GetGraphicsStateHandle(
640         const BASE_NS::string_view path, const BASE_NS::string_view variantName) const = 0;
641 
642     /** Get graphics state handle. Tries to find variant of graphics state with given render slot id.
643      *  Returns the given handle if its render slot id matches.
644      *  @param handle Graphics state handle.
645      *  @param renderSlotId Render slot id.
646      *  @return Returns shader graphics state handle for given slot.
647      */
648     virtual RenderHandle GetGraphicsStateHandle(const RenderHandle& handle, const uint32_t renderSlotId) const = 0;
649 
650     /** Get graphics state based on graphics state hash
651      *  @param hash A hash created with HashGraphicsState()
652      */
653     virtual RenderHandle GetGraphicsStateHandleByHash(const uint64_t hash) const = 0;
654 
655     /** Get graphics state handle based on shader handle
656      *  @param handle Valid shader handle.
657      */
658     virtual RenderHandle GetGraphicsStateHandleByShaderHandle(const RenderHandle& handle) const = 0;
659 
660     /** Get graphics state
661      *  @param handle Graphics state render handle
662      */
663     virtual const GraphicsState& GetGraphicsState(const RenderHandle& handle) const = 0;
664 
665     /** Get render slot ID
666      *  @param renderSlot Name of render slot
667      *  @return render slot id if found (~0u invalid)
668      */
669     virtual uint32_t GetRenderSlotId(const BASE_NS::string_view renderSlot) const = 0;
670 
671     /** Get render slot ID
672      *  @param handle Handle to resource
673      *  @return render slot mask if found (0 invalid)
674      */
675     virtual uint32_t GetRenderSlotId(const RenderHandle& handle) const = 0;
676 
677     /** Get render slot data. Get default data of render slot.
678      *  @param renderSlotId Render slot id.
679      *  @return render slot data.
680      */
681     virtual IShaderManager::RenderSlotData GetRenderSlotData(const uint32_t renderSlotId) const = 0;
682 
683     /** Get vertex input declaration handle by shader handle.
684      *  @param handle A handle of the shader which vertex input declaration data handle will be returned.
685      *  @return Returns a data handle for vertex input declaration.
686      */
687     virtual RenderHandle GetVertexInputDeclarationHandleByShaderHandle(const RenderHandle& handle) const = 0;
688 
689     /** Get vertex input declaration handle by vertex input declaration name.
690      *  @param path Path/Name of the vertex input declaration given in data.
691      *  @return Returns a data handle for vertex input declaration.
692      */
693     virtual RenderHandle GetVertexInputDeclarationHandle(const BASE_NS::string_view path) const = 0;
694 
695     /** Get vertex input declaration view by vertex input declaration data handle.
696      *  The return value should not be hold into as it contains array_views to data which my change.
697      *  @param handle A handle to the vertex input declaration data.
698      *  @return Returns a view to vertex input declaration data.
699      */
700     virtual VertexInputDeclarationView GetVertexInputDeclarationView(const RenderHandle& handle) const = 0;
701 
702     /** Get pipeline layout handle by shader handle.
703      *  @param handle A handle of the shader which pipeline layout data handle will be returned.
704      *  @return Returns a handle to pipeline layout.
705      */
706     virtual RenderHandle GetPipelineLayoutHandleByShaderHandle(const RenderHandle& handle) const = 0;
707 
708     /** Get pipeline layout by shader or compute shader pipeline layout handle.
709      *  @param handle A handle to pipeline layout.
710      *  @return Returns a const reference to pipeline layout.
711      */
712     virtual const PipelineLayout& GetPipelineLayout(const RenderHandle& handle) const = 0;
713 
714     /** Get pipeline layout handle by pipeline layout name.
715      *  @param path Path/Name of the pipeline layout.
716      *  @return Returns a handle to pipeline layout.
717      */
718     virtual RenderHandle GetPipelineLayoutHandle(const BASE_NS::string_view path) const = 0;
719 
720     /** Get pipeline layout handle for the shader reflection pipeline layout.
721      *  @param handle A handle to a valid shader or compute shader.
722      *  @return Returns a render handle to pipeline layout.
723      */
724     virtual RenderHandle GetReflectionPipelineLayoutHandle(const RenderHandle& handle) const = 0;
725 
726     /** Get pipeline layout reflected from the shader or compute shader pipeline layout handle.
727      *  @param handle A handle to a valid shader or compute shader.
728      *  @return Returns a const reference to pipeline layout.
729      */
730     virtual const PipelineLayout& GetReflectionPipelineLayout(const RenderHandle& handle) const = 0;
731 
732     /** Get specialization reflected from the given shader.
733      *  @param handle A handle to a valid shader or compute shader.
734      *  @return Returns a view to shader specialization. The struct should not be holded unto.
735      */
736     virtual ShaderSpecializationConstantView GetReflectionSpecialization(const RenderHandle& handle) const = 0;
737 
738     /** Get vertex input declaration reflected from the shader. (Zero values if shader does not have one)
739      *  @param handle A handle to a valid shader.
740      *  @return Returns a view to vertex input declaration view. The struct should not be holded unto.
741      */
742     virtual VertexInputDeclarationView GetReflectionVertexInputDeclaration(const RenderHandle& handle) const = 0;
743 
744     /** Get thread group size of a given shader. (Zero values if shader does not have thread group)
745      *  @param handle A handle to a valid compute shader.
746      *  @return Returns a shader thread group size.
747      */
748     virtual ShaderThreadGroup GetReflectionThreadGroupSize(const RenderHandle& handle) const = 0;
749 
750     /** Hash graphics state.
751      *  @return Returns a hash for shader related graphics state.
752      */
753     virtual uint64_t HashGraphicsState(const GraphicsState& graphicsState) const = 0;
754 
755     /** Simple check if handle is valid or invalid */
756     virtual bool IsValid(const RenderHandle& handle) const = 0;
757     /** Checks if resource is a compute shader */
758     virtual bool IsComputeShader(const RenderHandle& handle) const = 0;
759     /** Checks if resource is a shader */
760     virtual bool IsShader(const RenderHandle& handle) const = 0;
761 
762     /** Get shaders based on render handle (pipeline layout, vertex input declaration, graphics state).
763      * Not fast operation and should not be queried every frame.
764      * @param handle A handle to a valid render handle (pl, vid).
765      * @param shaderStateFlags Flags for specific shaders.
766      * @return Returns All shaders that use the specific handle.
767      */
768     virtual BASE_NS::vector<RenderHandle> GetShaders(
769         const RenderHandle& handle, const ShaderStageFlags shaderStageFlags) const = 0;
770 
771     /** Check compatibility of render resources.
772      *  @param lhs The base for compatibility check.
773      *  @param rhs The one which will be compared against the base.
774      *  @return Returns compatibility flags.
775      */
776     virtual IShaderManager::CompatibilityFlags GetCompatibilityFlags(
777         const RenderHandle& lhs, const RenderHandle& rhs) const = 0;
778 
779     /** Check forced graphics states. Can be set for render slot variants.
780      *  @param handle Graphics state or shader handle. Faster to check with graphics state handle.
781      *  @return Returns forced graphics state flags.
782      */
783     virtual GraphicsStateFlags GetForcedGraphicsStateFlags(const RenderHandle& handle) const = 0;
784 
785     /** Check forced graphics states. Can be set for render slot variants.
786      *  @param renderSlotId Render slot id. Find the base graphics state and checks the forced flags
787      *  @return Returns forced graphics state flags.
788      */
789     virtual GraphicsStateFlags GetForcedGraphicsStateFlags(const uint32_t renderSlotId) const = 0;
790 
791 protected:
792     IRenderNodeShaderManager() = default;
793     virtual ~IRenderNodeShaderManager() = default;
794 
795     IRenderNodeShaderManager(const IRenderNodeShaderManager&) = delete;
796     IRenderNodeShaderManager& operator=(const IRenderNodeShaderManager&) = delete;
797     IRenderNodeShaderManager(IRenderNodeShaderManager&&) = delete;
798     IRenderNodeShaderManager& operator=(IRenderNodeShaderManager&&) = delete;
799 };
800 /** @} */
801 RENDER_END_NAMESPACE()
802 
803 #endif // API_RENDER_DEVICE_ISHADER_MANAGER_H
804