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/ganesh/GrRenderTarget.h" 13 #include "src/gpu/ganesh/vk/GrVkImage.h" 14 15 #include "include/gpu/vk/GrVkTypes.h" 16 #include "src/gpu/ganesh/vk/GrVkRenderPass.h" 17 #include "src/gpu/ganesh/vk/GrVkResourceProvider.h" 18 19 class GrVkCaps; 20 class GrVkFramebuffer; 21 class GrVkGpu; 22 class GrVkImageView; 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<skgpu::MutableTextureStateRef>); 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 GrVkImage* 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 GrVkImage* 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 // Returns the GrVkImage of the non-msaa attachment. If the color attachment has 1 sample, 75 // then the color attachment will be returned. Otherwise, the resolve attachment is returned. 76 // Note that in this second case the resolve attachment may be null if this was created by 77 // wrapping an msaa VkImage. 78 GrVkImage* nonMSAAAttachment() const; 79 80 // Returns the attachment that is used for all external client facing operations. This will be 81 // either a wrapped color attachment or the resolve attachment for created VkImages. externalAttachment()82 GrVkImage* externalAttachment() const { 83 return fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get(); 84 } 85 86 const GrVkRenderPass* getSimpleRenderPass( 87 bool withResolve, 88 bool withStencil, 89 SelfDependencyFlags selfDepFlags, 90 LoadFromResolve); 91 GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle( 92 bool withResolve, 93 bool withStencil, 94 SelfDependencyFlags selfDepFlags, 95 LoadFromResolve); 96 wrapsSecondaryCommandBuffer()97 bool wrapsSecondaryCommandBuffer() const { return SkToBool(fExternalFramebuffer); } 98 sk_sp<GrVkFramebuffer> externalFramebuffer() const; 99 100 bool canAttemptStencilAttachment(bool useMSAASurface) const override; 101 102 GrBackendRenderTarget getBackendRenderTarget() const override; 103 104 bool getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc, 105 GrVkRenderPass::AttachmentFlags* flags, 106 bool withResolve, 107 bool withStencil); 108 109 // Reconstruct the render target attachment information from the programInfo. This includes 110 // which attachments the render target will have (color, stencil) and the attachments' formats 111 // and sample counts - cf. getAttachmentsDescriptor. 112 static void ReconstructAttachmentsDescriptor(const GrVkCaps& vkCaps, 113 const GrProgramInfo& programInfo, 114 GrVkRenderPass::AttachmentsDescriptor* desc, 115 GrVkRenderPass::AttachmentFlags* flags); 116 117 protected: 118 enum class CreateType { 119 kDirectlyWrapped, // We need to register this in the ctor 120 kFromTextureRT, // Skip registering this to cache since TexRT will handle it 121 }; 122 123 GrVkRenderTarget(GrVkGpu* gpu, 124 SkISize dimensions, 125 sk_sp<GrVkImage> colorAttachment, 126 sk_sp<GrVkImage> resolveImage, 127 CreateType createType, 128 std::string_view label); 129 130 void onAbandon() override; 131 void onRelease() override; 132 133 // This returns zero since the memory should all be handled by the attachments onGpuMemorySize()134 size_t onGpuMemorySize() const override { return 0; } 135 onSetLabel()136 void onSetLabel() override{} 137 138 private: 139 // For external framebuffers that wrap a secondary command buffer 140 GrVkRenderTarget(GrVkGpu* gpu, 141 SkISize dimensions, 142 sk_sp<GrVkFramebuffer> externalFramebuffer, 143 std::string_view label); 144 145 void setFlags(); 146 147 GrVkGpu* getVkGpu() const; 148 149 GrVkImage* dynamicMSAAAttachment(); 150 GrVkImage* msaaAttachment(); 151 152 std::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle> 153 createSimpleRenderPass(bool withResolve, 154 bool withStencil, 155 SelfDependencyFlags selfDepFlags, 156 LoadFromResolve); 157 void createFramebuffer(bool withResolve, 158 bool withStencil, 159 SelfDependencyFlags selfDepFlags, 160 LoadFromResolve); 161 162 bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override; 163 164 // In Vulkan we call the release proc after we are finished with the underlying 165 // GrVkImage::Resource object (which occurs after the GPU has finished all work on it). onSetRelease(sk_sp<RefCntedReleaseProc> releaseHelper)166 void onSetRelease(sk_sp<RefCntedReleaseProc> releaseHelper) override { 167 // Forward the release proc on to the GrVkImage of the resolve attachment if we have one, 168 // otherwise the color attachment. 169 GrVkImage* attachment = 170 fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get(); 171 attachment->setResourceRelease(std::move(releaseHelper)); 172 } 173 174 void releaseInternalObjects(); 175 176 sk_sp<GrVkImage> fColorAttachment; 177 sk_sp<GrVkImage> fResolveAttachment; 178 sk_sp<GrVkImage> fDynamicMSAAAttachment; 179 180 // We can have a renderpass with and without resolve attachment, stencil attachment, 181 // input attachment dependency, advanced blend dependency, and loading from resolve. All 5 of 182 // these being completely orthogonal. Thus we have a total of 32 types of render passes. We then 183 // cache a framebuffer for each type of these render passes. 184 static constexpr int kNumCachedFramebuffers = 32; 185 186 sk_sp<const GrVkFramebuffer> fCachedFramebuffers[kNumCachedFramebuffers]; 187 188 const GrVkDescriptorSet* fCachedInputDescriptorSet = nullptr; 189 190 sk_sp<GrVkFramebuffer> fExternalFramebuffer; 191 }; 192 193 #endif 194