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/GrVkImage.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkGpu.h" 11cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkImageView.h" 12cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkMemory.h" 13cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkTexture.h" 14cb93a386Sopenharmony_ci#include "src/gpu/vk/GrVkUtil.h" 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X) 17cb93a386Sopenharmony_ciconstexpr uint32_t VKIMAGE_LIMIT_SIZE = 10000 * 10000; // Vk-Image Size need less than 10000*10000 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_cisk_sp<GrVkImage> GrVkImage::MakeStencil(GrVkGpu* gpu, 20cb93a386Sopenharmony_ci SkISize dimensions, 21cb93a386Sopenharmony_ci int sampleCnt, 22cb93a386Sopenharmony_ci VkFormat format) { 23cb93a386Sopenharmony_ci VkImageUsageFlags vkUsageFlags = 24cb93a386Sopenharmony_ci VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 25cb93a386Sopenharmony_ci return GrVkImage::Make(gpu, 26cb93a386Sopenharmony_ci dimensions, 27cb93a386Sopenharmony_ci UsageFlags::kStencilAttachment, 28cb93a386Sopenharmony_ci sampleCnt, 29cb93a386Sopenharmony_ci format, 30cb93a386Sopenharmony_ci /*mipLevels=*/1, 31cb93a386Sopenharmony_ci vkUsageFlags, 32cb93a386Sopenharmony_ci GrProtected::kNo, 33cb93a386Sopenharmony_ci GrMemoryless::kNo, 34cb93a386Sopenharmony_ci SkBudgeted::kYes); 35cb93a386Sopenharmony_ci} 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_cisk_sp<GrVkImage> GrVkImage::MakeMSAA(GrVkGpu* gpu, 38cb93a386Sopenharmony_ci SkISize dimensions, 39cb93a386Sopenharmony_ci int numSamples, 40cb93a386Sopenharmony_ci VkFormat format, 41cb93a386Sopenharmony_ci GrProtected isProtected, 42cb93a386Sopenharmony_ci GrMemoryless memoryless) { 43cb93a386Sopenharmony_ci SkASSERT(numSamples > 1); 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ci VkImageUsageFlags vkUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 46cb93a386Sopenharmony_ci if (memoryless == GrMemoryless::kYes) { 47cb93a386Sopenharmony_ci vkUsageFlags |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT; 48cb93a386Sopenharmony_ci } else { 49cb93a386Sopenharmony_ci vkUsageFlags |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; 50cb93a386Sopenharmony_ci } 51cb93a386Sopenharmony_ci return GrVkImage::Make(gpu, 52cb93a386Sopenharmony_ci dimensions, 53cb93a386Sopenharmony_ci UsageFlags::kColorAttachment, 54cb93a386Sopenharmony_ci numSamples, 55cb93a386Sopenharmony_ci format, 56cb93a386Sopenharmony_ci /*mipLevels=*/1, 57cb93a386Sopenharmony_ci vkUsageFlags, 58cb93a386Sopenharmony_ci isProtected, 59cb93a386Sopenharmony_ci memoryless, 60cb93a386Sopenharmony_ci SkBudgeted::kYes); 61cb93a386Sopenharmony_ci} 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_cisk_sp<GrVkImage> GrVkImage::MakeTexture(GrVkGpu* gpu, 64cb93a386Sopenharmony_ci SkISize dimensions, 65cb93a386Sopenharmony_ci VkFormat format, 66cb93a386Sopenharmony_ci uint32_t mipLevels, 67cb93a386Sopenharmony_ci GrRenderable renderable, 68cb93a386Sopenharmony_ci int numSamples, 69cb93a386Sopenharmony_ci SkBudgeted budgeted, 70cb93a386Sopenharmony_ci GrProtected isProtected) { 71cb93a386Sopenharmony_ci UsageFlags usageFlags = UsageFlags::kTexture; 72cb93a386Sopenharmony_ci VkImageUsageFlags vkUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 73cb93a386Sopenharmony_ci VK_IMAGE_USAGE_TRANSFER_DST_BIT; 74cb93a386Sopenharmony_ci if (renderable == GrRenderable::kYes) { 75cb93a386Sopenharmony_ci usageFlags |= UsageFlags::kColorAttachment; 76cb93a386Sopenharmony_ci vkUsageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 77cb93a386Sopenharmony_ci // We always make our render targets support being used as input attachments 78cb93a386Sopenharmony_ci vkUsageFlags |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; 79cb93a386Sopenharmony_ci } 80cb93a386Sopenharmony_ci 81cb93a386Sopenharmony_ci return GrVkImage::Make(gpu, 82cb93a386Sopenharmony_ci dimensions, 83cb93a386Sopenharmony_ci usageFlags, 84cb93a386Sopenharmony_ci numSamples, 85cb93a386Sopenharmony_ci format, 86cb93a386Sopenharmony_ci mipLevels, 87cb93a386Sopenharmony_ci vkUsageFlags, 88cb93a386Sopenharmony_ci isProtected, 89cb93a386Sopenharmony_ci GrMemoryless::kNo, 90cb93a386Sopenharmony_ci budgeted); 91cb93a386Sopenharmony_ci} 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_cistatic bool make_views(GrVkGpu* gpu, 94cb93a386Sopenharmony_ci const GrVkImageInfo& info, 95cb93a386Sopenharmony_ci GrAttachment::UsageFlags attachmentUsages, 96cb93a386Sopenharmony_ci sk_sp<const GrVkImageView>* framebufferView, 97cb93a386Sopenharmony_ci sk_sp<const GrVkImageView>* textureView) { 98cb93a386Sopenharmony_ci GrVkImageView::Type viewType; 99cb93a386Sopenharmony_ci if (attachmentUsages & GrAttachment::UsageFlags::kStencilAttachment) { 100cb93a386Sopenharmony_ci // If we have stencil usage then we shouldn't have any other usages 101cb93a386Sopenharmony_ci SkASSERT(attachmentUsages == GrAttachment::UsageFlags::kStencilAttachment); 102cb93a386Sopenharmony_ci viewType = GrVkImageView::kStencil_Type; 103cb93a386Sopenharmony_ci } else { 104cb93a386Sopenharmony_ci viewType = GrVkImageView::kColor_Type; 105cb93a386Sopenharmony_ci } 106cb93a386Sopenharmony_ci 107cb93a386Sopenharmony_ci if (SkToBool(attachmentUsages & GrAttachment::UsageFlags::kStencilAttachment) || 108cb93a386Sopenharmony_ci SkToBool(attachmentUsages & GrAttachment::UsageFlags::kColorAttachment)) { 109cb93a386Sopenharmony_ci // Attachments can only have a mip level of 1 110cb93a386Sopenharmony_ci *framebufferView = GrVkImageView::Make( 111cb93a386Sopenharmony_ci gpu, info.fImage, info.fFormat, viewType, 1, info.fYcbcrConversionInfo); 112cb93a386Sopenharmony_ci if (!*framebufferView) { 113cb93a386Sopenharmony_ci return false; 114cb93a386Sopenharmony_ci } 115cb93a386Sopenharmony_ci } 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ci if (attachmentUsages & GrAttachment::UsageFlags::kTexture) { 118cb93a386Sopenharmony_ci *textureView = GrVkImageView::Make(gpu, 119cb93a386Sopenharmony_ci info.fImage, 120cb93a386Sopenharmony_ci info.fFormat, 121cb93a386Sopenharmony_ci viewType, 122cb93a386Sopenharmony_ci info.fLevelCount, 123cb93a386Sopenharmony_ci info.fYcbcrConversionInfo); 124cb93a386Sopenharmony_ci if (!*textureView) { 125cb93a386Sopenharmony_ci return false; 126cb93a386Sopenharmony_ci } 127cb93a386Sopenharmony_ci } 128cb93a386Sopenharmony_ci return true; 129cb93a386Sopenharmony_ci} 130cb93a386Sopenharmony_ci 131cb93a386Sopenharmony_cisk_sp<GrVkImage> GrVkImage::Make(GrVkGpu* gpu, 132cb93a386Sopenharmony_ci SkISize dimensions, 133cb93a386Sopenharmony_ci UsageFlags attachmentUsages, 134cb93a386Sopenharmony_ci int sampleCnt, 135cb93a386Sopenharmony_ci VkFormat format, 136cb93a386Sopenharmony_ci uint32_t mipLevels, 137cb93a386Sopenharmony_ci VkImageUsageFlags vkUsageFlags, 138cb93a386Sopenharmony_ci GrProtected isProtected, 139cb93a386Sopenharmony_ci GrMemoryless memoryless, 140cb93a386Sopenharmony_ci SkBudgeted budgeted) { 141cb93a386Sopenharmony_ci GrVkImage::ImageDesc imageDesc; 142cb93a386Sopenharmony_ci imageDesc.fImageType = VK_IMAGE_TYPE_2D; 143cb93a386Sopenharmony_ci imageDesc.fFormat = format; 144cb93a386Sopenharmony_ci imageDesc.fWidth = dimensions.width(); 145cb93a386Sopenharmony_ci imageDesc.fHeight = dimensions.height(); 146cb93a386Sopenharmony_ci imageDesc.fLevels = mipLevels; 147cb93a386Sopenharmony_ci imageDesc.fSamples = sampleCnt; 148cb93a386Sopenharmony_ci imageDesc.fImageTiling = VK_IMAGE_TILING_OPTIMAL; 149cb93a386Sopenharmony_ci imageDesc.fUsageFlags = vkUsageFlags; 150cb93a386Sopenharmony_ci imageDesc.fIsProtected = isProtected; 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci GrVkImageInfo info; 153cb93a386Sopenharmony_ci if (!GrVkImage::InitImageInfo(gpu, imageDesc, &info)) { 154cb93a386Sopenharmony_ci return nullptr; 155cb93a386Sopenharmony_ci } 156cb93a386Sopenharmony_ci 157cb93a386Sopenharmony_ci sk_sp<const GrVkImageView> framebufferView; 158cb93a386Sopenharmony_ci sk_sp<const GrVkImageView> textureView; 159cb93a386Sopenharmony_ci if (!make_views(gpu, info, attachmentUsages, &framebufferView, &textureView)) { 160cb93a386Sopenharmony_ci GrVkImage::DestroyImageInfo(gpu, &info); 161cb93a386Sopenharmony_ci return nullptr; 162cb93a386Sopenharmony_ci } 163cb93a386Sopenharmony_ci 164cb93a386Sopenharmony_ci sk_sp<GrBackendSurfaceMutableStateImpl> mutableState( 165cb93a386Sopenharmony_ci new GrBackendSurfaceMutableStateImpl(info.fImageLayout, info.fCurrentQueueFamily)); 166cb93a386Sopenharmony_ci return sk_sp<GrVkImage>(new GrVkImage(gpu, 167cb93a386Sopenharmony_ci dimensions, 168cb93a386Sopenharmony_ci attachmentUsages, 169cb93a386Sopenharmony_ci info, 170cb93a386Sopenharmony_ci std::move(mutableState), 171cb93a386Sopenharmony_ci std::move(framebufferView), 172cb93a386Sopenharmony_ci std::move(textureView), 173cb93a386Sopenharmony_ci budgeted)); 174cb93a386Sopenharmony_ci} 175cb93a386Sopenharmony_ci 176cb93a386Sopenharmony_cisk_sp<GrVkImage> GrVkImage::MakeWrapped(GrVkGpu* gpu, 177cb93a386Sopenharmony_ci SkISize dimensions, 178cb93a386Sopenharmony_ci const GrVkImageInfo& info, 179cb93a386Sopenharmony_ci sk_sp<GrBackendSurfaceMutableStateImpl> mutableState, 180cb93a386Sopenharmony_ci UsageFlags attachmentUsages, 181cb93a386Sopenharmony_ci GrWrapOwnership ownership, 182cb93a386Sopenharmony_ci GrWrapCacheable cacheable, 183cb93a386Sopenharmony_ci bool forSecondaryCB) { 184cb93a386Sopenharmony_ci sk_sp<const GrVkImageView> framebufferView; 185cb93a386Sopenharmony_ci sk_sp<const GrVkImageView> textureView; 186cb93a386Sopenharmony_ci if (!forSecondaryCB) { 187cb93a386Sopenharmony_ci if (!make_views(gpu, info, attachmentUsages, &framebufferView, &textureView)) { 188cb93a386Sopenharmony_ci return nullptr; 189cb93a386Sopenharmony_ci } 190cb93a386Sopenharmony_ci } 191cb93a386Sopenharmony_ci 192cb93a386Sopenharmony_ci GrBackendObjectOwnership backendOwnership = kBorrow_GrWrapOwnership == ownership 193cb93a386Sopenharmony_ci ? GrBackendObjectOwnership::kBorrowed 194cb93a386Sopenharmony_ci : GrBackendObjectOwnership::kOwned; 195cb93a386Sopenharmony_ci 196cb93a386Sopenharmony_ci return sk_sp<GrVkImage>(new GrVkImage(gpu, 197cb93a386Sopenharmony_ci dimensions, 198cb93a386Sopenharmony_ci attachmentUsages, 199cb93a386Sopenharmony_ci info, 200cb93a386Sopenharmony_ci std::move(mutableState), 201cb93a386Sopenharmony_ci std::move(framebufferView), 202cb93a386Sopenharmony_ci std::move(textureView), 203cb93a386Sopenharmony_ci backendOwnership, 204cb93a386Sopenharmony_ci cacheable, 205cb93a386Sopenharmony_ci forSecondaryCB)); 206cb93a386Sopenharmony_ci} 207cb93a386Sopenharmony_ci 208cb93a386Sopenharmony_ci// OH ISSUE: Integrate Destroy and Free 209cb93a386Sopenharmony_civoid GrVkImage::DestroyAndFreeImageMemory(const GrVkGpu* gpu, const GrVkAlloc& alloc, const VkImage& image) 210cb93a386Sopenharmony_ci{ 211cb93a386Sopenharmony_ci VK_CALL(gpu, DestroyImage(gpu->device(), image, nullptr)); 212cb93a386Sopenharmony_ci GrVkMemory::FreeImageMemory(gpu, alloc); 213cb93a386Sopenharmony_ci} 214cb93a386Sopenharmony_ci 215cb93a386Sopenharmony_ciGrVkImage::GrVkImage(GrVkGpu* gpu, 216cb93a386Sopenharmony_ci SkISize dimensions, 217cb93a386Sopenharmony_ci UsageFlags supportedUsages, 218cb93a386Sopenharmony_ci const GrVkImageInfo& info, 219cb93a386Sopenharmony_ci sk_sp<GrBackendSurfaceMutableStateImpl> mutableState, 220cb93a386Sopenharmony_ci sk_sp<const GrVkImageView> framebufferView, 221cb93a386Sopenharmony_ci sk_sp<const GrVkImageView> textureView, 222cb93a386Sopenharmony_ci SkBudgeted budgeted) 223cb93a386Sopenharmony_ci : GrAttachment(gpu, 224cb93a386Sopenharmony_ci dimensions, 225cb93a386Sopenharmony_ci supportedUsages, 226cb93a386Sopenharmony_ci info.fSampleCount, 227cb93a386Sopenharmony_ci info.fLevelCount > 1 ? GrMipmapped::kYes : GrMipmapped::kNo, 228cb93a386Sopenharmony_ci info.fProtected, 229cb93a386Sopenharmony_ci info.fAlloc.fFlags & GrVkAlloc::kLazilyAllocated_Flag ? GrMemoryless::kYes 230cb93a386Sopenharmony_ci : GrMemoryless::kNo) 231cb93a386Sopenharmony_ci , fInfo(info) 232cb93a386Sopenharmony_ci , fInitialQueueFamily(info.fCurrentQueueFamily) 233cb93a386Sopenharmony_ci , fMutableState(std::move(mutableState)) 234cb93a386Sopenharmony_ci , fFramebufferView(std::move(framebufferView)) 235cb93a386Sopenharmony_ci , fTextureView(std::move(textureView)) 236cb93a386Sopenharmony_ci#ifdef SKIA_OHOS 237cb93a386Sopenharmony_ci , fBudgeted(budgeted) 238cb93a386Sopenharmony_ci#endif 239cb93a386Sopenharmony_ci , fIsBorrowed(false) { 240cb93a386Sopenharmony_ci this->init(gpu, false); 241cb93a386Sopenharmony_ci this->setRealAlloc(true); // OH ISSUE: set real alloc flag 242cb93a386Sopenharmony_ci this->setRealAllocSize(dimensions.height() * dimensions.width() * 4); // OH ISSUE: set real alloc size 243cb93a386Sopenharmony_ci this->registerWithCache(budgeted); 244cb93a386Sopenharmony_ci} 245cb93a386Sopenharmony_ci 246cb93a386Sopenharmony_ciGrVkImage::GrVkImage(GrVkGpu* gpu, 247cb93a386Sopenharmony_ci SkISize dimensions, 248cb93a386Sopenharmony_ci UsageFlags supportedUsages, 249cb93a386Sopenharmony_ci const GrVkImageInfo& info, 250cb93a386Sopenharmony_ci sk_sp<GrBackendSurfaceMutableStateImpl> mutableState, 251cb93a386Sopenharmony_ci sk_sp<const GrVkImageView> framebufferView, 252cb93a386Sopenharmony_ci sk_sp<const GrVkImageView> textureView, 253cb93a386Sopenharmony_ci GrBackendObjectOwnership ownership, 254cb93a386Sopenharmony_ci GrWrapCacheable cacheable, 255cb93a386Sopenharmony_ci bool forSecondaryCB) 256cb93a386Sopenharmony_ci : GrAttachment(gpu, 257cb93a386Sopenharmony_ci dimensions, 258cb93a386Sopenharmony_ci supportedUsages, 259cb93a386Sopenharmony_ci info.fSampleCount, 260cb93a386Sopenharmony_ci info.fLevelCount > 1 ? GrMipmapped::kYes : GrMipmapped::kNo, 261cb93a386Sopenharmony_ci info.fProtected) 262cb93a386Sopenharmony_ci , fInfo(info) 263cb93a386Sopenharmony_ci , fInitialQueueFamily(info.fCurrentQueueFamily) 264cb93a386Sopenharmony_ci , fMutableState(std::move(mutableState)) 265cb93a386Sopenharmony_ci , fFramebufferView(std::move(framebufferView)) 266cb93a386Sopenharmony_ci , fTextureView(std::move(textureView)) 267cb93a386Sopenharmony_ci , fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership) { 268cb93a386Sopenharmony_ci this->init(gpu, forSecondaryCB); 269cb93a386Sopenharmony_ci this->registerWithCacheWrapped(cacheable); 270cb93a386Sopenharmony_ci} 271cb93a386Sopenharmony_ci 272cb93a386Sopenharmony_civoid GrVkImage::init(GrVkGpu* gpu, bool forSecondaryCB) { 273cb93a386Sopenharmony_ci SkASSERT(fMutableState->getImageLayout() == fInfo.fImageLayout); 274cb93a386Sopenharmony_ci SkASSERT(fMutableState->getQueueFamilyIndex() == fInfo.fCurrentQueueFamily); 275cb93a386Sopenharmony_ci#ifdef SK_DEBUG 276cb93a386Sopenharmony_ci if (fInfo.fImageUsageFlags & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 277cb93a386Sopenharmony_ci SkASSERT(SkToBool(fInfo.fImageUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT)); 278cb93a386Sopenharmony_ci } else { 279cb93a386Sopenharmony_ci if (fInfo.fAlloc.fFlags & GrVkAlloc::kLazilyAllocated_Flag) { 280cb93a386Sopenharmony_ci SkASSERT(fInfo.fImageUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT); 281cb93a386Sopenharmony_ci SkASSERT(!SkToBool(fInfo.fImageUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) && 282cb93a386Sopenharmony_ci !SkToBool(fInfo.fImageUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT)); 283cb93a386Sopenharmony_ci } else { 284cb93a386Sopenharmony_ci SkASSERT(!SkToBool(fInfo.fImageUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT)); 285cb93a386Sopenharmony_ci SkASSERT(SkToBool(fInfo.fImageUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) && 286cb93a386Sopenharmony_ci SkToBool(fInfo.fImageUsageFlags & VK_IMAGE_USAGE_TRANSFER_SRC_BIT)); 287cb93a386Sopenharmony_ci } 288cb93a386Sopenharmony_ci } 289cb93a386Sopenharmony_ci // We can't transfer from the non graphics queue to the graphics queue since we can't 290cb93a386Sopenharmony_ci // release the image from the original queue without having that queue. This limits us in terms 291cb93a386Sopenharmony_ci // of the types of queue indices we can handle. 292cb93a386Sopenharmony_ci if (fInfo.fCurrentQueueFamily != VK_QUEUE_FAMILY_IGNORED && 293cb93a386Sopenharmony_ci fInfo.fCurrentQueueFamily != VK_QUEUE_FAMILY_EXTERNAL && 294cb93a386Sopenharmony_ci fInfo.fCurrentQueueFamily != VK_QUEUE_FAMILY_FOREIGN_EXT) { 295cb93a386Sopenharmony_ci if (fInfo.fSharingMode == VK_SHARING_MODE_EXCLUSIVE) { 296cb93a386Sopenharmony_ci if (fInfo.fCurrentQueueFamily != gpu->queueIndex()) { 297cb93a386Sopenharmony_ci SkASSERT(false); 298cb93a386Sopenharmony_ci } 299cb93a386Sopenharmony_ci } else { 300cb93a386Sopenharmony_ci SkASSERT(false); 301cb93a386Sopenharmony_ci } 302cb93a386Sopenharmony_ci } 303cb93a386Sopenharmony_ci#endif 304cb93a386Sopenharmony_ci if (forSecondaryCB) { 305cb93a386Sopenharmony_ci fResource = nullptr; 306cb93a386Sopenharmony_ci } else if (fIsBorrowed) { 307cb93a386Sopenharmony_ci fResource = new BorrowedResource(gpu, fInfo.fImage, fInfo.fAlloc, fInfo.fImageTiling); 308cb93a386Sopenharmony_ci } else { 309cb93a386Sopenharmony_ci SkASSERT(VK_NULL_HANDLE != fInfo.fAlloc.fMemory); 310cb93a386Sopenharmony_ci fResource = new Resource(gpu, fInfo.fImage, fInfo.fAlloc, fInfo.fImageTiling); 311cb93a386Sopenharmony_ci } 312cb93a386Sopenharmony_ci} 313cb93a386Sopenharmony_ci 314cb93a386Sopenharmony_ciVkPipelineStageFlags GrVkImage::LayoutToPipelineSrcStageFlags(const VkImageLayout layout) { 315cb93a386Sopenharmony_ci if (VK_IMAGE_LAYOUT_GENERAL == layout) { 316cb93a386Sopenharmony_ci return VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 317cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout || 318cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) { 319cb93a386Sopenharmony_ci return VK_PIPELINE_STAGE_TRANSFER_BIT; 320cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout) { 321cb93a386Sopenharmony_ci return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 322cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL == layout || 323cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL == layout) { 324cb93a386Sopenharmony_ci return VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; 325cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout) { 326cb93a386Sopenharmony_ci return VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; 327cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_PREINITIALIZED == layout) { 328cb93a386Sopenharmony_ci return VK_PIPELINE_STAGE_HOST_BIT; 329cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_PRESENT_SRC_KHR == layout) { 330cb93a386Sopenharmony_ci return VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 331cb93a386Sopenharmony_ci } 332cb93a386Sopenharmony_ci 333cb93a386Sopenharmony_ci SkASSERT(VK_IMAGE_LAYOUT_UNDEFINED == layout); 334cb93a386Sopenharmony_ci return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 335cb93a386Sopenharmony_ci} 336cb93a386Sopenharmony_ci 337cb93a386Sopenharmony_ciVkAccessFlags GrVkImage::LayoutToSrcAccessMask(const VkImageLayout layout) { 338cb93a386Sopenharmony_ci // Currently we assume we will never being doing any explict shader writes (this doesn't include 339cb93a386Sopenharmony_ci // color attachment or depth/stencil writes). So we will ignore the 340cb93a386Sopenharmony_ci // VK_MEMORY_OUTPUT_SHADER_WRITE_BIT. 341cb93a386Sopenharmony_ci 342cb93a386Sopenharmony_ci // We can only directly access the host memory if we are in preinitialized or general layout, 343cb93a386Sopenharmony_ci // and the image is linear. 344cb93a386Sopenharmony_ci // TODO: Add check for linear here so we are not always adding host to general, and we should 345cb93a386Sopenharmony_ci // only be in preinitialized if we are linear 346cb93a386Sopenharmony_ci VkAccessFlags flags = 0; 347cb93a386Sopenharmony_ci if (VK_IMAGE_LAYOUT_GENERAL == layout) { 348cb93a386Sopenharmony_ci flags = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 349cb93a386Sopenharmony_ci VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | 350cb93a386Sopenharmony_ci VK_ACCESS_TRANSFER_WRITE_BIT | 351cb93a386Sopenharmony_ci VK_ACCESS_HOST_WRITE_BIT; 352cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_PREINITIALIZED == layout) { 353cb93a386Sopenharmony_ci flags = VK_ACCESS_HOST_WRITE_BIT; 354cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL == layout) { 355cb93a386Sopenharmony_ci flags = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 356cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL == layout) { 357cb93a386Sopenharmony_ci flags = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 358cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL == layout) { 359cb93a386Sopenharmony_ci flags = VK_ACCESS_TRANSFER_WRITE_BIT; 360cb93a386Sopenharmony_ci } else if (VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == layout || 361cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == layout || 362cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_PRESENT_SRC_KHR == layout) { 363cb93a386Sopenharmony_ci // There are no writes that need to be made available 364cb93a386Sopenharmony_ci flags = 0; 365cb93a386Sopenharmony_ci } 366cb93a386Sopenharmony_ci return flags; 367cb93a386Sopenharmony_ci} 368cb93a386Sopenharmony_ci 369cb93a386Sopenharmony_ciVkImageAspectFlags vk_format_to_aspect_flags(VkFormat format) { 370cb93a386Sopenharmony_ci switch (format) { 371cb93a386Sopenharmony_ci case VK_FORMAT_S8_UINT: 372cb93a386Sopenharmony_ci return VK_IMAGE_ASPECT_STENCIL_BIT; 373cb93a386Sopenharmony_ci case VK_FORMAT_D24_UNORM_S8_UINT: // fallthrough 374cb93a386Sopenharmony_ci case VK_FORMAT_D32_SFLOAT_S8_UINT: 375cb93a386Sopenharmony_ci return VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT; 376cb93a386Sopenharmony_ci default: 377cb93a386Sopenharmony_ci return VK_IMAGE_ASPECT_COLOR_BIT; 378cb93a386Sopenharmony_ci } 379cb93a386Sopenharmony_ci} 380cb93a386Sopenharmony_ci 381cb93a386Sopenharmony_civoid GrVkImage::setImageLayoutAndQueueIndex(const GrVkGpu* gpu, 382cb93a386Sopenharmony_ci VkImageLayout newLayout, 383cb93a386Sopenharmony_ci VkAccessFlags dstAccessMask, 384cb93a386Sopenharmony_ci VkPipelineStageFlags dstStageMask, 385cb93a386Sopenharmony_ci bool byRegion, 386cb93a386Sopenharmony_ci uint32_t newQueueFamilyIndex) { 387cb93a386Sopenharmony_ci// Enable the following block to test new devices to confirm their lazy images stay at 0 memory use. 388cb93a386Sopenharmony_ci#if 0 389cb93a386Sopenharmony_ci if (fInfo.fAlloc.fFlags & GrVkAlloc::kLazilyAllocated_Flag) { 390cb93a386Sopenharmony_ci VkDeviceSize size; 391cb93a386Sopenharmony_ci VK_CALL(gpu, GetDeviceMemoryCommitment(gpu->device(), fInfo.fAlloc.fMemory, &size)); 392cb93a386Sopenharmony_ci 393cb93a386Sopenharmony_ci SkDebugf("Lazy Image. This: %p, image: %d, size: %d\n", this, fInfo.fImage, size); 394cb93a386Sopenharmony_ci } 395cb93a386Sopenharmony_ci#endif 396cb93a386Sopenharmony_ci SkASSERT(!gpu->isDeviceLost()); 397cb93a386Sopenharmony_ci SkASSERT(newLayout == this->currentLayout() || 398cb93a386Sopenharmony_ci (VK_IMAGE_LAYOUT_UNDEFINED != newLayout && 399cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_PREINITIALIZED != newLayout)); 400cb93a386Sopenharmony_ci VkImageLayout currentLayout = this->currentLayout(); 401cb93a386Sopenharmony_ci uint32_t currentQueueIndex = this->currentQueueFamilyIndex(); 402cb93a386Sopenharmony_ci 403cb93a386Sopenharmony_ci#ifdef SK_DEBUG 404cb93a386Sopenharmony_ci if (fInfo.fSharingMode == VK_SHARING_MODE_CONCURRENT) { 405cb93a386Sopenharmony_ci if (newQueueFamilyIndex == VK_QUEUE_FAMILY_IGNORED) { 406cb93a386Sopenharmony_ci SkASSERT(currentQueueIndex == VK_QUEUE_FAMILY_IGNORED || 407cb93a386Sopenharmony_ci currentQueueIndex == VK_QUEUE_FAMILY_EXTERNAL || 408cb93a386Sopenharmony_ci currentQueueIndex == VK_QUEUE_FAMILY_FOREIGN_EXT); 409cb93a386Sopenharmony_ci } else { 410cb93a386Sopenharmony_ci SkASSERT(newQueueFamilyIndex == VK_QUEUE_FAMILY_EXTERNAL || 411cb93a386Sopenharmony_ci newQueueFamilyIndex == VK_QUEUE_FAMILY_FOREIGN_EXT); 412cb93a386Sopenharmony_ci SkASSERT(currentQueueIndex == VK_QUEUE_FAMILY_IGNORED); 413cb93a386Sopenharmony_ci } 414cb93a386Sopenharmony_ci } else { 415cb93a386Sopenharmony_ci SkASSERT(fInfo.fSharingMode == VK_SHARING_MODE_EXCLUSIVE); 416cb93a386Sopenharmony_ci if (newQueueFamilyIndex == VK_QUEUE_FAMILY_IGNORED || 417cb93a386Sopenharmony_ci currentQueueIndex == gpu->queueIndex()) { 418cb93a386Sopenharmony_ci SkASSERT(currentQueueIndex == VK_QUEUE_FAMILY_IGNORED || 419cb93a386Sopenharmony_ci currentQueueIndex == VK_QUEUE_FAMILY_EXTERNAL || 420cb93a386Sopenharmony_ci currentQueueIndex == VK_QUEUE_FAMILY_FOREIGN_EXT || 421cb93a386Sopenharmony_ci currentQueueIndex == gpu->queueIndex()); 422cb93a386Sopenharmony_ci } else if (newQueueFamilyIndex == VK_QUEUE_FAMILY_EXTERNAL || 423cb93a386Sopenharmony_ci newQueueFamilyIndex == VK_QUEUE_FAMILY_FOREIGN_EXT) { 424cb93a386Sopenharmony_ci SkASSERT(currentQueueIndex == VK_QUEUE_FAMILY_IGNORED || 425cb93a386Sopenharmony_ci currentQueueIndex == gpu->queueIndex()); 426cb93a386Sopenharmony_ci } 427cb93a386Sopenharmony_ci } 428cb93a386Sopenharmony_ci#endif 429cb93a386Sopenharmony_ci 430cb93a386Sopenharmony_ci if (fInfo.fSharingMode == VK_SHARING_MODE_EXCLUSIVE) { 431cb93a386Sopenharmony_ci if (newQueueFamilyIndex == VK_QUEUE_FAMILY_IGNORED) { 432cb93a386Sopenharmony_ci newQueueFamilyIndex = gpu->queueIndex(); 433cb93a386Sopenharmony_ci } 434cb93a386Sopenharmony_ci if (currentQueueIndex == VK_QUEUE_FAMILY_IGNORED) { 435cb93a386Sopenharmony_ci currentQueueIndex = gpu->queueIndex(); 436cb93a386Sopenharmony_ci } 437cb93a386Sopenharmony_ci } 438cb93a386Sopenharmony_ci 439cb93a386Sopenharmony_ci // If the old and new layout are the same and the layout is a read only layout, there is no need 440cb93a386Sopenharmony_ci // to put in a barrier unless we also need to switch queues. 441cb93a386Sopenharmony_ci if (newLayout == currentLayout && currentQueueIndex == newQueueFamilyIndex && 442cb93a386Sopenharmony_ci (VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL == currentLayout || 443cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL == currentLayout || 444cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL == currentLayout)) { 445cb93a386Sopenharmony_ci return; 446cb93a386Sopenharmony_ci } 447cb93a386Sopenharmony_ci 448cb93a386Sopenharmony_ci VkAccessFlags srcAccessMask = GrVkImage::LayoutToSrcAccessMask(currentLayout); 449cb93a386Sopenharmony_ci VkPipelineStageFlags srcStageMask = GrVkImage::LayoutToPipelineSrcStageFlags(currentLayout); 450cb93a386Sopenharmony_ci 451cb93a386Sopenharmony_ci VkImageAspectFlags aspectFlags = vk_format_to_aspect_flags(fInfo.fFormat); 452cb93a386Sopenharmony_ci 453cb93a386Sopenharmony_ci VkImageMemoryBarrier imageMemoryBarrier = { 454cb93a386Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 455cb93a386Sopenharmony_ci nullptr, // pNext 456cb93a386Sopenharmony_ci srcAccessMask, // srcAccessMask 457cb93a386Sopenharmony_ci dstAccessMask, // dstAccessMask 458cb93a386Sopenharmony_ci currentLayout, // oldLayout 459cb93a386Sopenharmony_ci newLayout, // newLayout 460cb93a386Sopenharmony_ci currentQueueIndex, // srcQueueFamilyIndex 461cb93a386Sopenharmony_ci newQueueFamilyIndex, // dstQueueFamilyIndex 462cb93a386Sopenharmony_ci fInfo.fImage, // image 463cb93a386Sopenharmony_ci { aspectFlags, 0, fInfo.fLevelCount, 0, 1 } // subresourceRange 464cb93a386Sopenharmony_ci }; 465cb93a386Sopenharmony_ci SkASSERT(srcAccessMask == imageMemoryBarrier.srcAccessMask); 466cb93a386Sopenharmony_ci gpu->addImageMemoryBarrier(this->resource(), srcStageMask, dstStageMask, byRegion, 467cb93a386Sopenharmony_ci &imageMemoryBarrier); 468cb93a386Sopenharmony_ci 469cb93a386Sopenharmony_ci this->updateImageLayout(newLayout); 470cb93a386Sopenharmony_ci this->setQueueFamilyIndex(newQueueFamilyIndex); 471cb93a386Sopenharmony_ci} 472cb93a386Sopenharmony_ci 473cb93a386Sopenharmony_cibool GrVkImage::InitImageInfo(GrVkGpu* gpu, const ImageDesc& imageDesc, GrVkImageInfo* info) { 474cb93a386Sopenharmony_ci if (0 == imageDesc.fWidth || 0 == imageDesc.fHeight) { 475cb93a386Sopenharmony_ci return false; 476cb93a386Sopenharmony_ci } 477cb93a386Sopenharmony_ci if ((imageDesc.fIsProtected == GrProtected::kYes) && !gpu->vkCaps().supportsProtectedMemory()) { 478cb93a386Sopenharmony_ci return false; 479cb93a386Sopenharmony_ci } 480cb93a386Sopenharmony_ci 481cb93a386Sopenharmony_ci bool isLinear = VK_IMAGE_TILING_LINEAR == imageDesc.fImageTiling; 482cb93a386Sopenharmony_ci VkImageLayout initialLayout = isLinear ? VK_IMAGE_LAYOUT_PREINITIALIZED 483cb93a386Sopenharmony_ci : VK_IMAGE_LAYOUT_UNDEFINED; 484cb93a386Sopenharmony_ci 485cb93a386Sopenharmony_ci // Create Image 486cb93a386Sopenharmony_ci VkSampleCountFlagBits vkSamples; 487cb93a386Sopenharmony_ci if (!GrSampleCountToVkSampleCount(imageDesc.fSamples, &vkSamples)) { 488cb93a386Sopenharmony_ci return false; 489cb93a386Sopenharmony_ci } 490cb93a386Sopenharmony_ci 491cb93a386Sopenharmony_ci SkASSERT(VK_IMAGE_TILING_OPTIMAL == imageDesc.fImageTiling || 492cb93a386Sopenharmony_ci VK_SAMPLE_COUNT_1_BIT == vkSamples); 493cb93a386Sopenharmony_ci 494cb93a386Sopenharmony_ci VkImageCreateFlags createflags = 0; 495cb93a386Sopenharmony_ci if (imageDesc.fIsProtected == GrProtected::kYes || gpu->protectedContext()) { 496cb93a386Sopenharmony_ci createflags |= VK_IMAGE_CREATE_PROTECTED_BIT; 497cb93a386Sopenharmony_ci } 498cb93a386Sopenharmony_ci const VkImageCreateInfo imageCreateInfo = { 499cb93a386Sopenharmony_ci VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // sType 500cb93a386Sopenharmony_ci nullptr, // pNext 501cb93a386Sopenharmony_ci createflags, // VkImageCreateFlags 502cb93a386Sopenharmony_ci imageDesc.fImageType, // VkImageType 503cb93a386Sopenharmony_ci imageDesc.fFormat, // VkFormat 504cb93a386Sopenharmony_ci { imageDesc.fWidth, imageDesc.fHeight, 1 }, // VkExtent3D 505cb93a386Sopenharmony_ci imageDesc.fLevels, // mipLevels 506cb93a386Sopenharmony_ci 1, // arrayLayers 507cb93a386Sopenharmony_ci vkSamples, // samples 508cb93a386Sopenharmony_ci imageDesc.fImageTiling, // VkImageTiling 509cb93a386Sopenharmony_ci imageDesc.fUsageFlags, // VkImageUsageFlags 510cb93a386Sopenharmony_ci VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode 511cb93a386Sopenharmony_ci 0, // queueFamilyCount 512cb93a386Sopenharmony_ci nullptr, // pQueueFamilyIndices 513cb93a386Sopenharmony_ci initialLayout // initialLayout 514cb93a386Sopenharmony_ci }; 515cb93a386Sopenharmony_ci 516cb93a386Sopenharmony_ci VkImage image = VK_NULL_HANDLE; 517cb93a386Sopenharmony_ci VkResult result; 518cb93a386Sopenharmony_ci if (imageDesc.fWidth * imageDesc.fHeight > VKIMAGE_LIMIT_SIZE) { 519cb93a386Sopenharmony_ci SkDebugf("GrVkImage::InitImageInfoInner failed, image is too large, width:%u, height::%u", 520cb93a386Sopenharmony_ci imageDesc.fWidth, imageDesc.fHeight); 521cb93a386Sopenharmony_ci return false; 522cb93a386Sopenharmony_ci } 523cb93a386Sopenharmony_ci GR_VK_CALL_RESULT(gpu, result, CreateImage(gpu->device(), &imageCreateInfo, nullptr, &image)); 524cb93a386Sopenharmony_ci if (result != VK_SUCCESS) { 525cb93a386Sopenharmony_ci return false; 526cb93a386Sopenharmony_ci } 527cb93a386Sopenharmony_ci 528cb93a386Sopenharmony_ci GrMemoryless memoryless = imageDesc.fUsageFlags & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT 529cb93a386Sopenharmony_ci ? GrMemoryless::kYes 530cb93a386Sopenharmony_ci : GrMemoryless::kNo; 531cb93a386Sopenharmony_ci GrVkAlloc alloc; 532cb93a386Sopenharmony_ci if (!GrVkMemory::AllocAndBindImageMemory(gpu, image, memoryless, &alloc, 533cb93a386Sopenharmony_ci imageDesc.fWidth * imageDesc.fHeight * 4) || 534cb93a386Sopenharmony_ci (memoryless == GrMemoryless::kYes && 535cb93a386Sopenharmony_ci !SkToBool(alloc.fFlags & GrVkAlloc::kLazilyAllocated_Flag))) { 536cb93a386Sopenharmony_ci VK_CALL(gpu, DestroyImage(gpu->device(), image, nullptr)); 537cb93a386Sopenharmony_ci return false; 538cb93a386Sopenharmony_ci } 539cb93a386Sopenharmony_ci 540cb93a386Sopenharmony_ci info->fImage = image; 541cb93a386Sopenharmony_ci info->fAlloc = alloc; 542cb93a386Sopenharmony_ci info->fImageTiling = imageDesc.fImageTiling; 543cb93a386Sopenharmony_ci info->fImageLayout = initialLayout; 544cb93a386Sopenharmony_ci info->fFormat = imageDesc.fFormat; 545cb93a386Sopenharmony_ci info->fImageUsageFlags = imageDesc.fUsageFlags; 546cb93a386Sopenharmony_ci info->fSampleCount = imageDesc.fSamples; 547cb93a386Sopenharmony_ci info->fLevelCount = imageDesc.fLevels; 548cb93a386Sopenharmony_ci info->fCurrentQueueFamily = VK_QUEUE_FAMILY_IGNORED; 549cb93a386Sopenharmony_ci info->fProtected = 550cb93a386Sopenharmony_ci (createflags & VK_IMAGE_CREATE_PROTECTED_BIT) ? GrProtected::kYes : GrProtected::kNo; 551cb93a386Sopenharmony_ci info->fSharingMode = VK_SHARING_MODE_EXCLUSIVE; 552cb93a386Sopenharmony_ci return true; 553cb93a386Sopenharmony_ci} 554cb93a386Sopenharmony_ci 555cb93a386Sopenharmony_civoid GrVkImage::DestroyImageInfo(const GrVkGpu* gpu, GrVkImageInfo* info) { 556cb93a386Sopenharmony_ci DestroyAndFreeImageMemory(gpu, info->fAlloc, info->fImage); 557cb93a386Sopenharmony_ci} 558cb93a386Sopenharmony_ci 559cb93a386Sopenharmony_ciGrVkImage::~GrVkImage() { 560cb93a386Sopenharmony_ci // should have been released first 561cb93a386Sopenharmony_ci SkASSERT(!fResource); 562cb93a386Sopenharmony_ci SkASSERT(!fFramebufferView); 563cb93a386Sopenharmony_ci SkASSERT(!fTextureView); 564cb93a386Sopenharmony_ci} 565cb93a386Sopenharmony_ci 566cb93a386Sopenharmony_civoid GrVkImage::prepareForPresent(GrVkGpu* gpu) { 567cb93a386Sopenharmony_ci VkImageLayout layout = this->currentLayout(); 568cb93a386Sopenharmony_ci if (fInitialQueueFamily != VK_QUEUE_FAMILY_EXTERNAL && 569cb93a386Sopenharmony_ci fInitialQueueFamily != VK_QUEUE_FAMILY_FOREIGN_EXT) { 570cb93a386Sopenharmony_ci if (gpu->vkCaps().supportsSwapchain()) { 571cb93a386Sopenharmony_ci layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 572cb93a386Sopenharmony_ci } 573cb93a386Sopenharmony_ci } 574cb93a386Sopenharmony_ci this->setImageLayoutAndQueueIndex(gpu, layout, 0, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, false, 575cb93a386Sopenharmony_ci fInitialQueueFamily); 576cb93a386Sopenharmony_ci} 577cb93a386Sopenharmony_ci 578cb93a386Sopenharmony_civoid GrVkImage::prepareForExternal(GrVkGpu* gpu) { 579cb93a386Sopenharmony_ci this->setImageLayoutAndQueueIndex(gpu, this->currentLayout(), 0, 580cb93a386Sopenharmony_ci VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, false, 581cb93a386Sopenharmony_ci fInitialQueueFamily); 582cb93a386Sopenharmony_ci} 583cb93a386Sopenharmony_ci 584cb93a386Sopenharmony_civoid GrVkImage::releaseImage() { 585cb93a386Sopenharmony_ci if (fResource) { 586cb93a386Sopenharmony_ci fResource->unref(); 587cb93a386Sopenharmony_ci fResource = nullptr; 588cb93a386Sopenharmony_ci } 589cb93a386Sopenharmony_ci fFramebufferView.reset(); 590cb93a386Sopenharmony_ci fTextureView.reset(); 591cb93a386Sopenharmony_ci fCachedBlendingInputDescSet.reset(); 592cb93a386Sopenharmony_ci fCachedMSAALoadInputDescSet.reset(); 593cb93a386Sopenharmony_ci} 594cb93a386Sopenharmony_ci 595cb93a386Sopenharmony_civoid GrVkImage::onRelease() { 596cb93a386Sopenharmony_ci this->releaseImage(); 597cb93a386Sopenharmony_ci GrAttachment::onRelease(); 598cb93a386Sopenharmony_ci} 599cb93a386Sopenharmony_ci 600cb93a386Sopenharmony_civoid GrVkImage::onAbandon() { 601cb93a386Sopenharmony_ci this->releaseImage(); 602cb93a386Sopenharmony_ci GrAttachment::onAbandon(); 603cb93a386Sopenharmony_ci} 604cb93a386Sopenharmony_ci 605cb93a386Sopenharmony_civoid GrVkImage::setResourceRelease(sk_sp<GrRefCntedCallback> releaseHelper) { 606cb93a386Sopenharmony_ci SkASSERT(fResource); 607cb93a386Sopenharmony_ci // Forward the release proc on to GrVkImage::Resource 608cb93a386Sopenharmony_ci fResource->setRelease(std::move(releaseHelper)); 609cb93a386Sopenharmony_ci} 610cb93a386Sopenharmony_ci 611cb93a386Sopenharmony_civoid GrVkImage::Resource::freeGPUData() const { 612cb93a386Sopenharmony_ci this->invokeReleaseProc(); 613cb93a386Sopenharmony_ci 614cb93a386Sopenharmony_ci // OH ISSUE: asyn memory reclaimer 615cb93a386Sopenharmony_ci auto reclaimer = fGpu->memoryReclaimer(); 616cb93a386Sopenharmony_ci if (reclaimer && reclaimer->addMemoryToWaitQueue(fGpu, fAlloc, fImage)) { 617cb93a386Sopenharmony_ci return; 618cb93a386Sopenharmony_ci } 619cb93a386Sopenharmony_ci 620cb93a386Sopenharmony_ci DestroyAndFreeImageMemory(fGpu, fAlloc, fImage); 621cb93a386Sopenharmony_ci} 622cb93a386Sopenharmony_ci 623cb93a386Sopenharmony_civoid GrVkImage::BorrowedResource::freeGPUData() const { 624cb93a386Sopenharmony_ci this->invokeReleaseProc(); 625cb93a386Sopenharmony_ci} 626cb93a386Sopenharmony_ci 627cb93a386Sopenharmony_cistatic void write_input_desc_set(GrVkGpu* gpu, 628cb93a386Sopenharmony_ci VkImageView view, 629cb93a386Sopenharmony_ci VkImageLayout layout, 630cb93a386Sopenharmony_ci VkDescriptorSet descSet) { 631cb93a386Sopenharmony_ci VkDescriptorImageInfo imageInfo; 632cb93a386Sopenharmony_ci memset(&imageInfo, 0, sizeof(VkDescriptorImageInfo)); 633cb93a386Sopenharmony_ci imageInfo.sampler = VK_NULL_HANDLE; 634cb93a386Sopenharmony_ci imageInfo.imageView = view; 635cb93a386Sopenharmony_ci imageInfo.imageLayout = layout; 636cb93a386Sopenharmony_ci 637cb93a386Sopenharmony_ci VkWriteDescriptorSet writeInfo; 638cb93a386Sopenharmony_ci memset(&writeInfo, 0, sizeof(VkWriteDescriptorSet)); 639cb93a386Sopenharmony_ci writeInfo.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 640cb93a386Sopenharmony_ci writeInfo.pNext = nullptr; 641cb93a386Sopenharmony_ci writeInfo.dstSet = descSet; 642cb93a386Sopenharmony_ci writeInfo.dstBinding = GrVkUniformHandler::kInputBinding; 643cb93a386Sopenharmony_ci writeInfo.dstArrayElement = 0; 644cb93a386Sopenharmony_ci writeInfo.descriptorCount = 1; 645cb93a386Sopenharmony_ci writeInfo.descriptorType = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; 646cb93a386Sopenharmony_ci writeInfo.pImageInfo = &imageInfo; 647cb93a386Sopenharmony_ci writeInfo.pBufferInfo = nullptr; 648cb93a386Sopenharmony_ci writeInfo.pTexelBufferView = nullptr; 649cb93a386Sopenharmony_ci 650cb93a386Sopenharmony_ci GR_VK_CALL(gpu->vkInterface(), UpdateDescriptorSets(gpu->device(), 1, &writeInfo, 0, nullptr)); 651cb93a386Sopenharmony_ci} 652cb93a386Sopenharmony_ci 653cb93a386Sopenharmony_cigr_rp<const GrVkDescriptorSet> GrVkImage::inputDescSetForBlending(GrVkGpu* gpu) { 654cb93a386Sopenharmony_ci if (!this->supportsInputAttachmentUsage()) { 655cb93a386Sopenharmony_ci return nullptr; 656cb93a386Sopenharmony_ci } 657cb93a386Sopenharmony_ci if (fCachedBlendingInputDescSet) { 658cb93a386Sopenharmony_ci return fCachedBlendingInputDescSet; 659cb93a386Sopenharmony_ci } 660cb93a386Sopenharmony_ci 661cb93a386Sopenharmony_ci fCachedBlendingInputDescSet.reset(gpu->resourceProvider().getInputDescriptorSet()); 662cb93a386Sopenharmony_ci if (!fCachedBlendingInputDescSet) { 663cb93a386Sopenharmony_ci return nullptr; 664cb93a386Sopenharmony_ci } 665cb93a386Sopenharmony_ci 666cb93a386Sopenharmony_ci write_input_desc_set(gpu, 667cb93a386Sopenharmony_ci this->framebufferView()->imageView(), 668cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_GENERAL, 669cb93a386Sopenharmony_ci *fCachedBlendingInputDescSet->descriptorSet()); 670cb93a386Sopenharmony_ci 671cb93a386Sopenharmony_ci return fCachedBlendingInputDescSet; 672cb93a386Sopenharmony_ci} 673cb93a386Sopenharmony_ci 674cb93a386Sopenharmony_cigr_rp<const GrVkDescriptorSet> GrVkImage::inputDescSetForMSAALoad(GrVkGpu* gpu) { 675cb93a386Sopenharmony_ci if (!this->supportsInputAttachmentUsage()) { 676cb93a386Sopenharmony_ci return nullptr; 677cb93a386Sopenharmony_ci } 678cb93a386Sopenharmony_ci if (fCachedMSAALoadInputDescSet) { 679cb93a386Sopenharmony_ci return fCachedMSAALoadInputDescSet; 680cb93a386Sopenharmony_ci } 681cb93a386Sopenharmony_ci 682cb93a386Sopenharmony_ci fCachedMSAALoadInputDescSet.reset(gpu->resourceProvider().getInputDescriptorSet()); 683cb93a386Sopenharmony_ci if (!fCachedMSAALoadInputDescSet) { 684cb93a386Sopenharmony_ci return nullptr; 685cb93a386Sopenharmony_ci } 686cb93a386Sopenharmony_ci 687cb93a386Sopenharmony_ci write_input_desc_set(gpu, 688cb93a386Sopenharmony_ci this->framebufferView()->imageView(), 689cb93a386Sopenharmony_ci VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, 690cb93a386Sopenharmony_ci *fCachedMSAALoadInputDescSet->descriptorSet()); 691cb93a386Sopenharmony_ci 692cb93a386Sopenharmony_ci return fCachedMSAALoadInputDescSet; 693cb93a386Sopenharmony_ci} 694cb93a386Sopenharmony_ci 695cb93a386Sopenharmony_ciGrVkGpu* GrVkImage::getVkGpu() const { 696cb93a386Sopenharmony_ci SkASSERT(!this->wasDestroyed()); 697cb93a386Sopenharmony_ci return static_cast<GrVkGpu*>(this->getGpu()); 698cb93a386Sopenharmony_ci} 699cb93a386Sopenharmony_ci 700cb93a386Sopenharmony_cisize_t GrVkImage::onGpuMemorySize() const 701cb93a386Sopenharmony_ci{ 702cb93a386Sopenharmony_ci if (supportedUsages() & UsageFlags::kTexture) { 703cb93a386Sopenharmony_ci return GrSurface::ComputeSize(this->backendFormat(), this->dimensions(), 1, this->mipmapped()); 704cb93a386Sopenharmony_ci } else { 705cb93a386Sopenharmony_ci return GrAttachment::onGpuMemorySize(); 706cb93a386Sopenharmony_ci } 707cb93a386Sopenharmony_ci} 708cb93a386Sopenharmony_ci 709cb93a386Sopenharmony_ci#if GR_TEST_UTILS 710cb93a386Sopenharmony_civoid GrVkImage::setCurrentQueueFamilyToGraphicsQueue(GrVkGpu* gpu) { 711cb93a386Sopenharmony_ci fMutableState->setQueueFamilyIndex(gpu->queueIndex()); 712cb93a386Sopenharmony_ci} 713cb93a386Sopenharmony_ci#endif 714cb93a386Sopenharmony_ci 715