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