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