xref: /aosp_15_r20/external/skia/src/gpu/graphite/ShaderInfo.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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                                             skia_private::TArray<SamplerDesc>* outDescs = nullptr);
54 
runtimeEffectDictionary()55     const RuntimeEffectDictionary* runtimeEffectDictionary() const {
56         return fRuntimeEffectDictionary;
57     }
ssboIndex()58     const char* ssboIndex() const { return fSsboIndex; }
59 
dstReadRequirement()60     DstReadRequirement dstReadRequirement() const { return fDstReadRequirement; }
blendInfo()61     const skgpu::BlendInfo& blendInfo() const { return fBlendInfo; }
62 
data()63     const skia_private::TArray<uint32_t>& data() const { return fData; }
64 
vertexSkSL()65     const std::string& vertexSkSL() const { return fVertexSkSL; }
fragmentSkSL()66     const std::string& fragmentSkSL() const { return fFragmentSkSL; }
vsLabel()67     const std::string& vsLabel() const { return fVSLabel; }
fsLabel()68     const std::string& fsLabel() const { return fFSLabel; }
69 
numFragmentTexturesAndSamplers()70     int numFragmentTexturesAndSamplers() const { return fNumFragmentTexturesAndSamplers; }
hasStepUniforms()71     bool hasStepUniforms() const { return fHasStepUniforms; }
hasPaintUniforms()72     bool hasPaintUniforms() const { return fHasPaintUniforms; }
hasGradientBuffer()73     bool hasGradientBuffer() const { return fHasGradientBuffer; }
74 
75     // Name used in-shader for gradient buffer uniform.
76     static constexpr char kGradientBufferName[] = "fsGradientBuffer";
77 
78 private:
79     ShaderInfo(const RuntimeEffectDictionary*, const char* ssboIndex);
80 
81     void generateVertexSkSL(const Caps*,
82                             const RenderStep*,
83                             bool useStorageBuffers);
84 
85     // Determines fNumFragmentTexturesAndSamplers, fHasPaintUniforms, fHasGradientBuffer, and if a
86     // valid SamplerDesc ptr is passed in, any immutable sampler SamplerDescs.
87     void generateFragmentSkSL(const Caps*,
88                               const ShaderCodeDictionary*,
89                               const RenderStep*,
90                               UniquePaintParamsID,
91                               bool useStorageBuffers,
92                               skgpu::Swizzle writeSwizzle,
93                               skia_private::TArray<SamplerDesc>* outDescs);
94 
95     bool needsLocalCoords() const;
96 
97     // Recursive method which traverses ShaderNodes in a depth-first manner to aggregate all
98     // ShaderNode data (not owned by ShaderNode) into ShaderInfo's owned fData.
99     // TODO(b/347072931): Ideally, this method could go away and each snippet's data could remain
100     // tied to its ID instead of accumulating it all here.
101     void aggregateSnippetData(const ShaderNode*);
102 
103     // All shader nodes and arrays of children pointers are held in this arena
104     SkArenaAlloc fShaderNodeAlloc{256};
105 
106     const RuntimeEffectDictionary* fRuntimeEffectDictionary;
107     const char* fSsboIndex;
108 
109     // De-compressed shader tree from a PaintParamsKey. There can be 1 or 2 root nodes, the first
110     // being the paint effects (rooted with a BlendCompose for the final paint blend) and the
111     // optional second being any analytic clip effect (geometric or shader treated as coverage).
112     SkSpan<const ShaderNode*> fRootNodes;
113     // The blendInfo represents the actual GPU blend operations, which may or may not completely
114     // implement the paint and coverage blending defined by the root nodes.
115     skgpu::BlendInfo fBlendInfo;
116     DstReadRequirement fDstReadRequirement = DstReadRequirement::kNone;
117 
118     // Note that fData is currently only used to store SamplerDesc information for shaders that have
119     // the option of using immutable samplers. However, other snippets could leverage this field to
120     // convey other information once data can be tied to snippetIDs (b/347072931).
121     skia_private::TArray<uint32_t> fData;
122 
123     std::string fVertexSkSL;
124     std::string fFragmentSkSL;
125     std::string fVSLabel;
126     std::string fFSLabel;
127 
128     int fNumFragmentTexturesAndSamplers = 0;
129     bool fHasStepUniforms = false;
130     bool fHasPaintUniforms = false;
131     bool fHasGradientBuffer = false;
132 };
133 
134 }  // namespace skgpu::graphite
135 
136 #endif  // skgpu_graphite_ShaderInfo_DEFINED
137