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