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