• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2024 Google LLC
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef skgpu_graphite_ShaderInfo_DEFINED
9 #define skgpu_graphite_ShaderInfo_DEFINED
10 
11 #include "include/private/base/SkTArray.h"
12 #include "src/base/SkArenaAlloc.h"
13 #include "src/gpu/Blend.h"
14 #include "src/gpu/Swizzle.h"
15 #include "src/gpu/graphite/Caps.h"
16 #include "src/gpu/graphite/ResourceTypes.h"
17 #include "src/gpu/graphite/UniquePaintParamsID.h"
18 
19 namespace skgpu::graphite {
20 
21 class RenderStep;
22 class RuntimeEffectDictionary;
23 class ShaderCodeDictionary;
24 class ShaderNode;
25 
26 // ShaderInfo holds all root ShaderNodes defined for a PaintParams as well as the extracted fixed
27 // function blending parameters and other aggregate requirements for the effect trees that have
28 // been linked into a single fragment program (sans any RenderStep fragment work and fixed SkSL
29 // logic required for all rendering in Graphite).
30 class ShaderInfo {
31 public:
32     // Accepts a real or, by default, an invalid/nullptr pointer to a container of SamplerDescs.
33     // Backend implementations which may utilize static / immutable samplers should pass in a real
34     // pointer to indicate that shader node data must be analyzed to determine whether
35     // immutable samplers are used, and if so, ascertain SamplerDescs for them.
36     // TODO(b/366220690): Actually perform this analysis.
37     //
38     // If provided a valid container ptr, this function will delegate the addition of SamplerDescs
39     // for each sampler the nodes utilize (dynamic and immutable). This way, a SamplerDesc's index
40     // within the container can inform its binding order. Each SamplerDesc will be either:
41     // 1) a default-constructed SamplerDesc, indicating the use of a "regular" dynamic sampler which
42     //    requires no special handling OR
43     // 2) a real SamplerDesc describing an immutable sampler. Backend pipelines can then use the
44     //    desc to obtain a real immutable sampler pointer (which typically must be included in
45     //    pipeline layouts)
46     static std::unique_ptr<ShaderInfo> Make(const Caps*,
47                                             const ShaderCodeDictionary*,
48                                             const RuntimeEffectDictionary*,
49                                             const RenderStep*,
50                                             UniquePaintParamsID,
51                                             bool useStorageBuffers,
52                                             skgpu::Swizzle writeSwizzle,
53                                             DstReadStrategy dstReadStrategyIfRequired,
54                                             skia_private::TArray<SamplerDesc>* outDescs = nullptr);
55 
shaderCodeDictionary()56     const ShaderCodeDictionary* shaderCodeDictionary() const {
57         return fShaderCodeDictionary;
58     }
runtimeEffectDictionary()59     const RuntimeEffectDictionary* runtimeEffectDictionary() const {
60         return fRuntimeEffectDictionary;
61     }
62 
ssboIndex()63     const char* ssboIndex() const { return fSsboIndex; }
64 
dstReadStrategy()65     DstReadStrategy dstReadStrategy() const { return fDstReadStrategy; }
blendInfo()66     const skgpu::BlendInfo& blendInfo() const { return fBlendInfo; }
67 
data()68     const skia_private::TArray<uint32_t>& data() const { return fData; }
69 
vertexSkSL()70     const std::string& vertexSkSL() const { return fVertexSkSL; }
fragmentSkSL()71     const std::string& fragmentSkSL() const { return fFragmentSkSL; }
vsLabel()72     const std::string& vsLabel() const { return fVSLabel; }
fsLabel()73     const std::string& fsLabel() const { return fFSLabel; }
74 
numFragmentTexturesAndSamplers()75     int numFragmentTexturesAndSamplers() const { return fNumFragmentTexturesAndSamplers; }
hasStepUniforms()76     bool hasStepUniforms() const { return fHasStepUniforms; }
hasPaintUniforms()77     bool hasPaintUniforms() const { return fHasPaintUniforms; }
hasGradientBuffer()78     bool hasGradientBuffer() const { return fHasGradientBuffer; }
79 
80     // Name used in-shader for gradient buffer uniform.
81     static constexpr char kGradientBufferName[] = "fsGradientBuffer";
82 
83 private:
84     ShaderInfo(const ShaderCodeDictionary*,
85                const RuntimeEffectDictionary*,
86                const char* ssboIndex,
87                DstReadStrategy);
88 
89     void generateVertexSkSL(const Caps*,
90                             const RenderStep*,
91                             bool useStorageBuffers);
92 
93     // Determines fNumFragmentTexturesAndSamplers, fHasPaintUniforms, fHasGradientBuffer, and if a
94     // valid SamplerDesc ptr is passed in, any immutable sampler SamplerDescs.
95     void generateFragmentSkSL(const Caps*,
96                               const ShaderCodeDictionary*,
97                               const RenderStep*,
98                               UniquePaintParamsID,
99                               bool useStorageBuffers,
100                               skgpu::Swizzle writeSwizzle,
101                               skia_private::TArray<SamplerDesc>* outDescs);
102 
103     bool needsLocalCoords() const;
104 
105     // Recursive method which traverses ShaderNodes in a depth-first manner to aggregate all
106     // ShaderNode data (not owned by ShaderNode) into ShaderInfo's owned fData.
107     // TODO(b/347072931): Ideally, this method could go away and each snippet's data could remain
108     // tied to its ID instead of accumulating it all here.
109     void aggregateSnippetData(const ShaderNode*);
110 
111     // All shader nodes and arrays of children pointers are held in this arena
112     SkArenaAlloc fShaderNodeAlloc{256};
113 
114     const ShaderCodeDictionary* fShaderCodeDictionary;
115     const RuntimeEffectDictionary* fRuntimeEffectDictionary;
116     const char* fSsboIndex;
117 
118     // De-compressed shader tree from a PaintParamsKey. There can be 1 or 2 root nodes, the first
119     // being the paint effects (rooted with a BlendCompose for the final paint blend) and the
120     // optional second being any analytic clip effect (geometric or shader treated as coverage).
121     SkSpan<const ShaderNode*> fRootNodes;
122     // The blendInfo represents the actual GPU blend operations, which may or may not completely
123     // implement the paint and coverage blending defined by the root nodes.
124     skgpu::BlendInfo fBlendInfo;
125     DstReadStrategy fDstReadStrategy = DstReadStrategy::kNoneRequired;
126 
127     // Note that fData is currently only used to store SamplerDesc information for shaders that have
128     // the option of using immutable samplers. However, other snippets could leverage this field to
129     // convey other information once data can be tied to snippetIDs (b/347072931).
130     skia_private::TArray<uint32_t> fData;
131 
132     std::string fVertexSkSL;
133     std::string fFragmentSkSL;
134     std::string fVSLabel;
135     std::string fFSLabel;
136 
137     int fNumFragmentTexturesAndSamplers = 0;
138     bool fHasStepUniforms = false;
139     bool fHasPaintUniforms = false;
140     bool fHasGradientBuffer = false;
141 };
142 
143 }  // namespace skgpu::graphite
144 
145 #endif  // skgpu_graphite_ShaderInfo_DEFINED
146