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 23 struct GrVkImageInfo; 24 25 class GrVkRenderTarget : public GrRenderTarget { 26 public: 27 static sk_sp<GrVkRenderTarget> MakeWrappedRenderTarget(GrVkGpu*, 28 SkISize, 29 int sampleCnt, 30 const GrVkImageInfo&, 31 sk_sp<GrBackendSurfaceMutableStateImpl>); 32 33 static sk_sp<GrVkRenderTarget> MakeSecondaryCBRenderTarget(GrVkGpu*, 34 SkISize, 35 const GrVkDrawableInfo& vkInfo); 36 37 ~GrVkRenderTarget() override; 38 39 GrBackendFormat backendFormat() const override; 40 41 using SelfDependencyFlags = GrVkRenderPass::SelfDependencyFlags; 42 using LoadFromResolve = GrVkRenderPass::LoadFromResolve; 43 44 const GrVkFramebuffer* getFramebuffer(bool withResolve, 45 bool withStencil, 46 SelfDependencyFlags selfDepFlags, 47 LoadFromResolve); getFramebuffer(const GrVkRenderPass & renderPass)48 const GrVkFramebuffer* getFramebuffer(const GrVkRenderPass& renderPass) { 49 return this->getFramebuffer(renderPass.hasResolveAttachment(), 50 renderPass.hasStencilAttachment(), 51 renderPass.selfDependencyFlags(), 52 renderPass.loadFromResolve()); 53 } 54 colorAttachment()55 GrVkImage* colorAttachment() const { 56 SkASSERT(!this->wrapsSecondaryCommandBuffer()); 57 return fColorAttachment.get(); 58 } colorAttachmentView()59 const GrVkImageView* colorAttachmentView() const { 60 SkASSERT(!this->wrapsSecondaryCommandBuffer()); 61 return this->colorAttachment()->framebufferView(); 62 } 63 resolveAttachment()64 GrVkImage* resolveAttachment() const { 65 SkASSERT(!this->wrapsSecondaryCommandBuffer()); 66 return fResolveAttachment.get(); 67 } resolveAttachmentView()68 const GrVkImageView* resolveAttachmentView() const { 69 SkASSERT(!this->wrapsSecondaryCommandBuffer()); 70 return fResolveAttachment->framebufferView(); 71 } 72 73 // Returns the GrVkImage of the non-msaa attachment. If the color attachment has 1 sample, 74 // then the color attachment will be returned. Otherwise, the resolve attachment is returned. 75 // Note that in this second case the resolve attachment may be null if this was created by 76 // wrapping an msaa VkImage. 77 GrVkImage* nonMSAAAttachment() const; 78 79 // Returns the attachment that is used for all external client facing operations. This will be 80 // either a wrapped color attachment or the resolve attachment for created VkImages. externalAttachment()81 GrVkImage* externalAttachment() const { 82 return fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get(); 83 } 84 85 const GrVkRenderPass* getSimpleRenderPass( 86 bool withResolve, 87 bool withStencil, 88 SelfDependencyFlags selfDepFlags, 89 LoadFromResolve); 90 GrVkResourceProvider::CompatibleRPHandle compatibleRenderPassHandle( 91 bool withResolve, 92 bool withStencil, 93 SelfDependencyFlags selfDepFlags, 94 LoadFromResolve); 95 wrapsSecondaryCommandBuffer()96 bool wrapsSecondaryCommandBuffer() const { return SkToBool(fExternalFramebuffer); } 97 sk_sp<GrVkFramebuffer> externalFramebuffer() const; 98 99 bool canAttemptStencilAttachment(bool useMSAASurface) const override; 100 101 GrBackendRenderTarget getBackendRenderTarget() const override; 102 103 void getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc, 104 GrVkRenderPass::AttachmentFlags* flags, 105 bool withResolve, 106 bool withStencil); 107 108 // Reconstruct the render target attachment information from the programInfo. This includes 109 // which attachments the render target will have (color, stencil) and the attachments' formats 110 // and sample counts - cf. getAttachmentsDescriptor. 111 static void ReconstructAttachmentsDescriptor(const GrVkCaps& vkCaps, 112 const GrProgramInfo& programInfo, 113 GrVkRenderPass::AttachmentsDescriptor* desc, 114 GrVkRenderPass::AttachmentFlags* flags); 115 116 protected: 117 enum class CreateType { 118 kDirectlyWrapped, // We need to register this in the ctor 119 kFromTextureRT, // Skip registering this to cache since TexRT will handle it 120 }; 121 122 GrVkRenderTarget(GrVkGpu* gpu, 123 SkISize dimensions, 124 sk_sp<GrVkImage> colorAttachment, 125 sk_sp<GrVkImage> resolveImage, 126 CreateType createType); 127 128 void onAbandon() override; 129 void onRelease() override; 130 131 // This returns zero since the memory should all be handled by the attachments onGpuMemorySize()132 size_t onGpuMemorySize() const override { return 0; } 133 134 private: 135 // For external framebuffers that wrap a secondary command buffer 136 GrVkRenderTarget(GrVkGpu* gpu, 137 SkISize dimensions, 138 sk_sp<GrVkFramebuffer> externalFramebuffer); 139 140 void setFlags(); 141 142 GrVkGpu* getVkGpu() const; 143 144 GrVkImage* dynamicMSAAAttachment(); 145 GrVkImage* msaaAttachment(); 146 147 // This return since the memory should all be handled by the attachments dumpMemoryStatistics(SkTraceMemoryDump * traceMemoryDump)148 void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override { 149 return; 150 } 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<GrRefCntedCallback> releaseHelper)166 void onSetRelease(sk_sp<GrRefCntedCallback> releaseHelper) override { 167 // Forward the release proc on to the GrVkImage of the release 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