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