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