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