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