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 std::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle> 148 createSimpleRenderPass(bool withResolve, 149 bool withStencil, 150 SelfDependencyFlags selfDepFlags, 151 LoadFromResolve); 152 void createFramebuffer(bool withResolve, 153 bool withStencil, 154 SelfDependencyFlags selfDepFlags, 155 LoadFromResolve); 156 157 bool completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) override; 158 159 // In Vulkan we call the release proc after we are finished with the underlying 160 // GrVkImage::Resource object (which occurs after the GPU has finished all work on it). onSetRelease(sk_sp<GrRefCntedCallback> releaseHelper)161 void onSetRelease(sk_sp<GrRefCntedCallback> releaseHelper) override { 162 // Forward the release proc on to the GrVkImage of the release attachment if we have one, 163 // otherwise the color attachment. 164 GrVkImage* attachment = 165 fResolveAttachment ? fResolveAttachment.get() : fColorAttachment.get(); 166 attachment->setResourceRelease(std::move(releaseHelper)); 167 } 168 169 void releaseInternalObjects(); 170 171 sk_sp<GrVkImage> fColorAttachment; 172 sk_sp<GrVkImage> fResolveAttachment; 173 sk_sp<GrVkImage> fDynamicMSAAAttachment; 174 175 // We can have a renderpass with and without resolve attachment, stencil attachment, 176 // input attachment dependency, advanced blend dependency, and loading from resolve. All 5 of 177 // these being completely orthogonal. Thus we have a total of 32 types of render passes. We then 178 // cache a framebuffer for each type of these render passes. 179 static constexpr int kNumCachedFramebuffers = 32; 180 181 sk_sp<const GrVkFramebuffer> fCachedFramebuffers[kNumCachedFramebuffers]; 182 183 const GrVkDescriptorSet* fCachedInputDescriptorSet = nullptr; 184 185 sk_sp<GrVkFramebuffer> fExternalFramebuffer; 186 }; 187 188 #endif 189