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