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