• 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 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     struct PipelineLayoutCreateInfo {
123         /* Path, used as a name */
124         BASE_NS::string_view path;
125         /* Reference to pipeline layout */
126         const PipelineLayout& pipelineLayout;
127         /* Render slot id */
128         uint32_t renderSlotId { ~0U };
129         /* Render slot id */
130         bool renderSlotDefault { false };
131     };
132     struct GraphicsStateCreateInfo {
133         /* Path, used as a name */
134         BASE_NS::string_view path;
135         /* Reference to graphics state */
136         const GraphicsState& graphicsState;
137     };
138     struct GraphicsStateVariantCreateInfo {
139         /* Render slot for the variant */
140         BASE_NS::string_view renderSlot;
141         /* Variant name for the graphics state */
142         BASE_NS::string_view variant;
143         /* Base graphics state name */
144         BASE_NS::string_view baseShaderState;
145         /* Base graphics state variant name */
146         BASE_NS::string_view baseVariant;
147         /* Forced graphics state flags */
148         GraphicsStateFlags stateFlags { 0u };
149         /* Render slot default */
150         bool renderSlotDefault { false };
151     };
152     struct VertexInputDeclarationCreateInfo {
153         /* Path, used as a name */
154         BASE_NS::string_view path;
155         /* Reference to vertex input declaration view */
156         const VertexInputDeclarationView vertexInputDeclarationView;
157         /* Render slot id */
158         uint32_t renderSlotId { ~0U };
159         /* Render slot default */
160         bool renderSlotDefault { false };
161     };
162     /* Id Description which can be fetched for handle */
163     struct IdDesc {
164         /* Unique path */
165         BASE_NS::string path;
166         /* Variant name */
167         BASE_NS::string variant;
168         /* Display name */
169         BASE_NS::string displayName;
170         /* Category name */
171         BASE_NS::string category;
172         /* Render slot id */
173         BASE_NS::string renderSlot;
174         /* Frame index when the shader was loaded. (Can be used as a "timestamp" for caching) */
175         uint64_t frameIndex { 0 };
176     };
177     /* Render slot data. Used for default render slot data handles */
178     struct RenderSlotData {
179         /** Render slot ID */
180         uint32_t renderSlotId { ~0u };
181         /** Shader handle */
182         RENDER_NS::RenderHandleReference shader;
183         /** Graphics state handle */
184         RENDER_NS::RenderHandleReference graphicsState;
185         /** Pipeline layout handle */
186         RENDER_NS::RenderHandleReference pipelineLayout;
187         /** Vertex input declaration */
188         RENDER_NS::RenderHandleReference vertexInputDeclaration;
189     };
190 
191     /* Shader files loading */
192     struct ShaderFilePathDesc {
193         /* Shaders path */
194         BASE_NS::string_view shaderPath;
195         /* Shader states path */
196         BASE_NS::string_view shaderStatePath;
197         /* Pipeline layouts path */
198         BASE_NS::string_view pipelineLayoutPath;
199         /* Vertex input declarations path */
200         BASE_NS::string_view vertexInputDeclarationPath;
201     };
202 
203     struct ShaderStateLoaderVariantData {
204         BASE_NS::string renderSlot;
205         BASE_NS::string variantName;
206 
207         BASE_NS::string baseShaderState;
208         BASE_NS::string baseVariantName;
209 
210         GraphicsStateFlags stateFlags { 0U };
211         bool renderSlotDefaultState { false };
212     };
213 
214     /** Describes a single shader variant. */
215     struct ShaderVariant {
216         bool renderSlotDefaultShader { false };
217         BASE_NS::string variantName;
218         BASE_NS::string displayName;
219 
220         struct ShaderSpvInfo {
221             BASE_NS::string shaderSpvPath;
222             ShaderStageFlags shaderType;
223         };
224         BASE_NS::vector<ShaderSpvInfo> shaders;
225 
226         BASE_NS::string vertexInputDeclaration;
227         BASE_NS::string pipelineLayout;
228         GraphicsState graphicsState;
229 
230         BASE_NS::string renderSlot;
231         BASE_NS::string shaderFileStr;
232         BASE_NS::string materialMetadata;
233 
234         GraphicsStateFlags stateFlags { 0U };
235 
236         /** Own base shader uri */
237         BASE_NS::string ownBaseShader;
238         /** Separate base shader with other shader uri */
239         BASE_NS::string addBaseShader;
240     };
241 
242     struct ShaderOutWriteResult {
243         /* error message, if any exists */
244         BASE_NS::string error;
245         bool success { false };
246         /* the shader as json string */
247         BASE_NS::string result;
248     };
249     struct ShaderGraphicsStateSaveInfo {
250         /* states, outputs one file with stateName as file name */
251         BASE_NS::string stateName;
252         /* states */
253         BASE_NS::vector<GraphicsState> states;
254         /* state variants */
255         BASE_NS::vector<ShaderStateLoaderVariantData> stateVariants;
256     };
257 
258     struct ShaderVertexInputDeclarationsSaveInfo {
259         /* vertex input declarations, outputs vid file */
260         BASE_NS::string vidName;
261         /* vertex input declaration view */
262         VertexInputDeclarationView vid;
263     };
264 
265     struct ShaderPipelineLayoutSaveInfo {
266         /* pipeline layouts, outputs single layout file */
267         BASE_NS::string layoutName;
268         /* pipeline layout */
269         PipelineLayout layout;
270     };
271 
272     struct ShaderVariantsSaveInfo {
273         /* shader variants, outputs one file with shaderName as file name */
274         BASE_NS::string shaderName;
275         /* category if any */
276         BASE_NS::string category;
277         /* shaders */
278         BASE_NS::vector<ShaderVariant> shaders;
279     };
280 
281     /** Shader data for typically needed shader data in render nodes
282      */
283     struct ShaderData {
284         /** Shader handle */
285         RenderHandle shader;
286         /** Pipeline layout handle */
287         RenderHandle pipelineLayout;
288         /** Pipeline layout data */
289         PipelineLayout pipelineLayoutData;
290     };
291     /** Graphics shader data for typically needed shader data in render nodes
292      */
293     struct GraphicsShaderData {
294         /** Shader handle */
295         RenderHandle shader;
296         /** Graphics state handle */
297         RenderHandle graphicsState;
298         /** Pipeline layout handle */
299         RenderHandle pipelineLayout;
300         /** vertex input layout handle */
301         RenderHandle vertexInputDeclaration;
302         /** Pipeline layout data */
303         PipelineLayout pipelineLayoutData;
304     };
305 
306     /** Get render handle reference of raw handle.
307      *  @param handle Raw render handle
308      *  @return Returns A render handle reference for the handle.
309      */
310     virtual RenderHandleReference Get(const RenderHandle& handle) const = 0;
311 
312     /** Create a compute shader. Prefer loading shaders from json files.
313      *  @param createInfo A create info with valid parameters.
314      *  @return Returns compute shader gpu resource handle.
315      */
316     virtual RenderHandleReference CreateComputeShader(const ComputeShaderCreateInfo& createInfo) = 0;
317 
318     /** Create a compute shader with a variant name. Prefer loading shaders from json files.
319      *  @param createInfo A create info with valid parameters.
320      *  @param additionalBaseShaderPath An additional base shader path/name from where the variant will be found as
321      * well.
322      *  @param variantName A variant name.
323      *  @return Returns compute shader gpu resource handle.
324      */
325     virtual RenderHandleReference CreateComputeShader(const ComputeShaderCreateInfo& createInfo,
326         const BASE_NS::string_view additionalBaseShaderPath, const BASE_NS::string_view variantName) = 0;
327 
328     /** Create a shader. Prefer loading shaders from json files.
329      *  @param createInfo A create info with valid parameters.
330      *  @return Returns shader gpu resource handle.
331      */
332     virtual RenderHandleReference CreateShader(const ShaderCreateInfo& createInfo) = 0;
333 
334     /** Create a shader. Prefer loading shaders from json files.
335      *  @param createInfo A create info with valid parameters.
336      *  @param additionalBaseShaderPath An additional base shader path/name from where the variant will be found as
337      * well.
338      *  @param variantName A variant name.
339      *  @return Returns shader gpu resource handle.
340      */
341     virtual RenderHandleReference CreateShader(const ShaderCreateInfo& createInfo,
342         const BASE_NS::string_view additionalBaseShaderPath, const BASE_NS::string_view variantName) = 0;
343 
344     /** Create a pipeline layout. Prefer loading pipeline layouts from json files.
345      *  @param createInfo A pipeline layout create info.
346      *  @return Returns pipeline layout render handle.
347      */
348     virtual RenderHandleReference CreatePipelineLayout(const PipelineLayoutCreateInfo& createInfo) = 0;
349 
350     /** Create a vertex input declaration. Prefer laoding vertex input declaration from json files.
351      *  @param createInfo A vertex input declaration create info.
352      *  @return Returns vertex input declaration handle.
353      */
354     virtual RenderHandleReference CreateVertexInputDeclaration(const VertexInputDeclarationCreateInfo& createInfo) = 0;
355 
356     /** Create a graphics state. Prefer loading graphics states from json files.
357      *  @param name Unique name of the graphics state. (Optional name, can be empty string view)
358      *  @param createInfo A graphics state create info.
359      *  @return Returns graphics state render handle.
360      */
361     virtual RenderHandleReference CreateGraphicsState(const GraphicsStateCreateInfo& createInfo) = 0;
362 
363     /** Create a graphics state with additional variant info. Prefer loading graphics states from json files.
364      *  @param createInfo A graphics state create info.
365      *  @param variantCreateInfo A create info for shader graphics state variant.
366      *  @return Returns graphics state render handle.
367      */
368     virtual RenderHandleReference CreateGraphicsState(
369         const GraphicsStateCreateInfo& createInfo, const GraphicsStateVariantCreateInfo& variantCreateInfo) = 0;
370 
371     /** Create a render slot id for render slot name. If render slot already created for the name the slot id is
372      * returned.
373      *  @param name Unique name of the render slot id.
374      *  @return Returns render slot id for the name.
375      */
376     virtual uint32_t CreateRenderSlotId(const BASE_NS::string_view name) = 0;
377 
378     /** Set render slot default data.
379      *  @param renderSlotData Render slot data.
380      */
381     virtual void SetRenderSlotData(const RenderSlotData& renderSlotData) = 0;
382 
383     /** Get shader handle.
384      *  @param path Path/Name of the shader.
385      *  @return Returns shader handle.
386      */
387     virtual RenderHandleReference GetShaderHandle(const BASE_NS::string_view path) const = 0;
388 
389     /** Get shader variant handle. One can fetch and explicit handle to variant.
390      *  @param path Path/Name of the base shader.
391      *  @param variantName Name of variant.
392      *  @return Returns shader gpu resource handle.
393      */
394     virtual RenderHandleReference GetShaderHandle(
395         const BASE_NS::string_view path, const BASE_NS::string_view variantName) const = 0;
396 
397     /** Get shader handle. Tries to find a shader variant for provided render slot id.
398      *  @param handle Shader handle.
399      *  @param renderSlotId Render slot id.
400      *  @return Returns shader handle for given render slot id.
401      */
402     virtual RenderHandleReference GetShaderHandle(
403         const RenderHandleReference& handle, const uint32_t renderSlotId) const = 0;
404 
405     /** Get shaders
406      *  @param renderSlotId Id of render slot
407      *  @return Returns shader handles for given render slot id.
408      */
409     virtual BASE_NS::vector<RenderHandleReference> GetShaders(const uint32_t renderSlotId) const = 0;
410 
411     /** Get graphics state based on path name
412      *  @param path Path/Name of the graphics state
413      */
414     virtual RenderHandleReference GetGraphicsStateHandle(const BASE_NS::string_view path) const = 0;
415 
416     /** Get graphics state based on name and variant name
417      *  @param path Path/Name of the graphics state
418      *  @param name Variant name of the graphics state
419      */
420     virtual RenderHandleReference GetGraphicsStateHandle(
421         const BASE_NS::string_view path, const BASE_NS::string_view variantName) const = 0;
422 
423     /** Get graphics state handle. Tries to find a graphics state variant for provided render slot id.
424      *  Returns the given handle if it's own slot matches.
425      *  @param handle Graphics state handle.
426      *  @param renderSlotId Render slot id.
427      *  @return Returns shader handle for given render slot id.
428      */
429     virtual RenderHandleReference GetGraphicsStateHandle(
430         const RenderHandleReference& handle, const uint32_t renderSlotId) const = 0;
431 
432     /** Get graphics state based on graphics state hash.
433      *  @param hash A hash created with HashGraphicsState().
434      *  @return Graphics state handle.
435      */
436     virtual RenderHandleReference GetGraphicsStateHandleByHash(const uint64_t hash) const = 0;
437 
438     /** Get graphics state handle based on shader handle. The default graphics in shader json.
439      *  @param handle Valid shader handle.
440      *  @return Graphics state handle.
441      */
442     virtual RenderHandleReference GetGraphicsStateHandleByShaderHandle(const RenderHandleReference& handle) const = 0;
443 
444     /** Get graphics state.
445      *  @param handle Graphics state render handle.
446      *  @return Graphics state for the handle.
447      */
448     virtual GraphicsState GetGraphicsState(const RenderHandleReference& handle) const = 0;
449 
450     /** Get graphics states.
451      *  @param renderSlotId Id of render slot.
452      *  @return Returns all graphics state handles for the render slot id.
453      */
454     virtual BASE_NS::vector<RenderHandleReference> GetGraphicsStates(const uint32_t renderSlotId) const = 0;
455 
456     /** Get render slot ID
457      *  @param renderSlot Name of render slot
458      *  @return render slot id if found (~0u invalid)
459      */
460     virtual uint32_t GetRenderSlotId(const BASE_NS::string_view renderSlot) const = 0;
461 
462     /** Get render slot ID.
463      *  @param handle Handle of shader or graphics state.
464      *  @return render slot id if found (~0u invalid)
465      */
466     virtual uint32_t GetRenderSlotId(const RenderHandleReference& handle) const = 0;
467 
468     /** Get render slot data. Get default data of render slot.
469      *  @param renderSlotId Render slot id.
470      *  @return render slot data.
471      */
472     virtual RenderSlotData GetRenderSlotData(const uint32_t renderSlotId) const = 0;
473 
474     /** Get render slot name.
475      *  @param renderSlotId Render slot id.
476      *  @return render slot name.
477      */
478     virtual BASE_NS::string GetRenderSlotName(const uint32_t renderSlotId) const = 0;
479 
480     /** Get vertex input declaration handle by shader handle.
481      *  @param handle A handle of the shader which vertex input declaration data handle will be returned.
482      *  @return Returns a data handle for vertex input declaration.
483      */
484     virtual RenderHandleReference GetVertexInputDeclarationHandleByShaderHandle(
485         const RenderHandleReference& handle) const = 0;
486 
487     /** Get vertex input declaration handle by vertex input declaration name.
488      *  @param path Path/Name of the vertex input declaration given in data.
489      *  @return Returns a data handle for vertex input declaration.
490      */
491     virtual RenderHandleReference GetVertexInputDeclarationHandle(const BASE_NS::string_view path) const = 0;
492 
493     /** Get vertex input declaration view by vertex input declaration data handle.
494      *  The return value should not be hold into as it contains array_views to data which my change.
495      *  @param handle A handle to the vertex input declaration data.
496      *  @return Returns a view to vertex input declaration data.
497      */
498     virtual VertexInputDeclarationView GetVertexInputDeclarationView(const RenderHandleReference& handle) const = 0;
499 
500     /** Get pipeline layout handle by shader handle.
501      *  @param handle A handle of the shader which pipeline layout data handle will be returned.
502      *  @return Returns a handle to pipeline layout.
503      */
504     virtual RenderHandleReference GetPipelineLayoutHandleByShaderHandle(const RenderHandleReference& handle) const = 0;
505 
506     /** Get pipeline layout by shader or compute shader pipeline layout handle.
507      *  @param handle A handle to pipeline layout.
508      *  @return Returns a const reference to pipeline layout.
509      */
510     virtual PipelineLayout GetPipelineLayout(const RenderHandleReference& handle) const = 0;
511 
512     /** Get pipeline layout handle by pipeline layout name.
513      *  @param path Path/Name of the pipeline layout.
514      *  @return Returns a handle to pipeline layout.
515      */
516     virtual RenderHandleReference GetPipelineLayoutHandle(const BASE_NS::string_view path) const = 0;
517 
518     /** Get pipeline layout handle for reflected shader data.
519      *  @param handle A handle to a valid shader or compute shader.
520      *  @return Returns a handle to pipeline layout.
521      */
522     virtual RenderHandleReference GetReflectionPipelineLayoutHandle(const RenderHandleReference& handle) const = 0;
523 
524     /** Get pipeline layout reflected from the shader or compute shader pipeline layout handle.
525      *  @param handle A handle to a valid shader or compute shader.
526      *  @return Returns a const reference to pipeline layout.
527      */
528     virtual PipelineLayout GetReflectionPipelineLayout(const RenderHandleReference& handle) const = 0;
529 
530     /** Get specialization reflected from the given shader.
531      *  @param handle A handle to a valid shader or compute shader.
532      *  @return Returns a view to shader specialization. The struct should not be holded unto.
533      */
534     virtual ShaderSpecializationConstantView GetReflectionSpecialization(const RenderHandleReference& handle) const = 0;
535 
536     /** Get vertex input declaration reflected from the shader. (Zero values if shader does not have one)
537      *  @param handle A handle to a valid shader.
538      *  @return Returns a view to vertex input declaration view. The struct should not be holded unto.
539      */
540     virtual VertexInputDeclarationView GetReflectionVertexInputDeclaration(
541         const RenderHandleReference& handle) const = 0;
542 
543     /** Get thread group size of a given shader. (Zero values if shader does not have thread group)
544      *  @param handle A handle to a valid compute shader.
545      *  @return Returns a shader thread group size.
546      */
547     virtual ShaderThreadGroup GetReflectionThreadGroupSize(const RenderHandleReference& handle) const = 0;
548 
549     /** Hash graphics state.
550      *  @return Returns a hash for shader related graphics state.
551      */
552     virtual uint64_t HashGraphicsState(const GraphicsState& graphicsState) const = 0;
553 
554     /** Checks if resource is a compute shader */
555     virtual bool IsComputeShader(const RenderHandleReference& handle) const = 0;
556     /** Checks if resource is a shader */
557     virtual bool IsShader(const RenderHandleReference& handle) const = 0;
558 
559     /** Load shader files.
560      * Looks for json files under paths for shaders, shader states, vertex input declarations, and pipeline
561      * layouts. Creates resources based on loaded data.
562      * NOTE: does not re-create shader modules if the module with the same spv has already been done.
563      * @param desc Paths to shader files
564      */
565     virtual void LoadShaderFiles(const ShaderFilePathDesc& desc) = 0;
566 
567     /** Load shader file and create resources.
568      *  NOTE: beware that shader json files can refer to names (not uris) of other shader resources (like pipeline
569      *  layout) and they need to be loaded before hand. Prefer using LoadShaderFiles() or automatic loading of shaders.
570      *  @param uri A uri to a valid shader data json file.
571      */
572     virtual void LoadShaderFile(const BASE_NS::string_view uri) = 0;
573 
574     /** Save graphics state
575      *  @param saveInfo Struct containing all the required info to build json
576      *  @return Returrn ShaderOutWriteResult which contains result
577      */
578     virtual ShaderOutWriteResult SaveShaderGraphicsState(const ShaderGraphicsStateSaveInfo& saveInfo) = 0;
579 
580     /** Save vertex input declaration
581      *  @param saveInfo Struct containing all the required info to build json
582      *  @return Returrn ShaderOutWriteResult which contains result
583      */
584     virtual ShaderOutWriteResult SaveShaderVertexInputDeclaration(
585         const ShaderVertexInputDeclarationsSaveInfo& saveInfo) = 0;
586 
587     /** Save pipeline layout
588      *  @param saveInfo Struct containing all the required info to build json
589      *  @return Returrn ShaderOutWriteResult which contains result
590      */
591     virtual ShaderOutWriteResult SaveShaderPipelineLayout(const ShaderPipelineLayoutSaveInfo& saveInfo) = 0;
592 
593     /** Save pipeline layout
594      *  @param saveInfo Struct containing all the required info to build json
595      *  @return Returrn ShaderOutWriteResult which contains result
596      */
597     virtual ShaderOutWriteResult SaveShaderVariants(const ShaderVariantsSaveInfo& saveInfo) = 0;
598 
599     /** Unload shader files.
600      * Looks for json files under paths for shaders, shader states, vertex input declarations, and pipeline
601      * layouts. Unloads/Destroys the shaders.
602      * @param desc Paths to shader files
603      */
604     virtual void UnloadShaderFiles(const ShaderFilePathDesc& desc) = 0;
605 
606     /** Get json string.
607      * @param handle A handle to a valid shader.
608      * @return Returns string view of loaded shader file.
609      */
610     virtual const BASE_NS::string_view GetShaderFile(const RenderHandleReference& handle) const = 0;
611 
612     /** Get material metadata for the shader.
613      * @param handle A handle to a valid shader.
614      * @return Returns available metadata as JSON.
615      */
616     virtual const CORE_NS::json::value* GetMaterialMetadata(const RenderHandleReference& handle) const = 0;
617 
618     /** Destroy shader data handle (shaders, pipeline layouts, shader states, vertex input declarations).
619      * @param handle A handle to a valid shader (pl, state, vid).
620      */
621     virtual void Destroy(const RenderHandleReference& handle) = 0;
622 
623     /** Get shaders based on render handle (pipeline layout, vertex input declaration, graphics state).
624      * Based on ShaderStageFlags searches for valid shaders.
625      * Not fast operation and should not be queried every frame.
626      * @param handle A handle to a valid render handle (pl, vid).
627      * @param shaderStateFlags Flags for specific shaders.
628      * @return Returns All shaders that use the specific handle.
629      */
630     virtual BASE_NS::vector<RenderHandleReference> GetShaders(
631         const RenderHandleReference& handle, const ShaderStageFlags shaderStageFlags) const = 0;
632 
633     /** Get IdDesc for a RenderHandle.
634      * @param handle A handle to a valid render handle.
635      * @return Returns IdDesc for a given handle.
636      */
637     virtual IdDesc GetIdDesc(const RenderHandleReference& handle) const = 0;
638 
639     /** Get frame update index for a RenderHandle.
640      * @param handle A handle to a valid render handle.
641      * @return Returns frame index.
642      */
643     virtual uint64_t GetFrameIndex(const RenderHandleReference& handle) const = 0;
644 
645     /** Reload shader file and create resources.
646      *  NOTE: Force re-creates shader modules from spv -files in shader json.
647      *  NOTE: Do not call on perf-critical path.
648      *  NOTE: beware that shader json files can refer to names (not uris) of other shader resources (like pipeline
649      *  layout) and they need to be loaded before hand. Prefer using LoadShaderFiles() or automatic loading of shaders.
650      *  @param uri A uri to a valid shader data json file.
651      */
652     virtual void ReloadShaderFile(const BASE_NS::string_view uri) = 0;
653 
654     /** Get all shaders.
655      *  @return vector of all shaders.
656      */
657     virtual BASE_NS::vector<RenderHandleReference> GetShaders() const = 0;
658 
659     /** Get all graphics states.
660      *  @return vector of all graphics states.
661      */
662     virtual BASE_NS::vector<RenderHandleReference> GetGraphicsStates() const = 0;
663 
664     /** Get all pipeline layouts.
665      *  @return vector of all pipeline layouts.
666      */
667     virtual BASE_NS::vector<RenderHandleReference> GetPipelineLayouts() const = 0;
668 
669     /** Get all vertex input declarations.
670      *  @return vector of all vertex input declarations.
671      */
672     virtual BASE_NS::vector<RenderHandleReference> GetVertexInputDeclarations() const = 0;
673 
674     /** Create shader pipeline binder.
675      *  @param handle Shader handle.
676      *  @return Returns shader pipeline binder.
677      */
678     virtual IShaderPipelineBinder::Ptr CreateShaderPipelineBinder(const RenderHandleReference& handle) const = 0;
679 
680     /** Create shader pipeline binder.
681      *  @param handle Shader handle.
682      *  @param plHandle Enforced pipeline layout handle.
683      *  @return Returns shader pipeline binder.
684      */
685     virtual IShaderPipelineBinder::Ptr CreateShaderPipelineBinder(
686         const RenderHandleReference& handle, const RenderHandleReference& plHandle) const = 0;
687 
688     /** Create shader pipeline binder.
689      *  @param handle Shader handle.
690      *  @param pipelineLayout Enforced pipeline layout.
691      *  @return Returns shader pipeline binder.
692      */
693     virtual IShaderPipelineBinder::Ptr CreateShaderPipelineBinder(
694         const RenderHandleReference& handle, const PipelineLayout& pipelineLayout) const = 0;
695 
696     /** Compatibility flags */
697     enum CompatibilityFlagBits {
698         /** Is compatible */
699         COMPATIBLE_BIT = 0x00000001,
700         /** Exact match */
701         EXACT_BIT = 0x00000002,
702     };
703     /** Container for compatibility flag flag bits */
704     using CompatibilityFlags = uint32_t;
705 
706     /** Check compatibility of render resources.
707      *  @param lhs The base for compatibility check.
708      *  @param rhs The one which will be compared against the base.
709      *  @return Returns compatibility flags.
710      */
711     virtual CompatibilityFlags GetCompatibilityFlags(
712         const RenderHandleReference& lhs, const RenderHandleReference& rhs) const = 0;
713 
714     /** Check forced graphics states. Can be set for render slot variants.
715      *  @param handle Graphics state or shader handle. Faster to check with graphics state handle.
716      *  @return Returns forced graphics state flags.
717      */
718     virtual GraphicsStateFlags GetForcedGraphicsStateFlags(const RenderHandleReference& handle) const = 0;
719 
720     /** Check forced graphics states. Can be set for render slot variants.
721      *  @param renderSlotId Render slot id. Find the base graphics state and checks the forced flags
722      *  @return Returns forced graphics state flags.
723      */
724     virtual GraphicsStateFlags GetForcedGraphicsStateFlags(const uint32_t renderSlotId) const = 0;
725 
726 protected:
727     IShaderManager() = default;
728     virtual ~IShaderManager() = default;
729 
730     IShaderManager(const IShaderManager&) = delete;
731     IShaderManager& operator=(const IShaderManager&) = delete;
732     IShaderManager(IShaderManager&&) = delete;
733     IShaderManager& operator=(IShaderManager&&) = delete;
734 };
735 
736 /** IRenderNodeShaderManager.
737  *  Shader manager interface to be used inside render nodes.
738  *
739  *  Some methods use faster path (no locking).
740  *  Some methods are not available like creation methods
741  */
742 class IRenderNodeShaderManager {
743 public:
744     /** Get shader handle (any type).
745      *  @param path Path/Name of the shader.
746      *  @return Returns shader handle.
747      */
748     virtual RenderHandle GetShaderHandle(const BASE_NS::string_view path) const = 0;
749 
750     /** Get shader handle.
751      *  @param path Path/Name of the shader.
752      *  @param variantName Name of the variant.
753      *  @return Returns shader gpu resource handle.
754      */
755     virtual RenderHandle GetShaderHandle(
756         const BASE_NS::string_view path, const BASE_NS::string_view variantName) const = 0;
757 
758     /** Get shader handle. Tries to find variant of shader with given render slot id.
759      *  @param handle Shader handle.
760      *  @param renderSlotId Render slot id.
761      *  @return Returns shader gpu resource handle for given slot.
762      */
763     virtual RenderHandle GetShaderHandle(const RenderHandle& handle, const uint32_t renderSlotId) const = 0;
764 
765     /** Get shaders
766      *  @param renderSlotId Id of render slot
767      */
768     virtual BASE_NS::vector<RenderHandle> GetShaders(const uint32_t renderSlotId) const = 0;
769 
770     /** Get graphics state based on name
771      *  @param path Path/Name of the graphics state
772      */
773     virtual RenderHandle GetGraphicsStateHandle(const BASE_NS::string_view path) const = 0;
774 
775     /** Get graphics state based on name
776      *  @param path Path/Name of the graphics state
777      *  @param variantName Variant name of the graphics state
778      */
779     virtual RenderHandle GetGraphicsStateHandle(
780         const BASE_NS::string_view path, const BASE_NS::string_view variantName) const = 0;
781 
782     /** Get graphics state handle. Tries to find variant of graphics state with given render slot id.
783      *  Returns the given handle if its render slot id matches.
784      *  @param handle Graphics state handle.
785      *  @param renderSlotId Render slot id.
786      *  @return Returns shader graphics state handle for given slot.
787      */
788     virtual RenderHandle GetGraphicsStateHandle(const RenderHandle& handle, const uint32_t renderSlotId) const = 0;
789 
790     /** Get graphics state based on graphics state hash
791      *  @param hash A hash created with HashGraphicsState()
792      */
793     virtual RenderHandle GetGraphicsStateHandleByHash(const uint64_t hash) const = 0;
794 
795     /** Get graphics state handle based on shader handle
796      *  @param handle Valid shader handle.
797      */
798     virtual RenderHandle GetGraphicsStateHandleByShaderHandle(const RenderHandle& handle) const = 0;
799 
800     /** Get graphics state
801      *  @param handle Graphics state render handle
802      */
803     virtual const GraphicsState& GetGraphicsState(const RenderHandle& handle) const = 0;
804 
805     /** Get render slot ID
806      *  @param renderSlot Name of render slot
807      *  @return render slot id if found (~0u invalid)
808      */
809     virtual uint32_t GetRenderSlotId(const BASE_NS::string_view renderSlot) const = 0;
810 
811     /** Get render slot ID
812      *  @param handle Handle to resource
813      *  @return render slot mask if found (0 invalid)
814      */
815     virtual uint32_t GetRenderSlotId(const RenderHandle& handle) const = 0;
816 
817     /** Get render slot data. Get default data of render slot.
818      *  @param renderSlotId Render slot id.
819      *  @return render slot data.
820      */
821     virtual IShaderManager::RenderSlotData GetRenderSlotData(const uint32_t renderSlotId) const = 0;
822 
823     /** Get vertex input declaration handle by shader handle.
824      *  @param handle A handle of the shader which vertex input declaration data handle will be returned.
825      *  @return Returns a data handle for vertex input declaration.
826      */
827     virtual RenderHandle GetVertexInputDeclarationHandleByShaderHandle(const RenderHandle& handle) const = 0;
828 
829     /** Get vertex input declaration handle by vertex input declaration name.
830      *  @param path Path/Name of the vertex input declaration given in data.
831      *  @return Returns a data handle for vertex input declaration.
832      */
833     virtual RenderHandle GetVertexInputDeclarationHandle(const BASE_NS::string_view path) const = 0;
834 
835     /** Get vertex input declaration view by vertex input declaration data handle.
836      *  The return value should not be hold into as it contains array_views to data which my change.
837      *  @param handle A handle to the vertex input declaration data.
838      *  @return Returns a view to vertex input declaration data.
839      */
840     virtual VertexInputDeclarationView GetVertexInputDeclarationView(const RenderHandle& handle) const = 0;
841 
842     /** Get pipeline layout handle by shader handle.
843      *  @param handle A handle of the shader which pipeline layout data handle will be returned.
844      *  @return Returns a handle to pipeline layout.
845      */
846     virtual RenderHandle GetPipelineLayoutHandleByShaderHandle(const RenderHandle& handle) const = 0;
847 
848     /** Get pipeline layout by shader or compute shader pipeline layout handle.
849      *  @param handle A handle to pipeline layout.
850      *  @return Returns a const reference to pipeline layout.
851      */
852     virtual const PipelineLayout& GetPipelineLayout(const RenderHandle& handle) const = 0;
853 
854     /** Get pipeline layout handle by pipeline layout name.
855      *  @param path Path/Name of the pipeline layout.
856      *  @return Returns a handle to pipeline layout.
857      */
858     virtual RenderHandle GetPipelineLayoutHandle(const BASE_NS::string_view path) const = 0;
859 
860     /** Get pipeline layout handle for the shader reflection pipeline layout.
861      *  @param handle A handle to a valid shader or compute shader.
862      *  @return Returns a render handle to pipeline layout.
863      */
864     virtual RenderHandle GetReflectionPipelineLayoutHandle(const RenderHandle& handle) const = 0;
865 
866     /** Get pipeline layout reflected from the shader or compute shader pipeline layout handle.
867      *  @param handle A handle to a valid shader or compute shader.
868      *  @return Returns a const reference to pipeline layout.
869      */
870     virtual const PipelineLayout& GetReflectionPipelineLayout(const RenderHandle& handle) const = 0;
871 
872     /** Get specialization reflected from the given shader.
873      *  @param handle A handle to a valid shader or compute shader.
874      *  @return Returns a view to shader specialization. The struct should not be holded unto.
875      */
876     virtual ShaderSpecializationConstantView GetReflectionSpecialization(const RenderHandle& handle) const = 0;
877 
878     /** Get vertex input declaration reflected from the shader. (Zero values if shader does not have one)
879      *  @param handle A handle to a valid shader.
880      *  @return Returns a view to vertex input declaration view. The struct should not be holded unto.
881      */
882     virtual VertexInputDeclarationView GetReflectionVertexInputDeclaration(const RenderHandle& handle) const = 0;
883 
884     /** Get thread group size of a given shader. (Zero values if shader does not have thread group)
885      *  @param handle A handle to a valid compute shader.
886      *  @return Returns a shader thread group size.
887      */
888     virtual ShaderThreadGroup GetReflectionThreadGroupSize(const RenderHandle& handle) const = 0;
889 
890     /** Hash graphics state.
891      *  @return Returns a hash for shader related graphics state.
892      */
893     virtual uint64_t HashGraphicsState(const GraphicsState& graphicsState) const = 0;
894 
895     /** Simple check if handle is valid or invalid */
896     virtual bool IsValid(const RenderHandle& handle) const = 0;
897     /** Checks if resource is a compute shader */
898     virtual bool IsComputeShader(const RenderHandle& handle) const = 0;
899     /** Checks if resource is a shader */
900     virtual bool IsShader(const RenderHandle& handle) const = 0;
901 
902     /** Get shaders based on render handle (pipeline layout, vertex input declaration, graphics state).
903      * Not fast operation and should not be queried every frame.
904      * @param handle A handle to a valid render handle (pl, vid).
905      * @param shaderStateFlags Flags for specific shaders.
906      * @return Returns All shaders that use the specific handle.
907      */
908     virtual BASE_NS::vector<RenderHandle> GetShaders(
909         const RenderHandle& handle, const ShaderStageFlags shaderStageFlags) const = 0;
910 
911     /** Check compatibility of render resources.
912      *  @param lhs The base for compatibility check.
913      *  @param rhs The one which will be compared against the base.
914      *  @return Returns compatibility flags.
915      */
916     virtual IShaderManager::CompatibilityFlags GetCompatibilityFlags(
917         const RenderHandle& lhs, const RenderHandle& rhs) const = 0;
918 
919     /** Check forced graphics states. Can be set for render slot variants.
920      *  @param handle Graphics state or shader handle. Faster to check with graphics state handle.
921      *  @return Returns forced graphics state flags.
922      */
923     virtual GraphicsStateFlags GetForcedGraphicsStateFlags(const RenderHandle& handle) const = 0;
924 
925     /** Check forced graphics states. Can be set for render slot variants.
926      *  @param renderSlotId Render slot id. Find the base graphics state and checks the forced flags
927      *  @return Returns forced graphics state flags.
928      */
929     virtual GraphicsStateFlags GetForcedGraphicsStateFlags(const uint32_t renderSlotId) const = 0;
930 
931     /** Get typical shader data fetched with the shader.
932      * @name name Name of the shader.
933      * @return shader data.
934      */
935     virtual IShaderManager::ShaderData GetShaderDataByShaderName(const BASE_NS::string_view name) const = 0;
936 
937     /** Get typical shader data fetched with the shader.
938      * @name handle Handle of the shader.
939      * @return shader data.
940      */
941     virtual IShaderManager::ShaderData GetShaderDataByShaderHandle(const RenderHandle handle) const = 0;
942 
943     /** Get typical graphics shader data fetched with the shader.
944      * @name handle Handle of the shader.
945      * @return graphics shader data.
946      */
947     virtual IShaderManager::GraphicsShaderData GetGraphicsShaderDataByShaderHandle(const RenderHandle handle) const = 0;
948 
949     /** Get IdDesc for a RenderHandle.
950      * @param handle A handle to a valid render handle.
951      * @return Returns IdDesc for a given handle.
952      */
953     virtual IShaderManager::IdDesc GetIdDesc(const RenderHandle& handle) const = 0;
954 
955 protected:
956     IRenderNodeShaderManager() = default;
957     virtual ~IRenderNodeShaderManager() = default;
958 
959     IRenderNodeShaderManager(const IRenderNodeShaderManager&) = delete;
960     IRenderNodeShaderManager& operator=(const IRenderNodeShaderManager&) = delete;
961     IRenderNodeShaderManager(IRenderNodeShaderManager&&) = delete;
962     IRenderNodeShaderManager& operator=(IRenderNodeShaderManager&&) = delete;
963 };
964 /** @} */
965 RENDER_END_NAMESPACE()
966 
967 #endif // API_RENDER_DEVICE_ISHADER_MANAGER_H
968