1 /*
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"
12 
13 #include "GrTypesPriv.h"
14 #include "SkTypes.h"
15 
16 #include "vk/GrVkDefines.h"
17 #include "vk/GrVkTypes.h"
18 
19 class GrVkGpu;
20 
21 class GrVkImage : SkNoncopyable {
22 private:
23     class Resource;
24 
25 public:
GrVkImage(const GrVkImageInfo & info,GrBackendObjectOwnership ownership)26     GrVkImage(const GrVkImageInfo& info, GrBackendObjectOwnership ownership)
27         : fInfo(info)
28         , fIsBorrowed(GrBackendObjectOwnership::kBorrowed == ownership) {
29         if (fIsBorrowed) {
30             fResource = new BorrowedResource(info.fImage, info.fAlloc, info.fImageTiling);
31         } else {
32             fResource = new Resource(info.fImage, info.fAlloc, info.fImageTiling);
33         }
34     }
35     virtual ~GrVkImage();
36 
image()37     VkImage image() const { return fInfo.fImage; }
alloc()38     const GrVkAlloc& alloc() const { return fInfo.fAlloc; }
imageFormat()39     VkFormat imageFormat() const { return fInfo.fFormat; }
mipLevels()40     uint32_t mipLevels() const { return fInfo.fLevelCount; }
resource()41     const Resource* resource() const { return fResource; }
isLinearTiled()42     bool isLinearTiled() const {
43         return SkToBool(VK_IMAGE_TILING_LINEAR == fInfo.fImageTiling);
44     }
isBorrowed()45     bool isBorrowed() const { return fIsBorrowed; }
46 
currentLayout()47     VkImageLayout currentLayout() const { return fInfo.fImageLayout; }
48 
49     void setImageLayout(const GrVkGpu* gpu,
50                         VkImageLayout newLayout,
51                         VkAccessFlags dstAccessMask,
52                         VkPipelineStageFlags dstStageMask,
53                         bool byRegion,
54                         bool releaseFamilyQueue = false);
55 
56     struct ImageDesc {
57         VkImageType         fImageType;
58         VkFormat            fFormat;
59         uint32_t            fWidth;
60         uint32_t            fHeight;
61         uint32_t            fLevels;
62         uint32_t            fSamples;
63         VkImageTiling       fImageTiling;
64         VkImageUsageFlags   fUsageFlags;
65         VkFlags             fMemProps;
66 
ImageDescImageDesc67         ImageDesc()
68             : fImageType(VK_IMAGE_TYPE_2D)
69             , fFormat(VK_FORMAT_UNDEFINED)
70             , fWidth(0)
71             , fHeight(0)
72             , fLevels(1)
73             , fSamples(1)
74             , fImageTiling(VK_IMAGE_TILING_OPTIMAL)
75             , fUsageFlags(0)
76             , fMemProps(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {}
77     };
78 
79     static bool InitImageInfo(const GrVkGpu* gpu, const ImageDesc& imageDesc, GrVkImageInfo*);
80     // Destroys the internal VkImage and VkDeviceMemory in the GrVkImageInfo
81     static void DestroyImageInfo(const GrVkGpu* gpu, GrVkImageInfo*);
82 
83     // These match the definitions in SkImage, for whence they came
84     typedef void* ReleaseCtx;
85     typedef void (*ReleaseProc)(ReleaseCtx);
86 
87     void setResourceRelease(sk_sp<GrReleaseProcHelper> releaseHelper);
88 
89 protected:
90     void releaseImage(const GrVkGpu* gpu);
91     void abandonImage();
92 
93     void setNewResource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling);
94 
95     GrVkImageInfo   fInfo;
96     bool            fIsBorrowed;
97 
98 private:
99     class Resource : public GrVkResource {
100     public:
Resource()101         Resource()
102                 : fImage(VK_NULL_HANDLE) {
103             fAlloc.fMemory = VK_NULL_HANDLE;
104             fAlloc.fOffset = 0;
105         }
106 
Resource(VkImage image,const GrVkAlloc & alloc,VkImageTiling tiling)107         Resource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
108             : fImage(image)
109             , fAlloc(alloc)
110             , fImageTiling(tiling) {}
111 
~Resource()112         ~Resource() override {
113             SkASSERT(!fReleaseHelper);
114         }
115 
116 #ifdef SK_TRACE_VK_RESOURCES
dumpInfo()117         void dumpInfo() const override {
118             SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt());
119         }
120 #endif
setRelease(sk_sp<GrReleaseProcHelper> releaseHelper)121         void setRelease(sk_sp<GrReleaseProcHelper> releaseHelper) {
122             fReleaseHelper = std::move(releaseHelper);
123         }
124     protected:
125         mutable sk_sp<GrReleaseProcHelper> fReleaseHelper;
126 
127     private:
128         void freeGPUData(const GrVkGpu* gpu) const override;
abandonGPUData()129         void abandonGPUData() const override {
130             SkASSERT(!fReleaseHelper);
131         }
132 
133         VkImage        fImage;
134         GrVkAlloc      fAlloc;
135         VkImageTiling  fImageTiling;
136 
137         typedef GrVkResource INHERITED;
138     };
139 
140     // for wrapped textures
141     class BorrowedResource : public Resource {
142     public:
BorrowedResource(VkImage image,const GrVkAlloc & alloc,VkImageTiling tiling)143         BorrowedResource(VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling)
144             : Resource(image, alloc, tiling) {
145         }
146     private:
invokeReleaseProc()147         void invokeReleaseProc() const {
148             if (fReleaseHelper) {
149                 // Depending on the ref count of fReleaseHelper this may or may not actually trigger
150                 // the ReleaseProc to be called.
151                 fReleaseHelper.reset();
152             }
153         }
154 
155         void freeGPUData(const GrVkGpu* gpu) const override;
156         void abandonGPUData() const override;
157     };
158 
159     Resource* fResource;
160 
161     friend class GrVkRenderTarget;
162 };
163 
164 #endif
165