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 GrVkCaps_DEFINED 9 #define GrVkCaps_DEFINED 10 11 #include "include/gpu/vk/GrVkTypes.h" 12 #include "src/gpu/GrCaps.h" 13 #include "src/gpu/vk/GrVkStencilAttachment.h" 14 15 class GrShaderCaps; 16 class GrVkExtensions; 17 struct GrVkInterface; 18 19 /** 20 * Stores some capabilities of a Vk backend. 21 */ 22 class GrVkCaps : public GrCaps { 23 public: 24 typedef GrVkStencilAttachment::Format StencilFormat; 25 26 /** 27 * Creates a GrVkCaps that is set such that nothing is supported. The init function should 28 * be called to fill out the caps. 29 */ 30 GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, 31 VkPhysicalDevice device, const VkPhysicalDeviceFeatures2& features, 32 uint32_t instanceVersion, uint32_t physicalDeviceVersion, 33 const GrVkExtensions& extensions, GrProtected isProtected = GrProtected::kNo); 34 35 bool isFormatSRGB(const GrBackendFormat&) const override; 36 bool isFormatCompressed(const GrBackendFormat&) const override; 37 38 39 bool isFormatTexturableAndUploadable(GrColorType, const GrBackendFormat&) const override; 40 bool isFormatTexturable(const GrBackendFormat&) const override; 41 bool isVkFormatTexturable(VkFormat) const; 42 isFormatCopyable(const GrBackendFormat &)43 bool isFormatCopyable(const GrBackendFormat&) const override { return true; } 44 45 bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, 46 int sampleCount = 1) const override; 47 bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override; 48 bool isFormatRenderable(VkFormat, int sampleCount) const; 49 50 int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override; 51 int getRenderTargetSampleCount(int requestedCount, VkFormat) const; 52 53 int maxRenderTargetSampleCount(const GrBackendFormat&) const override; 54 int maxRenderTargetSampleCount(VkFormat format) const; 55 56 SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType, 57 const GrBackendFormat& surfaceFormat, 58 GrColorType srcColorType) const override; 59 60 SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override; 61 isVkFormatTexturableLinearly(VkFormat format)62 bool isVkFormatTexturableLinearly(VkFormat format) const { 63 return SkToBool(FormatInfo::kTexturable_Flag & this->getFormatInfo(format).fLinearFlags); 64 } 65 formatCanBeDstofBlit(VkFormat format,bool linearTiled)66 bool formatCanBeDstofBlit(VkFormat format, bool linearTiled) const { 67 const FormatInfo& info = this->getFormatInfo(format); 68 const uint16_t& flags = linearTiled ? info.fLinearFlags : info.fOptimalFlags; 69 return SkToBool(FormatInfo::kBlitDst_Flag & flags); 70 } 71 formatCanBeSrcofBlit(VkFormat format,bool linearTiled)72 bool formatCanBeSrcofBlit(VkFormat format, bool linearTiled) const { 73 const FormatInfo& info = this->getFormatInfo(format); 74 const uint16_t& flags = linearTiled ? info.fLinearFlags : info.fOptimalFlags; 75 return SkToBool(FormatInfo::kBlitSrc_Flag & flags); 76 } 77 78 // On Adreno vulkan, they do not respect the imageOffset parameter at least in 79 // copyImageToBuffer. This flag says that we must do the copy starting from the origin always. mustDoCopiesFromOrigin()80 bool mustDoCopiesFromOrigin() const { 81 return fMustDoCopiesFromOrigin; 82 } 83 84 // Sometimes calls to QueueWaitIdle return before actually signalling the fences 85 // on the command buffers even though they have completed. This causes an assert to fire when 86 // destroying the command buffers. Therefore we add a sleep to make sure the fence signals. mustSleepOnTearDown()87 bool mustSleepOnTearDown() const { 88 return fMustSleepOnTearDown; 89 } 90 91 // Returns true if we should always make dedicated allocations for VkImages. shouldAlwaysUseDedicatedImageMemory()92 bool shouldAlwaysUseDedicatedImageMemory() const { 93 return fShouldAlwaysUseDedicatedImageMemory; 94 } 95 96 // Always use a transfer buffer instead of vkCmdUpdateBuffer to upload data to a VkBuffer. avoidUpdateBuffers()97 bool avoidUpdateBuffers() const { 98 return fAvoidUpdateBuffers; 99 } 100 101 /** 102 * Returns both a supported and most preferred stencil format to use in draws. 103 */ preferredStencilFormat()104 const StencilFormat& preferredStencilFormat() const { 105 return fPreferredStencilFormat; 106 } 107 108 // Returns whether the device supports VK_KHR_Swapchain. Internally Skia never uses any of the 109 // swapchain functions, but we may need to transition to and from the 110 // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR image layout, so we must know whether that layout is 111 // supported. supportsSwapchain()112 bool supportsSwapchain() const { return fSupportsSwapchain; } 113 114 // Returns whether the device supports the ability to extend VkPhysicalDeviceProperties struct. supportsPhysicalDeviceProperties2()115 bool supportsPhysicalDeviceProperties2() const { return fSupportsPhysicalDeviceProperties2; } 116 // Returns whether the device supports the ability to extend VkMemoryRequirements struct. supportsMemoryRequirements2()117 bool supportsMemoryRequirements2() const { return fSupportsMemoryRequirements2; } 118 119 // Returns whether the device supports the ability to extend the vkBindMemory call. supportsBindMemory2()120 bool supportsBindMemory2() const { return fSupportsBindMemory2; } 121 122 // Returns whether or not the device suports the various API maintenance fixes to Vulkan 1.0. In 123 // Vulkan 1.1 all these maintenance are part of the core spec. supportsMaintenance1()124 bool supportsMaintenance1() const { return fSupportsMaintenance1; } supportsMaintenance2()125 bool supportsMaintenance2() const { return fSupportsMaintenance2; } supportsMaintenance3()126 bool supportsMaintenance3() const { return fSupportsMaintenance3; } 127 128 // Returns true if the device supports passing in a flag to say we are using dedicated GPU when 129 // allocating memory. For some devices this allows them to return more optimized memory knowning 130 // they will never need to suballocate amonst multiple objects. supportsDedicatedAllocation()131 bool supportsDedicatedAllocation() const { return fSupportsDedicatedAllocation; } 132 133 // Returns true if the device supports importing of external memory into Vulkan memory. supportsExternalMemory()134 bool supportsExternalMemory() const { return fSupportsExternalMemory; } 135 // Returns true if the device supports importing Android hardware buffers into Vulkan memory. supportsAndroidHWBExternalMemory()136 bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; } 137 138 // Returns true if it supports ycbcr conversion for samplers supportsYcbcrConversion()139 bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; } 140 141 // Returns true if the device supports protected memory. supportsProtectedMemory()142 bool supportsProtectedMemory() const { return fSupportsProtectedMemory; } 143 144 /** 145 * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means 146 * the surface is not a render target, otherwise it is the number of samples in the render 147 * target. 148 */ 149 bool canCopyImage(VkFormat dstFormat, int dstSampleCnt, bool dstHasYcbcr, 150 VkFormat srcFormat, int srcSamplecnt, bool srcHasYcbcr) const; 151 152 bool canCopyAsBlit(VkFormat dstConfig, int dstSampleCnt, bool dstIsLinear, bool dstHasYcbcr, 153 VkFormat srcConfig, int srcSampleCnt, bool srcIsLinear, 154 bool srcHasYcbcr) const; 155 156 bool canCopyAsResolve(VkFormat dstConfig, int dstSampleCnt, bool dstHasYcbcr, 157 VkFormat srcConfig, int srcSamplecnt, bool srcHasYcbcr) const; 158 159 GrColorType getYUVAColorTypeFromBackendFormat(const GrBackendFormat&, 160 bool isAlphaChannel) const override; 161 162 GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override; 163 getFormatFromColorType(GrColorType colorType)164 VkFormat getFormatFromColorType(GrColorType colorType) const { 165 int idx = static_cast<int>(colorType); 166 return fColorTypeToFormatTable[idx]; 167 } 168 169 bool canClearTextureOnCreation() const override; 170 171 GrSwizzle getTextureSwizzle(const GrBackendFormat&, GrColorType) const override; 172 GrSwizzle getOutputSwizzle(const GrBackendFormat&, GrColorType) const override; 173 174 int getFragmentUniformBinding() const; 175 int getFragmentUniformSet() const; 176 177 #if GR_TEST_UTILS 178 std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override; 179 #endif 180 181 private: 182 enum VkVendor { 183 kAMD_VkVendor = 4098, 184 kARM_VkVendor = 5045, 185 kImagination_VkVendor = 4112, 186 kIntel_VkVendor = 32902, 187 kNvidia_VkVendor = 4318, 188 kQualcomm_VkVendor = 20803, 189 }; 190 191 void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, 192 VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&, 193 uint32_t physicalDeviceVersion, const GrVkExtensions&, GrProtected isProtected); 194 void initGrCaps(const GrVkInterface* vkInterface, 195 VkPhysicalDevice physDev, 196 const VkPhysicalDeviceProperties&, 197 const VkPhysicalDeviceMemoryProperties&, 198 const VkPhysicalDeviceFeatures2&, 199 const GrVkExtensions&); 200 void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&); 201 202 void initFormatTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&); 203 void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev); 204 205 void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&); 206 207 bool onSurfaceSupportsWritePixels(const GrSurface*) const override; 208 bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 209 const SkIRect& srcRect, const SkIPoint& dstPoint) const override; 210 GrBackendFormat onGetDefaultBackendFormat(GrColorType, GrRenderable) const override; 211 212 GrPixelConfig onGetConfigFromBackendFormat(const GrBackendFormat&, GrColorType) const override; 213 bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override; 214 215 SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&, 216 GrColorType) const override; 217 218 // ColorTypeInfo for a specific format 219 struct ColorTypeInfo { 220 GrColorType fColorType = GrColorType::kUnknown; 221 enum { 222 kUploadData_Flag = 0x1, 223 // Does Ganesh itself support rendering to this colorType & format pair. Renderability 224 // still additionally depends on if the format itself is renderable. 225 kRenderable_Flag = 0x2, 226 // Indicates that this colorType is supported only if we are wrapping a texture with 227 // the given format and colorType. We do not allow creation with this pair. 228 kWrappedOnly_Flag = 0x4, 229 }; 230 uint32_t fFlags = 0; 231 232 GrSwizzle fTextureSwizzle; 233 GrSwizzle fOutputSwizzle; 234 }; 235 236 struct FormatInfo { colorTypeFlagsFormatInfo237 uint32_t colorTypeFlags(GrColorType colorType) const { 238 for (int i = 0; i < fColorTypeInfoCount; ++i) { 239 if (fColorTypeInfos[i].fColorType == colorType) { 240 return fColorTypeInfos[i].fFlags; 241 } 242 } 243 return 0; 244 } 245 246 void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&, 247 VkFormat); 248 static void InitFormatFlags(VkFormatFeatureFlags, uint16_t* flags); 249 void initSampleCounts(const GrVkInterface*, VkPhysicalDevice, 250 const VkPhysicalDeviceProperties&, VkFormat); 251 252 enum { 253 kTexturable_Flag = 0x1, 254 kRenderable_Flag = 0x2, 255 kBlitSrc_Flag = 0x4, 256 kBlitDst_Flag = 0x8, 257 }; 258 259 uint16_t fOptimalFlags = 0; 260 uint16_t fLinearFlags = 0; 261 262 SkTDArray<int> fColorSampleCounts; 263 264 std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos; 265 int fColorTypeInfoCount = 0; 266 }; 267 static const size_t kNumVkFormats = 20; 268 FormatInfo fFormatTable[kNumVkFormats]; 269 270 FormatInfo& getFormatInfo(VkFormat); 271 const FormatInfo& getFormatInfo(VkFormat) const; 272 273 VkFormat fColorTypeToFormatTable[kGrColorTypeCnt]; 274 void setColorType(GrColorType, std::initializer_list<VkFormat> formats); 275 276 StencilFormat fPreferredStencilFormat; 277 278 SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos; 279 280 bool fMustDoCopiesFromOrigin = false; 281 bool fMustSleepOnTearDown = false; 282 bool fShouldAlwaysUseDedicatedImageMemory = false; 283 284 bool fAvoidUpdateBuffers = false; 285 286 bool fSupportsSwapchain = false; 287 288 bool fSupportsPhysicalDeviceProperties2 = false; 289 bool fSupportsMemoryRequirements2 = false; 290 bool fSupportsBindMemory2 = false; 291 bool fSupportsMaintenance1 = false; 292 bool fSupportsMaintenance2 = false; 293 bool fSupportsMaintenance3 = false; 294 295 bool fSupportsDedicatedAllocation = false; 296 bool fSupportsExternalMemory = false; 297 bool fSupportsAndroidHWBExternalMemory = false; 298 299 bool fSupportsYcbcrConversion = false; 300 301 bool fSupportsProtectedMemory = false; 302 303 typedef GrCaps INHERITED; 304 }; 305 306 #endif 307