| /* | |
| * Copyright 2024 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef skgpu_graphite_ShaderInfo_DEFINED | |
| #define skgpu_graphite_ShaderInfo_DEFINED | |
| #include "include/private/base/SkTArray.h" | |
| #include "src/base/SkArenaAlloc.h" | |
| #include "src/gpu/Blend.h" | |
| #include "src/gpu/Swizzle.h" | |
| #include "src/gpu/graphite/Caps.h" | |
| #include "src/gpu/graphite/ResourceTypes.h" | |
| #include "src/gpu/graphite/UniquePaintParamsID.h" | |
| namespace skgpu::graphite { | |
| class RenderStep; | |
| class RuntimeEffectDictionary; | |
| class ShaderCodeDictionary; | |
| class ShaderNode; | |
| enum class TextureFormat : uint8_t; | |
| // ShaderInfo holds all root ShaderNodes defined for a PaintParams as well as the extracted fixed | |
| // function blending parameters and other aggregate requirements for the effect trees that have | |
| // been linked into a single fragment program (sans any RenderStep fragment work and fixed SkSL | |
| // logic required for all rendering in Graphite). | |
| class ShaderInfo { | |
| public: | |
| // Accepts a real or, by default, an invalid/nullptr pointer to a container of SamplerDescs. | |
| // Backend implementations which may utilize static / immutable samplers should pass in a real | |
| // pointer to indicate that shader node data must be analyzed to determine whether | |
| // immutable samplers are used, and if so, ascertain SamplerDescs for them. | |
| // TODO(b/366220690): Actually perform this analysis. | |
| // | |
| // If provided a valid container ptr, this function will delegate the addition of SamplerDescs | |
| // for each sampler the nodes utilize (dynamic and immutable). This way, a SamplerDesc's index | |
| // within the container can inform its binding order. Each SamplerDesc will be either: | |
| // 1) a default-constructed SamplerDesc, indicating the use of a "regular" dynamic sampler which | |
| // requires no special handling OR | |
| // 2) a real SamplerDesc describing an immutable sampler. Backend pipelines can then use the | |
| // desc to obtain a real immutable sampler pointer (which typically must be included in | |
| // pipeline layouts) | |
| static std::unique_ptr<ShaderInfo> Make(const Caps*, | |
| const ShaderCodeDictionary*, | |
| const RuntimeEffectDictionary*, | |
| const RenderStep*, | |
| UniquePaintParamsID, | |
| bool useStorageBuffers, | |
| TextureFormat targetFormat, | |
| skgpu::Swizzle writeSwizzle, | |
| DstReadStrategy dstReadStrategy, | |
| skia_private::TArray<SamplerDesc>* outDescs = nullptr); | |
| const ShaderCodeDictionary* shaderCodeDictionary() const { | |
| return fShaderCodeDictionary; | |
| } | |
| const RuntimeEffectDictionary* runtimeEffectDictionary() const { | |
| return fRuntimeEffectDictionary; | |
| } | |
| const char* shadingSsboIndex() const { return fShadingSsboIndex; } | |
| DstReadStrategy dstReadStrategy() const { return fDstReadStrategy; } | |
| const skgpu::BlendInfo& blendInfo() const { return fBlendInfo; } | |
| const skia_private::TArray<uint32_t>& data() const { return fData; } | |
| const std::string& vertexSkSL() const { return fVertexSkSL; } | |
| const std::string& fragmentSkSL() const { return fFragmentSkSL; } | |
| const std::string& vsLabel() const { return fVSLabel; } | |
| const std::string& fsLabel() const { return fFSLabel; } | |
| int numFragmentTexturesAndSamplers() const { return fNumFragmentTexturesAndSamplers; } | |
| bool hasStepUniforms() const { return fHasStepUniforms; } | |
| bool hasPaintUniforms() const { return fHasPaintUniforms; } | |
| bool hasGradientBuffer() const { return fHasGradientBuffer; } | |
| // Name used in-shader for gradient buffer uniform. | |
| static constexpr char kGradientBufferName[] = "fsGradientBuffer"; | |
| private: | |
| ShaderInfo(const ShaderCodeDictionary*, | |
| const RuntimeEffectDictionary*, | |
| const char* ssboIndex, | |
| DstReadStrategy); | |
| void generateVertexSkSL(const Caps*, | |
| const RenderStep*, | |
| bool useStorageBuffers, | |
| SkSpan<const ShaderNode*> rootNodes); | |
| // Determines fNumFragmentTexturesAndSamplers, fHasPaintUniforms, fHasGradientBuffer, | |
| // fHasSsboIndicesVarying, and if a valid SamplerDesc ptr is passed in, any immutable | |
| // sampler SamplerDescs. | |
| void generateFragmentSkSL(const Caps*, | |
| const ShaderCodeDictionary*, | |
| const RenderStep*, | |
| UniquePaintParamsID, | |
| bool useStorageBuffers, | |
| TextureFormat targetFormat, | |
| skgpu::Swizzle writeSwizzle, | |
| skia_private::TArray<SamplerDesc>* outDescs, | |
| SkArenaAlloc& shaderNodeAlloc, | |
| SkSpan<const ShaderNode*>* rootNodes); | |
| bool needsLocalCoords() const { return fNeedsLocalCoords; } | |
| // Recursive method which traverses ShaderNodes in a depth-first manner to aggregate all | |
| // ShaderNode data (not owned by ShaderNode) into ShaderInfo's owned fData. | |
| // TODO(b/347072931): Ideally, this method could go away and each snippet's data could remain | |
| // tied to its ID instead of accumulating it all here. | |
| void aggregateSnippetData(const ShaderNode*); | |
| const ShaderCodeDictionary* fShaderCodeDictionary; | |
| const RuntimeEffectDictionary* fRuntimeEffectDictionary; | |
| const char* fShadingSsboIndex; | |
| // The blendInfo represents the actual GPU blend operations, which may or may not completely | |
| // implement the paint and coverage blending defined by the root nodes. | |
| skgpu::BlendInfo fBlendInfo; | |
| DstReadStrategy fDstReadStrategy = DstReadStrategy::kNoneRequired; | |
| // Note that fData is currently only used to store SamplerDesc information for shaders that have | |
| // the option of using immutable samplers. However, other snippets could leverage this field to | |
| // convey other information once data can be tied to snippetIDs (b/347072931). | |
| skia_private::TArray<uint32_t> fData; | |
| std::string fVertexSkSL; | |
| std::string fFragmentSkSL; | |
| std::string fVSLabel; | |
| std::string fFSLabel; | |
| int fNumFragmentTexturesAndSamplers = 0; | |
| bool fHasStepUniforms = false; | |
| bool fHasPaintUniforms = false; | |
| bool fHasLiftedPaintUniforms = false; | |
| bool fHasGradientBuffer = false; | |
| bool fHasSsboIndicesVarying = false; | |
| bool fNeedsLocalCoords = false; | |
| }; | |
| } // namespace skgpu::graphite | |
| #endif // skgpu_graphite_ShaderInfo_DEFINED |