/* * Copyright 2021 Google LLC * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "src/gpu/graphite/DrawPass.h" #include "include/gpu/graphite/GraphiteTypes.h" #include "include/gpu/graphite/Recorder.h" #include "include/private/base/SkAlign.h" #include "src/core/SkTraceEvent.h" #include "src/gpu/graphite/Buffer.h" #include "src/gpu/graphite/BufferManager.h" #include "src/gpu/graphite/Caps.h" #include "src/gpu/graphite/ContextPriv.h" #include "src/gpu/graphite/ContextUtils.h" #include "src/gpu/graphite/DrawContext.h" #include "src/gpu/graphite/DrawList.h" #include "src/gpu/graphite/DrawWriter.h" #include "src/gpu/graphite/GlobalCache.h" #include "src/gpu/graphite/GraphicsPipeline.h" #include "src/gpu/graphite/GraphicsPipelineDesc.h" #include "src/gpu/graphite/Log.h" #include "src/gpu/graphite/PaintParamsKey.h" #include "src/gpu/graphite/PipelineData.h" #include "src/gpu/graphite/PipelineDataCache.h" #include "src/gpu/graphite/RecorderPriv.h" #include "src/gpu/graphite/Renderer.h" #include "src/gpu/graphite/ResourceProvider.h" #include "src/gpu/graphite/Sampler.h" #include "src/gpu/graphite/Texture.h" #include "src/gpu/graphite/UniformManager.h" #include "src/gpu/graphite/geom/BoundsManager.h" #include "src/base/SkMathPriv.h" #include "src/base/SkTBlockList.h" #include <algorithm> #include <unordered_map> usingnamespaceskia_private; namespace skgpu::graphite { namespace { // Helper to manage packed fields within a uint64_t template <uint64_t Bits, uint64_t Offset> struct Bitfield { … }; // This class maps objects to a dense index which can then be used to look them up later template <typename T, typename V = T, typename C = V> class DenseBiMap { … }; // Tracks uniform data on the CPU and then its transition to storage in a GPU buffer (ubo or ssbo). struct CpuOrGpuData { … }; // Tracks the combination of textures from the paint and from the RenderStep to describe the full // binding that needs to be in the command list. struct TextureBinding { … }; using UniformCache = DenseBiMap<const UniformDataBlock*, CpuOrGpuData>; using TextureBindingCache = DenseBiMap<TextureBinding>; using GraphicsPipelineCache = DenseBiMap<GraphicsPipelineDesc>; // Automatically merges and manages texture bindings and uniform bindings sourced from either the // paint or the RenderStep. Tracks the bound state based on last-provided unique index to write // Bind commands to a CommandList when necessary. class TextureBindingTracker { … }; // Collects and writes uniform data either to uniform buffers or to shared storage buffers, and // tracks when bindings need to change between draws. class UniformTracker { … }; class GradientBufferTracker { … }; } // namespace /////////////////////////////////////////////////////////////////////////////////////////////////// /** * Each Draw in a DrawList might be processed by multiple RenderSteps (determined by the Draw's * Renderer), which can be sorted independently. Each (step, draw) pair produces its own SortKey. * * The goal of sorting draws for the DrawPass is to minimize pipeline transitions and dynamic binds * within a pipeline, while still respecting the overall painter's order. This decreases the number * of low-level draw commands in a command buffer and increases the size of those, allowing the GPU * to operate more efficiently and have fewer bubbles within its own instruction stream. * * The Draw's CompresssedPaintersOrder and DisjointStencilINdex represent the most significant bits * of the key, and are shared by all SortKeys produced by the same draw. Next, the pipeline * description is encoded in two steps: * 1. The index of the RenderStep packed in the high bits to ensure each step for a draw is * ordered correctly. * 2. An index into a cache of pipeline descriptions is used to encode the identity of the * pipeline (SortKeys that differ in the bits from #1 necessarily would have different * descriptions, but then the specific ordering of the RenderSteps isn't enforced). * Last, the SortKey encodes an index into the set of uniform bindings accumulated for a DrawPass. * This allows the SortKey to cluster draw steps that have both a compatible pipeline and do not * require rebinding uniform data or other state (e.g. scissor). Since the uniform data index and * the pipeline description index are packed into indices and not actual pointers, a given SortKey * is only valid for the a specific DrawList->DrawPass conversion. */ class DrawPass::SortKey { … }; /////////////////////////////////////////////////////////////////////////////////////////////////// DrawPass::DrawPass(sk_sp<TextureProxy> target, std::pair<LoadOp, StoreOp> ops, std::array<float, 4> clearColor) : … { … } DrawPass::~DrawPass() = default; std::unique_ptr<DrawPass> DrawPass::Make(Recorder* recorder, std::unique_ptr<DrawList> draws, sk_sp<TextureProxy> target, const SkImageInfo& targetInfo, std::pair<LoadOp, StoreOp> ops, std::array<float, 4> clearColor, sk_sp<TextureProxy> dstCopy, SkIPoint dstCopyOffset) { … } bool DrawPass::prepareResources(ResourceProvider* resourceProvider, const RuntimeEffectDictionary* runtimeDict, const RenderPassDesc& renderPassDesc) { … } void DrawPass::addResourceRefs(CommandBuffer* commandBuffer) const { … } const Texture* DrawPass::getTexture(size_t index) const { … } const Sampler* DrawPass::getSampler(size_t index) const { … } } // namespace skgpu::graphite