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 "include/core/SkTypes.h" 12 #include "include/gpu/GrBackendSurface.h" 13 #include "include/gpu/vk/GrVkTypes.h" 14 #include "include/private/GrTypesPriv.h" 15 #include "include/private/GrVkTypesPriv.h" 16 #include "src/gpu/GrBackendSurfaceMutableStateImpl.h" 17 #include "src/gpu/GrManagedResource.h" 18 #include "src/gpu/GrTexture.h" 19 20 class GrVkGpu; 21 class GrVkTexture; 22 23 class GrVkImage : SkNoncopyable { 24 private: 25 class Resource; 26 27 public: 28 GrVkImage(const GrVkGpu* gpu, 29 const GrVkImageInfo& info, 30 sk_sp<GrBackendSurfaceMutableStateImpl> mutableState, 31 GrBackendObjectOwnership ownership, 32 bool forSecondaryCB = false); 33 34 virtual ~GrVkImage(); 35 image()36 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 } alloc()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 } vkImageInfo()48 const GrVkImageInfo& vkImageInfo() const { return fInfo; } imageFormat()49 VkFormat imageFormat() const { return fInfo.fFormat; } getBackendFormat()50 GrBackendFormat getBackendFormat() const { 51 if (fResource && this->ycbcrConversionInfo().isValid()) { 52 SkASSERT(this->imageFormat() == this->ycbcrConversionInfo().fFormat); 53 return GrBackendFormat::MakeVk(this->ycbcrConversionInfo()); 54 } 55 SkASSERT(this->imageFormat() != VK_FORMAT_UNDEFINED); 56 return GrBackendFormat::MakeVk(this->imageFormat()); 57 } mipLevels()58 uint32_t mipLevels() const { return fInfo.fLevelCount; } ycbcrConversionInfo()59 const GrVkYcbcrConversionInfo& ycbcrConversionInfo() const { 60 // Should only be called when we have a real fResource object, i.e. never when being used as 61 // a RT in an external secondary command buffer. 62 SkASSERT(fResource); 63 return fInfo.fYcbcrConversionInfo; 64 } vkUsageFlags()65 VkImageUsageFlags vkUsageFlags() { return fInfo.fImageUsageFlags; } supportsInputAttachmentUsage()66 bool supportsInputAttachmentUsage() const { 67 return fInfo.fImageUsageFlags & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; 68 } resource()69 const Resource* resource() const { 70 SkASSERT(fResource); 71 return fResource; 72 } isLinearTiled()73 bool isLinearTiled() const { 74 // Should only be called when we have a real fResource object, i.e. never when being used as 75 // a RT in an external secondary command buffer. 76 SkASSERT(fResource); 77 return SkToBool(VK_IMAGE_TILING_LINEAR == fInfo.fImageTiling); 78 } isBorrowed()79 bool isBorrowed() const { return fIsBorrowed; } 80 getMutableState()81 sk_sp<GrBackendSurfaceMutableStateImpl> getMutableState() const { return fMutableState; } 82 currentLayout()83 VkImageLayout currentLayout() const { return fMutableState->getImageLayout(); } 84 85 void setImageLayoutAndQueueIndex(const GrVkGpu* gpu, 86 VkImageLayout newLayout, 87 VkAccessFlags dstAccessMask, 88 VkPipelineStageFlags dstStageMask, 89 bool byRegion, 90 uint32_t newQueueFamilyIndex); 91 setImageLayout(const GrVkGpu * gpu,VkImageLayout newLayout,VkAccessFlags dstAccessMask,VkPipelineStageFlags dstStageMask,bool byRegion)92 void setImageLayout(const GrVkGpu* gpu, 93 VkImageLayout newLayout, 94 VkAccessFlags dstAccessMask, 95 VkPipelineStageFlags dstStageMask, 96 bool byRegion) { 97 this->setImageLayoutAndQueueIndex(gpu, newLayout, dstAccessMask, dstStageMask, byRegion, 98 VK_QUEUE_FAMILY_IGNORED); 99 } 100 currentQueueFamilyIndex()101 uint32_t currentQueueFamilyIndex() const { return fMutableState->getQueueFamilyIndex(); } 102 setQueueFamilyIndex(uint32_t queueFamilyIndex)103 void setQueueFamilyIndex(uint32_t queueFamilyIndex) { 104 fMutableState->setQueueFamilyIndex(queueFamilyIndex); 105 } 106 107 // Returns the image to its original queue family and changes the layout to present if the queue 108 // family is not external or foreign. 109 void prepareForPresent(GrVkGpu* gpu); 110 111 // Returns the image to its original queue family 112 void prepareForExternal(GrVkGpu* gpu); 113 114 // This simply updates our tracking of the image layout and does not actually do any gpu work. 115 // This is only used for mip map generation where we are manually changing the layouts as we 116 // blit each layer, and then at the end need to update our tracking. updateImageLayout(VkImageLayout newLayout)117 void updateImageLayout(VkImageLayout newLayout) { 118 // Should only be called when we have a real fResource object, i.e. never when being used as 119 // a RT in an external secondary command buffer. 120 SkASSERT(fResource); 121 fMutableState->setImageLayout(newLayout); 122 } 123 124 struct ImageDesc { 125 VkImageType fImageType; 126 VkFormat fFormat; 127 uint32_t fWidth; 128 uint32_t fHeight; 129 uint32_t fLevels; 130 uint32_t fSamples; 131 VkImageTiling fImageTiling; 132 VkImageUsageFlags fUsageFlags; 133 VkFlags fMemProps; 134 GrProtected fIsProtected; 135 ImageDescImageDesc136 ImageDesc() 137 : fImageType(VK_IMAGE_TYPE_2D) 138 , fFormat(VK_FORMAT_UNDEFINED) 139 , fWidth(0) 140 , fHeight(0) 141 , fLevels(1) 142 , fSamples(1) 143 , fImageTiling(VK_IMAGE_TILING_OPTIMAL) 144 , fUsageFlags(0) 145 , fMemProps(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) 146 , fIsProtected(GrProtected::kNo) {} 147 }; 148 149 static bool InitImageInfo(GrVkGpu* gpu, const ImageDesc& imageDesc, GrVkImageInfo*); 150 // Destroys the internal VkImage and VkDeviceMemory in the GrVkImageInfo 151 static void DestroyImageInfo(const GrVkGpu* gpu, GrVkImageInfo*); 152 153 // These match the definitions in SkImage, for whence they came 154 typedef void* ReleaseCtx; 155 typedef void (*ReleaseProc)(ReleaseCtx); 156 157 void setResourceRelease(sk_sp<GrRefCntedCallback> releaseHelper); 158 159 // Helpers to use for setting the layout of the VkImage 160 static VkPipelineStageFlags LayoutToPipelineSrcStageFlags(const VkImageLayout layout); 161 static VkAccessFlags LayoutToSrcAccessMask(const VkImageLayout layout); 162 163 #if GR_TEST_UTILS 164 void setCurrentQueueFamilyToGraphicsQueue(GrVkGpu* gpu); 165 #endif 166 167 protected: 168 void releaseImage(); hasResource()169 bool hasResource() const { return fResource; } 170 171 GrVkImageInfo fInfo; 172 uint32_t fInitialQueueFamily; 173 sk_sp<GrBackendSurfaceMutableStateImpl> fMutableState; 174 bool fIsBorrowed; 175 176 private: 177 class Resource : public GrTextureResource { 178 public: Resource(const GrVkGpu * gpu)179 explicit Resource(const GrVkGpu* gpu) 180 : fGpu(gpu) 181 , fImage(VK_NULL_HANDLE) { 182 fAlloc.fMemory = VK_NULL_HANDLE; 183 fAlloc.fOffset = 0; 184 } 185 Resource(const GrVkGpu * gpu,VkImage image,const GrVkAlloc & alloc,VkImageTiling tiling)186 Resource(const GrVkGpu* gpu, VkImage image, const GrVkAlloc& alloc, VkImageTiling tiling) 187 : fGpu(gpu) 188 , fImage(image) 189 , fAlloc(alloc) 190 , fImageTiling(tiling) {} 191 ~Resource()192 ~Resource() override {} 193 194 #ifdef SK_TRACE_MANAGED_RESOURCES dumpInfo()195 void dumpInfo() const override { 196 SkDebugf("GrVkImage: %d (%d refs)\n", fImage, this->getRefCnt()); 197 } 198 #endif 199 200 #ifdef SK_DEBUG asVkImageResource()201 const GrManagedResource* asVkImageResource() const override { return this; } 202 #endif 203 204 private: 205 void freeGPUData() const override; 206 207 const GrVkGpu* fGpu; 208 VkImage fImage; 209 GrVkAlloc fAlloc; 210 VkImageTiling fImageTiling; 211 212 using INHERITED = GrTextureResource; 213 }; 214 215 // for wrapped textures 216 class BorrowedResource : public Resource { 217 public: BorrowedResource(const GrVkGpu * gpu,VkImage image,const GrVkAlloc & alloc,VkImageTiling tiling)218 BorrowedResource(const GrVkGpu* gpu, VkImage image, const GrVkAlloc& alloc, 219 VkImageTiling tiling) 220 : Resource(gpu, image, alloc, tiling) { 221 } 222 private: 223 void freeGPUData() const override; 224 }; 225 226 Resource* fResource; 227 228 friend class GrVkRenderTarget; 229 }; 230 231 #endif 232