| /* | |
| * 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/SkTArray.h" | |
| #include "src/core/SkArenaAlloc.h" | |
| #include "src/gpu/Blend.h" | |
| #include "src/gpu/Swizzle.h" | |
| #include "src/gpu/graphite/Attribute.h" | |
| #include "src/gpu/graphite/Caps.h" | |
| #include "src/gpu/graphite/DescriptorData.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 RenderPassDesc& rpDesc, | |
| const RenderStep*, | |
| UniquePaintParamsID, | |
| skia_private::TArray<SamplerDesc>* outDescs = nullptr); | |
| const ShaderCodeDictionary* shaderCodeDictionary() const { | |
| return fShaderCodeDictionary; | |
| } | |
| const RuntimeEffectDictionary* runtimeEffectDictionary() const { | |
| return fRuntimeEffectDictionary; | |
| } | |
| const char* uniformSsboIndex() const { return fUniformSsboIndex; } | |
| const DepthStencilSettings& depthStencilSettings() const { return fDepthStencilSettings; } | |
| DstReadStrategy dstReadStrategy() const { return fDstReadStrategy; } | |
| const skgpu::BlendInfo& blendInfo() const { return fBlendInfo; } | |
| 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; } | |
| // Matches ContextUtils::GetPipelineLabel() for the same args that were passed to Make() | |
| const std::string& pipelineLabel() const { return fPipelineLabel; } | |
| int numFragmentTexturesAndSamplers() const { return fNumFragmentTexturesAndSamplers; } | |
| bool hasCombinedUniforms() const { return fHasCombinedUniforms; } | |
| bool usesStorageBuffer() const { return SkToBool(fStorageBufferStages); } | |
| SkEnumBitMask<PipelineStageFlags> storageBufferStages() const { return fStorageBufferStages; } | |
| bool vsUsesStorage() const { | |
| return SkToBool(fStorageBufferStages & PipelineStageFlags::kVertexShader); | |
| } | |
| bool fsUsesStorage() const { | |
| return SkToBool(fStorageBufferStages & PipelineStageFlags::kFragmentShader); | |
| } | |
| SkSpan<const Attribute> appendAttributes() const { return fAppendAttrs; } | |
| // Name used in-shader for storage buffer uniform. | |
| static constexpr char kStorageBufferName[] = "fsStorageBuffer"; | |
| private: | |
| struct SharedGeneratorData; | |
| ShaderInfo(const ShaderCodeDictionary*, | |
| const RuntimeEffectDictionary*, | |
| const char* uniformSsboIndex, | |
| DstReadStrategy); | |
| // Determines fNumFragmentTexturesAndSamplers, fHasPaintUniforms, fHasStorageBuffer, | |
| // fHasSsboIndexVarying, and if a valid SamplerDesc ptr is passed in, any immutable | |
| // sampler SamplerDescs. | |
| void generateFragmentSkSL(const Caps*, | |
| const ShaderCodeDictionary*, | |
| const char* label, | |
| const RenderStep*, | |
| UniquePaintParamsID, | |
| TextureFormat targetFormat, | |
| skgpu::Swizzle writeSwizzle, | |
| skia_private::TArray<SamplerDesc>* outDescs, | |
| const SharedGeneratorData&); | |
| void generateVertexSkSL(const Caps*, | |
| const RenderStep*, | |
| const SharedGeneratorData&); | |
| #if defined(GPU_TEST_UTILS) | |
| friend class TextureFallbackTest; | |
| static std::string EmitStorageFallbackTexture(const ResourceBindingRequirements&, | |
| const RenderStep*); | |
| #endif | |
| const ShaderCodeDictionary* fShaderCodeDictionary; | |
| const RuntimeEffectDictionary* fRuntimeEffectDictionary; | |
| const char* fUniformSsboIndex; | |
| // The final DepthStencilSettings for the pipeline, combined from the RenderStep's requirements | |
| // and the rest of the render pass. | |
| DepthStencilSettings fDepthStencilSettings; | |
| // 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; | |
| std::string fVertexSkSL; | |
| std::string fFragmentSkSL; | |
| std::string fVSLabel; | |
| std::string fFSLabel; | |
| std::string fPipelineLabel; | |
| int fNumFragmentTexturesAndSamplers = 0; | |
| bool fHasCombinedUniforms = false; | |
| SkEnumBitMask<PipelineStageFlags> fStorageBufferStages = {}; | |
| // Append attributes defined by the render step and any attributes within the paint key via | |
| // a mesh shader snippet. | |
| skia_private::TArray<Attribute> fAppendAttrs; | |
| }; | |
| } // namespace skgpu::graphite | |
| #endif // skgpu_graphite_ShaderInfo_DEFINED |