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/GrVkTextureRenderTarget.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/gpu/GrDirectContextPriv.h" 11cb93a386Sopenharmony_ci#include "src/gpu/GrResourceProvider.h" 12cb93a386Sopenharmony_ci#include "src/gpu/GrTexture.h" 13cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h" 14cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkImage.h" 15cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkImageView.h" 16cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkUtil.h" 17cb93a386Sopenharmony_ci 18cb93a386Sopenharmony_ci#include "src/core/SkMipmap.h" 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci#include "include/gpu/vk/GrVkTypes.h" 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ci#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X) 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ciGrVkTextureRenderTarget::GrVkTextureRenderTarget( 25cb93a386Sopenharmony_ci GrVkGpu* gpu, 26cb93a386Sopenharmony_ci SkBudgeted budgeted, 27cb93a386Sopenharmony_ci SkISize dimensions, 28cb93a386Sopenharmony_ci sk_sp<GrVkImage> texture, 29cb93a386Sopenharmony_ci sk_sp<GrVkImage> colorAttachment, 30cb93a386Sopenharmony_ci sk_sp<GrVkImage> resolveAttachment, 31cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus) 32cb93a386Sopenharmony_ci : GrSurface(gpu, dimensions, texture->isProtected() ? GrProtected::kYes : GrProtected::kNo) 33cb93a386Sopenharmony_ci , GrVkTexture(gpu, dimensions, std::move(texture), mipmapStatus) 34cb93a386Sopenharmony_ci , GrVkRenderTarget(gpu, dimensions, std::move(colorAttachment), 35cb93a386Sopenharmony_ci std::move(resolveAttachment), CreateType::kFromTextureRT) { 36cb93a386Sopenharmony_ci#ifdef SKIA_OHOS 37cb93a386Sopenharmony_ci GrVkImage* image = textureImage(); 38cb93a386Sopenharmony_ci if (image && image->GetBudgeted() == SkBudgeted::kYes) { 39cb93a386Sopenharmony_ci this->registerWithCache(SkBudgeted::kNo); 40cb93a386Sopenharmony_ci } else { 41cb93a386Sopenharmony_ci this->registerWithCache(budgeted); 42cb93a386Sopenharmony_ci } 43cb93a386Sopenharmony_ci#else 44cb93a386Sopenharmony_ci this->registerWithCache(budgeted); 45cb93a386Sopenharmony_ci#endif 46cb93a386Sopenharmony_ci} 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_ciGrVkTextureRenderTarget::GrVkTextureRenderTarget( 49cb93a386Sopenharmony_ci GrVkGpu* gpu, 50cb93a386Sopenharmony_ci SkISize dimensions, 51cb93a386Sopenharmony_ci sk_sp<GrVkImage> texture, 52cb93a386Sopenharmony_ci sk_sp<GrVkImage> colorAttachment, 53cb93a386Sopenharmony_ci sk_sp<GrVkImage> resolveAttachment, 54cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus, 55cb93a386Sopenharmony_ci GrWrapCacheable cacheable) 56cb93a386Sopenharmony_ci : GrSurface(gpu, dimensions, texture->isProtected() ? GrProtected::kYes : GrProtected::kNo) 57cb93a386Sopenharmony_ci , GrVkTexture(gpu, dimensions, std::move(texture), mipmapStatus) 58cb93a386Sopenharmony_ci , GrVkRenderTarget(gpu, dimensions, std::move(colorAttachment), 59cb93a386Sopenharmony_ci std::move(resolveAttachment), CreateType::kFromTextureRT) { 60cb93a386Sopenharmony_ci this->registerWithCacheWrapped(cacheable); 61cb93a386Sopenharmony_ci} 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_cibool create_rt_attachments(GrVkGpu* gpu, SkISize dimensions, VkFormat format, int sampleCnt, 64cb93a386Sopenharmony_ci GrProtected isProtected, 65cb93a386Sopenharmony_ci sk_sp<GrVkImage> texture, 66cb93a386Sopenharmony_ci sk_sp<GrVkImage>* colorAttachment, 67cb93a386Sopenharmony_ci sk_sp<GrVkImage>* resolveAttachment) { 68cb93a386Sopenharmony_ci if (sampleCnt > 1) { 69cb93a386Sopenharmony_ci auto rp = gpu->getContext()->priv().resourceProvider(); 70cb93a386Sopenharmony_ci sk_sp<GrAttachment> msaaAttachment = rp->makeMSAAAttachment( 71cb93a386Sopenharmony_ci dimensions, GrBackendFormat::MakeVk(format), sampleCnt, isProtected, 72cb93a386Sopenharmony_ci GrMemoryless::kNo); 73cb93a386Sopenharmony_ci if (!msaaAttachment) { 74cb93a386Sopenharmony_ci return false; 75cb93a386Sopenharmony_ci } 76cb93a386Sopenharmony_ci *colorAttachment = sk_sp<GrVkImage>(static_cast<GrVkImage*>(msaaAttachment.release())); 77cb93a386Sopenharmony_ci *resolveAttachment = std::move(texture); 78cb93a386Sopenharmony_ci } else { 79cb93a386Sopenharmony_ci *colorAttachment = std::move(texture); 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci return true; 82cb93a386Sopenharmony_ci} 83cb93a386Sopenharmony_ci 84cb93a386Sopenharmony_cisk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeNewTextureRenderTarget( 85cb93a386Sopenharmony_ci GrVkGpu* gpu, 86cb93a386Sopenharmony_ci SkBudgeted budgeted, 87cb93a386Sopenharmony_ci SkISize dimensions, 88cb93a386Sopenharmony_ci VkFormat format, 89cb93a386Sopenharmony_ci uint32_t mipLevels, 90cb93a386Sopenharmony_ci int sampleCnt, 91cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus, 92cb93a386Sopenharmony_ci GrProtected isProtected) { 93cb93a386Sopenharmony_ci sk_sp<GrVkImage> texture = GrVkImage::MakeTexture(gpu, 94cb93a386Sopenharmony_ci dimensions, 95cb93a386Sopenharmony_ci format, 96cb93a386Sopenharmony_ci mipLevels, 97cb93a386Sopenharmony_ci GrRenderable::kYes, 98cb93a386Sopenharmony_ci /*numSamples=*/1, 99cb93a386Sopenharmony_ci budgeted, 100cb93a386Sopenharmony_ci isProtected); 101cb93a386Sopenharmony_ci if (!texture) { 102cb93a386Sopenharmony_ci return nullptr; 103cb93a386Sopenharmony_ci } 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_ci sk_sp<GrVkImage> colorAttachment; 106cb93a386Sopenharmony_ci sk_sp<GrVkImage> resolveAttachment; 107cb93a386Sopenharmony_ci if (!create_rt_attachments(gpu, dimensions, format, sampleCnt, isProtected, texture, 108cb93a386Sopenharmony_ci &colorAttachment, &resolveAttachment)) { 109cb93a386Sopenharmony_ci return nullptr; 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci SkASSERT(colorAttachment); 112cb93a386Sopenharmony_ci SkASSERT(sampleCnt == 1 || resolveAttachment); 113cb93a386Sopenharmony_ci return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget( 114cb93a386Sopenharmony_ci gpu, budgeted, dimensions, std::move(texture), std::move(colorAttachment), 115cb93a386Sopenharmony_ci std::move(resolveAttachment), mipmapStatus)); 116cb93a386Sopenharmony_ci} 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_cisk_sp<GrVkTextureRenderTarget> GrVkTextureRenderTarget::MakeWrappedTextureRenderTarget( 119cb93a386Sopenharmony_ci GrVkGpu* gpu, 120cb93a386Sopenharmony_ci SkISize dimensions, 121cb93a386Sopenharmony_ci int sampleCnt, 122cb93a386Sopenharmony_ci GrWrapOwnership wrapOwnership, 123cb93a386Sopenharmony_ci GrWrapCacheable cacheable, 124cb93a386Sopenharmony_ci const GrVkImageInfo& info, 125cb93a386Sopenharmony_ci sk_sp<GrBackendSurfaceMutableStateImpl> mutableState) { 126cb93a386Sopenharmony_ci // Adopted textures require both image and allocation because we're responsible for freeing 127cb93a386Sopenharmony_ci SkASSERT(VK_NULL_HANDLE != info.fImage && 128cb93a386Sopenharmony_ci (kBorrow_GrWrapOwnership == wrapOwnership || VK_NULL_HANDLE != info.fAlloc.fMemory)); 129cb93a386Sopenharmony_ci 130cb93a386Sopenharmony_ci GrAttachment::UsageFlags textureUsageFlags = GrAttachment::UsageFlags::kTexture; 131cb93a386Sopenharmony_ci if (info.fImageUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 132cb93a386Sopenharmony_ci textureUsageFlags |= GrAttachment::UsageFlags::kColorAttachment; 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci 135cb93a386Sopenharmony_ci sk_sp<GrVkImage> texture = GrVkImage::MakeWrapped(gpu, 136cb93a386Sopenharmony_ci dimensions, 137cb93a386Sopenharmony_ci info, 138cb93a386Sopenharmony_ci std::move(mutableState), 139cb93a386Sopenharmony_ci textureUsageFlags, 140cb93a386Sopenharmony_ci wrapOwnership, 141cb93a386Sopenharmony_ci cacheable); 142cb93a386Sopenharmony_ci if (!texture) { 143cb93a386Sopenharmony_ci return nullptr; 144cb93a386Sopenharmony_ci } 145cb93a386Sopenharmony_ci 146cb93a386Sopenharmony_ci sk_sp<GrVkImage> colorAttachment; 147cb93a386Sopenharmony_ci sk_sp<GrVkImage> resolveAttachment; 148cb93a386Sopenharmony_ci if (!create_rt_attachments(gpu, dimensions, info.fFormat, sampleCnt, info.fProtected, texture, 149cb93a386Sopenharmony_ci &colorAttachment, &resolveAttachment)) { 150cb93a386Sopenharmony_ci return nullptr; 151cb93a386Sopenharmony_ci } 152cb93a386Sopenharmony_ci SkASSERT(colorAttachment); 153cb93a386Sopenharmony_ci SkASSERT(sampleCnt == 1 || resolveAttachment); 154cb93a386Sopenharmony_ci 155cb93a386Sopenharmony_ci GrMipmapStatus mipmapStatus = 156cb93a386Sopenharmony_ci info.fLevelCount > 1 ? GrMipmapStatus::kDirty : GrMipmapStatus::kNotAllocated; 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci return sk_sp<GrVkTextureRenderTarget>(new GrVkTextureRenderTarget( 159cb93a386Sopenharmony_ci gpu, dimensions, std::move(texture), std::move(colorAttachment), 160cb93a386Sopenharmony_ci std::move(resolveAttachment), mipmapStatus, cacheable)); 161cb93a386Sopenharmony_ci} 162cb93a386Sopenharmony_ci 163cb93a386Sopenharmony_cisize_t GrVkTextureRenderTarget::onGpuMemorySize() const { 164cb93a386Sopenharmony_ci // The GrTexture[RenderTarget] is built up by a bunch of attachments each of which are their 165cb93a386Sopenharmony_ci // own GrGpuResource. Ideally the GrRenderTarget would not be a GrGpuResource and the GrTexture 166cb93a386Sopenharmony_ci // would just merge with the new GrSurface/Attachment world. Then we could just depend on each 167cb93a386Sopenharmony_ci // attachment to give its own size since we don't have GrGpuResources owning other 168cb93a386Sopenharmony_ci // GrGpuResources. Until we get to that point we need to live in some hybrid world. We will let 169cb93a386Sopenharmony_ci // the msaa and stencil attachments track their own size because they do get cached separately. 170cb93a386Sopenharmony_ci // For all GrTexture* based things we will continue to to use the GrTexture* to report size and 171cb93a386Sopenharmony_ci // the owned attachments will have no size and be uncached. 172cb93a386Sopenharmony_ci#ifdef SK_DEBUG 173cb93a386Sopenharmony_ci // The nonMSAA attachment (either color or resolve depending on numSamples should have size of 174cb93a386Sopenharmony_ci // zero since it is a texture attachment. 175cb93a386Sopenharmony_ci SkASSERT(this->nonMSAAAttachment()->gpuMemorySize() == 0); 176cb93a386Sopenharmony_ci if (this->numSamples() > 1) { 177cb93a386Sopenharmony_ci // Msaa attachment should have a valid size 178cb93a386Sopenharmony_ci SkASSERT(this->colorAttachment()->gpuMemorySize() == 179cb93a386Sopenharmony_ci GrSurface::ComputeSize(this->backendFormat(), this->dimensions(), 180cb93a386Sopenharmony_ci this->numSamples(), GrMipMapped::kNo)); 181cb93a386Sopenharmony_ci } 182cb93a386Sopenharmony_ci#endif 183cb93a386Sopenharmony_ci return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(), 184cb93a386Sopenharmony_ci 1 /*colorSamplesPerPixel*/, this->mipmapped()); 185cb93a386Sopenharmony_ci} 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_civoid GrVkTextureRenderTarget::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { 188cb93a386Sopenharmony_ci SkString resourceName = this->getResourceName(); 189cb93a386Sopenharmony_ci resourceName.append("/texture_renderbuffer"); 190cb93a386Sopenharmony_ci this->dumpMemoryStatisticsPriv(traceMemoryDump, resourceName, "RenderTarget", 191cb93a386Sopenharmony_ci this->gpuMemorySize()); 192cb93a386Sopenharmony_ci}