blob: 1df25eb8969a56b7ba9cbf05b249287cabfd4118 [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 Daniel4065d452018-11-16 15:43:41 -050013#include "GrBackendSurface.h"
Brian Salomon614c1a82018-12-19 15:42:06 -050014#include "GrTexture.h"
jvanverth900bd4a2016-04-29 13:53:12 -070015#include "GrTypesPriv.h"
Greg Daniel52e16d92018-04-10 09:34:07 -040016#include "GrVkImageLayout.h"
Brian Salomon614c1a82018-12-19 15:42:06 -050017#include "GrVkResource.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050018#include "SkTypes.h"
egdanielb2df0c22016-05-13 11:30:37 -070019#include "vk/GrVkTypes.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050020
21class GrVkGpu;
Brian Salomon614c1a82018-12-19 15:42:06 -050022class GrVkTexture;
Greg Daniel164a9f02016-02-22 09:56:40 -050023
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:
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500118 void releaseImage(GrVkGpu* gpu);
Greg Daniel164a9f02016-02-22 09:56:40 -0500119 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 }
Brian Salomon614c1a82018-12-19 15:42:06 -0500154
155 /**
156 * These are used to coordinate calling the idle proc between the GrVkTexture and the
157 * Resource. If the GrVkTexture becomes purgeable and if there are no command buffers
158 * referring to the Resource then it calls the proc. Otherwise, the Resource calls it
159 * when the last command buffer reference goes away and the GrVkTexture is purgeable.
160 */
161 void setIdleProc(GrVkTexture* owner, GrTexture::IdleProc, void* context) const;
162 void removeOwningTexture() const;
163
164 /**
165 * We track how many outstanding references this Resource has in command buffers and
166 * when the count reaches zero we call the idle proc.
167 */
168 void notifyAddedToCommandBuffer() const override;
169 void notifyRemovedFromCommandBuffer() const override;
170 bool isOwnedByCommandBuffer() const { return fNumCommandBufferOwners > 0; }
171
Greg Danielcef213c2017-04-21 11:52:27 -0400172 protected:
Greg Daniel6a0176b2018-01-30 09:28:44 -0500173 mutable sk_sp<GrReleaseProcHelper> fReleaseHelper;
Greg Danielcef213c2017-04-21 11:52:27 -0400174
egdanielb2df0c22016-05-13 11:30:37 -0700175 private:
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500176 void freeGPUData(GrVkGpu* gpu) const override;
Greg Danielcef213c2017-04-21 11:52:27 -0400177 void abandonGPUData() const override {
Greg Daniel6a0176b2018-01-30 09:28:44 -0500178 SkASSERT(!fReleaseHelper);
Greg Danielcef213c2017-04-21 11:52:27 -0400179 }
egdanielb2df0c22016-05-13 11:30:37 -0700180
jvanverth1e305ba2016-06-01 09:39:15 -0700181 VkImage fImage;
182 GrVkAlloc fAlloc;
jvanverth6b6ffc42016-06-13 14:28:07 -0700183 VkImageTiling fImageTiling;
Brian Salomon614c1a82018-12-19 15:42:06 -0500184 mutable int fNumCommandBufferOwners = 0;
185 mutable GrTexture::IdleProc* fIdleProc = nullptr;
186 mutable void* fIdleProcContext = nullptr;
187 mutable GrVkTexture* fOwningTexture = nullptr;
egdanielb2df0c22016-05-13 11:30:37 -0700188
189 typedef GrVkResource INHERITED;
190 };
191
192 // for wrapped textures
193 class BorrowedResource : public Resource {
194 public:
jvanverth6b6ffc42016-06-13 14:28:07 -0700195 BorrowedResource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
196 : Resource(image, alloc, tiling) {
egdanielb2df0c22016-05-13 11:30:37 -0700197 }
198 private:
Greg Danielcef213c2017-04-21 11:52:27 -0400199 void invokeReleaseProc() const {
Greg Daniel6a0176b2018-01-30 09:28:44 -0500200 if (fReleaseHelper) {
201 // Depending on the ref count of fReleaseHelper this may or may not actually trigger
202 // the ReleaseProc to be called.
203 fReleaseHelper.reset();
Greg Danielcef213c2017-04-21 11:52:27 -0400204 }
205 }
206
Ethan Nicholas8e265a72018-12-12 16:22:40 -0500207 void freeGPUData(GrVkGpu* gpu) const override;
Greg Danielcef213c2017-04-21 11:52:27 -0400208 void abandonGPUData() const override;
egdanielb2df0c22016-05-13 11:30:37 -0700209 };
210
Greg Daniel6a0176b2018-01-30 09:28:44 -0500211 Resource* fResource;
Greg Daniel164a9f02016-02-22 09:56:40 -0500212
egdanielb2df0c22016-05-13 11:30:37 -0700213 friend class GrVkRenderTarget;
Greg Daniel164a9f02016-02-22 09:56:40 -0500214};
215
216#endif