blob: 2d6a2203c55fc8c33c8b4ceb594fe35b38a902f4 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkTypes.h"
12#include "include/gpu/GrBackendSurface.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/gpu/vk/GrVkTypes.h"
14#include "include/private/GrTypesPriv.h"
Greg Daniel6c6caf42020-05-29 12:11:05 -040015#include "include/private/GrVkTypesPriv.h"
16#include "src/gpu/GrBackendSurfaceMutableStateImpl.h"
Jim Van Verth3e192162020-03-10 16:23:16 -040017#include "src/gpu/GrManagedResource.h"
Greg Daniel456f9b52020-03-05 19:14:18 +000018#include "src/gpu/GrTexture.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050019
20class GrVkGpu;
Brian Salomon614c1a82018-12-19 15:42:06 -050021class GrVkTexture;
Greg Daniel164a9f02016-02-22 09:56:40 -050022
23class GrVkImage : SkNoncopyable {
egdanielb2df0c22016-05-13 11:30:37 -070024private:
25 class Resource;
26
Greg Daniel164a9f02016-02-22 09:56:40 -050027public:
Greg Daniel6c6caf42020-05-29 12:11:05 -040028 GrVkImage(const GrVkGpu* gpu,
29 const GrVkImageInfo& info,
30 sk_sp<GrBackendSurfaceMutableStateImpl> mutableState,
31 GrBackendObjectOwnership ownership,
Greg Danielaa9d99f2020-06-02 11:10:41 -040032 bool forSecondaryCB = false);
33
Greg Daniel164a9f02016-02-22 09:56:40 -050034 virtual ~GrVkImage();
35
Greg Danielb46add82019-01-02 14:51:29 -050036 VkImage image() const {
37 // Should only be called when we have a real fResource object, i.e. never when being used as
38 // a RT in an external secondary command buffer.
39 SkASSERT(fResource);
40 return fInfo.fImage;
41 }
42 const GrVkAlloc& alloc() const {
43 // Should only be called when we have a real fResource object, i.e. never when being used as
44 // a RT in an external secondary command buffer.
45 SkASSERT(fResource);
46 return fInfo.fAlloc;
47 }
egdanielb2df0c22016-05-13 11:30:37 -070048 VkFormat imageFormat() const { return fInfo.fFormat; }
Greg Daniel4065d452018-11-16 15:43:41 -050049 GrBackendFormat getBackendFormat() const {
Greg Daniel89df7842019-02-21 12:40:21 -050050 if (fResource && this->ycbcrConversionInfo().isValid()) {
Sergey Ulanov2739fd22019-08-11 22:46:33 -070051 SkASSERT(this->imageFormat() == this->ycbcrConversionInfo().fFormat);
Greg Daniel89df7842019-02-21 12:40:21 -050052 return GrBackendFormat::MakeVk(this->ycbcrConversionInfo());
53 }
54 SkASSERT(this->imageFormat() != VK_FORMAT_UNDEFINED);
Greg Daniel4065d452018-11-16 15:43:41 -050055 return GrBackendFormat::MakeVk(this->imageFormat());
56 }
egdaniel7ac5da82016-07-15 13:41:42 -070057 uint32_t mipLevels() const { return fInfo.fLevelCount; }
Greg Daniel9a51a862018-11-30 10:18:14 -050058 const GrVkYcbcrConversionInfo& ycbcrConversionInfo() const {
Greg Danielb46add82019-01-02 14:51:29 -050059 // Should only be called when we have a real fResource object, i.e. never when being used as
60 // a RT in an external secondary command buffer.
61 SkASSERT(fResource);
Greg Daniel9a51a862018-11-30 10:18:14 -050062 return fInfo.fYcbcrConversionInfo;
63 }
Greg Danielbf7acb22020-08-21 13:32:51 -040064 bool supportsInputAttachmentUsage() const {
65 return fInfo.fImageUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
66 }
Greg Danielb46add82019-01-02 14:51:29 -050067 const Resource* resource() const {
68 SkASSERT(fResource);
69 return fResource;
70 }
Greg Daniel164a9f02016-02-22 09:56:40 -050071 bool isLinearTiled() const {
Greg Danielb46add82019-01-02 14:51:29 -050072 // Should only be called when we have a real fResource object, i.e. never when being used as
73 // a RT in an external secondary command buffer.
74 SkASSERT(fResource);
egdanielb2df0c22016-05-13 11:30:37 -070075 return SkToBool(VK_IMAGE_TILING_LINEAR == fInfo.fImageTiling);
Greg Daniel164a9f02016-02-22 09:56:40 -050076 }
Brian Osman13dddce2017-05-09 13:19:50 -040077 bool isBorrowed() const { return fIsBorrowed; }
Greg Daniel164a9f02016-02-22 09:56:40 -050078
Greg Daniel6c6caf42020-05-29 12:11:05 -040079 sk_sp<GrBackendSurfaceMutableStateImpl> getMutableState() const { return fMutableState; }
Greg Daniel52e16d92018-04-10 09:34:07 -040080
Greg Daniel6c6caf42020-05-29 12:11:05 -040081 VkImageLayout currentLayout() const { return fMutableState->getImageLayout(); }
Greg Daniel164a9f02016-02-22 09:56:40 -050082
Greg Daniel7f3408b2020-06-03 13:31:00 -040083 void setImageLayoutAndQueueIndex(const GrVkGpu* gpu,
84 VkImageLayout newLayout,
85 VkAccessFlags dstAccessMask,
86 VkPipelineStageFlags dstStageMask,
87 bool byRegion,
88 uint32_t newQueueFamilyIndex);
89
egdaniel58a8d922016-04-21 08:03:10 -070090 void setImageLayout(const GrVkGpu* gpu,
91 VkImageLayout newLayout,
Greg Daniel164a9f02016-02-22 09:56:40 -050092 VkAccessFlags dstAccessMask,
Greg Daniel164a9f02016-02-22 09:56:40 -050093 VkPipelineStageFlags dstStageMask,
Greg Daniel7f3408b2020-06-03 13:31:00 -040094 bool byRegion) {
95 this->setImageLayoutAndQueueIndex(gpu, newLayout, dstAccessMask, dstStageMask, byRegion,
96 VK_QUEUE_FAMILY_IGNORED);
97 }
Greg Daniel164a9f02016-02-22 09:56:40 -050098
Greg Daniel6c6caf42020-05-29 12:11:05 -040099 uint32_t currentQueueFamilyIndex() const { return fMutableState->getQueueFamilyIndex(); }
100
101 void setQueueFamilyIndex(uint32_t queueFamilyIndex) {
102 fMutableState->setQueueFamilyIndex(queueFamilyIndex);
103 }
104
Greg Danielbae71212019-03-01 15:24:35 -0500105 // Returns the image to its original queue family and changes the layout to present if the queue
106 // family is not external or foreign.
107 void prepareForPresent(GrVkGpu* gpu);
108
Greg Daniel797efca2019-05-09 14:04:20 -0400109 // Returns the image to its original queue family
110 void prepareForExternal(GrVkGpu* gpu);
111
Greg Daniel31cc7312018-03-05 11:41:06 -0500112 // This simply updates our tracking of the image layout and does not actually do any gpu work.
113 // This is only used for mip map generation where we are manually changing the layouts as we
114 // blit each layer, and then at the end need to update our tracking.
Greg Daniel52e16d92018-04-10 09:34:07 -0400115 void updateImageLayout(VkImageLayout newLayout) {
Greg Danielb46add82019-01-02 14:51:29 -0500116 // Should only be called when we have a real fResource object, i.e. never when being used as
117 // a RT in an external secondary command buffer.
118 SkASSERT(fResource);
Greg Daniel6c6caf42020-05-29 12:11:05 -0400119 fMutableState->setImageLayout(newLayout);
Greg Daniel52e16d92018-04-10 09:34:07 -0400120 }
Greg Daniel31cc7312018-03-05 11:41:06 -0500121
Greg Daniel164a9f02016-02-22 09:56:40 -0500122 struct ImageDesc {
123 VkImageType fImageType;
124 VkFormat fFormat;
125 uint32_t fWidth;
126 uint32_t fHeight;
127 uint32_t fLevels;
128 uint32_t fSamples;
129 VkImageTiling fImageTiling;
130 VkImageUsageFlags fUsageFlags;
131 VkFlags fMemProps;
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400132 GrProtected fIsProtected;
Greg Daniel164a9f02016-02-22 09:56:40 -0500133
134 ImageDesc()
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400135 : fImageType(VK_IMAGE_TYPE_2D)
136 , fFormat(VK_FORMAT_UNDEFINED)
137 , fWidth(0)
138 , fHeight(0)
139 , fLevels(1)
140 , fSamples(1)
141 , fImageTiling(VK_IMAGE_TILING_OPTIMAL)
142 , fUsageFlags(0)
143 , fMemProps(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
144 , fIsProtected(GrProtected::kNo) {}
Greg Daniel164a9f02016-02-22 09:56:40 -0500145 };
146
Greg Daniele643da62019-11-05 12:36:42 -0500147 static bool InitImageInfo(GrVkGpu* gpu, const ImageDesc& imageDesc, GrVkImageInfo*);
egdanielb2df0c22016-05-13 11:30:37 -0700148 // Destroys the internal VkImage and VkDeviceMemory in the GrVkImageInfo
149 static void DestroyImageInfo(const GrVkGpu* gpu, GrVkImageInfo*);
Greg Daniel164a9f02016-02-22 09:56:40 -0500150
Greg Danielcef213c2017-04-21 11:52:27 -0400151 // These match the definitions in SkImage, for whence they came
152 typedef void* ReleaseCtx;
153 typedef void (*ReleaseProc)(ReleaseCtx);
154
Brian Salomonb2c5dae2019-03-04 10:25:17 -0500155 void setResourceRelease(sk_sp<GrRefCntedCallback> releaseHelper);
Greg Danielcef213c2017-04-21 11:52:27 -0400156
Greg Daniel6ddbafc2018-05-24 12:34:29 -0400157 // Helpers to use for setting the layout of the VkImage
Greg Danielf7828d02018-10-09 12:01:32 -0400158 static VkPipelineStageFlags LayoutToPipelineSrcStageFlags(const VkImageLayout layout);
Greg Daniel6ddbafc2018-05-24 12:34:29 -0400159 static VkAccessFlags LayoutToSrcAccessMask(const VkImageLayout layout);
160
Greg Daniel59dc1482019-02-22 10:46:38 -0500161#if GR_TEST_UTILS
162 void setCurrentQueueFamilyToGraphicsQueue(GrVkGpu* gpu);
163#endif
164
Greg Daniel164a9f02016-02-22 09:56:40 -0500165protected:
Greg Daniel03535f42020-06-05 14:18:42 -0400166 void releaseImage();
Brian Salomon9bc76d92019-01-24 12:18:33 -0500167 bool hasResource() const { return fResource; }
Greg Daniel164a9f02016-02-22 09:56:40 -0500168
Greg Daniel6c6caf42020-05-29 12:11:05 -0400169 GrVkImageInfo fInfo;
170 uint32_t fInitialQueueFamily;
171 sk_sp<GrBackendSurfaceMutableStateImpl> fMutableState;
172 bool fIsBorrowed;
egdanielb2df0c22016-05-13 11:30:37 -0700173
174private:
Jim Van Verth3e192162020-03-10 16:23:16 -0400175 class Resource : public GrTextureResource {
egdanielb2df0c22016-05-13 11:30:37 -0700176 public:
Jim Van Verth5082df12020-03-11 16:14:51 -0400177 explicit Resource(const GrVkGpu* gpu)
178 : fGpu(gpu)
179 , fImage(VK_NULL_HANDLE) {
jvanverth1e305ba2016-06-01 09:39:15 -0700180 fAlloc.fMemory = VK_NULL_HANDLE;
181 fAlloc.fOffset = 0;
egdanielb2df0c22016-05-13 11:30:37 -0700182 }
183
Jim Van Verth5082df12020-03-11 16:14:51 -0400184 Resource(const GrVkGpu* gpu, VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
185 : fGpu(gpu)
186 , fImage(image)
Greg Danielcef213c2017-04-21 11:52:27 -0400187 , fAlloc(alloc)
188 , fImageTiling(tiling) {}
egdanielb2df0c22016-05-13 11:30:37 -0700189
Jim Van Verth3e192162020-03-10 16:23:16 -0400190 ~Resource() override {}
egdanielb2df0c22016-05-13 11:30:37 -0700191
Jim Van Verth3e192162020-03-10 16:23:16 -0400192#ifdef SK_TRACE_MANAGED_RESOURCES
jvanverth7ec92412016-07-06 09:24:57 -0700193 void dumpInfo() const override {
egdaniela95220d2016-07-21 11:50:37 -0700194 SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt());
jvanverth7ec92412016-07-06 09:24:57 -0700195 }
196#endif
Brian Salomon8cabb322019-02-22 10:44:19 -0500197
Greg Danield922f332020-04-27 11:21:36 -0400198#ifdef SK_DEBUG
199 const GrManagedResource* asVkImageResource() const override { return this; }
200#endif
201
egdanielb2df0c22016-05-13 11:30:37 -0700202 private:
Jim Van Verth5082df12020-03-11 16:14:51 -0400203 void freeGPUData() const override;
egdanielb2df0c22016-05-13 11:30:37 -0700204
Jim Van Verth5082df12020-03-11 16:14:51 -0400205 const GrVkGpu* fGpu;
jvanverth1e305ba2016-06-01 09:39:15 -0700206 VkImage fImage;
207 GrVkAlloc fAlloc;
jvanverth6b6ffc42016-06-13 14:28:07 -0700208 VkImageTiling fImageTiling;
egdanielb2df0c22016-05-13 11:30:37 -0700209
John Stiles7571f9e2020-09-02 22:42:33 -0400210 using INHERITED = GrTextureResource;
egdanielb2df0c22016-05-13 11:30:37 -0700211 };
212
213 // for wrapped textures
214 class BorrowedResource : public Resource {
215 public:
Jim Van Verth5082df12020-03-11 16:14:51 -0400216 BorrowedResource(const GrVkGpu* gpu, VkImage image, const GrVkAlloc& alloc,
217 VkImageTiling tiling)
218 : Resource(gpu, image, alloc, tiling) {
egdanielb2df0c22016-05-13 11:30:37 -0700219 }
220 private:
Jim Van Verth5082df12020-03-11 16:14:51 -0400221 void freeGPUData() const override;
egdanielb2df0c22016-05-13 11:30:37 -0700222 };
223
Greg Daniel6a0176b2018-01-30 09:28:44 -0500224 Resource* fResource;
Greg Daniel164a9f02016-02-22 09:56:40 -0500225
egdanielb2df0c22016-05-13 11:30:37 -0700226 friend class GrVkRenderTarget;
Greg Daniel164a9f02016-02-22 09:56:40 -0500227};
228
229#endif