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 14 class GrShaderCaps; 15 class GrVkExtensions; 16 struct GrVkInterface; 17 class GrVkRenderTarget; 18 19 /** 20 * Stores some capabilities of a Vk backend. 21 */ 22 class GrVkCaps : public GrCaps { 23 public: 24 /** 25 * Creates a GrVkCaps that is set such that nothing is supported. The init function should 26 * be called to fill out the caps. 27 */ 28 GrVkCaps(const GrContextOptions& contextOptions, 29 const GrVkInterface* vkInterface, 30 VkPhysicalDevice device, 31 const VkPhysicalDeviceFeatures2& features, 32 uint32_t instanceVersion, 33 uint32_t physicalDeviceVersion, 34 const GrVkExtensions& extensions, 35 GrProtected isProtected = GrProtected::kNo); 36 37 bool isFormatSRGB(const GrBackendFormat&) const override; 38 39 bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const override; 40 bool isVkFormatTexturable(VkFormat) const; 41 isFormatCopyable(const GrBackendFormat &)42 bool isFormatCopyable(const GrBackendFormat&) const override { return true; } 43 44 bool isFormatAsColorTypeRenderable(GrColorType ct, 45 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 // Gets the GrColorType that should be used to transfer data in/out of a transfer buffer to 79 // write/read data when using a VkFormat with a specified color type. 80 GrColorType transferColorType(VkFormat, GrColorType surfaceColorType) const; 81 82 // On some GPUs (Windows Nvidia and Imagination) calls to QueueWaitIdle return before actually 83 // signalling the fences on the command buffers even though they have completed. This causes 84 // issues when then deleting the command buffers. Therefore we additionally will call 85 // vkWaitForFences on each outstanding command buffer to make sure the driver signals the fence. mustSyncCommandBuffersWithQueue()86 bool mustSyncCommandBuffersWithQueue() const { return fMustSyncCommandBuffersWithQueue; } 87 88 // Returns true if we should always make dedicated allocations for VkImages. shouldAlwaysUseDedicatedImageMemory()89 bool shouldAlwaysUseDedicatedImageMemory() const { 90 return fShouldAlwaysUseDedicatedImageMemory; 91 } 92 93 // Always use a transfer buffer instead of vkCmdUpdateBuffer to upload data to a VkBuffer. avoidUpdateBuffers()94 bool avoidUpdateBuffers() const { return fAvoidUpdateBuffers; } 95 96 /** 97 * Returns both a supported and most preferred stencil format to use in draws. 98 */ preferredStencilFormat()99 VkFormat preferredStencilFormat() const { return fPreferredStencilFormat; } 100 101 // Returns total number of bits used by stencil + depth + padding GetStencilFormatTotalBitCount(VkFormat format)102 static int GetStencilFormatTotalBitCount(VkFormat format) { 103 switch (format) { 104 case VK_FORMAT_S8_UINT: 105 return 8; 106 case VK_FORMAT_D24_UNORM_S8_UINT: 107 return 32; 108 case VK_FORMAT_D32_SFLOAT_S8_UINT: 109 // can optionally have 24 unused bits at the end so we assume the total bits is 64. 110 return 64; 111 default: 112 SkASSERT(false); 113 return 0; 114 } 115 } 116 117 // Returns whether the device supports VK_KHR_Swapchain. Internally Skia never uses any of the 118 // swapchain functions, but we may need to transition to and from the 119 // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR image layout, so we must know whether that layout is 120 // supported. supportsSwapchain()121 bool supportsSwapchain() const { return fSupportsSwapchain; } 122 123 // Returns whether the device supports the ability to extend VkPhysicalDeviceProperties struct. supportsPhysicalDeviceProperties2()124 bool supportsPhysicalDeviceProperties2() const { return fSupportsPhysicalDeviceProperties2; } 125 // Returns whether the device supports the ability to extend VkMemoryRequirements struct. supportsMemoryRequirements2()126 bool supportsMemoryRequirements2() const { return fSupportsMemoryRequirements2; } 127 128 // Returns whether the device supports the ability to extend the vkBindMemory call. supportsBindMemory2()129 bool supportsBindMemory2() const { return fSupportsBindMemory2; } 130 131 // Returns whether or not the device suports the various API maintenance fixes to Vulkan 1.0. In 132 // Vulkan 1.1 all these maintenance are part of the core spec. supportsMaintenance1()133 bool supportsMaintenance1() const { return fSupportsMaintenance1; } supportsMaintenance2()134 bool supportsMaintenance2() const { return fSupportsMaintenance2; } supportsMaintenance3()135 bool supportsMaintenance3() const { return fSupportsMaintenance3; } 136 137 // Returns true if the device supports passing in a flag to say we are using dedicated GPU when 138 // allocating memory. For some devices this allows them to return more optimized memory knowning 139 // they will never need to suballocate amonst multiple objects. supportsDedicatedAllocation()140 bool supportsDedicatedAllocation() const { return fSupportsDedicatedAllocation; } 141 142 // Returns true if the device supports importing of external memory into Vulkan memory. supportsExternalMemory()143 bool supportsExternalMemory() const { return fSupportsExternalMemory; } 144 // Returns true if the device supports importing Android hardware buffers into Vulkan memory. supportsAndroidHWBExternalMemory()145 bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; } 146 147 // Returns true if it supports ycbcr conversion for samplers supportsYcbcrConversion()148 bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; } 149 150 // Returns the number of descriptor slots used by immutable ycbcr VkImages. 151 // 152 // TODO: We should update this to return a count for a specific format or external format. We 153 // can use vkGetPhysicalDeviceImageFormatProperties2 with a 154 // VkSamplerYcbcrConversionImageFormatProperties to query this. However, right now that call 155 // does not support external android formats which is where the majority of ycbcr images are 156 // coming from. So for now we stay safe and always return 3 here which is the max value that the 157 // count could be for any format. ycbcrCombinedImageSamplerDescriptorCount()158 uint32_t ycbcrCombinedImageSamplerDescriptorCount() const { 159 return 3; 160 } 161 162 // Returns true if the device supports protected memory. supportsProtectedMemory()163 bool supportsProtectedMemory() const { return fSupportsProtectedMemory; } 164 165 // Returns true if the VK_EXT_image_drm_format_modifier is enabled. supportsDRMFormatModifiers()166 bool supportsDRMFormatModifiers() const { return fSupportsDRMFormatModifiers; } 167 168 // Returns whether we prefer to record draws directly into a primary command buffer. preferPrimaryOverSecondaryCommandBuffers()169 bool preferPrimaryOverSecondaryCommandBuffers() const { 170 return fPreferPrimaryOverSecondaryCommandBuffers; 171 } 172 maxPerPoolCachedSecondaryCommandBuffers()173 int maxPerPoolCachedSecondaryCommandBuffers() const { 174 return fMaxPerPoolCachedSecondaryCommandBuffers; 175 } 176 maxInputAttachmentDescriptors()177 uint32_t maxInputAttachmentDescriptors() const { return fMaxInputAttachmentDescriptors; } 178 mustInvalidatePrimaryCmdBufferStateAfterClearAttachments()179 bool mustInvalidatePrimaryCmdBufferStateAfterClearAttachments() const { 180 return fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments; 181 } 182 183 // For host visible allocations, this returns true if we require that they are coherent. This 184 // is used to work around bugs for devices that don't handle non-coherent memory correctly. mustUseCoherentHostVisibleMemory()185 bool mustUseCoherentHostVisibleMemory() const { return fMustUseCoherentHostVisibleMemory; } 186 187 // Returns whether a pure GPU accessible buffer is more performant to read than a buffer that is 188 // also host visible. If so then in some cases we may prefer the cost of doing a copy to the 189 // buffer. This typically would only be the case for buffers that are written once and read 190 // many times on the gpu. gpuOnlyBuffersMorePerformant()191 bool gpuOnlyBuffersMorePerformant() const { return fGpuOnlyBuffersMorePerformant; } 192 193 // For our CPU write and GPU read buffers (vertex, uniform, etc.), should we keep these buffers 194 // persistently mapped. In general the answer will be yes. The main case we don't do this is 195 // when using special memory that is DEVICE_LOCAL and HOST_VISIBLE on discrete GPUs. shouldPersistentlyMapCpuToGpuBuffers()196 bool shouldPersistentlyMapCpuToGpuBuffers() const { 197 return fShouldPersistentlyMapCpuToGpuBuffers; 198 } 199 200 // The max draw count that can be passed into indirect draw calls. maxDrawIndirectDrawCount()201 uint32_t maxDrawIndirectDrawCount() const { return fMaxDrawIndirectDrawCount; } 202 203 /** 204 * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means 205 * the surface is not a render target, otherwise it is the number of samples in the render 206 * target. 207 */ 208 bool canCopyImage(VkFormat dstFormat, 209 int dstSampleCnt, 210 bool dstHasYcbcr, 211 VkFormat srcFormat, 212 int srcSamplecnt, 213 bool srcHasYcbcr) const; 214 215 bool canCopyAsBlit(VkFormat dstConfig, 216 int dstSampleCnt, 217 bool dstIsLinear, 218 bool dstHasYcbcr, 219 VkFormat srcConfig, 220 int srcSampleCnt, 221 bool srcIsLinear, 222 bool srcHasYcbcr) const; 223 224 bool canCopyAsResolve(VkFormat dstConfig, 225 int dstSampleCnt, 226 bool dstHasYcbcr, 227 VkFormat srcConfig, 228 int srcSamplecnt, 229 bool srcHasYcbcr) const; 230 231 GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override; 232 getFormatFromColorType(GrColorType colorType)233 VkFormat getFormatFromColorType(GrColorType colorType) const { 234 int idx = static_cast<int>(colorType); 235 return fColorTypeToFormatTable[idx]; 236 } 237 238 GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override; 239 240 uint64_t computeFormatKey(const GrBackendFormat&) const override; 241 242 int getFragmentUniformBinding() const; 243 int getFragmentUniformSet() const; 244 245 void addExtraSamplerKey(GrProcessorKeyBuilder*, 246 GrSamplerState, 247 const GrBackendFormat&) const override; 248 249 GrProgramDesc makeDesc(GrRenderTarget*, 250 const GrProgramInfo&, 251 ProgramDescOverrideFlags) const override; 252 253 GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const override; 254 255 VkShaderStageFlags getPushConstantStageFlags() const; 256 257 // If true then when doing MSAA draws, we will prefer to discard the msaa attachment on load 258 // and stores. The use of this feature for specific draws depends on the render target having a 259 // resolve attachment, and if we need to load previous data the resolve attachment must be 260 // usable as an input attachment. Otherwise we will just write out and store the msaa attachment 261 // like normal. 262 // This flag is similar to enabling gl render to texture for msaa rendering. preferDiscardableMSAAAttachment()263 bool preferDiscardableMSAAAttachment() const { return fPreferDiscardableMSAAAttachment; } mustLoadFullImageWithDiscardableMSAA()264 bool mustLoadFullImageWithDiscardableMSAA() const { 265 return fMustLoadFullImageWithDiscardableMSAA; 266 } supportsDiscardableMSAAForDMSAA()267 bool supportsDiscardableMSAAForDMSAA() const { return fSupportsDiscardableMSAAForDMSAA; } 268 bool renderTargetSupportsDiscardableMSAA(const GrVkRenderTarget*) const; 269 bool programInfoWillUseDiscardableMSAA(const GrProgramInfo&) const; 270 dmsaaResolveCanBeUsedAsTextureInSameRenderPass()271 bool dmsaaResolveCanBeUsedAsTextureInSameRenderPass() const override { return false; } 272 supportsMemorylessAttachments()273 bool supportsMemorylessAttachments() const { return fSupportsMemorylessAttachments; } 274 275 #if GR_TEST_UTILS 276 std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override; 277 #endif 278 279 private: 280 enum VkVendor { 281 kAMD_VkVendor = 4098, 282 kARM_VkVendor = 5045, 283 kImagination_VkVendor = 4112, 284 kIntel_VkVendor = 32902, 285 kNvidia_VkVendor = 4318, 286 kQualcomm_VkVendor = 20803, 287 }; 288 289 void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, 290 VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&, 291 uint32_t physicalDeviceVersion, const GrVkExtensions&, GrProtected isProtected); 292 void initGrCaps(const GrVkInterface* vkInterface, 293 VkPhysicalDevice physDev, 294 const VkPhysicalDeviceProperties&, 295 const VkPhysicalDeviceMemoryProperties&, 296 const VkPhysicalDeviceFeatures2&, 297 const GrVkExtensions&); 298 void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&); 299 300 void initFormatTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&); 301 void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev); 302 303 void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&); 304 305 bool onSurfaceSupportsWritePixels(const GrSurface*) const override; 306 bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 307 const SkIRect& srcRect, const SkIPoint& dstPoint) const override; 308 GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override; 309 310 bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override; 311 312 SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&, 313 GrColorType) const override; 314 315 GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override; 316 317 GrDstSampleFlags onGetDstSampleFlagsForProxy(const GrRenderTargetProxy*) const override; 318 319 bool onSupportsDynamicMSAA(const GrRenderTargetProxy*) const override; 320 321 // ColorTypeInfo for a specific format 322 struct ColorTypeInfo { 323 GrColorType fColorType = GrColorType::kUnknown; 324 GrColorType fTransferColorType = GrColorType::kUnknown; 325 enum { 326 kUploadData_Flag = 0x1, 327 // Does Ganesh itself support rendering to this colorType & format pair. Renderability 328 // still additionally depends on if the format itself is renderable. 329 kRenderable_Flag = 0x2, 330 // Indicates that this colorType is supported only if we are wrapping a texture with 331 // the given format and colorType. We do not allow creation with this pair. 332 kWrappedOnly_Flag = 0x4, 333 }; 334 uint32_t fFlags = 0; 335 336 GrSwizzle fReadSwizzle; 337 GrSwizzle fWriteSwizzle; 338 }; 339 340 struct FormatInfo { colorTypeFlagsFormatInfo341 uint32_t colorTypeFlags(GrColorType colorType) const { 342 for (int i = 0; i < fColorTypeInfoCount; ++i) { 343 if (fColorTypeInfos[i].fColorType == colorType) { 344 return fColorTypeInfos[i].fFlags; 345 } 346 } 347 return 0; 348 } 349 350 void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&, 351 VkFormat); 352 static void InitFormatFlags(VkFormatFeatureFlags, uint16_t* flags); 353 void initSampleCounts(const GrVkInterface*, VkPhysicalDevice, 354 const VkPhysicalDeviceProperties&, VkFormat); 355 356 enum { 357 kTexturable_Flag = 0x1, 358 kRenderable_Flag = 0x2, 359 kBlitSrc_Flag = 0x4, 360 kBlitDst_Flag = 0x8, 361 }; 362 363 uint16_t fOptimalFlags = 0; 364 uint16_t fLinearFlags = 0; 365 366 SkTDArray<int> fColorSampleCounts; 367 368 std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos; 369 int fColorTypeInfoCount = 0; 370 }; 371 static const size_t kNumVkFormats = 22; 372 FormatInfo fFormatTable[kNumVkFormats]; 373 374 FormatInfo& getFormatInfo(VkFormat); 375 const FormatInfo& getFormatInfo(VkFormat) const; 376 377 VkFormat fColorTypeToFormatTable[kGrColorTypeCnt]; 378 void setColorType(GrColorType, std::initializer_list<VkFormat> formats); 379 380 VkFormat fPreferredStencilFormat; 381 382 SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos; 383 384 bool fMustSyncCommandBuffersWithQueue = false; 385 bool fShouldAlwaysUseDedicatedImageMemory = false; 386 387 bool fAvoidUpdateBuffers = false; 388 389 bool fSupportsSwapchain = false; 390 391 bool fSupportsPhysicalDeviceProperties2 = false; 392 bool fSupportsMemoryRequirements2 = false; 393 bool fSupportsBindMemory2 = false; 394 bool fSupportsMaintenance1 = false; 395 bool fSupportsMaintenance2 = false; 396 bool fSupportsMaintenance3 = false; 397 398 bool fSupportsDedicatedAllocation = false; 399 bool fSupportsExternalMemory = false; 400 bool fSupportsAndroidHWBExternalMemory = false; 401 402 bool fSupportsYcbcrConversion = false; 403 404 bool fSupportsProtectedMemory = false; 405 406 bool fSupportsDRMFormatModifiers = false; 407 408 bool fPreferPrimaryOverSecondaryCommandBuffers = true; 409 bool fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments = false; 410 411 bool fMustUseCoherentHostVisibleMemory = false; 412 bool fGpuOnlyBuffersMorePerformant = false; 413 bool fShouldPersistentlyMapCpuToGpuBuffers = true; 414 415 // We default this to 100 since we already cap the max render tasks at 100 before doing a 416 // submission in the GrDrawingManager, so we shouldn't be going over 100 secondary command 417 // buffers per primary anyways. 418 int fMaxPerPoolCachedSecondaryCommandBuffers = 100; 419 420 uint32_t fMaxInputAttachmentDescriptors = 0; 421 422 bool fPreferDiscardableMSAAAttachment = false; 423 bool fMustLoadFullImageWithDiscardableMSAA = false; 424 bool fSupportsDiscardableMSAAForDMSAA = true; 425 bool fSupportsMemorylessAttachments = false; 426 427 uint32_t fMaxDrawIndirectDrawCount = 0; 428 429 using INHERITED = GrCaps; 430 }; 431 432 #endif 433