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/GrVkAttachment.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 /** 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, const GrVkInterface* vkInterface, 29 VkPhysicalDevice device, const VkPhysicalDeviceFeatures2& features, 30 uint32_t instanceVersion, uint32_t physicalDeviceVersion, 31 const GrVkExtensions& extensions, GrProtected isProtected = GrProtected::kNo); 32 33 bool isFormatSRGB(const GrBackendFormat&) const override; 34 35 bool isFormatTexturable(const GrBackendFormat&) const override; 36 bool isVkFormatTexturable(VkFormat) const; 37 isFormatCopyable(const GrBackendFormat &)38 bool isFormatCopyable(const GrBackendFormat&) const override { return true; } 39 40 bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, 41 int sampleCount = 1) const override; 42 bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const override; 43 bool isFormatRenderable(VkFormat, int sampleCount) const; 44 45 int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const override; 46 int getRenderTargetSampleCount(int requestedCount, VkFormat) const; 47 48 int maxRenderTargetSampleCount(const GrBackendFormat&) const override; 49 int maxRenderTargetSampleCount(VkFormat format) const; 50 51 SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType, 52 const GrBackendFormat& surfaceFormat, 53 GrColorType srcColorType) const override; 54 55 SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const override; 56 isVkFormatTexturableLinearly(VkFormat format)57 bool isVkFormatTexturableLinearly(VkFormat format) const { 58 return SkToBool(FormatInfo::kTexturable_Flag & this->getFormatInfo(format).fLinearFlags); 59 } 60 formatCanBeDstofBlit(VkFormat format,bool linearTiled)61 bool formatCanBeDstofBlit(VkFormat format, bool linearTiled) const { 62 const FormatInfo& info = this->getFormatInfo(format); 63 const uint16_t& flags = linearTiled ? info.fLinearFlags : info.fOptimalFlags; 64 return SkToBool(FormatInfo::kBlitDst_Flag & flags); 65 } 66 formatCanBeSrcofBlit(VkFormat format,bool linearTiled)67 bool formatCanBeSrcofBlit(VkFormat format, bool linearTiled) const { 68 const FormatInfo& info = this->getFormatInfo(format); 69 const uint16_t& flags = linearTiled ? info.fLinearFlags : info.fOptimalFlags; 70 return SkToBool(FormatInfo::kBlitSrc_Flag & flags); 71 } 72 73 // Sometimes calls to QueueWaitIdle return before actually signalling the fences 74 // on the command buffers even though they have completed. This causes an assert to fire when 75 // destroying the command buffers. Therefore we add a sleep to make sure the fence signals. mustSleepOnTearDown()76 bool mustSleepOnTearDown() const { 77 return fMustSleepOnTearDown; 78 } 79 80 // Returns true if we should always make dedicated allocations for VkImages. shouldAlwaysUseDedicatedImageMemory()81 bool shouldAlwaysUseDedicatedImageMemory() const { 82 return fShouldAlwaysUseDedicatedImageMemory; 83 } 84 85 // Always use a transfer buffer instead of vkCmdUpdateBuffer to upload data to a VkBuffer. avoidUpdateBuffers()86 bool avoidUpdateBuffers() const { 87 return fAvoidUpdateBuffers; 88 } 89 90 /** 91 * Returns both a supported and most preferred stencil format to use in draws. 92 */ preferredStencilFormat()93 VkFormat preferredStencilFormat() const { 94 return fPreferredStencilFormat; 95 } 96 97 // Returns total number of bits used by stencil + depth + padding GetStencilFormatTotalBitCount(VkFormat format)98 static int GetStencilFormatTotalBitCount(VkFormat format) { 99 switch (format) { 100 case VK_FORMAT_S8_UINT: 101 return 8; 102 case VK_FORMAT_D24_UNORM_S8_UINT: 103 return 32; 104 case VK_FORMAT_D32_SFLOAT_S8_UINT: 105 // can optionally have 24 unused bits at the end so we assume the total bits is 64. 106 return 64; 107 default: 108 SkASSERT(false); 109 return 0; 110 } 111 } 112 113 // Returns whether the device supports VK_KHR_Swapchain. Internally Skia never uses any of the 114 // swapchain functions, but we may need to transition to and from the 115 // VK_IMAGE_LAYOUT_PRESENT_SRC_KHR image layout, so we must know whether that layout is 116 // supported. supportsSwapchain()117 bool supportsSwapchain() const { return fSupportsSwapchain; } 118 119 // Returns whether the device supports the ability to extend VkPhysicalDeviceProperties struct. supportsPhysicalDeviceProperties2()120 bool supportsPhysicalDeviceProperties2() const { return fSupportsPhysicalDeviceProperties2; } 121 // Returns whether the device supports the ability to extend VkMemoryRequirements struct. supportsMemoryRequirements2()122 bool supportsMemoryRequirements2() const { return fSupportsMemoryRequirements2; } 123 124 // Returns whether the device supports the ability to extend the vkBindMemory call. supportsBindMemory2()125 bool supportsBindMemory2() const { return fSupportsBindMemory2; } 126 127 // Returns whether or not the device suports the various API maintenance fixes to Vulkan 1.0. In 128 // Vulkan 1.1 all these maintenance are part of the core spec. supportsMaintenance1()129 bool supportsMaintenance1() const { return fSupportsMaintenance1; } supportsMaintenance2()130 bool supportsMaintenance2() const { return fSupportsMaintenance2; } supportsMaintenance3()131 bool supportsMaintenance3() const { return fSupportsMaintenance3; } 132 133 // Returns true if the device supports passing in a flag to say we are using dedicated GPU when 134 // allocating memory. For some devices this allows them to return more optimized memory knowning 135 // they will never need to suballocate amonst multiple objects. supportsDedicatedAllocation()136 bool supportsDedicatedAllocation() const { return fSupportsDedicatedAllocation; } 137 138 // Returns true if the device supports importing of external memory into Vulkan memory. supportsExternalMemory()139 bool supportsExternalMemory() const { return fSupportsExternalMemory; } 140 // Returns true if the device supports importing Android hardware buffers into Vulkan memory. supportsAndroidHWBExternalMemory()141 bool supportsAndroidHWBExternalMemory() const { return fSupportsAndroidHWBExternalMemory; } 142 143 // Returns true if it supports ycbcr conversion for samplers supportsYcbcrConversion()144 bool supportsYcbcrConversion() const { return fSupportsYcbcrConversion; } 145 146 // Returns true if the device supports protected memory. supportsProtectedMemory()147 bool supportsProtectedMemory() const { return fSupportsProtectedMemory; } 148 149 // Returns whether we prefer to record draws directly into a primary command buffer. preferPrimaryOverSecondaryCommandBuffers()150 bool preferPrimaryOverSecondaryCommandBuffers() const { 151 return fPreferPrimaryOverSecondaryCommandBuffers; 152 } 153 maxPerPoolCachedSecondaryCommandBuffers()154 int maxPerPoolCachedSecondaryCommandBuffers() const { 155 return fMaxPerPoolCachedSecondaryCommandBuffers; 156 } 157 maxInputAttachmentDescriptors()158 uint32_t maxInputAttachmentDescriptors() const { return fMaxInputAttachmentDescriptors; } 159 preferCachedCpuMemory()160 bool preferCachedCpuMemory() const { return fPreferCachedCpuMemory; } 161 mustInvalidatePrimaryCmdBufferStateAfterClearAttachments()162 bool mustInvalidatePrimaryCmdBufferStateAfterClearAttachments() const { 163 return fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments; 164 } 165 166 /** 167 * Helpers used by canCopySurface. In all cases if the SampleCnt parameter is zero that means 168 * the surface is not a render target, otherwise it is the number of samples in the render 169 * target. 170 */ 171 bool canCopyImage(VkFormat dstFormat, int dstSampleCnt, bool dstHasYcbcr, 172 VkFormat srcFormat, int srcSamplecnt, bool srcHasYcbcr) const; 173 174 bool canCopyAsBlit(VkFormat dstConfig, int dstSampleCnt, bool dstIsLinear, bool dstHasYcbcr, 175 VkFormat srcConfig, int srcSampleCnt, bool srcIsLinear, 176 bool srcHasYcbcr) const; 177 178 bool canCopyAsResolve(VkFormat dstConfig, int dstSampleCnt, bool dstHasYcbcr, 179 VkFormat srcConfig, int srcSamplecnt, bool srcHasYcbcr) const; 180 181 GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const override; 182 getFormatFromColorType(GrColorType colorType)183 VkFormat getFormatFromColorType(GrColorType colorType) const { 184 int idx = static_cast<int>(colorType); 185 return fColorTypeToFormatTable[idx]; 186 } 187 188 GrSwizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const override; 189 190 uint64_t computeFormatKey(const GrBackendFormat&) const override; 191 192 int getFragmentUniformBinding() const; 193 int getFragmentUniformSet() const; 194 195 void addExtraSamplerKey(GrProcessorKeyBuilder*, 196 GrSamplerState, 197 const GrBackendFormat&) const override; 198 199 GrProgramDesc makeDesc(GrRenderTarget*, const GrProgramInfo&) const override; 200 201 GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const override; 202 203 #if GR_TEST_UTILS 204 std::vector<TestFormatColorTypeCombination> getTestingCombinations() const override; 205 #endif 206 207 private: 208 enum VkVendor { 209 kAMD_VkVendor = 4098, 210 kARM_VkVendor = 5045, 211 kImagination_VkVendor = 4112, 212 kIntel_VkVendor = 32902, 213 kNvidia_VkVendor = 4318, 214 kQualcomm_VkVendor = 20803, 215 }; 216 217 void init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface, 218 VkPhysicalDevice device, const VkPhysicalDeviceFeatures2&, 219 uint32_t physicalDeviceVersion, const GrVkExtensions&, GrProtected isProtected); 220 void initGrCaps(const GrVkInterface* vkInterface, 221 VkPhysicalDevice physDev, 222 const VkPhysicalDeviceProperties&, 223 const VkPhysicalDeviceMemoryProperties&, 224 const VkPhysicalDeviceFeatures2&, 225 const GrVkExtensions&); 226 void initShaderCaps(const VkPhysicalDeviceProperties&, const VkPhysicalDeviceFeatures2&); 227 228 void initFormatTable(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&); 229 void initStencilFormat(const GrVkInterface* iface, VkPhysicalDevice physDev); 230 231 void applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties&); 232 233 bool onSurfaceSupportsWritePixels(const GrSurface*) const override; 234 bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 235 const SkIRect& srcRect, const SkIPoint& dstPoint) const override; 236 GrBackendFormat onGetDefaultBackendFormat(GrColorType) const override; 237 238 bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const override; 239 240 SupportedRead onSupportedReadPixelsColorType(GrColorType, const GrBackendFormat&, 241 GrColorType) const override; 242 243 GrSwizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const override; 244 245 GrDstSampleType onGetDstSampleTypeForProxy(const GrRenderTargetProxy*) const override; 246 247 // ColorTypeInfo for a specific format 248 struct ColorTypeInfo { 249 GrColorType fColorType = GrColorType::kUnknown; 250 enum { 251 kUploadData_Flag = 0x1, 252 // Does Ganesh itself support rendering to this colorType & format pair. Renderability 253 // still additionally depends on if the format itself is renderable. 254 kRenderable_Flag = 0x2, 255 // Indicates that this colorType is supported only if we are wrapping a texture with 256 // the given format and colorType. We do not allow creation with this pair. 257 kWrappedOnly_Flag = 0x4, 258 }; 259 uint32_t fFlags = 0; 260 261 GrSwizzle fReadSwizzle; 262 GrSwizzle fWriteSwizzle; 263 }; 264 265 struct FormatInfo { colorTypeFlagsFormatInfo266 uint32_t colorTypeFlags(GrColorType colorType) const { 267 for (int i = 0; i < fColorTypeInfoCount; ++i) { 268 if (fColorTypeInfos[i].fColorType == colorType) { 269 return fColorTypeInfos[i].fFlags; 270 } 271 } 272 return 0; 273 } 274 275 void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&, 276 VkFormat); 277 static void InitFormatFlags(VkFormatFeatureFlags, uint16_t* flags); 278 void initSampleCounts(const GrVkInterface*, VkPhysicalDevice, 279 const VkPhysicalDeviceProperties&, VkFormat); 280 281 enum { 282 kTexturable_Flag = 0x1, 283 kRenderable_Flag = 0x2, 284 kBlitSrc_Flag = 0x4, 285 kBlitDst_Flag = 0x8, 286 }; 287 288 uint16_t fOptimalFlags = 0; 289 uint16_t fLinearFlags = 0; 290 291 SkTDArray<int> fColorSampleCounts; 292 293 std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos; 294 int fColorTypeInfoCount = 0; 295 }; 296 static const size_t kNumVkFormats = 22; 297 FormatInfo fFormatTable[kNumVkFormats]; 298 299 FormatInfo& getFormatInfo(VkFormat); 300 const FormatInfo& getFormatInfo(VkFormat) const; 301 302 VkFormat fColorTypeToFormatTable[kGrColorTypeCnt]; 303 void setColorType(GrColorType, std::initializer_list<VkFormat> formats); 304 305 VkFormat fPreferredStencilFormat; 306 307 SkSTArray<1, GrVkYcbcrConversionInfo> fYcbcrInfos; 308 309 bool fMustSleepOnTearDown = false; 310 bool fShouldAlwaysUseDedicatedImageMemory = false; 311 312 bool fAvoidUpdateBuffers = false; 313 314 bool fSupportsSwapchain = false; 315 316 bool fSupportsPhysicalDeviceProperties2 = false; 317 bool fSupportsMemoryRequirements2 = false; 318 bool fSupportsBindMemory2 = false; 319 bool fSupportsMaintenance1 = false; 320 bool fSupportsMaintenance2 = false; 321 bool fSupportsMaintenance3 = false; 322 323 bool fSupportsDedicatedAllocation = false; 324 bool fSupportsExternalMemory = false; 325 bool fSupportsAndroidHWBExternalMemory = false; 326 327 bool fSupportsYcbcrConversion = false; 328 329 bool fSupportsProtectedMemory = false; 330 331 bool fPreferPrimaryOverSecondaryCommandBuffers = true; 332 bool fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments = false; 333 334 // We default this to 100 since we already cap the max render tasks at 100 before doing a 335 // submission in the GrDrawingManager, so we shouldn't be going over 100 secondary command 336 // buffers per primary anyways. 337 int fMaxPerPoolCachedSecondaryCommandBuffers = 100; 338 339 uint32_t fMaxInputAttachmentDescriptors = 0; 340 341 bool fPreferCachedCpuMemory = true; 342 343 using INHERITED = GrCaps; 344 }; 345 346 #endif 347