1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci* Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci* 4cb93a386Sopenharmony_ci* Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci* found in the LICENSE file. 6cb93a386Sopenharmony_ci*/ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#ifndef GrVkRenderPass_DEFINED 9cb93a386Sopenharmony_ci#define GrVkRenderPass_DEFINED 10cb93a386Sopenharmony_ci 11cb93a386Sopenharmony_ci#include "include/gpu/GrTypes.h" 12cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkTypes.h" 13cb93a386Sopenharmony_ci#include "include/private/SkMacros.h" 14cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkManagedResource.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci#include <cinttypes> 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ciclass GrProcessorKeyBuilder; 19cb93a386Sopenharmony_ciclass GrVkGpu; 20cb93a386Sopenharmony_ciclass GrVkRenderTarget; 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ciclass GrVkRenderPass : public GrVkManagedResource { 23cb93a386Sopenharmony_cipublic: 24cb93a386Sopenharmony_ci struct LoadStoreOps { 25cb93a386Sopenharmony_ci VkAttachmentLoadOp fLoadOp; 26cb93a386Sopenharmony_ci VkAttachmentStoreOp fStoreOp; 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ci LoadStoreOps(VkAttachmentLoadOp loadOp, VkAttachmentStoreOp storeOp) 29cb93a386Sopenharmony_ci : fLoadOp(loadOp) 30cb93a386Sopenharmony_ci , fStoreOp(storeOp) {} 31cb93a386Sopenharmony_ci 32cb93a386Sopenharmony_ci bool operator==(const LoadStoreOps& right) const { 33cb93a386Sopenharmony_ci return fLoadOp == right.fLoadOp && fStoreOp == right.fStoreOp; 34cb93a386Sopenharmony_ci } 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci bool operator!=(const LoadStoreOps& right) const { 37cb93a386Sopenharmony_ci return !(*this == right); 38cb93a386Sopenharmony_ci } 39cb93a386Sopenharmony_ci }; 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci // Used when importing an external render pass. In this case we have to explicitly be told the 42cb93a386Sopenharmony_ci // color attachment index 43cb93a386Sopenharmony_ci explicit GrVkRenderPass(const GrVkGpu* gpu, VkRenderPass renderPass, 44cb93a386Sopenharmony_ci uint32_t colorAttachmentIndex) 45cb93a386Sopenharmony_ci : INHERITED(gpu) 46cb93a386Sopenharmony_ci , fRenderPass(renderPass) 47cb93a386Sopenharmony_ci , fAttachmentFlags(kExternal_AttachmentFlag) 48cb93a386Sopenharmony_ci , fSelfDepFlags(SelfDependencyFlags::kNone) 49cb93a386Sopenharmony_ci , fLoadFromResolve(LoadFromResolve::kNo) 50cb93a386Sopenharmony_ci , fClearValueCount(0) 51cb93a386Sopenharmony_ci , fColorAttachmentIndex(colorAttachmentIndex) {} 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci struct AttachmentsDescriptor { 54cb93a386Sopenharmony_ci struct AttachmentDesc { 55cb93a386Sopenharmony_ci VkFormat fFormat; 56cb93a386Sopenharmony_ci int fSamples; 57cb93a386Sopenharmony_ci LoadStoreOps fLoadStoreOps; 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_ci AttachmentDesc() 60cb93a386Sopenharmony_ci : fFormat(VK_FORMAT_UNDEFINED) 61cb93a386Sopenharmony_ci , fSamples(0) 62cb93a386Sopenharmony_ci , fLoadStoreOps(VK_ATTACHMENT_LOAD_OP_LOAD, VK_ATTACHMENT_STORE_OP_STORE) {} 63cb93a386Sopenharmony_ci bool operator==(const AttachmentDesc& right) const { 64cb93a386Sopenharmony_ci return (fFormat == right.fFormat && 65cb93a386Sopenharmony_ci fSamples == right.fSamples && 66cb93a386Sopenharmony_ci fLoadStoreOps == right.fLoadStoreOps); 67cb93a386Sopenharmony_ci } 68cb93a386Sopenharmony_ci bool operator!=(const AttachmentDesc& right) const { 69cb93a386Sopenharmony_ci return !(*this == right); 70cb93a386Sopenharmony_ci } 71cb93a386Sopenharmony_ci bool isCompatible(const AttachmentDesc& desc) const { 72cb93a386Sopenharmony_ci return (fFormat == desc.fFormat && fSamples == desc.fSamples); 73cb93a386Sopenharmony_ci } 74cb93a386Sopenharmony_ci }; 75cb93a386Sopenharmony_ci AttachmentDesc fColor; 76cb93a386Sopenharmony_ci AttachmentDesc fResolve; 77cb93a386Sopenharmony_ci AttachmentDesc fStencil; 78cb93a386Sopenharmony_ci uint32_t fAttachmentCount; 79cb93a386Sopenharmony_ci }; 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci enum AttachmentFlags { 82cb93a386Sopenharmony_ci kColor_AttachmentFlag = 0x1, 83cb93a386Sopenharmony_ci kStencil_AttachmentFlag = 0x2, 84cb93a386Sopenharmony_ci kResolve_AttachmentFlag = 0x4, 85cb93a386Sopenharmony_ci // The external attachment flag signals that this render pass is imported from an external 86cb93a386Sopenharmony_ci // client. Since we don't know every attachment on the render pass we don't set any of the 87cb93a386Sopenharmony_ci // specific attachment flags when using external. However, the external render pass must 88cb93a386Sopenharmony_ci // at least have a color attachment. 89cb93a386Sopenharmony_ci kExternal_AttachmentFlag = 0x8, 90cb93a386Sopenharmony_ci }; 91cb93a386Sopenharmony_ci SK_DECL_BITFIELD_OPS_FRIENDS(AttachmentFlags); 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci enum class SelfDependencyFlags { 94cb93a386Sopenharmony_ci kNone = 0, 95cb93a386Sopenharmony_ci kForInputAttachment = 1 << 0, 96cb93a386Sopenharmony_ci kForNonCoherentAdvBlend = 1 << 1, 97cb93a386Sopenharmony_ci }; 98cb93a386Sopenharmony_ci GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(SelfDependencyFlags); 99cb93a386Sopenharmony_ci 100cb93a386Sopenharmony_ci enum class LoadFromResolve { 101cb93a386Sopenharmony_ci kNo, 102cb93a386Sopenharmony_ci kLoad, 103cb93a386Sopenharmony_ci }; 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_ci static GrVkRenderPass* CreateSimple(GrVkGpu*, 106cb93a386Sopenharmony_ci AttachmentsDescriptor*, 107cb93a386Sopenharmony_ci AttachmentFlags, 108cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, 109cb93a386Sopenharmony_ci LoadFromResolve); 110cb93a386Sopenharmony_ci static GrVkRenderPass* Create(GrVkGpu*, 111cb93a386Sopenharmony_ci const GrVkRenderPass& compatibleRenderPass, 112cb93a386Sopenharmony_ci const LoadStoreOps& colorOp, 113cb93a386Sopenharmony_ci const LoadStoreOps& resolveOp, 114cb93a386Sopenharmony_ci const LoadStoreOps& stencilOp); 115cb93a386Sopenharmony_ci 116cb93a386Sopenharmony_ci // The following return the index of the render pass attachment array for the given attachment. 117cb93a386Sopenharmony_ci // If the render pass does not have the given attachment it will return false and not set the 118cb93a386Sopenharmony_ci // index value. 119cb93a386Sopenharmony_ci bool colorAttachmentIndex(uint32_t* index) const; 120cb93a386Sopenharmony_ci bool stencilAttachmentIndex(uint32_t* index) const; 121cb93a386Sopenharmony_ci bool hasStencilAttachment() const { return fAttachmentFlags & kStencil_AttachmentFlag; } 122cb93a386Sopenharmony_ci bool hasResolveAttachment() const { return fAttachmentFlags & kResolve_AttachmentFlag; } 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci SelfDependencyFlags selfDependencyFlags() const { return fSelfDepFlags; } 125cb93a386Sopenharmony_ci LoadFromResolve loadFromResolve() const { return fLoadFromResolve; } 126cb93a386Sopenharmony_ci 127cb93a386Sopenharmony_ci // Returns whether or not the structure of a RenderTarget matches that of the VkRenderPass in 128cb93a386Sopenharmony_ci // this object. Specifically this compares that the number of attachments, format of 129cb93a386Sopenharmony_ci // attachments, and sample counts are all the same. This function is used in the creation of 130cb93a386Sopenharmony_ci // basic RenderPasses that can be used when creating a VkFrameBuffer object. 131cb93a386Sopenharmony_ci bool isCompatible(GrVkRenderTarget* target, 132cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, 133cb93a386Sopenharmony_ci LoadFromResolve) const; 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_ci bool isCompatible(const GrVkRenderPass& renderPass) const; 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci bool isCompatible(const AttachmentsDescriptor&, 138cb93a386Sopenharmony_ci const AttachmentFlags&, 139cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, 140cb93a386Sopenharmony_ci LoadFromResolve) const; 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci bool isCompatibleExternalRP(VkRenderPass) const; 143cb93a386Sopenharmony_ci 144cb93a386Sopenharmony_ci SkDEBUGCODE(bool isExternal() const { return fAttachmentFlags & kExternal_AttachmentFlag; }) 145cb93a386Sopenharmony_ci 146cb93a386Sopenharmony_ci bool equalLoadStoreOps(const LoadStoreOps& colorOps, 147cb93a386Sopenharmony_ci const LoadStoreOps& resolveOps, 148cb93a386Sopenharmony_ci const LoadStoreOps& stencilOps) const; 149cb93a386Sopenharmony_ci 150cb93a386Sopenharmony_ci VkRenderPass vkRenderPass() const { return fRenderPass; } 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci const VkExtent2D& granularity() const { return fGranularity; } 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_ci // Returns the number of clear colors needed to begin this render pass. Currently this will 155cb93a386Sopenharmony_ci // either only be 0 or 1 since we only ever clear the color attachment. 156cb93a386Sopenharmony_ci uint32_t clearValueCount() const { return fClearValueCount; } 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_ci void genKey(GrProcessorKeyBuilder*) const; 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_ci static void GenKey(GrProcessorKeyBuilder*, 162cb93a386Sopenharmony_ci AttachmentFlags, 163cb93a386Sopenharmony_ci const AttachmentsDescriptor&, 164cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, 165cb93a386Sopenharmony_ci LoadFromResolve, 166cb93a386Sopenharmony_ci uint64_t externalRenderPass); 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_ci#ifdef SK_TRACE_MANAGED_RESOURCES 169cb93a386Sopenharmony_ci void dumpInfo() const override { 170cb93a386Sopenharmony_ci SkDebugf("GrVkRenderPass: %" PRIdPTR " (%d refs)\n", 171cb93a386Sopenharmony_ci (intptr_t)fRenderPass, this->getRefCnt()); 172cb93a386Sopenharmony_ci } 173cb93a386Sopenharmony_ci#endif 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_ciprivate: 176cb93a386Sopenharmony_ci GrVkRenderPass(const GrVkGpu*, VkRenderPass, AttachmentFlags, const AttachmentsDescriptor&, 177cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, LoadFromResolve, const VkExtent2D& granularity, 178cb93a386Sopenharmony_ci uint32_t clearValueCount); 179cb93a386Sopenharmony_ci 180cb93a386Sopenharmony_ci static GrVkRenderPass* Create(GrVkGpu* gpu, 181cb93a386Sopenharmony_ci AttachmentFlags, 182cb93a386Sopenharmony_ci AttachmentsDescriptor*, 183cb93a386Sopenharmony_ci const LoadStoreOps& colorOps, 184cb93a386Sopenharmony_ci const LoadStoreOps& resolveOp, 185cb93a386Sopenharmony_ci const LoadStoreOps& stencilOps, 186cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, 187cb93a386Sopenharmony_ci LoadFromResolve); 188cb93a386Sopenharmony_ci 189cb93a386Sopenharmony_ci void freeGPUData() const override; 190cb93a386Sopenharmony_ci 191cb93a386Sopenharmony_ci VkRenderPass fRenderPass; 192cb93a386Sopenharmony_ci AttachmentFlags fAttachmentFlags; 193cb93a386Sopenharmony_ci AttachmentsDescriptor fAttachmentsDescriptor; 194cb93a386Sopenharmony_ci SelfDependencyFlags fSelfDepFlags; 195cb93a386Sopenharmony_ci LoadFromResolve fLoadFromResolve; 196cb93a386Sopenharmony_ci VkExtent2D fGranularity; 197cb93a386Sopenharmony_ci uint32_t fClearValueCount; 198cb93a386Sopenharmony_ci // For internally created render passes we assume the color attachment index is always 0. 199cb93a386Sopenharmony_ci uint32_t fColorAttachmentIndex = 0; 200cb93a386Sopenharmony_ci uint32_t fResolveAttachmentIndex = 0; 201cb93a386Sopenharmony_ci 202cb93a386Sopenharmony_ci using INHERITED = GrVkManagedResource; 203cb93a386Sopenharmony_ci}; 204cb93a386Sopenharmony_ci 205cb93a386Sopenharmony_ciSK_MAKE_BITFIELD_OPS(GrVkRenderPass::AttachmentFlags) 206cb93a386Sopenharmony_ciGR_MAKE_BITFIELD_CLASS_OPS(GrVkRenderPass::SelfDependencyFlags) 207cb93a386Sopenharmony_ci 208cb93a386Sopenharmony_ci#endif 209