/* * Copyright 2021 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_DrawPass_DEFINED #define skgpu_graphite_DrawPass_DEFINED #include "include/core/SkRect.h" #include "include/core/SkRefCnt.h" #include "include/core/SkSpan.h" #include "include/private/SkTArray.h" #include "src/gpu/graphite/DrawCommands.h" #include "src/gpu/graphite/GraphicsPipeline.h" #include "src/gpu/graphite/GraphicsPipelineDesc.h" #include "src/gpu/graphite/GraphicsPipelineHandle.h" #include "src/gpu/graphite/ResourceTypes.h" #include "src/gpu/graphite/StorageContext.h" struct SkImageInfo; namespace skgpu::graphite { class CommandBuffer; class DrawList; class GraphicsPipeline; struct RenderPassDesc; class ResourceProvider; class RuntimeEffectDictionary; class TextureProxy; enum class DstReadStrategy : uint8_t; enum class LoadOp : uint8_t; enum class StoreOp : uint8_t; /** * DrawPass is analogous to a subpass, storing the drawing operations in the order they are stored * in the eventual command buffer, as well as the surface proxy the operations are intended for. * DrawPasses are grouped into a RenderPassTask for execution within a single render pass if the * subpasses are compatible with each other. * * Unlike DrawList, DrawPasses are immutable and represent as closely as possible what will be * stored in the command buffer while being flexible as to how the pass is incorporated. Depending * on the backend, it may even be able to write accumulated vertex and uniform data directly to * mapped GPU memory, although that is the extent of the CPU->GPU work they perform before they are * executed by a RenderPassTask. */ class DrawPass { public: ~DrawPass(); // Defined relative to the top-left corner of the surface the DrawPass renders to, and is // contained within its dimensions. const SkIRect& bounds() const { return fBounds; } TextureProxy* target() const { return fTarget.get(); } std::pair ops() const { return fOps; } std::array clearColor() const { return fClearColor; } size_t vertexBufferSize() const { return 0; } size_t uniformBufferSize() const { return 0; } // Instantiate and prepare any resources used by the DrawPass that require the Recorder's // ResourceProvider. This includes things likes GraphicsPipelines, sampled Textures, Samplers, // etc. // Note that, due to possible threaded compilation, the Pipelines are not guaranteed to be // complete until Context::insertRecording time. bool prepareResources(ResourceProvider*, sk_sp, const RenderPassDesc&); DrawPassCommands::List::Iter commands() const { return fCommandList.commands(); } int commandCount() const { return fCommandList.count(); } // The handles aren't guaranteed to have been resolved to GraphicsPipelines until // after addResourceRefs() is called const GraphicsPipeline* getPipeline(size_t index) const { SkASSERT(fPipelinesHaveBeenResolved); return fPipelineHandles[index].pipelineOrNull().get(); } // Proxies are always valid but may not be instantiated until after prepareResources() is called SkSpan> sampledTextures() const { return fSampledTextures; } // The handles aren't guaranteed to have been resolved to GraphicsPipelines until // after addResourceRefs() is called SkSpan pipelineHandles() const { return fPipelineHandles; } // Handles for the StorageContext data associated with the draw pass. const BindBufferInfo& storageBufferInfo() const { return fStorageBufferInfo; } const TextureProxy* storageFallbackTexture() const { return fStorageFallbackTexture.get(); } SkEnumBitMask storageBufferStages() const { return fStorageBufferStages; } [[nodiscard]] bool addResourceRefs(ResourceProvider*, CommandBuffer*); private: friend class DrawList; // For the constructor and setStorageResult friend class DrawListLayer; // '' void setStorageResult(StorageContextResult result); DrawPass(sk_sp target, std::pair ops, std::array clearColor); DrawPassCommands::List fCommandList; sk_sp fTarget; SkIRect fBounds; std::pair fOps; std::array fClearColor; // The pipelines are referenced by index in BindGraphicsPipeline, but that will index into // fPipelineHandles. skia_private::TArray fPipelineDescs; skia_private::TArray fPipelineDrawAreas; // These resources all get instantiated during prepareResources. skia_private::TArray fPipelineHandles; skia_private::TArray> fSampledTextures; SkDEBUGCODE(bool fPipelinesHaveBeenResolved = false;) // set in addResourceRefs BindBufferInfo fStorageBufferInfo; sk_sp fStorageFallbackTexture; // In Vulkan, when storage buffers are not supported, image layout transition barriers must be // submitted before beginning the render pass (before any pipeline is active). So store a copy // of the shader stage visibility here. SkEnumBitMask fStorageBufferStages; }; } // namespace skgpu::graphite #endif // skgpu_graphite_DrawPass_DEFINED