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 9 #ifndef GrVkRenderTarget_DEFINED 10 #define GrVkRenderTarget_DEFINED 11 12 #include "src/gpu/GrRenderTarget.h" 13 #include "src/gpu/vk/GrVkImage.h" 14 15 #include "include/gpu/vk/GrVkTypes.h" 16 #include "src/gpu/vk/GrVkRenderPass.h" 17 #include "src/gpu/vk/GrVkResourceProvider.h" 18 19 class GrVkFramebuffer; 20 class GrVkGpu; 21 class GrVkImageView; 22 class GrVkAttachment; 23 24 struct GrVkImageInfo; 25 26 class GrVkRenderTarget : public GrRenderTarget { 27 public: 28 static sk_sp<GrVkRenderTarget> MakeWrappedRenderTarget(GrVkGpu*, 29 SkISize, 30 int sampleCnt, 31 const GrVkImageInfo&, 32 sk_sp<GrBackendSurfaceMutableStateImpl>); 33 34 static sk_sp<GrVkRenderTarget> MakeSecondaryCBRenderTarget(GrVkGpu*, 35 SkISize, 36 const GrVkDrawableInfo& vkInfo); 37 38 ~GrVkRenderTarget() override; 39 40 GrBackendFormat backendFormat() const override; 41 42 using SelfDependencyFlags = GrVkRenderPass::SelfDependencyFlags; 43 using LoadFromResolve = GrVkRenderPass::LoadFromResolve; 44 45 const GrVkFramebuffer* getFramebuffer(bool withResolve, 46 bool withStencil, 47 SelfDependencyFlags selfDepFlags, 48 LoadFromResolve); getFramebuffer(const GrVkRenderPass & renderPass)49 const GrVkFramebuffer* getFramebuffer(const GrVkRenderPass& renderPass) { 50 return this->getFramebuffer(renderPass.hasResolveAttachment(), 51 renderPass.hasStencilAttachment(), 52 renderPass.selfDependencyFlags(), 53 renderPass.loadFromResolve()); 54 } 55 colorAttachment()56 GrVkAttachment* colorAttachment() const { 57 SkASSERT(!this->wrapsSecondaryCommandBuffer()); 58 return fColorAttachment.get(); 59 } colorAttachmentView()60 const GrVkImageView* colorAttachmentView() const { 61 SkASSERT(!this->wrapsSecondaryCommandBuffer()); 62 return this->colorAttachment()->framebufferView(); 63 } 64 resolveAttachment()65 GrVkAttachment* resolveAttachment() const { 66 SkASSERT(!this->wrapsSecondaryCommandBuffer()); 67 return fResolveAttachment.get(); 68 } resolveAttachmentView()69 const GrVkImageView* resolveAttachmentView() const { 70 SkASSERT(!this->wrapsSecondaryCommandBuffer()); 71 return fResolveAttachment->framebufferView(); 72 } 73 74 const GrManagedResource* stencilImageResource() const; 75 const GrVkImageView* stencilAttachmentView() const; 76 77 // Returns the GrVkAttachment of the non-msaa attachment. If the color attachment has 1 sample, 78 // then the color attachment will be returned. Otherwise, the resolve attachment is returned. 79 // Note that in this second case the resolve attachment may be null if this was created by 80 // wrapping an msaa VkImage. 81 GrVkAttachment* nonMSAAAttachment() const; 82 83 // Returns the attachment that is used for all external client facing operations. This will be 84 // either a wrapped color attachment or the resolve attachment for created VkImages. externalAttachment()85 GrVkAttachment* externalAttachment() const { 86 return fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get(); 87 } 88 89 const GrVkRenderPass* getSimpleRenderPass( 90 bool withResolve, 91 bool withStencil, 92 SelfDependencyFlags selfDepFlags, 93 LoadFromResolve); 94 GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle( 95 bool withResolve, 96 bool withStencil, 97 SelfDependencyFlags selfDepFlags, 98 LoadFromResolve); 99 wrapsSecondaryCommandBuffer()100 bool wrapsSecondaryCommandBuffer() const { return SkToBool(fExternalFramebuffer); } 101 sk_sp<GrVkFramebuffer> externalFramebuffer() const; 102 canAttemptStencilAttachment(bool useMSAASurface)103 bool canAttemptStencilAttachment(bool useMSAASurface) const override { 104 SkASSERT(useMSAASurface == (this->numSamples() > 1)); 105 // We don't know the status of the stencil attachment for wrapped external secondary command 106 // buffers so we just assume we don't have one. 107 return !this->wrapsSecondaryCommandBuffer(); 108 } 109 110 GrBackendRenderTarget getBackendRenderTarget() const override; 111 112 void getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc, 113 GrVkRenderPass::AttachmentFlags* flags, 114 bool withResolve, 115 bool withStencil); 116 117 // Reconstruct the render target attachment information from the programInfo. This includes 118 // which attachments the render target will have (color, stencil) and the attachments' formats 119 // and sample counts - cf. getAttachmentsDescriptor. 120 static void ReconstructAttachmentsDescriptor(const GrVkCaps& vkCaps, 121 const GrProgramInfo& programInfo, 122 GrVkRenderPass::AttachmentsDescriptor* desc, 123 GrVkRenderPass::AttachmentFlags* flags); 124 125 protected: 126 enum class CreateType { 127 kDirectlyWrapped, // We need to register this in the ctor 128 kFromTextureRT, // Skip registering this to cache since TexRT will handle it 129 }; 130 131 GrVkRenderTarget(GrVkGpu* gpu, 132 SkISize dimensions, 133 sk_sp<GrVkAttachment> colorAttachment, 134 sk_sp<GrVkAttachment> resolveAttachment, 135 CreateType createType); 136 137 void onAbandon() override; 138 void onRelease() override; 139 140 // This returns zero since the memory should all be handled by the attachments onGpuMemorySize()141 size_t onGpuMemorySize() const override { return 0; } 142 143 private: 144 // For external framebuffers that wrap a secondary command buffer 145 GrVkRenderTarget(GrVkGpu* gpu, 146 SkISize dimensions, 147 sk_sp<GrVkFramebuffer> externalFramebuffer); 148 149 void setFlags(); 150 151 GrVkGpu* getVkGpu() const; 152 153 GrVkAttachment* dynamicMSAAAttachment(); 154 GrVkAttachment* msaaAttachment(); 155 156 std::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle> 157 createSimpleRenderPass(bool withResolve, 158 bool withStencil, 159 SelfDependencyFlags selfDepFlags, 160 LoadFromResolve); 161 void createFramebuffer(bool withResolve, 162 bool withStencil, 163 SelfDependencyFlags selfDepFlags, 164 LoadFromResolve); 165 166 bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override; 167 168 // In Vulkan we call the release proc after we are finished with the underlying 169 // GrVkImage::Resource object (which occurs after the GPU has finished all work on it). onSetRelease(sk_sp<GrRefCntedCallback> releaseHelper)170 void onSetRelease(sk_sp<GrRefCntedCallback> releaseHelper) override { 171 // Forward the release proc on to the GrVkImage of the release attachment if we have one, 172 // otherwise the color attachment. 173 GrVkAttachment* attachment = 174 fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get(); 175 attachment->setResourceRelease(std::move(releaseHelper)); 176 } 177 178 void releaseInternalObjects(); 179 180 sk_sp<GrVkAttachment> fColorAttachment; 181 sk_sp<GrVkAttachment> fResolveAttachment; 182 sk_sp<GrVkAttachment> fDynamicMSAAAttachment; 183 184 // We can have a renderpass with and without resolve attachment, stencil attachment, 185 // input attachment dependency, advanced blend dependency, and loading from resolve. All 5 of 186 // these being completely orthogonal. Thus we have a total of 32 types of render passes. We then 187 // cache a framebuffer for each type of these render passes. 188 static constexpr int kNumCachedFramebuffers = 32; 189 190 sk_sp<const GrVkFramebuffer> fCachedFramebuffers[kNumCachedFramebuffers]; 191 192 const GrVkDescriptorSet* fCachedInputDescriptorSet = nullptr; 193 194 sk_sp<GrVkFramebuffer> fExternalFramebuffer; 195 }; 196 197 #endif 198