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