1 2 /* 3 * Copyright 2016 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 #ifndef GrVkTypes_DEFINED 10 #define GrVkTypes_DEFINED 11 12 #include "include/core/SkTypes.h" 13 #include "include/gpu/vk/GrVkVulkan.h" 14 15 #ifndef VK_VERSION_1_1 16 #error Skia requires the use of Vulkan 1.1 headers 17 #endif 18 19 #include <functional> 20 #include "include/gpu/GrTypes.h" 21 22 typedef intptr_t GrVkBackendMemory; 23 24 /** 25 * Types for interacting with Vulkan resources created externally to Skia. GrBackendObjects for 26 * Vulkan textures are really const GrVkImageInfo* 27 */ 28 struct GrVkAlloc { GrVkAllocGrVkAlloc29 GrVkAlloc() 30 : fMemory(VK_NULL_HANDLE) 31 , fOffset(0) 32 , fSize(0) 33 , fFlags(0) 34 , fBackendMemory(0) 35 , fUsesSystemHeap(false) {} 36 GrVkAllocGrVkAlloc37 GrVkAlloc(VkDeviceMemory memory, VkDeviceSize offset, VkDeviceSize size, uint32_t flags) 38 : fMemory(memory) 39 , fOffset(offset) 40 , fSize(size) 41 , fFlags(flags) 42 , fBackendMemory(0) 43 , fUsesSystemHeap(false) {} 44 45 VkDeviceMemory fMemory; // can be VK_NULL_HANDLE iff is an RT and is borrowed 46 VkDeviceSize fOffset; 47 VkDeviceSize fSize; // this can be indeterminate iff Tex uses borrow semantics 48 uint32_t fFlags; 49 GrVkBackendMemory fBackendMemory; // handle to memory allocated via GrVkMemoryAllocator. 50 51 enum Flag { 52 kNoncoherent_Flag = 0x1, // memory must be flushed to device after mapping 53 kMappable_Flag = 0x2, // memory is able to be mapped. 54 }; 55 56 bool operator==(const GrVkAlloc& that) const { 57 return fMemory == that.fMemory && fOffset == that.fOffset && fSize == that.fSize && 58 fFlags == that.fFlags && fUsesSystemHeap == that.fUsesSystemHeap; 59 } 60 61 private: 62 friend class GrVkHeap; // For access to usesSystemHeap 63 bool fUsesSystemHeap; 64 }; 65 66 // This struct is used to pass in the necessary information to create a VkSamplerYcbcrConversion 67 // object for an VkExternalFormatANDROID. 68 struct GrVkYcbcrConversionInfo { GrVkYcbcrConversionInfoGrVkYcbcrConversionInfo69 GrVkYcbcrConversionInfo() 70 : fFormat(VK_FORMAT_UNDEFINED) 71 , fExternalFormat(0) 72 , fYcbcrModel(VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY) 73 , fYcbcrRange(VK_SAMPLER_YCBCR_RANGE_ITU_FULL) 74 , fXChromaOffset(VK_CHROMA_LOCATION_COSITED_EVEN) 75 , fYChromaOffset(VK_CHROMA_LOCATION_COSITED_EVEN) 76 , fChromaFilter(VK_FILTER_NEAREST) 77 , fForceExplicitReconstruction(false) {} 78 GrVkYcbcrConversionInfoGrVkYcbcrConversionInfo79 GrVkYcbcrConversionInfo(VkFormat format, 80 int64_t externalFormat, 81 VkSamplerYcbcrModelConversion ycbcrModel, 82 VkSamplerYcbcrRange ycbcrRange, 83 VkChromaLocation xChromaOffset, 84 VkChromaLocation yChromaOffset, 85 VkFilter chromaFilter, 86 VkBool32 forceExplicitReconstruction, 87 VkFormatFeatureFlags formatFeatures) 88 : fFormat(format) 89 , fExternalFormat(externalFormat) 90 , fYcbcrModel(ycbcrModel) 91 , fYcbcrRange(ycbcrRange) 92 , fXChromaOffset(xChromaOffset) 93 , fYChromaOffset(yChromaOffset) 94 , fChromaFilter(chromaFilter) 95 , fForceExplicitReconstruction(forceExplicitReconstruction) 96 , fFormatFeatures(formatFeatures) { 97 SkASSERT(fYcbcrModel != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY); 98 // Either format or externalFormat must be specified. 99 SkASSERT((fFormat != VK_FORMAT_UNDEFINED) ^ (externalFormat != 0)); 100 } 101 GrVkYcbcrConversionInfoGrVkYcbcrConversionInfo102 GrVkYcbcrConversionInfo(VkSamplerYcbcrModelConversion ycbcrModel, 103 VkSamplerYcbcrRange ycbcrRange, 104 VkChromaLocation xChromaOffset, 105 VkChromaLocation yChromaOffset, 106 VkFilter chromaFilter, 107 VkBool32 forceExplicitReconstruction, 108 uint64_t externalFormat, 109 VkFormatFeatureFlags externalFormatFeatures) 110 : GrVkYcbcrConversionInfo(VK_FORMAT_UNDEFINED, externalFormat, ycbcrModel, ycbcrRange, 111 xChromaOffset, yChromaOffset, chromaFilter, 112 forceExplicitReconstruction, externalFormatFeatures) {} 113 114 bool operator==(const GrVkYcbcrConversionInfo& that) const { 115 // Invalid objects are not required to have all other fields initialized or matching. 116 if (!this->isValid() && !that.isValid()) { 117 return true; 118 } 119 return this->fFormat == that.fFormat && 120 this->fExternalFormat == that.fExternalFormat && 121 this->fYcbcrModel == that.fYcbcrModel && 122 this->fYcbcrRange == that.fYcbcrRange && 123 this->fXChromaOffset == that.fXChromaOffset && 124 this->fYChromaOffset == that.fYChromaOffset && 125 this->fChromaFilter == that.fChromaFilter && 126 this->fForceExplicitReconstruction == that.fForceExplicitReconstruction; 127 } 128 bool operator!=(const GrVkYcbcrConversionInfo& that) const { return !(*this == that); } 129 isValidGrVkYcbcrConversionInfo130 bool isValid() const { return fYcbcrModel != VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY; } 131 132 // Format of the source image. Must be set to VK_FORMAT_UNDEFINED for external images or 133 // a valid image format otherwise. 134 VkFormat fFormat; 135 136 // The external format. Must be non-zero for external images, zero otherwise. 137 // Should be compatible to be used in a VkExternalFormatANDROID struct. 138 uint64_t fExternalFormat; 139 140 VkSamplerYcbcrModelConversion fYcbcrModel; 141 VkSamplerYcbcrRange fYcbcrRange; 142 VkChromaLocation fXChromaOffset; 143 VkChromaLocation fYChromaOffset; 144 VkFilter fChromaFilter; 145 VkBool32 fForceExplicitReconstruction; 146 147 // For external images format features here should be those returned by a call to 148 // vkAndroidHardwareBufferFormatPropertiesANDROID 149 VkFormatFeatureFlags fFormatFeatures; 150 }; 151 152 struct GrVkImageInfo { 153 VkImage fImage; 154 GrVkAlloc fAlloc; 155 VkImageTiling fImageTiling; 156 VkImageLayout fImageLayout; 157 VkFormat fFormat; 158 uint32_t fLevelCount; 159 uint32_t fCurrentQueueFamily; 160 GrProtected fProtected; 161 GrVkYcbcrConversionInfo fYcbcrConversionInfo; 162 GrVkImageInfoGrVkImageInfo163 GrVkImageInfo() 164 : fImage(VK_NULL_HANDLE) 165 , fAlloc() 166 , fImageTiling(VK_IMAGE_TILING_OPTIMAL) 167 , fImageLayout(VK_IMAGE_LAYOUT_UNDEFINED) 168 , fFormat(VK_FORMAT_UNDEFINED) 169 , fLevelCount(0) 170 , fCurrentQueueFamily(VK_QUEUE_FAMILY_IGNORED) 171 , fProtected(GrProtected::kNo) 172 , fYcbcrConversionInfo() {} 173 174 GrVkImageInfo(VkImage image, 175 GrVkAlloc alloc, 176 VkImageTiling imageTiling, 177 VkImageLayout layout, 178 VkFormat format, 179 uint32_t levelCount, 180 uint32_t currentQueueFamily = VK_QUEUE_FAMILY_IGNORED, 181 GrProtected isProtected = GrProtected::kNo, 182 GrVkYcbcrConversionInfo ycbcrConversionInfo = GrVkYcbcrConversionInfo()) fImageGrVkImageInfo183 : fImage(image) 184 , fAlloc(alloc) 185 , fImageTiling(imageTiling) 186 , fImageLayout(layout) 187 , fFormat(format) 188 , fLevelCount(levelCount) 189 , fCurrentQueueFamily(currentQueueFamily) 190 , fProtected(isProtected) 191 , fYcbcrConversionInfo(ycbcrConversionInfo) {} 192 GrVkImageInfoGrVkImageInfo193 GrVkImageInfo(const GrVkImageInfo& info, VkImageLayout layout) 194 : fImage(info.fImage) 195 , fAlloc(info.fAlloc) 196 , fImageTiling(info.fImageTiling) 197 , fImageLayout(layout) 198 , fFormat(info.fFormat) 199 , fLevelCount(info.fLevelCount) 200 , fCurrentQueueFamily(info.fCurrentQueueFamily) 201 , fProtected(info.fProtected) 202 , fYcbcrConversionInfo(info.fYcbcrConversionInfo) {} 203 204 // This gives a way for a client to update the layout of the Image if they change the layout 205 // while we're still holding onto the wrapped texture. They will first need to get a handle 206 // to our internal GrVkImageInfo by calling getTextureHandle on a GrVkTexture. updateImageLayoutGrVkImageInfo207 void updateImageLayout(VkImageLayout layout) { fImageLayout = layout; } 208 209 bool operator==(const GrVkImageInfo& that) const { 210 return fImage == that.fImage && fAlloc == that.fAlloc && 211 fImageTiling == that.fImageTiling && fImageLayout == that.fImageLayout && 212 fFormat == that.fFormat && fLevelCount == that.fLevelCount && 213 fCurrentQueueFamily == that.fCurrentQueueFamily && fProtected == that.fProtected && 214 fYcbcrConversionInfo == that.fYcbcrConversionInfo; 215 } 216 }; 217 218 using GrVkGetProc = std::function<PFN_vkVoidFunction( 219 const char*, // function name 220 VkInstance, // instance or VK_NULL_HANDLE 221 VkDevice // device or VK_NULL_HANDLE 222 )>; 223 224 /** 225 * This object is wrapped in a GrBackendDrawableInfo and passed in as an argument to 226 * drawBackendGpu() calls on an SkDrawable. The drawable will use this info to inject direct 227 * Vulkan calls into our stream of GPU draws. 228 * 229 * The SkDrawable is given a secondary VkCommandBuffer in which to record draws. The GPU backend 230 * will then execute that command buffer within a render pass it is using for its own draws. The 231 * drawable is also given the attachment of the color index, a compatible VkRenderPass, and the 232 * VkFormat of the color attachment so that it can make VkPipeline objects for the draws. The 233 * SkDrawable must not alter the state of the VkRenderpass or sub pass. 234 * 235 * Additionally, the SkDrawable may fill in the passed in fDrawBounds with the bounds of the draws 236 * that it submits to the command buffer. This will be used by the GPU backend for setting the 237 * bounds in vkCmdBeginRenderPass. If fDrawBounds is not updated, we will assume that the entire 238 * attachment may have been written to. 239 * 240 * The SkDrawable is always allowed to create its own command buffers and submit them to the queue 241 * to render offscreen textures which will be sampled in draws added to the passed in 242 * VkCommandBuffer. If this is done the SkDrawable is in charge of adding the required memory 243 * barriers to the queue for the sampled images since the Skia backend will not do this. 244 * 245 * The VkImage is informational only and should not be used or modified in any ways. 246 */ 247 struct GrVkDrawableInfo { 248 VkCommandBuffer fSecondaryCommandBuffer; 249 uint32_t fColorAttachmentIndex; 250 VkRenderPass fCompatibleRenderPass; 251 VkFormat fFormat; 252 VkRect2D* fDrawBounds; 253 VkImage fImage; 254 }; 255 256 #endif 257