| /* |
| * Copyright 2015 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef GrVkRenderPass_DEFINED |
| #define GrVkRenderPass_DEFINED |
| |
| #include "include/gpu/GrTypes.h" |
| #include "include/gpu/vk/GrVkTypes.h" |
| #include "include/private/base/SkMacros.h" |
| #include "src/gpu/ganesh/vk/GrVkManagedResource.h" |
| |
| #include <cinttypes> |
| |
| class GrVkGpu; |
| class GrVkRenderTarget; |
| namespace skgpu { |
| class KeyBuilder; |
| } |
| |
| class GrVkRenderPass : public GrVkManagedResource { |
| public: |
| struct LoadStoreOps { |
| VkAttachmentLoadOp fLoadOp; |
| VkAttachmentStoreOp fStoreOp; |
| |
| LoadStoreOps(VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp) |
| : fLoadOp(loadOp) |
| , fStoreOp(storeOp) {} |
| |
| bool operator==(const LoadStoreOps& right) const { |
| return fLoadOp == right.fLoadOp && fStoreOp == right.fStoreOp; |
| } |
| |
| bool operator!=(const LoadStoreOps& right) const { |
| return !(*this == right); |
| } |
| }; |
| |
| // Used when importing an external render pass. In this case we have to explicitly be told the |
| // color attachment index |
| explicit GrVkRenderPass(const GrVkGpu* gpu, VkRenderPass renderPass, |
| uint32_t colorAttachmentIndex) |
| : INHERITED(gpu) |
| , fRenderPass(renderPass) |
| , fAttachmentFlags(kExternal_AttachmentFlag) |
| , fSelfDepFlags(SelfDependencyFlags::kNone) |
| , fLoadFromResolve(LoadFromResolve::kNo) |
| , fClearValueCount(0) |
| , fColorAttachmentIndex(colorAttachmentIndex) {} |
| |
| struct AttachmentsDescriptor { |
| struct AttachmentDesc { |
| VkFormat fFormat; |
| int fSamples; |
| LoadStoreOps fLoadStoreOps; |
| |
| AttachmentDesc() |
| : fFormat(VK_FORMAT_UNDEFINED) |
| , fSamples(0) |
| , fLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE) {} |
| bool operator==(const AttachmentDesc& right) const { |
| return (fFormat == right.fFormat && |
| fSamples == right.fSamples && |
| fLoadStoreOps == right.fLoadStoreOps); |
| } |
| bool operator!=(const AttachmentDesc& right) const { |
| return !(*this == right); |
| } |
| bool isCompatible(const AttachmentDesc& desc) const { |
| return (fFormat == desc.fFormat && fSamples == desc.fSamples); |
| } |
| }; |
| AttachmentDesc fColor; |
| AttachmentDesc fResolve; |
| AttachmentDesc fStencil; |
| uint32_t fAttachmentCount; |
| }; |
| |
| enum AttachmentFlags : uint32_t { |
| kColor_AttachmentFlag = 0x1, |
| kStencil_AttachmentFlag = 0x2, |
| kResolve_AttachmentFlag = 0x4, |
| // The external attachment flag signals that this render pass is imported from an external |
| // client. Since we don't know every attachment on the render pass we don't set any of the |
| // specific attachment flags when using external. However, the external render pass must |
| // at least have a color attachment. |
| kExternal_AttachmentFlag = 0x8, |
| }; |
| SK_DECL_BITFIELD_OPS_FRIENDS(AttachmentFlags); |
| |
| enum class SelfDependencyFlags { |
| kNone = 0, |
| kForInputAttachment = 1 << 0, |
| kForNonCoherentAdvBlend = 1 << 1, |
| }; |
| GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(SelfDependencyFlags); |
| |
| enum class LoadFromResolve { |
| kNo, |
| kLoad, |
| }; |
| |
| static GrVkRenderPass* CreateSimple(GrVkGpu*, |
| AttachmentsDescriptor*, |
| AttachmentFlags, |
| SelfDependencyFlags selfDepFlags, |
| LoadFromResolve); |
| static GrVkRenderPass* Create(GrVkGpu*, |
| const GrVkRenderPass& compatibleRenderPass, |
| const LoadStoreOps& colorOp, |
| const LoadStoreOps& resolveOp, |
| const LoadStoreOps& stencilOp); |
| |
| // The following return the index of the render pass attachment array for the given attachment. |
| // If the render pass does not have the given attachment it will return false and not set the |
| // index value. |
| bool colorAttachmentIndex(uint32_t* index) const; |
| bool stencilAttachmentIndex(uint32_t* index) const; |
| bool hasStencilAttachment() const { return fAttachmentFlags & kStencil_AttachmentFlag; } |
| bool hasResolveAttachment() const { return fAttachmentFlags & kResolve_AttachmentFlag; } |
| |
| SelfDependencyFlags selfDependencyFlags() const { return fSelfDepFlags; } |
| LoadFromResolve loadFromResolve() const { return fLoadFromResolve; } |
| |
| // Returns whether or not the structure of a RenderTarget matches that of the VkRenderPass in |
| // this object. Specifically this compares that the number of attachments, format of |
| // attachments, and sample counts are all the same. This function is used in the creation of |
| // basic RenderPasses that can be used when creating a VkFrameBuffer object. |
| bool isCompatible(GrVkRenderTarget* target, |
| SelfDependencyFlags selfDepFlags, |
| LoadFromResolve) const; |
| |
| bool isCompatible(const GrVkRenderPass& renderPass) const; |
| |
| bool isCompatible(const AttachmentsDescriptor&, |
| const AttachmentFlags&, |
| SelfDependencyFlags selfDepFlags, |
| LoadFromResolve) const; |
| |
| bool isCompatibleExternalRP(VkRenderPass) const; |
| |
| SkDEBUGCODE(bool isExternal() const { return fAttachmentFlags & kExternal_AttachmentFlag; }) |
| |
| bool equalLoadStoreOps(const LoadStoreOps& colorOps, |
| const LoadStoreOps& resolveOps, |
| const LoadStoreOps& stencilOps) const; |
| |
| VkRenderPass vkRenderPass() const { return fRenderPass; } |
| |
| const VkExtent2D& granularity() const { return fGranularity; } |
| |
| // Returns the number of clear colors needed to begin this render pass. Currently this will |
| // either only be 0 or 1 since we only ever clear the color attachment. |
| uint32_t clearValueCount() const { return fClearValueCount; } |
| |
| |
| void genKey(skgpu::KeyBuilder*) const; |
| |
| static void GenKey(skgpu::KeyBuilder*, |
| AttachmentFlags, |
| const AttachmentsDescriptor&, |
| SelfDependencyFlags selfDepFlags, |
| LoadFromResolve, |
| uint64_t externalRenderPass); |
| |
| #ifdef SK_TRACE_MANAGED_RESOURCES |
| void dumpInfo() const override { |
| SkDebugf("GrVkRenderPass: %" PRIdPTR " (%d refs)\n", |
| (intptr_t)fRenderPass, this->getRefCnt()); |
| } |
| #endif |
| |
| private: |
| GrVkRenderPass(const GrVkGpu*, VkRenderPass, AttachmentFlags, const AttachmentsDescriptor&, |
| SelfDependencyFlags selfDepFlags, LoadFromResolve, const VkExtent2D& granularity, |
| uint32_t clearValueCount); |
| |
| static GrVkRenderPass* Create(GrVkGpu* gpu, |
| AttachmentFlags, |
| AttachmentsDescriptor*, |
| const LoadStoreOps& colorOps, |
| const LoadStoreOps& resolveOp, |
| const LoadStoreOps& stencilOps, |
| SelfDependencyFlags selfDepFlags, |
| LoadFromResolve); |
| |
| void freeGPUData() const override; |
| |
| VkRenderPass fRenderPass; |
| AttachmentFlags fAttachmentFlags; |
| AttachmentsDescriptor fAttachmentsDescriptor; |
| SelfDependencyFlags fSelfDepFlags; |
| LoadFromResolve fLoadFromResolve; |
| VkExtent2D fGranularity; |
| uint32_t fClearValueCount; |
| // For internally created render passes we assume the color attachment index is always 0. |
| uint32_t fColorAttachmentIndex = 0; |
| |
| using INHERITED = GrVkManagedResource; |
| }; |
| |
| SK_MAKE_BITFIELD_OPS(GrVkRenderPass::AttachmentFlags) |
| GR_MAKE_BITFIELD_CLASS_OPS(GrVkRenderPass::SelfDependencyFlags) |
| |
| #endif |