1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2015 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkRenderTarget.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "include/gpu/GrBackendSurface.h" 11cb93a386Sopenharmony_ci#include "include/gpu/GrDirectContext.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrBackendSurfaceMutableStateImpl.h" 13cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 14cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h" 15cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkCommandBuffer.h" 16cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkDescriptorSet.h" 17cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkFramebuffer.h" 18cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h" 19cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkImageView.h" 20cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkResourceProvider.h" 21cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkUtil.h" 22cb93a386Sopenharmony_ci 23cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkTypes.h" 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ci#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X) 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_cistatic int renderpass_features_to_index(bool hasResolve, bool hasStencil, 28cb93a386Sopenharmony_ci GrVkRenderPass::SelfDependencyFlags selfDepFlags, 29cb93a386Sopenharmony_ci GrVkRenderPass::LoadFromResolve loadFromReslove) { 30cb93a386Sopenharmony_ci int index = 0; 31cb93a386Sopenharmony_ci if (hasResolve) { 32cb93a386Sopenharmony_ci index += 1; 33cb93a386Sopenharmony_ci } 34cb93a386Sopenharmony_ci if (hasStencil) { 35cb93a386Sopenharmony_ci index += 2; 36cb93a386Sopenharmony_ci } 37cb93a386Sopenharmony_ci if (selfDepFlags & GrVkRenderPass::SelfDependencyFlags::kForInputAttachment) { 38cb93a386Sopenharmony_ci index += 4; 39cb93a386Sopenharmony_ci } 40cb93a386Sopenharmony_ci if (selfDepFlags & GrVkRenderPass::SelfDependencyFlags::kForNonCoherentAdvBlend) { 41cb93a386Sopenharmony_ci index += 8; 42cb93a386Sopenharmony_ci } 43cb93a386Sopenharmony_ci if (loadFromReslove == GrVkRenderPass::LoadFromResolve::kLoad) { 44cb93a386Sopenharmony_ci index += 16; 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci return index; 47cb93a386Sopenharmony_ci} 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci// We're virtually derived from GrSurface (via GrRenderTarget) so its 50cb93a386Sopenharmony_ci// constructor must be explicitly called. 51cb93a386Sopenharmony_ciGrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, 52cb93a386Sopenharmony_ci SkISize dimensions, 53cb93a386Sopenharmony_ci sk_sp<GrVkImage> colorAttachment, 54cb93a386Sopenharmony_ci sk_sp<GrVkImage> resolveAttachment, 55cb93a386Sopenharmony_ci CreateType createType) 56cb93a386Sopenharmony_ci : GrSurface(gpu, dimensions, 57cb93a386Sopenharmony_ci colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo) 58cb93a386Sopenharmony_ci // for the moment we only support 1:1 color to stencil 59cb93a386Sopenharmony_ci , GrRenderTarget(gpu, dimensions, colorAttachment->numSamples(), 60cb93a386Sopenharmony_ci colorAttachment->isProtected() ? GrProtected::kYes : GrProtected::kNo) 61cb93a386Sopenharmony_ci , fColorAttachment(std::move(colorAttachment)) 62cb93a386Sopenharmony_ci , fResolveAttachment(std::move(resolveAttachment)) 63cb93a386Sopenharmony_ci , fCachedFramebuffers() { 64cb93a386Sopenharmony_ci SkASSERT(fColorAttachment); 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ci if (fColorAttachment->numSamples() == 1 && fColorAttachment->supportsInputAttachmentUsage()) { 67cb93a386Sopenharmony_ci SkASSERT(!resolveAttachment); 68cb93a386Sopenharmony_ci // When we have a single sampled color attachment, we set both the color and resolve 69cb93a386Sopenharmony_ci // to the same attachment. This way if we use DMAA on this render target we will resolve 70cb93a386Sopenharmony_ci // to the single target attachment. 71cb93a386Sopenharmony_ci fResolveAttachment = fColorAttachment; 72cb93a386Sopenharmony_ci } 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci SkASSERT(!resolveAttachment || 75cb93a386Sopenharmony_ci (fResolveAttachment->isProtected() == fColorAttachment->isProtected())); 76cb93a386Sopenharmony_ci SkASSERT(SkToBool(fColorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)); 77cb93a386Sopenharmony_ci this->setFlags(); 78cb93a386Sopenharmony_ci if (createType == CreateType::kDirectlyWrapped) { 79cb93a386Sopenharmony_ci this->registerWithCacheWrapped(GrWrapCacheable::kNo); 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci} 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_ciGrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu, 84cb93a386Sopenharmony_ci SkISize dimensions, 85cb93a386Sopenharmony_ci sk_sp<GrVkFramebuffer> externalFramebuffer) 86cb93a386Sopenharmony_ci : GrSurface(gpu, dimensions, 87cb93a386Sopenharmony_ci externalFramebuffer->colorAttachment()->isProtected() ? GrProtected::kYes 88cb93a386Sopenharmony_ci : GrProtected::kNo) 89cb93a386Sopenharmony_ci , GrRenderTarget(gpu, dimensions, 1, 90cb93a386Sopenharmony_ci externalFramebuffer->colorAttachment()->isProtected() ? GrProtected::kYes 91cb93a386Sopenharmony_ci : GrProtected::kNo) 92cb93a386Sopenharmony_ci , fCachedFramebuffers() 93cb93a386Sopenharmony_ci , fExternalFramebuffer(externalFramebuffer) { 94cb93a386Sopenharmony_ci SkASSERT(fExternalFramebuffer); 95cb93a386Sopenharmony_ci SkASSERT(!fColorAttachment); 96cb93a386Sopenharmony_ci SkDEBUGCODE(auto colorAttachment = fExternalFramebuffer->colorAttachment()); 97cb93a386Sopenharmony_ci SkASSERT(colorAttachment); 98cb93a386Sopenharmony_ci SkASSERT(colorAttachment->numSamples() == 1); 99cb93a386Sopenharmony_ci SkASSERT(SkToBool(colorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)); 100cb93a386Sopenharmony_ci SkASSERT(!SkToBool(colorAttachment->vkUsageFlags() & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)); 101cb93a386Sopenharmony_ci this->setFlags(); 102cb93a386Sopenharmony_ci this->registerWithCacheWrapped(GrWrapCacheable::kNo); 103cb93a386Sopenharmony_ci} 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_civoid GrVkRenderTarget::setFlags() { 106cb93a386Sopenharmony_ci if (this->wrapsSecondaryCommandBuffer()) { 107cb93a386Sopenharmony_ci return; 108cb93a386Sopenharmony_ci } 109cb93a386Sopenharmony_ci GrVkImage* nonMSAAAttachment = this->nonMSAAAttachment(); 110cb93a386Sopenharmony_ci if (nonMSAAAttachment && nonMSAAAttachment->supportsInputAttachmentUsage()) { 111cb93a386Sopenharmony_ci this->setVkRTSupportsInputAttachment(); 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci} 114cb93a386Sopenharmony_ci 115cb93a386Sopenharmony_cisk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeWrappedRenderTarget( 116cb93a386Sopenharmony_ci GrVkGpu* gpu, 117cb93a386Sopenharmony_ci SkISize dimensions, 118cb93a386Sopenharmony_ci int sampleCnt, 119cb93a386Sopenharmony_ci const GrVkImageInfo& info, 120cb93a386Sopenharmony_ci sk_sp<GrBackendSurfaceMutableStateImpl> mutableState) { 121cb93a386Sopenharmony_ci SkASSERT(VK_NULL_HANDLE != info.fImage); 122cb93a386Sopenharmony_ci SkASSERT(1 == info.fLevelCount); 123cb93a386Sopenharmony_ci SkASSERT(sampleCnt >= 1 && info.fSampleCount >= 1); 124cb93a386Sopenharmony_ci 125cb93a386Sopenharmony_ci int wrappedImageSampleCnt = static_cast<int>(info.fSampleCount); 126cb93a386Sopenharmony_ci if (sampleCnt != wrappedImageSampleCnt && wrappedImageSampleCnt != 1) { 127cb93a386Sopenharmony_ci return nullptr; 128cb93a386Sopenharmony_ci } 129cb93a386Sopenharmony_ci 130cb93a386Sopenharmony_ci sk_sp<GrVkImage> wrappedAttachment = 131cb93a386Sopenharmony_ci GrVkImage::MakeWrapped(gpu, 132cb93a386Sopenharmony_ci dimensions, 133cb93a386Sopenharmony_ci info, 134cb93a386Sopenharmony_ci std::move(mutableState), 135cb93a386Sopenharmony_ci GrAttachment::UsageFlags::kColorAttachment, 136cb93a386Sopenharmony_ci kBorrow_GrWrapOwnership, 137cb93a386Sopenharmony_ci GrWrapCacheable::kNo); 138cb93a386Sopenharmony_ci if (!wrappedAttachment) { 139cb93a386Sopenharmony_ci return nullptr; 140cb93a386Sopenharmony_ci } 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci sk_sp<GrVkImage> colorAttachment; 143cb93a386Sopenharmony_ci colorAttachment = std::move(wrappedAttachment); 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_ci if (!colorAttachment) { 146cb93a386Sopenharmony_ci return nullptr; 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci 149cb93a386Sopenharmony_ci GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu,dimensions, std::move(colorAttachment), 150cb93a386Sopenharmony_ci nullptr, CreateType::kDirectlyWrapped); 151cb93a386Sopenharmony_ci return sk_sp<GrVkRenderTarget>(vkRT); 152cb93a386Sopenharmony_ci} 153cb93a386Sopenharmony_ci 154cb93a386Sopenharmony_cisk_sp<GrVkRenderTarget> GrVkRenderTarget::MakeSecondaryCBRenderTarget( 155cb93a386Sopenharmony_ci GrVkGpu* gpu, SkISize dimensions, const GrVkDrawableInfo& vkInfo) { 156cb93a386Sopenharmony_ci const GrVkRenderPass* rp = gpu->resourceProvider().findCompatibleExternalRenderPass( 157cb93a386Sopenharmony_ci vkInfo.fCompatibleRenderPass, vkInfo.fColorAttachmentIndex); 158cb93a386Sopenharmony_ci if (!rp) { 159cb93a386Sopenharmony_ci return nullptr; 160cb93a386Sopenharmony_ci } 161cb93a386Sopenharmony_ci 162cb93a386Sopenharmony_ci if (vkInfo.fSecondaryCommandBuffer == VK_NULL_HANDLE) { 163cb93a386Sopenharmony_ci return nullptr; 164cb93a386Sopenharmony_ci } 165cb93a386Sopenharmony_ci 166cb93a386Sopenharmony_ci // We only set the few properties of the GrVkImageInfo that we know like layout and format. The 167cb93a386Sopenharmony_ci // others we keep at the default "null" values. 168cb93a386Sopenharmony_ci GrVkImageInfo info; 169cb93a386Sopenharmony_ci info.fImageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 170cb93a386Sopenharmony_ci info.fFormat = vkInfo.fFormat; 171cb93a386Sopenharmony_ci info.fImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | 172cb93a386Sopenharmony_ci VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 173cb93a386Sopenharmony_ci 174cb93a386Sopenharmony_ci sk_sp<GrBackendSurfaceMutableStateImpl> mutableState(new GrBackendSurfaceMutableStateImpl( 175cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_QUEUE_FAMILY_IGNORED)); 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_ci sk_sp<GrVkImage> colorAttachment = 178cb93a386Sopenharmony_ci GrVkImage::MakeWrapped(gpu, 179cb93a386Sopenharmony_ci dimensions, 180cb93a386Sopenharmony_ci info, 181cb93a386Sopenharmony_ci std::move(mutableState), 182cb93a386Sopenharmony_ci GrAttachment::UsageFlags::kColorAttachment, 183cb93a386Sopenharmony_ci kBorrow_GrWrapOwnership, 184cb93a386Sopenharmony_ci GrWrapCacheable::kNo, 185cb93a386Sopenharmony_ci true); 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ci std::unique_ptr<GrVkSecondaryCommandBuffer> scb( 188cb93a386Sopenharmony_ci GrVkSecondaryCommandBuffer::Create(vkInfo.fSecondaryCommandBuffer, rp)); 189cb93a386Sopenharmony_ci if (!scb) { 190cb93a386Sopenharmony_ci return nullptr; 191cb93a386Sopenharmony_ci } 192cb93a386Sopenharmony_ci 193cb93a386Sopenharmony_ci sk_sp<GrVkFramebuffer> framebuffer(new GrVkFramebuffer( 194cb93a386Sopenharmony_ci gpu, std::move(colorAttachment), sk_sp<const GrVkRenderPass>(rp), 195cb93a386Sopenharmony_ci std::move(scb))); 196cb93a386Sopenharmony_ci 197cb93a386Sopenharmony_ci GrVkRenderTarget* vkRT = new GrVkRenderTarget(gpu, dimensions, std::move(framebuffer)); 198cb93a386Sopenharmony_ci 199cb93a386Sopenharmony_ci return sk_sp<GrVkRenderTarget>(vkRT); 200cb93a386Sopenharmony_ci} 201cb93a386Sopenharmony_ci 202cb93a386Sopenharmony_ciGrBackendFormat GrVkRenderTarget::backendFormat() const { 203cb93a386Sopenharmony_ci if (this->wrapsSecondaryCommandBuffer()) { 204cb93a386Sopenharmony_ci return fExternalFramebuffer->colorAttachment()->backendFormat(); 205cb93a386Sopenharmony_ci } 206cb93a386Sopenharmony_ci return fColorAttachment->backendFormat(); 207cb93a386Sopenharmony_ci} 208cb93a386Sopenharmony_ci 209cb93a386Sopenharmony_ciGrVkImage* GrVkRenderTarget::nonMSAAAttachment() const { 210cb93a386Sopenharmony_ci if (fColorAttachment->numSamples() == 1) { 211cb93a386Sopenharmony_ci return fColorAttachment.get(); 212cb93a386Sopenharmony_ci } else { 213cb93a386Sopenharmony_ci return fResolveAttachment.get(); 214cb93a386Sopenharmony_ci } 215cb93a386Sopenharmony_ci} 216cb93a386Sopenharmony_ci 217cb93a386Sopenharmony_ciGrVkImage* GrVkRenderTarget::dynamicMSAAAttachment() { 218cb93a386Sopenharmony_ci if (fDynamicMSAAAttachment) { 219cb93a386Sopenharmony_ci return fDynamicMSAAAttachment.get(); 220cb93a386Sopenharmony_ci } 221cb93a386Sopenharmony_ci const GrVkImage* nonMSAAColorAttachment = this->colorAttachment(); 222cb93a386Sopenharmony_ci SkASSERT(nonMSAAColorAttachment->numSamples() == 1); 223cb93a386Sopenharmony_ci 224cb93a386Sopenharmony_ci GrVkGpu* gpu = this->getVkGpu(); 225cb93a386Sopenharmony_ci auto rp = gpu->getContext()->priv().resourceProvider(); 226cb93a386Sopenharmony_ci 227cb93a386Sopenharmony_ci const GrBackendFormat& format = nonMSAAColorAttachment->backendFormat(); 228cb93a386Sopenharmony_ci 229cb93a386Sopenharmony_ci GrMemoryless memoryless = 230cb93a386Sopenharmony_ci gpu->vkCaps().supportsMemorylessAttachments() ? GrMemoryless::kYes : GrMemoryless::kNo; 231cb93a386Sopenharmony_ci 232cb93a386Sopenharmony_ci sk_sp<GrAttachment> msaaAttachment = 233cb93a386Sopenharmony_ci rp->getDiscardableMSAAAttachment(nonMSAAColorAttachment->dimensions(), 234cb93a386Sopenharmony_ci format, 235cb93a386Sopenharmony_ci gpu->caps()->internalMultisampleCount(format), 236cb93a386Sopenharmony_ci GrProtected(nonMSAAColorAttachment->isProtected()), 237cb93a386Sopenharmony_ci memoryless); 238cb93a386Sopenharmony_ci if (!msaaAttachment) { 239cb93a386Sopenharmony_ci return nullptr; 240cb93a386Sopenharmony_ci } 241cb93a386Sopenharmony_ci fDynamicMSAAAttachment = sk_sp<GrVkImage>(static_cast<GrVkImage*>(msaaAttachment.release())); 242cb93a386Sopenharmony_ci return fDynamicMSAAAttachment.get(); 243cb93a386Sopenharmony_ci} 244cb93a386Sopenharmony_ci 245cb93a386Sopenharmony_ciGrVkImage* GrVkRenderTarget::msaaAttachment() { 246cb93a386Sopenharmony_ci return this->colorAttachment()->numSamples() == 1 ? this->dynamicMSAAAttachment() 247cb93a386Sopenharmony_ci : this->colorAttachment(); 248cb93a386Sopenharmony_ci} 249cb93a386Sopenharmony_ci 250cb93a386Sopenharmony_cibool GrVkRenderTarget::canAttemptStencilAttachment(bool useMSAASurface) const { 251cb93a386Sopenharmony_ci SkASSERT(!useMSAASurface || this->numSamples() > 1 || 252cb93a386Sopenharmony_ci this->getVkGpu()->vkCaps().supportsDiscardableMSAAForDMSAA()); 253cb93a386Sopenharmony_ci if (!useMSAASurface && this->numSamples() > 1) { 254cb93a386Sopenharmony_ci return false; 255cb93a386Sopenharmony_ci } 256cb93a386Sopenharmony_ci bool validMSAA = true; 257cb93a386Sopenharmony_ci if (useMSAASurface) { 258cb93a386Sopenharmony_ci validMSAA = this->numSamples() > 1 || 259cb93a386Sopenharmony_ci (this->getVkGpu()->vkCaps().supportsDiscardableMSAAForDMSAA() && 260cb93a386Sopenharmony_ci this->colorAttachment()->supportsInputAttachmentUsage()); 261cb93a386Sopenharmony_ci } 262cb93a386Sopenharmony_ci // We don't know the status of the stencil attachment for wrapped external secondary command 263cb93a386Sopenharmony_ci // buffers so we just assume we don't have one. 264cb93a386Sopenharmony_ci return validMSAA && !this->wrapsSecondaryCommandBuffer(); 265cb93a386Sopenharmony_ci} 266cb93a386Sopenharmony_ci 267cb93a386Sopenharmony_cibool GrVkRenderTarget::completeStencilAttachment(GrAttachment* stencil, bool useMSAASurface) { 268cb93a386Sopenharmony_ci SkASSERT(!this->wrapsSecondaryCommandBuffer()); 269cb93a386Sopenharmony_ci SkASSERT(!useMSAASurface || 270cb93a386Sopenharmony_ci this->numSamples() > 1 || 271cb93a386Sopenharmony_ci this->getVkGpu()->vkCaps().supportsDiscardableMSAAForDMSAA()); 272cb93a386Sopenharmony_ci return true; 273cb93a386Sopenharmony_ci} 274cb93a386Sopenharmony_ci 275cb93a386Sopenharmony_cisk_sp<GrVkFramebuffer> GrVkRenderTarget::externalFramebuffer() const { 276cb93a386Sopenharmony_ci return fExternalFramebuffer; 277cb93a386Sopenharmony_ci} 278cb93a386Sopenharmony_ci 279cb93a386Sopenharmony_ciGrVkResourceProvider::CompatibleRPHandle GrVkRenderTarget::compatibleRenderPassHandle( 280cb93a386Sopenharmony_ci bool withResolve, 281cb93a386Sopenharmony_ci bool withStencil, 282cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, 283cb93a386Sopenharmony_ci LoadFromResolve loadFromResolve) { 284cb93a386Sopenharmony_ci SkASSERT(!this->wrapsSecondaryCommandBuffer()); 285cb93a386Sopenharmony_ci 286cb93a386Sopenharmony_ci const GrVkFramebuffer* fb = 287cb93a386Sopenharmony_ci this->getFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve); 288cb93a386Sopenharmony_ci if (!fb) { 289cb93a386Sopenharmony_ci return {}; 290cb93a386Sopenharmony_ci } 291cb93a386Sopenharmony_ci 292cb93a386Sopenharmony_ci return fb->compatibleRenderPassHandle(); 293cb93a386Sopenharmony_ci} 294cb93a386Sopenharmony_ci 295cb93a386Sopenharmony_ciconst GrVkRenderPass* GrVkRenderTarget::getSimpleRenderPass(bool withResolve, 296cb93a386Sopenharmony_ci bool withStencil, 297cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, 298cb93a386Sopenharmony_ci LoadFromResolve loadFromResolve) { 299cb93a386Sopenharmony_ci if (this->wrapsSecondaryCommandBuffer()) { 300cb93a386Sopenharmony_ci return fExternalFramebuffer->externalRenderPass(); 301cb93a386Sopenharmony_ci } 302cb93a386Sopenharmony_ci 303cb93a386Sopenharmony_ci const GrVkFramebuffer* fb = 304cb93a386Sopenharmony_ci this->getFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve); 305cb93a386Sopenharmony_ci if (!fb) { 306cb93a386Sopenharmony_ci return nullptr; 307cb93a386Sopenharmony_ci } 308cb93a386Sopenharmony_ci 309cb93a386Sopenharmony_ci return fb->compatibleRenderPass(); 310cb93a386Sopenharmony_ci} 311cb93a386Sopenharmony_ci 312cb93a386Sopenharmony_cistd::pair<const GrVkRenderPass*, GrVkResourceProvider::CompatibleRPHandle> 313cb93a386Sopenharmony_ciGrVkRenderTarget::createSimpleRenderPass(bool withResolve, 314cb93a386Sopenharmony_ci bool withStencil, 315cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, 316cb93a386Sopenharmony_ci LoadFromResolve loadFromResolve) { 317cb93a386Sopenharmony_ci SkASSERT(!this->wrapsSecondaryCommandBuffer()); 318cb93a386Sopenharmony_ci 319cb93a386Sopenharmony_ci GrVkResourceProvider& rp = this->getVkGpu()->resourceProvider(); 320cb93a386Sopenharmony_ci 321cb93a386Sopenharmony_ci GrVkResourceProvider::CompatibleRPHandle handle; 322cb93a386Sopenharmony_ci const GrVkRenderPass* renderPass = rp.findCompatibleRenderPass( 323cb93a386Sopenharmony_ci this, &handle, withResolve, withStencil, selfDepFlags, 324cb93a386Sopenharmony_ci loadFromResolve); 325cb93a386Sopenharmony_ci SkASSERT(!renderPass || handle.isValid()); 326cb93a386Sopenharmony_ci return {renderPass, handle}; 327cb93a386Sopenharmony_ci} 328cb93a386Sopenharmony_ci 329cb93a386Sopenharmony_ciconst GrVkFramebuffer* GrVkRenderTarget::getFramebuffer(bool withResolve, 330cb93a386Sopenharmony_ci bool withStencil, 331cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, 332cb93a386Sopenharmony_ci LoadFromResolve loadFromResolve) { 333cb93a386Sopenharmony_ci int cacheIndex = 334cb93a386Sopenharmony_ci renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve); 335cb93a386Sopenharmony_ci SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedFramebuffers); 336cb93a386Sopenharmony_ci if (auto fb = fCachedFramebuffers[cacheIndex]) { 337cb93a386Sopenharmony_ci return fb.get(); 338cb93a386Sopenharmony_ci } 339cb93a386Sopenharmony_ci 340cb93a386Sopenharmony_ci this->createFramebuffer(withResolve, withStencil, selfDepFlags, loadFromResolve); 341cb93a386Sopenharmony_ci return fCachedFramebuffers[cacheIndex].get(); 342cb93a386Sopenharmony_ci} 343cb93a386Sopenharmony_ci 344cb93a386Sopenharmony_civoid GrVkRenderTarget::createFramebuffer(bool withResolve, 345cb93a386Sopenharmony_ci bool withStencil, 346cb93a386Sopenharmony_ci SelfDependencyFlags selfDepFlags, 347cb93a386Sopenharmony_ci LoadFromResolve loadFromResolve) { 348cb93a386Sopenharmony_ci SkASSERT(!this->wrapsSecondaryCommandBuffer()); 349cb93a386Sopenharmony_ci GrVkGpu* gpu = this->getVkGpu(); 350cb93a386Sopenharmony_ci 351cb93a386Sopenharmony_ci auto[renderPass, compatibleHandle] = 352cb93a386Sopenharmony_ci this->createSimpleRenderPass(withResolve, withStencil, selfDepFlags, loadFromResolve); 353cb93a386Sopenharmony_ci if (!renderPass) { 354cb93a386Sopenharmony_ci return; 355cb93a386Sopenharmony_ci } 356cb93a386Sopenharmony_ci SkASSERT(compatibleHandle.isValid()); 357cb93a386Sopenharmony_ci 358cb93a386Sopenharmony_ci int cacheIndex = 359cb93a386Sopenharmony_ci renderpass_features_to_index(withResolve, withStencil, selfDepFlags, loadFromResolve); 360cb93a386Sopenharmony_ci SkASSERT(cacheIndex < GrVkRenderTarget::kNumCachedFramebuffers); 361cb93a386Sopenharmony_ci 362cb93a386Sopenharmony_ci GrVkImage* resolve = withResolve ? this->resolveAttachment() : nullptr; 363cb93a386Sopenharmony_ci GrVkImage* colorAttachment = withResolve ? this->msaaAttachment() : this->colorAttachment(); 364cb93a386Sopenharmony_ci 365cb93a386Sopenharmony_ci // Stencil attachment view is stored in the base RT stencil attachment 366cb93a386Sopenharmony_ci bool useMSAA = this->numSamples() > 1 || withResolve; 367cb93a386Sopenharmony_ci GrVkImage* stencil = withStencil ? static_cast<GrVkImage*>(this->getStencilAttachment(useMSAA)) 368cb93a386Sopenharmony_ci : nullptr; 369cb93a386Sopenharmony_ci fCachedFramebuffers[cacheIndex] = 370cb93a386Sopenharmony_ci GrVkFramebuffer::Make(gpu, this->dimensions(), 371cb93a386Sopenharmony_ci sk_sp<const GrVkRenderPass>(renderPass), 372cb93a386Sopenharmony_ci colorAttachment, resolve, stencil, compatibleHandle); 373cb93a386Sopenharmony_ci} 374cb93a386Sopenharmony_ci 375cb93a386Sopenharmony_civoid GrVkRenderTarget::getAttachmentsDescriptor(GrVkRenderPass::AttachmentsDescriptor* desc, 376cb93a386Sopenharmony_ci GrVkRenderPass::AttachmentFlags* attachmentFlags, 377cb93a386Sopenharmony_ci bool withResolve, 378cb93a386Sopenharmony_ci bool withStencil) { 379cb93a386Sopenharmony_ci SkASSERT(!this->wrapsSecondaryCommandBuffer()); 380cb93a386Sopenharmony_ci const GrVkImage* colorAttachment = 381cb93a386Sopenharmony_ci withResolve ? this->msaaAttachment() : this->colorAttachment(); 382cb93a386Sopenharmony_ci 383cb93a386Sopenharmony_ci desc->fColor.fFormat = colorAttachment->imageFormat(); 384cb93a386Sopenharmony_ci desc->fColor.fSamples = colorAttachment->numSamples(); 385cb93a386Sopenharmony_ci *attachmentFlags = GrVkRenderPass::kColor_AttachmentFlag; 386cb93a386Sopenharmony_ci uint32_t attachmentCount = 1; 387cb93a386Sopenharmony_ci 388cb93a386Sopenharmony_ci if (withResolve) { 389cb93a386Sopenharmony_ci desc->fResolve.fFormat = desc->fColor.fFormat; 390cb93a386Sopenharmony_ci desc->fResolve.fSamples = 1; 391cb93a386Sopenharmony_ci *attachmentFlags |= GrVkRenderPass::kResolve_AttachmentFlag; 392cb93a386Sopenharmony_ci ++attachmentCount; 393cb93a386Sopenharmony_ci } 394cb93a386Sopenharmony_ci 395cb93a386Sopenharmony_ci if (withStencil) { 396cb93a386Sopenharmony_ci bool useMSAA = this->numSamples() > 1 || withResolve; 397cb93a386Sopenharmony_ci const GrAttachment* stencil = this->getStencilAttachment(useMSAA); 398cb93a386Sopenharmony_ci SkASSERT(stencil); 399cb93a386Sopenharmony_ci const GrVkImage* vkStencil = static_cast<const GrVkImage*>(stencil); 400cb93a386Sopenharmony_ci desc->fStencil.fFormat = vkStencil->imageFormat(); 401cb93a386Sopenharmony_ci desc->fStencil.fSamples = vkStencil->numSamples(); 402cb93a386Sopenharmony_ci SkASSERT(desc->fStencil.fSamples == desc->fColor.fSamples); 403cb93a386Sopenharmony_ci *attachmentFlags |= GrVkRenderPass::kStencil_AttachmentFlag; 404cb93a386Sopenharmony_ci ++attachmentCount; 405cb93a386Sopenharmony_ci } 406cb93a386Sopenharmony_ci desc->fAttachmentCount = attachmentCount; 407cb93a386Sopenharmony_ci} 408cb93a386Sopenharmony_ci 409cb93a386Sopenharmony_civoid GrVkRenderTarget::ReconstructAttachmentsDescriptor(const GrVkCaps& vkCaps, 410cb93a386Sopenharmony_ci const GrProgramInfo& programInfo, 411cb93a386Sopenharmony_ci GrVkRenderPass::AttachmentsDescriptor* desc, 412cb93a386Sopenharmony_ci GrVkRenderPass::AttachmentFlags* flags) { 413cb93a386Sopenharmony_ci VkFormat format; 414cb93a386Sopenharmony_ci SkAssertResult(programInfo.backendFormat().asVkFormat(&format)); 415cb93a386Sopenharmony_ci 416cb93a386Sopenharmony_ci desc->fColor.fFormat = format; 417cb93a386Sopenharmony_ci desc->fColor.fSamples = programInfo.numSamples(); 418cb93a386Sopenharmony_ci *flags = GrVkRenderPass::kColor_AttachmentFlag; 419cb93a386Sopenharmony_ci uint32_t attachmentCount = 1; 420cb93a386Sopenharmony_ci 421cb93a386Sopenharmony_ci if (vkCaps.programInfoWillUseDiscardableMSAA(programInfo)) { 422cb93a386Sopenharmony_ci desc->fResolve.fFormat = desc->fColor.fFormat; 423cb93a386Sopenharmony_ci desc->fResolve.fSamples = 1; 424cb93a386Sopenharmony_ci *flags |= GrVkRenderPass::kResolve_AttachmentFlag; 425cb93a386Sopenharmony_ci ++attachmentCount; 426cb93a386Sopenharmony_ci } 427cb93a386Sopenharmony_ci 428cb93a386Sopenharmony_ci SkASSERT(!programInfo.isStencilEnabled() || programInfo.needsStencil()); 429cb93a386Sopenharmony_ci if (programInfo.needsStencil()) { 430cb93a386Sopenharmony_ci VkFormat stencilFormat = vkCaps.preferredStencilFormat(); 431cb93a386Sopenharmony_ci desc->fStencil.fFormat = stencilFormat; 432cb93a386Sopenharmony_ci desc->fStencil.fSamples = programInfo.numSamples(); 433cb93a386Sopenharmony_ci SkASSERT(desc->fStencil.fSamples == desc->fColor.fSamples); 434cb93a386Sopenharmony_ci *flags |= GrVkRenderPass::kStencil_AttachmentFlag; 435cb93a386Sopenharmony_ci ++attachmentCount; 436cb93a386Sopenharmony_ci } 437cb93a386Sopenharmony_ci desc->fAttachmentCount = attachmentCount; 438cb93a386Sopenharmony_ci} 439cb93a386Sopenharmony_ci 440cb93a386Sopenharmony_ciGrVkRenderTarget::~GrVkRenderTarget() { 441cb93a386Sopenharmony_ci // either release or abandon should have been called by the owner of this object. 442cb93a386Sopenharmony_ci SkASSERT(!fColorAttachment); 443cb93a386Sopenharmony_ci SkASSERT(!fResolveAttachment); 444cb93a386Sopenharmony_ci SkASSERT(!fDynamicMSAAAttachment); 445cb93a386Sopenharmony_ci 446cb93a386Sopenharmony_ci for (int i = 0; i < kNumCachedFramebuffers; ++i) { 447cb93a386Sopenharmony_ci SkASSERT(!fCachedFramebuffers[i]); 448cb93a386Sopenharmony_ci } 449cb93a386Sopenharmony_ci 450cb93a386Sopenharmony_ci SkASSERT(!fCachedInputDescriptorSet); 451cb93a386Sopenharmony_ci} 452cb93a386Sopenharmony_ci 453cb93a386Sopenharmony_civoid GrVkRenderTarget::releaseInternalObjects() { 454cb93a386Sopenharmony_ci fColorAttachment.reset(); 455cb93a386Sopenharmony_ci fResolveAttachment.reset(); 456cb93a386Sopenharmony_ci fDynamicMSAAAttachment.reset(); 457cb93a386Sopenharmony_ci 458cb93a386Sopenharmony_ci for (int i = 0; i < kNumCachedFramebuffers; ++i) { 459cb93a386Sopenharmony_ci if (fCachedFramebuffers[i]) { 460cb93a386Sopenharmony_ci fCachedFramebuffers[i].reset(); 461cb93a386Sopenharmony_ci } 462cb93a386Sopenharmony_ci } 463cb93a386Sopenharmony_ci 464cb93a386Sopenharmony_ci if (fCachedInputDescriptorSet) { 465cb93a386Sopenharmony_ci fCachedInputDescriptorSet->recycle(); 466cb93a386Sopenharmony_ci fCachedInputDescriptorSet = nullptr; 467cb93a386Sopenharmony_ci } 468cb93a386Sopenharmony_ci 469cb93a386Sopenharmony_ci fExternalFramebuffer.reset(); 470cb93a386Sopenharmony_ci} 471cb93a386Sopenharmony_ci 472cb93a386Sopenharmony_civoid GrVkRenderTarget::onRelease() { 473cb93a386Sopenharmony_ci this->releaseInternalObjects(); 474cb93a386Sopenharmony_ci GrRenderTarget::onRelease(); 475cb93a386Sopenharmony_ci} 476cb93a386Sopenharmony_ci 477cb93a386Sopenharmony_civoid GrVkRenderTarget::onAbandon() { 478cb93a386Sopenharmony_ci this->releaseInternalObjects(); 479cb93a386Sopenharmony_ci GrRenderTarget::onAbandon(); 480cb93a386Sopenharmony_ci} 481cb93a386Sopenharmony_ci 482cb93a386Sopenharmony_ciGrBackendRenderTarget GrVkRenderTarget::getBackendRenderTarget() const { 483cb93a386Sopenharmony_ci SkASSERT(!this->wrapsSecondaryCommandBuffer()); 484cb93a386Sopenharmony_ci // This should only get called with a non-released GrVkRenderTargets. 485cb93a386Sopenharmony_ci SkASSERT(!this->wasDestroyed()); 486cb93a386Sopenharmony_ci // If we have a resolve attachment that is what we return for the backend render target 487cb93a386Sopenharmony_ci const GrVkImage* beAttachment = this->externalAttachment(); 488cb93a386Sopenharmony_ci return GrBackendRenderTarget(beAttachment->width(), beAttachment->height(), 489cb93a386Sopenharmony_ci beAttachment->vkImageInfo(), beAttachment->getMutableState()); 490cb93a386Sopenharmony_ci} 491cb93a386Sopenharmony_ci 492cb93a386Sopenharmony_ciGrVkGpu* GrVkRenderTarget::getVkGpu() const { 493cb93a386Sopenharmony_ci SkASSERT(!this->wasDestroyed()); 494cb93a386Sopenharmony_ci return static_cast<GrVkGpu*>(this->getGpu()); 495cb93a386Sopenharmony_ci} 496