blob: 44c8ce2ce97afa259ed8b2558b42b58326aa0333 [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrVkImage_DEFINED
9#define GrVkImage_DEFINED
10
Greg Daniel54bfb182018-11-20 17:12:36 -050011#include "GrVkVulkan.h"
12
Greg Daniel164a9f02016-02-22 09:56:40 -050013#include "GrVkResource.h"
jvanverth900bd4a2016-04-29 13:53:12 -070014
Greg Daniel4065d452018-11-16 15:43:41 -050015#include "GrBackendSurface.h"
jvanverth900bd4a2016-04-29 13:53:12 -070016#include "GrTypesPriv.h"
Greg Daniel52e16d92018-04-10 09:34:07 -040017#include "GrVkImageLayout.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050018#include "SkTypes.h"
19
egdanielb2df0c22016-05-13 11:30:37 -070020#include "vk/GrVkTypes.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050021
22class GrVkGpu;
23
24class GrVkImage : SkNoncopyable {
egdanielb2df0c22016-05-13 11:30:37 -070025private:
26 class Resource;
27
Greg Daniel164a9f02016-02-22 09:56:40 -050028public:
Greg Daniel52e16d92018-04-10 09:34:07 -040029 GrVkImage(const GrVkImageInfo& info, sk_sp<GrVkImageLayout> layout,
30 GrBackendObjectOwnership ownership)
31 : fInfo(info)
Greg Danielecddbc02018-08-30 16:39:34 -040032 , fInitialQueueFamily(info.fCurrentQueueFamily)
Greg Daniel52e16d92018-04-10 09:34:07 -040033 , fLayout(std::move(layout))
34 , fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership) {
35 SkASSERT(fLayout->getImageLayout() == fInfo.fImageLayout);
Greg Daniel1591c382017-08-17 15:37:20 -040036 if (fIsBorrowed) {
jvanverth6b6ffc42016-06-13 14:28:07 -070037 fResource = new BorrowedResource(info.fImage, info.fAlloc, info.fImageTiling);
Greg Daniel164a9f02016-02-22 09:56:40 -050038 } else {
jvanverth6b6ffc42016-06-13 14:28:07 -070039 fResource = new Resource(info.fImage, info.fAlloc, info.fImageTiling);
Greg Daniel164a9f02016-02-22 09:56:40 -050040 }
Greg Daniel164a9f02016-02-22 09:56:40 -050041 }
Greg Daniel164a9f02016-02-22 09:56:40 -050042 virtual ~GrVkImage();
43
egdanielb2df0c22016-05-13 11:30:37 -070044 VkImage image() const { return fInfo.fImage; }
jvanverth1e305ba2016-06-01 09:39:15 -070045 const GrVkAlloc& alloc() const { return fInfo.fAlloc; }
egdanielb2df0c22016-05-13 11:30:37 -070046 VkFormat imageFormat() const { return fInfo.fFormat; }
Greg Daniel4065d452018-11-16 15:43:41 -050047 GrBackendFormat getBackendFormat() const {
48 return GrBackendFormat::MakeVk(this->imageFormat());
49 }
egdaniel7ac5da82016-07-15 13:41:42 -070050 uint32_t mipLevels() const { return fInfo.fLevelCount; }
Greg Daniel9a51a862018-11-30 10:18:14 -050051 const GrVkYcbcrConversionInfo& ycbcrConversionInfo() const {
52 return fInfo.fYcbcrConversionInfo;
53 }
Greg Daniel164a9f02016-02-22 09:56:40 -050054 const Resource* resource() const { return fResource; }
55 bool isLinearTiled() const {
egdanielb2df0c22016-05-13 11:30:37 -070056 return SkToBool(VK_IMAGE_TILING_LINEAR == fInfo.fImageTiling);
Greg Daniel164a9f02016-02-22 09:56:40 -050057 }
Brian Osman13dddce2017-05-09 13:19:50 -040058 bool isBorrowed() const { return fIsBorrowed; }
Greg Daniel164a9f02016-02-22 09:56:40 -050059
Greg Daniel52e16d92018-04-10 09:34:07 -040060 sk_sp<GrVkImageLayout> grVkImageLayout() const { return fLayout; }
61
62 VkImageLayout currentLayout() const {
Greg Daniel52e16d92018-04-10 09:34:07 -040063 return fLayout->getImageLayout();
64 }
Greg Daniel164a9f02016-02-22 09:56:40 -050065
egdaniel58a8d922016-04-21 08:03:10 -070066 void setImageLayout(const GrVkGpu* gpu,
67 VkImageLayout newLayout,
Greg Daniel164a9f02016-02-22 09:56:40 -050068 VkAccessFlags dstAccessMask,
Greg Daniel164a9f02016-02-22 09:56:40 -050069 VkPipelineStageFlags dstStageMask,
Greg Danielecddbc02018-08-30 16:39:34 -040070 bool byRegion,
71 bool releaseFamilyQueue = false);
Greg Daniel164a9f02016-02-22 09:56:40 -050072
Greg Daniel31cc7312018-03-05 11:41:06 -050073 // This simply updates our tracking of the image layout and does not actually do any gpu work.
74 // This is only used for mip map generation where we are manually changing the layouts as we
75 // blit each layer, and then at the end need to update our tracking.
Greg Daniel52e16d92018-04-10 09:34:07 -040076 void updateImageLayout(VkImageLayout newLayout) {
77 fLayout->setImageLayout(newLayout);
Greg Daniel52e16d92018-04-10 09:34:07 -040078 }
Greg Daniel31cc7312018-03-05 11:41:06 -050079
Greg Daniel164a9f02016-02-22 09:56:40 -050080 struct ImageDesc {
81 VkImageType fImageType;
82 VkFormat fFormat;
83 uint32_t fWidth;
84 uint32_t fHeight;
85 uint32_t fLevels;
86 uint32_t fSamples;
87 VkImageTiling fImageTiling;
88 VkImageUsageFlags fUsageFlags;
89 VkFlags fMemProps;
90
91 ImageDesc()
92 : fImageType(VK_IMAGE_TYPE_2D)
93 , fFormat(VK_FORMAT_UNDEFINED)
94 , fWidth(0)
95 , fHeight(0)
96 , fLevels(1)
97 , fSamples(1)
98 , fImageTiling(VK_IMAGE_TILING_OPTIMAL)
99 , fUsageFlags(0)
100 , fMemProps(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {}
101 };
102
egdanielb2df0c22016-05-13 11:30:37 -0700103 static bool InitImageInfo(const GrVkGpu* gpu, const ImageDesc& imageDesc, GrVkImageInfo*);
104 // Destroys the internal VkImage and VkDeviceMemory in the GrVkImageInfo
105 static void DestroyImageInfo(const GrVkGpu* gpu, GrVkImageInfo*);
Greg Daniel164a9f02016-02-22 09:56:40 -0500106
Greg Danielcef213c2017-04-21 11:52:27 -0400107 // These match the definitions in SkImage, for whence they came
108 typedef void* ReleaseCtx;
109 typedef void (*ReleaseProc)(ReleaseCtx);
110
Greg Daniel6a0176b2018-01-30 09:28:44 -0500111 void setResourceRelease(sk_sp<GrReleaseProcHelper> releaseHelper);
Greg Danielcef213c2017-04-21 11:52:27 -0400112
Greg Daniel6ddbafc2018-05-24 12:34:29 -0400113 // Helpers to use for setting the layout of the VkImage
Greg Danielf7828d02018-10-09 12:01:32 -0400114 static VkPipelineStageFlags LayoutToPipelineSrcStageFlags(const VkImageLayout layout);
Greg Daniel6ddbafc2018-05-24 12:34:29 -0400115 static VkAccessFlags LayoutToSrcAccessMask(const VkImageLayout layout);
116
Greg Daniel164a9f02016-02-22 09:56:40 -0500117protected:
Greg Daniel164a9f02016-02-22 09:56:40 -0500118 void releaseImage(const GrVkGpu* gpu);
119 void abandonImage();
120
jvanverth6b6ffc42016-06-13 14:28:07 -0700121 void setNewResource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling);
egdanielb2df0c22016-05-13 11:30:37 -0700122
Greg Daniel52e16d92018-04-10 09:34:07 -0400123 GrVkImageInfo fInfo;
Greg Danielecddbc02018-08-30 16:39:34 -0400124 uint32_t fInitialQueueFamily;
Greg Daniel52e16d92018-04-10 09:34:07 -0400125 sk_sp<GrVkImageLayout> fLayout;
Greg Daniel52e16d92018-04-10 09:34:07 -0400126 bool fIsBorrowed;
egdanielb2df0c22016-05-13 11:30:37 -0700127
128private:
egdanielb2df0c22016-05-13 11:30:37 -0700129 class Resource : public GrVkResource {
130 public:
131 Resource()
Greg Daniel6a0176b2018-01-30 09:28:44 -0500132 : fImage(VK_NULL_HANDLE) {
jvanverth1e305ba2016-06-01 09:39:15 -0700133 fAlloc.fMemory = VK_NULL_HANDLE;
134 fAlloc.fOffset = 0;
egdanielb2df0c22016-05-13 11:30:37 -0700135 }
136
jvanverth6b6ffc42016-06-13 14:28:07 -0700137 Resource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
Greg Daniel6a0176b2018-01-30 09:28:44 -0500138 : fImage(image)
Greg Danielcef213c2017-04-21 11:52:27 -0400139 , fAlloc(alloc)
140 , fImageTiling(tiling) {}
egdanielb2df0c22016-05-13 11:30:37 -0700141
Greg Danielcef213c2017-04-21 11:52:27 -0400142 ~Resource() override {
Greg Daniel6a0176b2018-01-30 09:28:44 -0500143 SkASSERT(!fReleaseHelper);
Greg Danielcef213c2017-04-21 11:52:27 -0400144 }
egdanielb2df0c22016-05-13 11:30:37 -0700145
jvanverth7ec92412016-07-06 09:24:57 -0700146#ifdef SK_TRACE_VK_RESOURCES
147 void dumpInfo() const override {
egdaniela95220d2016-07-21 11:50:37 -0700148 SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt());
jvanverth7ec92412016-07-06 09:24:57 -0700149 }
150#endif
Greg Daniel6a0176b2018-01-30 09:28:44 -0500151 void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) {
152 fReleaseHelper = std::move(releaseHelper);
Greg Danielcef213c2017-04-21 11:52:27 -0400153 }
154 protected:
Greg Daniel6a0176b2018-01-30 09:28:44 -0500155 mutable sk_sp<GrReleaseProcHelper> fReleaseHelper;
Greg Danielcef213c2017-04-21 11:52:27 -0400156
egdanielb2df0c22016-05-13 11:30:37 -0700157 private:
158 void freeGPUData(const GrVkGpu* gpu) const override;
Greg Danielcef213c2017-04-21 11:52:27 -0400159 void abandonGPUData() const override {
Greg Daniel6a0176b2018-01-30 09:28:44 -0500160 SkASSERT(!fReleaseHelper);
Greg Danielcef213c2017-04-21 11:52:27 -0400161 }
egdanielb2df0c22016-05-13 11:30:37 -0700162
jvanverth1e305ba2016-06-01 09:39:15 -0700163 VkImage fImage;
164 GrVkAlloc fAlloc;
jvanverth6b6ffc42016-06-13 14:28:07 -0700165 VkImageTiling fImageTiling;
egdanielb2df0c22016-05-13 11:30:37 -0700166
167 typedef GrVkResource INHERITED;
168 };
169
170 // for wrapped textures
171 class BorrowedResource : public Resource {
172 public:
jvanverth6b6ffc42016-06-13 14:28:07 -0700173 BorrowedResource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
174 : Resource(image, alloc, tiling) {
egdanielb2df0c22016-05-13 11:30:37 -0700175 }
176 private:
Greg Danielcef213c2017-04-21 11:52:27 -0400177 void invokeReleaseProc() const {
Greg Daniel6a0176b2018-01-30 09:28:44 -0500178 if (fReleaseHelper) {
179 // Depending on the ref count of fReleaseHelper this may or may not actually trigger
180 // the ReleaseProc to be called.
181 fReleaseHelper.reset();
Greg Danielcef213c2017-04-21 11:52:27 -0400182 }
183 }
184
egdanielb2df0c22016-05-13 11:30:37 -0700185 void freeGPUData(const GrVkGpu* gpu) const override;
Greg Danielcef213c2017-04-21 11:52:27 -0400186 void abandonGPUData() const override;
egdanielb2df0c22016-05-13 11:30:37 -0700187 };
188
Greg Daniel6a0176b2018-01-30 09:28:44 -0500189 Resource* fResource;
Greg Daniel164a9f02016-02-22 09:56:40 -0500190
egdanielb2df0c22016-05-13 11:30:37 -0700191 friend class GrVkRenderTarget;
Greg Daniel164a9f02016-02-22 09:56:40 -0500192};
193
194#endif