blob: 7381e635e3d2901eb9fc1b7d3f2a30abb7662f50 [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
11#include "GrVkResource.h"
jvanverth900bd4a2016-04-29 13:53:12 -070012
13#include "GrTypesPriv.h"
Greg Daniel52e16d92018-04-10 09:34:07 -040014#include "GrVkImageLayout.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050015#include "SkTypes.h"
16
jvanverthe50f3e72016-03-28 07:03:06 -070017#include "vk/GrVkDefines.h"
egdanielb2df0c22016-05-13 11:30:37 -070018#include "vk/GrVkTypes.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050019
20class GrVkGpu;
21
22class GrVkImage : SkNoncopyable {
egdanielb2df0c22016-05-13 11:30:37 -070023private:
24 class Resource;
25
Greg Daniel164a9f02016-02-22 09:56:40 -050026public:
Greg Daniel52e16d92018-04-10 09:34:07 -040027 GrVkImage(const GrVkImageInfo& info, sk_sp<GrVkImageLayout> layout,
28 GrBackendObjectOwnership ownership)
29 : fInfo(info)
Greg Danielecddbc02018-08-30 16:39:34 -040030 , fInitialQueueFamily(info.fCurrentQueueFamily)
Greg Daniel52e16d92018-04-10 09:34:07 -040031 , fLayout(std::move(layout))
32 , fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership) {
33 SkASSERT(fLayout->getImageLayout() == fInfo.fImageLayout);
Greg Daniel1591c382017-08-17 15:37:20 -040034 if (fIsBorrowed) {
jvanverth6b6ffc42016-06-13 14:28:07 -070035 fResource = new BorrowedResource(info.fImage, info.fAlloc, info.fImageTiling);
Greg Daniel164a9f02016-02-22 09:56:40 -050036 } else {
jvanverth6b6ffc42016-06-13 14:28:07 -070037 fResource = new Resource(info.fImage, info.fAlloc, info.fImageTiling);
Greg Daniel164a9f02016-02-22 09:56:40 -050038 }
Greg Daniel164a9f02016-02-22 09:56:40 -050039 }
Greg Daniel164a9f02016-02-22 09:56:40 -050040 virtual ~GrVkImage();
41
egdanielb2df0c22016-05-13 11:30:37 -070042 VkImage image() const { return fInfo.fImage; }
jvanverth1e305ba2016-06-01 09:39:15 -070043 const GrVkAlloc& alloc() const { return fInfo.fAlloc; }
egdanielb2df0c22016-05-13 11:30:37 -070044 VkFormat imageFormat() const { return fInfo.fFormat; }
egdaniel7ac5da82016-07-15 13:41:42 -070045 uint32_t mipLevels() const { return fInfo.fLevelCount; }
Greg Daniel164a9f02016-02-22 09:56:40 -050046 const Resource* resource() const { return fResource; }
47 bool isLinearTiled() const {
egdanielb2df0c22016-05-13 11:30:37 -070048 return SkToBool(VK_IMAGE_TILING_LINEAR == fInfo.fImageTiling);
Greg Daniel164a9f02016-02-22 09:56:40 -050049 }
Brian Osman13dddce2017-05-09 13:19:50 -040050 bool isBorrowed() const { return fIsBorrowed; }
Greg Daniel164a9f02016-02-22 09:56:40 -050051
Greg Daniel52e16d92018-04-10 09:34:07 -040052 sk_sp<GrVkImageLayout> grVkImageLayout() const { return fLayout; }
53
54 VkImageLayout currentLayout() const {
Greg Daniel52e16d92018-04-10 09:34:07 -040055 return fLayout->getImageLayout();
56 }
Greg Daniel164a9f02016-02-22 09:56:40 -050057
egdaniel58a8d922016-04-21 08:03:10 -070058 void setImageLayout(const GrVkGpu* gpu,
59 VkImageLayout newLayout,
Greg Daniel164a9f02016-02-22 09:56:40 -050060 VkAccessFlags dstAccessMask,
Greg Daniel164a9f02016-02-22 09:56:40 -050061 VkPipelineStageFlags dstStageMask,
Greg Danielecddbc02018-08-30 16:39:34 -040062 bool byRegion,
63 bool releaseFamilyQueue = false);
Greg Daniel164a9f02016-02-22 09:56:40 -050064
Greg Daniel31cc7312018-03-05 11:41:06 -050065 // This simply updates our tracking of the image layout and does not actually do any gpu work.
66 // This is only used for mip map generation where we are manually changing the layouts as we
67 // blit each layer, and then at the end need to update our tracking.
Greg Daniel52e16d92018-04-10 09:34:07 -040068 void updateImageLayout(VkImageLayout newLayout) {
69 fLayout->setImageLayout(newLayout);
Greg Daniel52e16d92018-04-10 09:34:07 -040070 }
Greg Daniel31cc7312018-03-05 11:41:06 -050071
Greg Daniel164a9f02016-02-22 09:56:40 -050072 struct ImageDesc {
73 VkImageType fImageType;
74 VkFormat fFormat;
75 uint32_t fWidth;
76 uint32_t fHeight;
77 uint32_t fLevels;
78 uint32_t fSamples;
79 VkImageTiling fImageTiling;
80 VkImageUsageFlags fUsageFlags;
81 VkFlags fMemProps;
82
83 ImageDesc()
84 : fImageType(VK_IMAGE_TYPE_2D)
85 , fFormat(VK_FORMAT_UNDEFINED)
86 , fWidth(0)
87 , fHeight(0)
88 , fLevels(1)
89 , fSamples(1)
90 , fImageTiling(VK_IMAGE_TILING_OPTIMAL)
91 , fUsageFlags(0)
92 , fMemProps(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {}
93 };
94
egdanielb2df0c22016-05-13 11:30:37 -070095 static bool InitImageInfo(const GrVkGpu* gpu, const ImageDesc& imageDesc, GrVkImageInfo*);
96 // Destroys the internal VkImage and VkDeviceMemory in the GrVkImageInfo
97 static void DestroyImageInfo(const GrVkGpu* gpu, GrVkImageInfo*);
Greg Daniel164a9f02016-02-22 09:56:40 -050098
Greg Danielcef213c2017-04-21 11:52:27 -040099 // These match the definitions in SkImage, for whence they came
100 typedef void* ReleaseCtx;
101 typedef void (*ReleaseProc)(ReleaseCtx);
102
Greg Daniel6a0176b2018-01-30 09:28:44 -0500103 void setResourceRelease(sk_sp<GrReleaseProcHelper> releaseHelper);
Greg Danielcef213c2017-04-21 11:52:27 -0400104
Greg Daniel6ddbafc2018-05-24 12:34:29 -0400105 // Helpers to use for setting the layout of the VkImage
Greg Danielf7828d02018-10-09 12:01:32 -0400106 static VkPipelineStageFlags LayoutToPipelineSrcStageFlags(const VkImageLayout layout);
Greg Daniel6ddbafc2018-05-24 12:34:29 -0400107 static VkAccessFlags LayoutToSrcAccessMask(const VkImageLayout layout);
108
Greg Daniel164a9f02016-02-22 09:56:40 -0500109protected:
Greg Daniel164a9f02016-02-22 09:56:40 -0500110 void releaseImage(const GrVkGpu* gpu);
111 void abandonImage();
112
jvanverth6b6ffc42016-06-13 14:28:07 -0700113 void setNewResource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling);
egdanielb2df0c22016-05-13 11:30:37 -0700114
Greg Daniel52e16d92018-04-10 09:34:07 -0400115 GrVkImageInfo fInfo;
Greg Danielecddbc02018-08-30 16:39:34 -0400116 uint32_t fInitialQueueFamily;
Greg Daniel52e16d92018-04-10 09:34:07 -0400117 sk_sp<GrVkImageLayout> fLayout;
Greg Daniel52e16d92018-04-10 09:34:07 -0400118 bool fIsBorrowed;
egdanielb2df0c22016-05-13 11:30:37 -0700119
120private:
egdanielb2df0c22016-05-13 11:30:37 -0700121 class Resource : public GrVkResource {
122 public:
123 Resource()
Greg Daniel6a0176b2018-01-30 09:28:44 -0500124 : fImage(VK_NULL_HANDLE) {
jvanverth1e305ba2016-06-01 09:39:15 -0700125 fAlloc.fMemory = VK_NULL_HANDLE;
126 fAlloc.fOffset = 0;
egdanielb2df0c22016-05-13 11:30:37 -0700127 }
128
jvanverth6b6ffc42016-06-13 14:28:07 -0700129 Resource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
Greg Daniel6a0176b2018-01-30 09:28:44 -0500130 : fImage(image)
Greg Danielcef213c2017-04-21 11:52:27 -0400131 , fAlloc(alloc)
132 , fImageTiling(tiling) {}
egdanielb2df0c22016-05-13 11:30:37 -0700133
Greg Danielcef213c2017-04-21 11:52:27 -0400134 ~Resource() override {
Greg Daniel6a0176b2018-01-30 09:28:44 -0500135 SkASSERT(!fReleaseHelper);
Greg Danielcef213c2017-04-21 11:52:27 -0400136 }
egdanielb2df0c22016-05-13 11:30:37 -0700137
jvanverth7ec92412016-07-06 09:24:57 -0700138#ifdef SK_TRACE_VK_RESOURCES
139 void dumpInfo() const override {
egdaniela95220d2016-07-21 11:50:37 -0700140 SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt());
jvanverth7ec92412016-07-06 09:24:57 -0700141 }
142#endif
Greg Daniel6a0176b2018-01-30 09:28:44 -0500143 void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) {
144 fReleaseHelper = std::move(releaseHelper);
Greg Danielcef213c2017-04-21 11:52:27 -0400145 }
146 protected:
Greg Daniel6a0176b2018-01-30 09:28:44 -0500147 mutable sk_sp<GrReleaseProcHelper> fReleaseHelper;
Greg Danielcef213c2017-04-21 11:52:27 -0400148
egdanielb2df0c22016-05-13 11:30:37 -0700149 private:
150 void freeGPUData(const GrVkGpu* gpu) const override;
Greg Danielcef213c2017-04-21 11:52:27 -0400151 void abandonGPUData() const override {
Greg Daniel6a0176b2018-01-30 09:28:44 -0500152 SkASSERT(!fReleaseHelper);
Greg Danielcef213c2017-04-21 11:52:27 -0400153 }
egdanielb2df0c22016-05-13 11:30:37 -0700154
jvanverth1e305ba2016-06-01 09:39:15 -0700155 VkImage fImage;
156 GrVkAlloc fAlloc;
jvanverth6b6ffc42016-06-13 14:28:07 -0700157 VkImageTiling fImageTiling;
egdanielb2df0c22016-05-13 11:30:37 -0700158
159 typedef GrVkResource INHERITED;
160 };
161
162 // for wrapped textures
163 class BorrowedResource : public Resource {
164 public:
jvanverth6b6ffc42016-06-13 14:28:07 -0700165 BorrowedResource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
166 : Resource(image, alloc, tiling) {
egdanielb2df0c22016-05-13 11:30:37 -0700167 }
168 private:
Greg Danielcef213c2017-04-21 11:52:27 -0400169 void invokeReleaseProc() const {
Greg Daniel6a0176b2018-01-30 09:28:44 -0500170 if (fReleaseHelper) {
171 // Depending on the ref count of fReleaseHelper this may or may not actually trigger
172 // the ReleaseProc to be called.
173 fReleaseHelper.reset();
Greg Danielcef213c2017-04-21 11:52:27 -0400174 }
175 }
176
egdanielb2df0c22016-05-13 11:30:37 -0700177 void freeGPUData(const GrVkGpu* gpu) const override;
Greg Danielcef213c2017-04-21 11:52:27 -0400178 void abandonGPUData() const override;
egdanielb2df0c22016-05-13 11:30:37 -0700179 };
180
Greg Daniel6a0176b2018-01-30 09:28:44 -0500181 Resource* fResource;
Greg Daniel164a9f02016-02-22 09:56:40 -0500182
egdanielb2df0c22016-05-13 11:30:37 -0700183 friend class GrVkRenderTarget;
Greg Daniel164a9f02016-02-22 09:56:40 -0500184};
185
186#endif