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