Flutter Engine
The Flutter Engine
GrVkCaps.cpp
Go to the documentation of this file.
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
9
10#include <memory>
11
20#include "src/gpu/KeyBuilder.h"
28#include "src/gpu/ganesh/SkGr.h"
38
39#ifdef SK_BUILD_FOR_ANDROID
40#include <sys/system_properties.h>
41#endif
42
44 const skgpu::VulkanInterface* vkInterface,
45 VkPhysicalDevice physDev,
46 const VkPhysicalDeviceFeatures2& features,
47 uint32_t instanceVersion,
48 uint32_t physicalDeviceVersion,
50 GrProtected isProtected)
51 : INHERITED(contextOptions) {
52 /**************************************************************************
53 * GrCaps fields
54 **************************************************************************/
55 fMipmapSupport = true; // always available in Vulkan
56 fAnisoSupport = true; // always available in Vulkan
57 fNPOTTextureTileSupport = true; // always available in Vulkan
58 fReuseScratchTextures = true; //TODO: figure this out
59 fGpuTracingSupport = false; //TODO: figure this out
60 fOversizedStencilSupport = false; //TODO: figure this out
62
63 fSemaphoreSupport = true; // always available in Vulkan
68
69 // We always copy in/out of a transfer buffer so it's trivial to support row bytes.
72
76
77 fMaxRenderTargetSize = 4096; // minimum required by spec
78 fMaxTextureSize = 4096; // minimum required by spec
79
81
83
84 fShaderCaps = std::make_unique<GrShaderCaps>();
85
86 this->init(contextOptions, vkInterface, physDev, features, physicalDeviceVersion, extensions,
87 isProtected);
88}
89
90namespace {
91/**
92 * This comes from section 37.1.6 of the Vulkan spec. Format is
93 * (<bits>|<tag>)_<block_size>_<texels_per_block>.
94 */
95enum class FormatCompatibilityClass {
96 k8_1_1,
97 k16_2_1,
98 k24_3_1,
99 k32_4_1,
100 k64_8_1,
101 k10x6_64_6_1,
102 kBC1_RGB_8_16_1,
103 kBC1_RGBA_8_16,
104 kETC2_RGB_8_16,
105};
106} // anonymous namespace
107
108static FormatCompatibilityClass format_compatibility_class(VkFormat format) {
109 switch (format) {
117 return FormatCompatibilityClass::k32_4_1;
118
120 return FormatCompatibilityClass::k8_1_1;
121
129 return FormatCompatibilityClass::k16_2_1;
130
133 return FormatCompatibilityClass::k64_8_1;
134
136 return FormatCompatibilityClass::k24_3_1;
137
139 return FormatCompatibilityClass::k10x6_64_6_1;
140
142 return FormatCompatibilityClass::kETC2_RGB_8_16;
143
145 return FormatCompatibilityClass::kBC1_RGB_8_16_1;
146
148 return FormatCompatibilityClass::kBC1_RGBA_8_16;
149
150 default:
151 SK_ABORT("Unsupported VkFormat");
152 }
153}
154
155bool GrVkCaps::canCopyImage(VkFormat dstFormat, int dstSampleCnt, bool dstHasYcbcr,
156 VkFormat srcFormat, int srcSampleCnt, bool srcHasYcbcr) const {
157 if ((dstSampleCnt > 1 || srcSampleCnt > 1) && dstSampleCnt != srcSampleCnt) {
158 return false;
159 }
160
161 if (dstHasYcbcr || srcHasYcbcr) {
162 return false;
163 }
164
165 // We require that all Vulkan GrSurfaces have been created with transfer_dst and transfer_src
166 // as image usage flags.
167 return format_compatibility_class(srcFormat) == format_compatibility_class(dstFormat);
168}
169
170bool GrVkCaps::canCopyAsBlit(VkFormat dstFormat, int dstSampleCnt, bool dstIsLinear,
171 bool dstHasYcbcr, VkFormat srcFormat, int srcSampleCnt,
172 bool srcIsLinear, bool srcHasYcbcr) const {
173 // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src
174 // as image usage flags.
175 if (!this->formatCanBeDstofBlit(dstFormat, dstIsLinear) ||
176 !this->formatCanBeSrcofBlit(srcFormat, srcIsLinear)) {
177 return false;
178 }
179
180 // We cannot blit images that are multisampled. Will need to figure out if we can blit the
181 // resolved msaa though.
182 if (dstSampleCnt > 1 || srcSampleCnt > 1) {
183 return false;
184 }
185
186 if (dstHasYcbcr || srcHasYcbcr) {
187 return false;
188 }
189
190 return true;
191}
192
193bool GrVkCaps::canCopyAsResolve(VkFormat dstFormat, int dstSampleCnt, bool dstHasYcbcr,
194 VkFormat srcFormat, int srcSampleCnt, bool srcHasYcbcr) const {
195 // The src surface must be multisampled.
196 if (srcSampleCnt <= 1) {
197 return false;
198 }
199
200 // The dst must not be multisampled.
201 if (dstSampleCnt > 1) {
202 return false;
203 }
204
205 // Surfaces must have the same format.
206 if (srcFormat != dstFormat) {
207 return false;
208 }
209
210 if (dstHasYcbcr || srcHasYcbcr) {
211 return false;
212 }
213
214 return true;
215}
216
217bool GrVkCaps::onCanCopySurface(const GrSurfaceProxy* dst, const SkIRect& dstRect,
218 const GrSurfaceProxy* src, const SkIRect& srcRect) const {
219 if (src->isProtected() == GrProtected::kYes && dst->isProtected() != GrProtected::kYes) {
220 return false;
221 }
222
223 // TODO: Figure out a way to track if we've wrapped a linear texture in a proxy (e.g.
224 // PromiseImage which won't get instantiated right away. Does this need a similar thing like the
225 // tracking of external or rectangle textures in GL? For now we don't create linear textures
226 // internally, and I don't believe anyone is wrapping them.
227 bool srcIsLinear = false;
228 bool dstIsLinear = false;
229
230 int dstSampleCnt = 0;
231 int srcSampleCnt = 0;
232 if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
233 // Copying to or from render targets that wrap a secondary command buffer is not allowed
234 // since they would require us to know the VkImage, which we don't have, as well as need us
235 // to stop and start the VkRenderPass which we don't have access to.
236 if (rtProxy->wrapsVkSecondaryCB()) {
237 return false;
238 }
239 if (this->preferDiscardableMSAAAttachment() && dst->asTextureProxy() &&
240 rtProxy->supportsVkInputAttachment()) {
241 dstSampleCnt = 1;
242 } else {
243 dstSampleCnt = rtProxy->numSamples();
244 }
245 }
246 if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
247 // Copying to or from render targets that wrap a secondary command buffer is not allowed
248 // since they would require us to know the VkImage, which we don't have, as well as need us
249 // to stop and start the VkRenderPass which we don't have access to.
250 if (rtProxy->wrapsVkSecondaryCB()) {
251 return false;
252 }
253 if (this->preferDiscardableMSAAAttachment() && src->asTextureProxy() &&
254 rtProxy->supportsVkInputAttachment()) {
255 srcSampleCnt = 1;
256 } else {
257 srcSampleCnt = rtProxy->numSamples();
258 }
259 }
260 SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
261 SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
262
263 bool dstHasYcbcr = false;
264 if (auto ycbcr = GrBackendFormats::GetVkYcbcrConversionInfo(dst->backendFormat())) {
265 if (ycbcr->isValid()) {
266 dstHasYcbcr = true;
267 }
268 }
269
270 bool srcHasYcbcr = false;
271 if (auto ycbcr = GrBackendFormats::GetVkYcbcrConversionInfo(src->backendFormat())) {
272 if (ycbcr->isValid()) {
273 srcHasYcbcr = true;
274 }
275 }
276
277 VkFormat dstFormat, srcFormat;
278 SkAssertResult(GrBackendFormats::AsVkFormat(dst->backendFormat(), &dstFormat));
279 SkAssertResult(GrBackendFormats::AsVkFormat(src->backendFormat(), &srcFormat));
280
281 // Only blits support scaling, but since we've already clamped the src and dst rects,
282 // the dimensions of the scaled blit aren't important to know if it's allowed.
283 const bool copyScales = srcRect.size() != dstRect.size();
284 if (!copyScales && (this->canCopyImage(dstFormat, dstSampleCnt, dstHasYcbcr,
285 srcFormat, srcSampleCnt, srcHasYcbcr) ||
286 this->canCopyAsResolve(dstFormat, dstSampleCnt, dstHasYcbcr,
287 srcFormat, srcSampleCnt, srcHasYcbcr))) {
288 return true;
289 }
290 return this->canCopyAsBlit(dstFormat, dstSampleCnt, dstIsLinear, dstHasYcbcr,
291 srcFormat, srcSampleCnt, srcIsLinear, srcHasYcbcr);
292
293}
294
295void GrVkCaps::init(const GrContextOptions& contextOptions,
296 const skgpu::VulkanInterface* vkInterface,
297 VkPhysicalDevice physDev,
298 const VkPhysicalDeviceFeatures2& features,
299 uint32_t physicalDeviceVersion,
301 GrProtected isProtected) {
303 GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));
304
305#if defined(GR_TEST_UTILS)
306 this->setDeviceName(properties.deviceName);
307#endif
308
309 VkPhysicalDeviceMemoryProperties memoryProperties;
310 GR_VK_CALL(vkInterface, GetPhysicalDeviceMemoryProperties(physDev, &memoryProperties));
311
312 SkASSERT(physicalDeviceVersion <= properties.apiVersion);
313
314 if (extensions.hasExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME, 1)) {
315 fSupportsSwapchain = true;
316 }
317
318 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
320 fSupportsPhysicalDeviceProperties2 = true;
321 }
322
323 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
325 fSupportsMemoryRequirements2 = true;
326 }
327
328 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
330 fSupportsBindMemory2 = true;
331 }
332
333 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
335 fSupportsMaintenance1 = true;
336 }
337
338 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
340 fSupportsMaintenance2 = true;
341 }
342
343 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
345 fSupportsMaintenance3 = true;
346 }
347
348 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
350 this->supportsMemoryRequirements2())) {
351 fSupportsDedicatedAllocation = true;
352 }
353
354 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
356 this->supportsPhysicalDeviceProperties2() &&
358 this->supportsDedicatedAllocation())) {
359 fSupportsExternalMemory = true;
360 }
361
362#ifdef SK_BUILD_FOR_ANDROID
363 // Currently Adreno devices are not supporting the QUEUE_FAMILY_FOREIGN_EXTENSION, so until they
364 // do we don't explicitly require it here even the spec says it is required.
365 if (extensions.hasExtension(
367 /* extensions.hasExtension(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, 1) &&*/
368 this->supportsExternalMemory() &&
369 this->supportsBindMemory2()) {
370 fSupportsAndroidHWBExternalMemory = true;
372 }
373#endif
374
375 auto ycbcrFeatures = skgpu::GetExtensionFeatureStruct<
377 features,
379 if (ycbcrFeatures && ycbcrFeatures->samplerYcbcrConversion &&
380 (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
382 this->supportsMaintenance1() && this->supportsBindMemory2() &&
383 this->supportsMemoryRequirements2() && this->supportsPhysicalDeviceProperties2()))) {
384 fSupportsYcbcrConversion = true;
385 }
386
387 // We always push back the default skgpu::VulkanYcbcrConversionInfo so that the case of no
388 // conversion will return a key of 0.
390
391 if ((isProtected == GrProtected::kYes) &&
392 (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0))) {
394 fAvoidUpdateBuffers = true;
395 fShouldAlwaysUseDedicatedImageMemory = true;
396 }
397
399 fSupportsDRMFormatModifiers = true;
400 }
401
402 if (extensions.hasExtension(VK_EXT_DEVICE_FAULT_EXTENSION_NAME, 1)) {
403 fSupportsDeviceFaultInfo = true;
404 }
405
406 fMaxInputAttachmentDescriptors = properties.limits.maxDescriptorSetInputAttachments;
407
408 fMaxSamplerAnisotropy = properties.limits.maxSamplerAnisotropy;
409
410 // On desktop GPUs we have found that this does not provide much benefit. The perf results show
411 // a mix of regressions, some improvements, and lots of no changes. Thus it is not worth
412 // enabling this (especially with the rendering artifacts) on desktop.
413 //
414 // On Adreno devices we were expecting to see perf gains. But instead there were actually a lot
415 // of perf regressions and only a few perf wins. This needs some follow up with qualcomm since
416 // we do expect this to be a big win on tilers.
417 //
418 // On ARM devices we are seeing an average perf win of around 50%-60% across the board.
419 if (kARM_VkVendor == properties.vendorID) {
420 // We currently don't see any Vulkan devices that expose a memory type that supports
421 // both lazy allocated and protected memory. So for simplicity we just disable the
422 // use of memoryless attachments when using protected memory. In the future, if we ever
423 // do see devices that support both, we can look through the device's memory types here
424 // and see if any support both flags.
426 fSupportsMemorylessAttachments = !fSupportsProtectedContent;
427 }
428
429 this->initGrCaps(vkInterface, physDev, properties, memoryProperties, features, extensions);
430 this->initShaderCaps(properties, features);
431
432 if (kQualcomm_VkVendor == properties.vendorID) {
433 // A "clear" load for atlases runs faster on QC than a "discard" load followed by a
434 // scissored clear.
435 // On NVIDIA and Intel, the discard load followed by clear is faster.
436 // TODO: Evaluate on ARM, Imagination, and ATI.
438 }
439
440 if (properties.vendorID == kNvidia_VkVendor || properties.vendorID == kAMD_VkVendor) {
441 // On discrete GPUs it can be faster to read gpu only memory compared to memory that is also
442 // mappable on the host.
443 fGpuOnlyBuffersMorePerformant = true;
444
445 // On discrete GPUs we try to use special DEVICE_LOCAL and HOST_VISIBLE memory for our
446 // cpu write, gpu read buffers. This memory is not ideal to be kept persistently mapped.
447 // Some discrete GPUs do not expose this special memory, however we still disable
448 // persistently mapped buffers for all of them since most GPUs with updated drivers do
449 // expose it. If this becomes an issue we can try to be more fine grained.
450 fShouldPersistentlyMapCpuToGpuBuffers = false;
451 }
452
453 if (kQualcomm_VkVendor == properties.vendorID) {
454 // On Qualcomm it looks like using vkCmdUpdateBuffer is slower than using a transfer buffer
455 // even for small sizes.
456 fAvoidUpdateBuffers = true;
457 }
458
459 fNativeDrawIndirectSupport = features.features.drawIndirectFirstInstance;
460 if (properties.vendorID == kQualcomm_VkVendor) {
461 // Indirect draws seem slow on QC. Disable until we can investigate. http://skbug.com/11139
463 }
464
466 fMaxDrawIndirectDrawCount = properties.limits.maxDrawIndirectCount;
467 SkASSERT(fMaxDrawIndirectDrawCount == 1 || features.features.multiDrawIndirect);
468 }
469
470#ifdef SK_BUILD_FOR_UNIX
471 if (kNvidia_VkVendor == properties.vendorID) {
472 // On nvidia linux we see a big perf regression when not using dedicated image allocations.
473 fShouldAlwaysUseDedicatedImageMemory = true;
474 }
475#endif
476
477 this->initFormatTable(contextOptions, vkInterface, physDev, properties, features, extensions);
478 this->initStencilFormat(vkInterface, physDev);
479
480 if (contextOptions.fMaxCachedVulkanSecondaryCommandBuffers >= 0) {
481 fMaxPerPoolCachedSecondaryCommandBuffers =
483 }
484
485 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
486 this->applyDriverCorrectnessWorkarounds(properties);
487 }
488
489 this->finishInitialization(contextOptions);
490}
491
492void GrVkCaps::applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties& properties) {
493#if defined(SK_BUILD_FOR_WIN)
494 if (kNvidia_VkVendor == properties.vendorID || kIntel_VkVendor == properties.vendorID) {
495 fMustSyncCommandBuffersWithQueue = true;
496 }
497#elif defined(SK_BUILD_FOR_ANDROID)
498 if (kImagination_VkVendor == properties.vendorID) {
499 fMustSyncCommandBuffersWithQueue = true;
500 }
501#endif
502
503 // Defaults to zero since all our workaround checks that use this consider things "fixed" once
504 // above a certain api level. So this will just default to it being less which will enable
505 // workarounds.
506 int androidAPIVersion = 0;
507#if defined(SK_BUILD_FOR_ANDROID)
508 char androidAPIVersionStr[PROP_VALUE_MAX];
509 int strLength = __system_property_get("ro.build.version.sdk", androidAPIVersionStr);
510 // Defaults to zero since most checks care if it is greater than a specific value. So this will
511 // just default to it being less.
512 androidAPIVersion = (strLength == 0) ? 0 : atoi(androidAPIVersionStr);
513#endif
514
515 // Protected memory features have problems in Android P and earlier.
516 if (fSupportsProtectedContent && (kQualcomm_VkVendor == properties.vendorID)) {
517 if (androidAPIVersion <= 28) {
519 }
520 }
521
522 // On Mali galaxy s7 we see lots of rendering issues when we suballocate VkImages.
523 if (kARM_VkVendor == properties.vendorID && androidAPIVersion <= 28) {
524 fShouldAlwaysUseDedicatedImageMemory = true;
525 }
526
527 // On Mali galaxy s7 and s9 we see lots of rendering issues with image filters dropping out when
528 // using only primary command buffers. We also see issues on the P30 running android 28.
529 if (kARM_VkVendor == properties.vendorID && androidAPIVersion <= 28) {
530 fPreferPrimaryOverSecondaryCommandBuffers = false;
531 // If we are using secondary command buffers our code isn't setup to insert barriers into
532 // the secondary cb so we need to disable support for them.
535 }
536
537 // We've seen numerous driver bugs on qualcomm devices running on android P (api 28) or earlier
538 // when trying to using discardable msaa attachments and loading from resolve. So we disable the
539 // feature for those devices.
540 if (properties.vendorID == kQualcomm_VkVendor && androidAPIVersion <= 28) {
542 fSupportsDiscardableMSAAForDMSAA = false;
543 }
544
545 // On the Mali G76 and T880, the Perlin noise code needs to aggressively snap to multiples
546 // of 1/255 to avoid artifacts in the double table lookup.
547 if (kARM_VkVendor == properties.vendorID) {
548 fShaderCaps->fPerlinNoiseRoundingFix = true;
549 }
550
551 // On various devices, when calling vkCmdClearAttachments on a primary command buffer, it
552 // corrupts the bound buffers on the command buffer. As a workaround we invalidate our knowledge
553 // of bound buffers so that we will rebind them on the next draw.
554 if (kQualcomm_VkVendor == properties.vendorID || kAMD_VkVendor == properties.vendorID) {
555 fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments = true;
556 }
557
558 // On Qualcomm and Arm the gpu resolves an area larger than the render pass bounds when using
559 // discardable msaa attachments. This causes the resolve to resolve uninitialized data from the
560 // msaa image into the resolve image.
561 // This also occurs on swiftshader: b/303705884
562 if (properties.vendorID == kQualcomm_VkVendor ||
563 properties.vendorID == kARM_VkVendor ||
564 (properties.vendorID == kGoogle_VkVendor &&
565 properties.deviceID == kSwiftshader_DeviceID)) {
566 fMustLoadFullImageWithDiscardableMSAA = true;
567 }
568
569 // There seems to be bug in swiftshader when we reuse scratch buffers for uploads. We end up
570 // with very slight pixel diffs. For example:
571 // (https://ci.chromium.org/ui/p/chromium/builders/try/linux-rel/1585128/overview).
572 // Since swiftshader is only really used for testing, to try and make things more stable we
573 // disable the reuse of buffers.
574 if (properties.vendorID == kGoogle_VkVendor && properties.deviceID == kSwiftshader_DeviceID) {
575 fReuseScratchBuffers = false;
576 }
577
578 ////////////////////////////////////////////////////////////////////////////
579 // GrCaps workarounds
580 ////////////////////////////////////////////////////////////////////////////
581
582 if (kARM_VkVendor == properties.vendorID) {
583 fAvoidWritePixelsFastPath = true; // bugs.skia.org/8064
584 }
585
586 // AMD advertises support for MAX_UINT vertex input attributes, but in reality only supports 32.
587 if (kAMD_VkVendor == properties.vendorID) {
589 }
590
591 // Adreno devices fail when trying to read the dest using an input attachment and texture
592 // barriers.
593 if (kQualcomm_VkVendor == properties.vendorID) {
595 }
596
597#ifdef SK_BUILD_FOR_WIN
598 // Gen 12 Intel devices running on windows has issues using barriers for dst reads. This is seen
599 // when running the unit tests SkRuntimeEffect_Blender_GPU and DMSAA_aa_dst_read_after_dmsaa.
600 //
601 // Additionally, as of 2023-01-19 the latest driver compatible with Intel Iris Graphics 540
602 // (9th gen Skylake microarchitecture) produce SkRuntimeEffect_Blender and DMSAA deltas that
603 // are unacceptable and break our tests. The drivers in question are version 31.0.101.2115 and
604 // can be downloaded from
605 // https://www.intel.com/content/www/us/en/download/762755/intel-6th-10th-gen-processor-graphics-windows.html.
606 // This is likely due to bugs in the driver. As a temporary workaround, we disable texture
607 // barrier support in Skylake and newer generations (i.e. 9th gen or newer).
608 if (kIntel_VkVendor == properties.vendorID &&
609 GetIntelGen(GetIntelGPUType(properties.deviceID)) >= 9) {
611 }
612#endif
613
614 // On ARM indirect draws are broken on Android 9 and earlier. This was tested on a P30 and
615 // Mate 20x running android 9.
616 if (properties.vendorID == kARM_VkVendor && androidAPIVersion <= 28) {
618 }
619
620 ////////////////////////////////////////////////////////////////////////////
621 // GrShaderCaps workarounds
622 ////////////////////////////////////////////////////////////////////////////
623
624 if (kImagination_VkVendor == properties.vendorID) {
625 fShaderCaps->fAtan2ImplementedAsAtanYOverX = true;
626 }
627
628 // ARM GPUs calculate `matrix * vector` in SPIR-V at full precision, even when the inputs are
629 // RelaxedPrecision. Rewriting the multiply as a sum of vector*scalar fixes this. (skia:11769)
630 if (kARM_VkVendor == properties.vendorID) {
631 fShaderCaps->fRewriteMatrixVectorMultiply = true;
632 }
633}
634
635void GrVkCaps::initGrCaps(const skgpu::VulkanInterface* vkInterface,
636 VkPhysicalDevice physDev,
637 const VkPhysicalDeviceProperties& properties,
638 const VkPhysicalDeviceMemoryProperties& memoryProperties,
639 const VkPhysicalDeviceFeatures2& features,
641 // So GPUs, like AMD, are reporting MAX_INT support vertex attributes. In general, there is no
642 // need for us ever to support that amount, and it makes tests which tests all the vertex
643 // attribs timeout looping over that many. For now, we'll cap this at 64 max and can raise it if
644 // we ever find that need.
645 static const uint32_t kMaxVertexAttributes = 64;
647 kMaxVertexAttributes);
648
649 // GrCaps::fSampleLocationsSupport refers to the ability to *query* the sample locations (not
650 // program them). For now we just set this to true if the device uses standard locations, and
651 // return the standard locations back when queried.
652 if (properties.limits.standardSampleLocations) {
654 }
655
658 }
659
660 fWireframeSupport = true;
661
662 // We could actually query and get a max size for each config, however maxImageDimension2D will
663 // give the minimum max size across all configs. So for simplicity we will use that for now.
664 fMaxRenderTargetSize = std::min(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX);
665 fMaxTextureSize = std::min(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX);
666
667 // TODO: check if RT's larger than 4k incur a performance cost on ARM.
669
670 fMaxPushConstantsSize = std::min(properties.limits.maxPushConstantsSize, (uint32_t)INT_MAX);
671
672 // Assuming since we will always map in the end to upload the data we might as well just map
673 // from the get go. There is no hard data to suggest this is faster or slower.
675
677
679
681 this->supportsPhysicalDeviceProperties2()) {
682
684 blendProps.sType =
686 blendProps.pNext = nullptr;
687
690 props.pNext = &blendProps;
691
692 GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties2(physDev, &props));
693
694 if (blendProps.advancedBlendAllOperations == VK_TRUE) {
696
697 auto blendFeatures = skgpu::GetExtensionFeatureStruct<
699 features,
701 );
702 if (blendFeatures && blendFeatures->advancedBlendCoherentOperations == VK_TRUE) {
704 } else {
706 }
707 }
708 }
709
710 if (kARM_VkVendor == properties.vendorID) {
712 }
713}
714
715void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties,
716 const VkPhysicalDeviceFeatures2& features) {
718 shaderCaps->fVersionDeclString = "#version 330\n";
719
720 // Ganesh + Vulkan always emits `sk_Clockwise` to avoid some Adreno rendering errors.
722
723 // Vulkan is based off ES 3.0 so the following should all be supported
726 // Flat interpolation appears to be slow on Qualcomm GPUs. This was tested in GL and is assumed
727 // to be true with Vulkan as well.
728 shaderCaps->fPreferFlatInterpolation = kQualcomm_VkVendor != properties.vendorID;
729
731
734
736
744
745 // Assume the minimum precisions mandated by the SPIR-V spec.
747 shaderCaps->fHalfIs32Bits = false;
748
752 (uint32_t)INT_MAX);
753}
754
756 VkPhysicalDevice physDev,
758 VkFormatProperties props;
759 memset(&props, 0, sizeof(VkFormatProperties));
760 GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
762}
763
764void GrVkCaps::initStencilFormat(const skgpu::VulkanInterface* interface,
765 VkPhysicalDevice physDev) {
766 if (stencil_format_supported(interface, physDev, VK_FORMAT_S8_UINT)) {
767 fPreferredStencilFormat = VK_FORMAT_S8_UINT;
768 } else if (stencil_format_supported(interface, physDev, VK_FORMAT_D24_UNORM_S8_UINT)) {
769 fPreferredStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
770 } else {
772 fPreferredStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
773 }
774}
775
778
779 switch (format) {
781 return true;
782 default:
783 return false;
784 }
785}
786
787// These are all the valid VkFormats that we support in Skia. They are roughly ordered from most
788// frequently used to least to improve look up times in arrays.
789static constexpr VkFormat kVkFormats[] = {
815};
816
817void GrVkCaps::setColorType(GrColorType colorType, std::initializer_list<VkFormat> formats) {
818#ifdef SK_DEBUG
819 for (size_t i = 0; i < kNumVkFormats; ++i) {
820 const auto& formatInfo = fFormatTable[i];
821 for (int j = 0; j < formatInfo.fColorTypeInfoCount; ++j) {
822 const auto& ctInfo = formatInfo.fColorTypeInfos[j];
823 if (ctInfo.fColorType == colorType &&
824 !SkToBool(ctInfo.fFlags & ColorTypeInfo::kWrappedOnly_Flag)) {
825 bool found = false;
826 for (auto it = formats.begin(); it != formats.end(); ++it) {
827 if (kVkFormats[i] == *it) {
828 found = true;
829 }
830 }
831 SkASSERT(found);
832 }
833 }
834 }
835#endif
836 int idx = static_cast<int>(colorType);
837 for (auto it = formats.begin(); it != formats.end(); ++it) {
838 const auto& info = this->getFormatInfo(*it);
839 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
840 if (info.fColorTypeInfos[i].fColorType == colorType) {
841 fColorTypeToFormatTable[idx] = *it;
842 return;
843 }
844 }
845 }
846}
847
848const GrVkCaps::FormatInfo& GrVkCaps::getFormatInfo(VkFormat format) const {
849 GrVkCaps* nonConstThis = const_cast<GrVkCaps*>(this);
850 return nonConstThis->getFormatInfo(format);
851}
852
853GrVkCaps::FormatInfo& GrVkCaps::getFormatInfo(VkFormat format) {
854 static_assert(std::size(kVkFormats) == GrVkCaps::kNumVkFormats,
855 "Size of VkFormats array must match static value in header");
856 for (size_t i = 0; i < std::size(kVkFormats); ++i) {
857 if (kVkFormats[i] == format) {
858 return fFormatTable[i];
859 }
860 }
861 static FormatInfo kInvalidFormat;
862 return kInvalidFormat;
863}
864
865void GrVkCaps::initFormatTable(const GrContextOptions& contextOptions,
866 const skgpu::VulkanInterface* interface,
867 VkPhysicalDevice physDev,
868 const VkPhysicalDeviceProperties& properties,
869 const VkPhysicalDeviceFeatures2& features,
871 static_assert(std::size(kVkFormats) == GrVkCaps::kNumVkFormats,
872 "Size of VkFormats array must match static value in header");
873
874 std::fill_n(fColorTypeToFormatTable, kGrColorTypeCnt, VK_FORMAT_UNDEFINED);
875
876 // Go through all the formats and init their support surface and data GrColorTypes.
877 // Format: VK_FORMAT_R8G8B8A8_UNORM
878 {
880 auto& info = this->getFormatInfo(format);
881 info.init(contextOptions, interface, physDev, properties, format);
882 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
883 info.fColorTypeInfoCount = 2;
884 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
885 int ctIdx = 0;
886 // Format: VK_FORMAT_R8G8B8A8_UNORM, Surface: kRGBA_8888
887 {
889 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
890 ctInfo.fColorType = ct;
891 ctInfo.fTransferColorType = ct;
892 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
893 }
894 // Format: VK_FORMAT_R8G8B8A8_UNORM, Surface: kRGB_888x
895 {
896 constexpr GrColorType ct = GrColorType::kRGB_888x;
897 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
898 ctInfo.fColorType = ct;
899 ctInfo.fTransferColorType = ct;
900 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
901 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
902 }
903 }
904 }
905
906 // Format: VK_FORMAT_R8_UNORM
907 {
909 auto& info = this->getFormatInfo(format);
910 info.init(contextOptions, interface, physDev, properties, format);
911 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
912 info.fColorTypeInfoCount = 3;
913 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
914 int ctIdx = 0;
915 // Format: VK_FORMAT_R8_UNORM, Surface: kR_8
916 {
917 constexpr GrColorType ct = GrColorType::kR_8;
918 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
919 ctInfo.fColorType = ct;
920 ctInfo.fTransferColorType = ct;
921 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
922 }
923 // Format: VK_FORMAT_R8_UNORM, Surface: kAlpha_8
924 {
925 constexpr GrColorType ct = GrColorType::kAlpha_8;
926 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
927 ctInfo.fColorType = ct;
928 ctInfo.fTransferColorType = ct;
929 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
930 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
931 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
932 }
933 // Format: VK_FORMAT_R8_UNORM, Surface: kGray_8
934 {
935 constexpr GrColorType ct = GrColorType::kGray_8;
936 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
937 ctInfo.fColorType = ct;
938 ctInfo.fTransferColorType = ct;
939 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
940 ctInfo.fReadSwizzle = skgpu::Swizzle("rrr1");
941 }
942 }
943 }
944 // Format: VK_FORMAT_B8G8R8A8_UNORM
945 {
947 auto& info = this->getFormatInfo(format);
948 info.init(contextOptions, interface, physDev, properties, format);
949 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
950 info.fColorTypeInfoCount = 2;
951 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
952 int ctIdx = 0;
953 // Format: VK_FORMAT_B8G8R8A8_UNORM, Surface: kBGRA_8888
954 {
956 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
957 ctInfo.fColorType = ct;
958 ctInfo.fTransferColorType = ct;
959 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
960 }
961 // Format: VK_FORMAT_B8G8R8A8_UNORM, Surface: kRGB_888x
962 // TODO: add and use kBGR_888X instead
963 {
964 constexpr GrColorType ct = GrColorType::kRGB_888x;
965 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
966 ctInfo.fColorType = ct;
967 ctInfo.fTransferColorType = GrColorType::kBGRA_8888;
968 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
969 ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
970 }
971 }
972 }
973 // Format: VK_FORMAT_R5G6B5_UNORM_PACK16
974 {
976 auto& info = this->getFormatInfo(format);
977 info.init(contextOptions, interface, physDev, properties, format);
978 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
979 info.fColorTypeInfoCount = 1;
980 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
981 int ctIdx = 0;
982 // Format: VK_FORMAT_R5G6B5_UNORM_PACK16, Surface: kBGR_565
983 {
984 constexpr GrColorType ct = GrColorType::kBGR_565;
985 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
986 ctInfo.fColorType = ct;
987 ctInfo.fTransferColorType = ct;
988 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
989 }
990 }
991 }
992 // Format: VK_FORMAT_B5G6R5_UNORM_PACK16
993 {
995 auto& info = this->getFormatInfo(format);
996 info.init(contextOptions, interface, physDev, properties, format);
997 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
998 info.fColorTypeInfoCount = 2;
999 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1000 int ctIdx = 0;
1001 // Format: VK_FORMAT_B5G6R5_UNORM_PACK16, Surface: kRGB_565
1002 {
1003 constexpr GrColorType ct = GrColorType::kRGB_565;
1004 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1005 ctInfo.fColorType = ct;
1006 ctInfo.fTransferColorType = ct;
1007 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1008 }
1009 // Format: VK_FORMAT_B5G6R5_UNORM_PACK16, Surface: kBGR_565
1010 // We need this because there is no kBGR_565_SkColorType.
1011 {
1012 constexpr GrColorType ct = GrColorType::kBGR_565;
1013 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1014 ctInfo.fColorType = ct;
1015 ctInfo.fTransferColorType = GrColorType::kRGB_565;
1016 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
1017 }
1018 }
1019 }
1020 // Format: VK_FORMAT_R16G16B16A16_SFLOAT
1021 {
1023 auto& info = this->getFormatInfo(format);
1024 info.init(contextOptions, interface, physDev, properties, format);
1025 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1026 info.fColorTypeInfoCount = 2;
1027 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1028 int ctIdx = 0;
1029 // Format: VK_FORMAT_R16G16B16A16_SFLOAT, Surface: GrColorType::kRGBA_F16
1030 {
1031 constexpr GrColorType ct = GrColorType::kRGBA_F16;
1032 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1033 ctInfo.fColorType = ct;
1034 ctInfo.fTransferColorType = ct;
1035 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1036 }
1037 // Format: VK_FORMAT_R16G16B16A16_SFLOAT, Surface: GrColorType::kRGBA_F16_Clamped
1038 {
1040 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1041 ctInfo.fColorType = ct;
1042 ctInfo.fTransferColorType = ct;
1043 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1044 }
1045 }
1046 }
1047 // Format: VK_FORMAT_R16_SFLOAT
1048 {
1050 auto& info = this->getFormatInfo(format);
1051 info.init(contextOptions, interface, physDev, properties, format);
1052 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1053 info.fColorTypeInfoCount = 1;
1054 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1055 int ctIdx = 0;
1056 // Format: VK_FORMAT_R16_SFLOAT, Surface: kAlpha_F16
1057 {
1058 constexpr GrColorType ct = GrColorType::kAlpha_F16;
1059 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1060 ctInfo.fColorType = ct;
1061 ctInfo.fTransferColorType = ct;
1062 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1063 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
1064 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
1065 }
1066 }
1067 }
1068 // Format: VK_FORMAT_R8G8B8_UNORM
1069 {
1071 auto& info = this->getFormatInfo(format);
1072 info.init(contextOptions, interface, physDev, properties, format);
1073 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1074 info.fColorTypeInfoCount = 1;
1075 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1076 int ctIdx = 0;
1077 // Format: VK_FORMAT_R8G8B8_UNORM, Surface: kRGB_888x
1078 {
1079 constexpr GrColorType ct = GrColorType::kRGB_888x;
1080 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1081 ctInfo.fColorType = ct;
1082 // The Vulkan format is 3 bpp so we must convert to/from that when transferring.
1083 ctInfo.fTransferColorType = GrColorType::kRGB_888;
1084 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1085 }
1086 }
1087 }
1088 // Format: VK_FORMAT_R8G8_UNORM
1089 {
1091 auto& info = this->getFormatInfo(format);
1092 info.init(contextOptions, interface, physDev, properties, format);
1093 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1094 info.fColorTypeInfoCount = 1;
1095 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1096 int ctIdx = 0;
1097 // Format: VK_FORMAT_R8G8_UNORM, Surface: kRG_88
1098 {
1099 constexpr GrColorType ct = GrColorType::kRG_88;
1100 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1101 ctInfo.fColorType = ct;
1102 ctInfo.fTransferColorType = ct;
1103 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1104 }
1105 }
1106 }
1107 // Format: VK_FORMAT_A2B10G10R10_UNORM_PACK32
1108 {
1110 auto& info = this->getFormatInfo(format);
1111 info.init(contextOptions, interface, physDev, properties, format);
1112 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1113 info.fColorTypeInfoCount = 1;
1114 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1115 int ctIdx = 0;
1116 // Format: VK_FORMAT_A2B10G10R10_UNORM_PACK32, Surface: kRGBA_1010102
1117 {
1119 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1120 ctInfo.fColorType = ct;
1121 ctInfo.fTransferColorType = ct;
1122 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1123 }
1124 }
1125 }
1126 // Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32
1127 {
1129 auto& info = this->getFormatInfo(format);
1130 info.init(contextOptions, interface, physDev, properties, format);
1131 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1132 info.fColorTypeInfoCount = 1;
1133 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1134 int ctIdx = 0;
1135 // Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, Surface: kBGRA_1010102
1136 {
1138 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1139 ctInfo.fColorType = ct;
1140 ctInfo.fTransferColorType = ct;
1141 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1142 }
1143 }
1144 }
1145
1146 bool supportsRGBA10x6 = false;
1148 auto rgba10x6Feature =
1149 skgpu::GetExtensionFeatureStruct<VkPhysicalDeviceRGBA10X6FormatsFeaturesEXT>(
1151 // Technically without this extension and exabled feature we could still use this format to
1152 // sample with a ycbcr sampler. But for simplicity until we have clients requesting that, we
1153 // limit the use of this format to cases where we have the extension supported.
1154 supportsRGBA10x6 = rgba10x6Feature && rgba10x6Feature->formatRgba10x6WithoutYCbCrSampler;
1155 }
1156
1157 // Format: VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16
1158 if (supportsRGBA10x6) {
1160 auto& info = this->getFormatInfo(format);
1161 info.init(contextOptions, interface, physDev, properties, format);
1162 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1163 info.fColorTypeInfoCount = 1;
1164 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1165 int ctIdx = 0;
1166 // Format: VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16, Surface: kRGBA_10x6
1167 {
1168 constexpr GrColorType ct = GrColorType::kRGBA_10x6;
1169 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1170 ctInfo.fColorType = ct;
1171 ctInfo.fTransferColorType = ct;
1172 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1173 }
1174 }
1175 }
1176
1177 // Format: VK_FORMAT_B4G4R4A4_UNORM_PACK16
1178 {
1180 auto& info = this->getFormatInfo(format);
1181 info.init(contextOptions, interface, physDev, properties, format);
1182 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1183 info.fColorTypeInfoCount = 1;
1184 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1185 int ctIdx = 0;
1186 // Format: VK_FORMAT_B4G4R4A4_UNORM_PACK16, Surface: kABGR_4444
1187 {
1188 constexpr GrColorType ct = GrColorType::kABGR_4444;
1189 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1190 ctInfo.fColorType = ct;
1191 ctInfo.fTransferColorType = ct;
1192 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1193 ctInfo.fReadSwizzle = skgpu::Swizzle::BGRA();
1194 ctInfo.fWriteSwizzle = skgpu::Swizzle::BGRA();
1195 }
1196 }
1197 }
1198
1199 // Format: VK_FORMAT_R4G4B4A4_UNORM_PACK16
1200 {
1202 auto& info = this->getFormatInfo(format);
1203 info.init(contextOptions, interface, physDev, properties, format);
1204 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1205 info.fColorTypeInfoCount = 1;
1206 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1207 int ctIdx = 0;
1208 // Format: VK_FORMAT_R4G4B4A4_UNORM_PACK16, Surface: kABGR_4444
1209 {
1210 constexpr GrColorType ct = GrColorType::kABGR_4444;
1211 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1212 ctInfo.fColorType = ct;
1213 ctInfo.fTransferColorType = ct;
1214 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1215 }
1216 }
1217 }
1218 // Format: VK_FORMAT_R8G8B8A8_SRGB
1219 {
1221 auto& info = this->getFormatInfo(format);
1222 info.init(contextOptions, interface, physDev, properties, format);
1223 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1224 info.fColorTypeInfoCount = 1;
1225 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1226 int ctIdx = 0;
1227 // Format: VK_FORMAT_R8G8B8A8_SRGB, Surface: kRGBA_8888_SRGB
1228 {
1230 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1231 ctInfo.fColorType = ct;
1232 ctInfo.fTransferColorType = ct;
1233 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1234 }
1235 }
1236 }
1237 // Format: VK_FORMAT_R16_UNORM
1238 {
1240 auto& info = this->getFormatInfo(format);
1241 info.init(contextOptions, interface, physDev, properties, format);
1242 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1243 info.fColorTypeInfoCount = 1;
1244 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1245 int ctIdx = 0;
1246 // Format: VK_FORMAT_R16_UNORM, Surface: kAlpha_16
1247 {
1248 constexpr GrColorType ct = GrColorType::kAlpha_16;
1249 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1250 ctInfo.fColorType = ct;
1251 ctInfo.fTransferColorType = ct;
1252 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1253 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
1254 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
1255 }
1256 }
1257 }
1258 // Format: VK_FORMAT_R16G16_UNORM
1259 {
1261 auto& info = this->getFormatInfo(format);
1262 info.init(contextOptions, interface, physDev, properties, format);
1263 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1264 info.fColorTypeInfoCount = 1;
1265 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1266 int ctIdx = 0;
1267 // Format: VK_FORMAT_R16G16_UNORM, Surface: kRG_1616
1268 {
1269 constexpr GrColorType ct = GrColorType::kRG_1616;
1270 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1271 ctInfo.fColorType = ct;
1272 ctInfo.fTransferColorType = ct;
1273 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1274 }
1275 }
1276 }
1277 // Format: VK_FORMAT_R16G16B16A16_UNORM
1278 {
1280 auto& info = this->getFormatInfo(format);
1281 info.init(contextOptions, interface, physDev, properties, format);
1282 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1283 info.fColorTypeInfoCount = 1;
1284 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1285 int ctIdx = 0;
1286 // Format: VK_FORMAT_R16G16B16A16_UNORM, Surface: kRGBA_16161616
1287 {
1289 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1290 ctInfo.fColorType = ct;
1291 ctInfo.fTransferColorType = ct;
1292 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1293 }
1294 }
1295 }
1296 // Format: VK_FORMAT_R16G16_SFLOAT
1297 {
1299 auto& info = this->getFormatInfo(format);
1300 info.init(contextOptions, interface, physDev, properties, format);
1301 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1302 info.fColorTypeInfoCount = 1;
1303 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1304 int ctIdx = 0;
1305 // Format: VK_FORMAT_R16G16_SFLOAT, Surface: kRG_F16
1306 {
1307 constexpr GrColorType ct = GrColorType::kRG_F16;
1308 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1309 ctInfo.fColorType = ct;
1310 ctInfo.fTransferColorType = ct;
1311 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1312 }
1313 }
1314 }
1315 // Format: VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM
1316 {
1318 auto& info = this->getFormatInfo(format);
1319 if (fSupportsYcbcrConversion) {
1320 info.init(contextOptions, interface, physDev, properties, format);
1321 }
1322 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1323 info.fColorTypeInfoCount = 1;
1324 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1325 int ctIdx = 0;
1326 // Format: VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, Surface: kRGB_888x
1327 {
1328 constexpr GrColorType ct = GrColorType::kRGB_888x;
1329 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1330 ctInfo.fColorType = ct;
1331 ctInfo.fTransferColorType = ct;
1332 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kWrappedOnly_Flag;
1333 }
1334 }
1335 }
1336 // Format: VK_FORMAT_G8_B8R8_2PLANE_420_UNORM
1337 {
1339 auto& info = this->getFormatInfo(format);
1340 if (fSupportsYcbcrConversion) {
1341 info.init(contextOptions, interface, physDev, properties, format);
1342 }
1343 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1344 info.fColorTypeInfoCount = 1;
1345 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1346 int ctIdx = 0;
1347 // Format: VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, Surface: kRGB_888x
1348 {
1349 constexpr GrColorType ct = GrColorType::kRGB_888x;
1350 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1351 ctInfo.fColorType = ct;
1352 ctInfo.fTransferColorType = ct;
1353 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kWrappedOnly_Flag;
1354 }
1355 }
1356 }
1357 // Format: VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16
1358 {
1360 auto& info = this->getFormatInfo(format);
1361 if (fSupportsYcbcrConversion) {
1362 info.init(contextOptions, interface, physDev, properties, format);
1363 }
1364 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1365 info.fColorTypeInfoCount = 1;
1366 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
1367 int ctIdx = 0;
1368 // Format: VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, Surface: kRGBA_1010102
1369 {
1371 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1372 ctInfo.fColorType = ct;
1373 ctInfo.fTransferColorType = ct;
1374 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kWrappedOnly_Flag;
1375 }
1376 }
1377 }
1378 // Format: VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK
1379 {
1381 auto& info = this->getFormatInfo(format);
1382 info.init(contextOptions, interface, physDev, properties, format);
1383 // Setting this to texel block size
1384 // No supported GrColorTypes.
1385 }
1386
1387 // Format: VK_FORMAT_BC1_RGB_UNORM_BLOCK
1388 {
1390 auto& info = this->getFormatInfo(format);
1391 info.init(contextOptions, interface, physDev, properties, format);
1392 // Setting this to texel block size
1393 // No supported GrColorTypes.
1394 }
1395
1396 // Format: VK_FORMAT_BC1_RGBA_UNORM_BLOCK
1397 {
1399 auto& info = this->getFormatInfo(format);
1400 info.init(contextOptions, interface, physDev, properties, format);
1401 // Setting this to texel block size
1402 // No supported GrColorTypes.
1403 }
1404
1405 ////////////////////////////////////////////////////////////////////////////
1406 // Map GrColorTypes (used for creating GrSurfaces) to VkFormats. The order in which the formats
1407 // are passed into the setColorType function indicates the priority in selecting which format
1408 // we use for a given GrcolorType.
1409
1410 this->setColorType(GrColorType::kAlpha_8, { VK_FORMAT_R8_UNORM });
1416 this->setColorType(GrColorType::kRGBA_8888, { VK_FORMAT_R8G8B8A8_UNORM });
1418 this->setColorType(GrColorType::kRGB_888x, { VK_FORMAT_R8G8B8_UNORM,
1421 this->setColorType(GrColorType::kRG_88, { VK_FORMAT_R8G8_UNORM });
1422 this->setColorType(GrColorType::kBGRA_8888, { VK_FORMAT_B8G8R8A8_UNORM });
1425 this->setColorType(GrColorType::kGray_8, { VK_FORMAT_R8_UNORM });
1426 this->setColorType(GrColorType::kAlpha_F16, { VK_FORMAT_R16_SFLOAT });
1429 this->setColorType(GrColorType::kAlpha_16, { VK_FORMAT_R16_UNORM });
1430 this->setColorType(GrColorType::kRG_1616, { VK_FORMAT_R16G16_UNORM });
1432 this->setColorType(GrColorType::kRG_F16, { VK_FORMAT_R16G16_SFLOAT });
1433}
1434
1435void GrVkCaps::FormatInfo::InitFormatFlags(VkFormatFeatureFlags vkFlags, uint16_t* flags) {
1438 *flags = *flags | kTexturable_Flag;
1439
1440 // Ganesh assumes that all renderable surfaces are also texturable
1442 *flags = *flags | kRenderable_Flag;
1443 }
1444 }
1445 // TODO: For Vk w/ VK_KHR_maintenance1 extension support, check
1446 // VK_FORMAT_FEATURE_TRANSFER_[SRC|DST]_BIT_KHR explicitly to set copy flags
1447 // Can do similar check for VK_KHR_sampler_ycbcr_conversion added bits
1448
1450 *flags = *flags | kBlitSrc_Flag;
1451 }
1452
1454 *flags = *flags | kBlitDst_Flag;
1455 }
1456}
1457
1458void GrVkCaps::FormatInfo::initSampleCounts(const GrContextOptions& contextOptions,
1459 const skgpu::VulkanInterface* interface,
1460 VkPhysicalDevice physDev,
1461 const VkPhysicalDeviceProperties& physProps,
1462 VkFormat format) {
1467 VkImageFormatProperties properties;
1468 GR_VK_CALL(interface, GetPhysicalDeviceImageFormatProperties(physDev,
1469 format,
1472 usage,
1473 0, // createFlags
1474 &properties));
1477 fColorSampleCounts.push_back(1);
1478 }
1479 if (kImagination_VkVendor == physProps.vendorID) {
1480 // MSAA does not work on imagination
1481 return;
1482 }
1483 if (kIntel_VkVendor == physProps.vendorID) {
1484 if (GetIntelGen(GetIntelGPUType(physProps.deviceID)) < 12 ||
1485 !contextOptions.fAllowMSAAOnNewIntel) {
1486 // MSAA doesn't work well on Intel GPUs chromium:527565, chromium:983926
1487 return;
1488 }
1489 }
1491 fColorSampleCounts.push_back(2);
1492 }
1494 fColorSampleCounts.push_back(4);
1495 }
1497 fColorSampleCounts.push_back(8);
1498 }
1500 fColorSampleCounts.push_back(16);
1501 }
1502 // Standard sample locations are not defined for more than 16 samples, and we don't need more
1503 // than 16. Omit 32 and 64.
1504}
1505
1506void GrVkCaps::FormatInfo::init(const GrContextOptions& contextOptions,
1507 const skgpu::VulkanInterface* interface,
1508 VkPhysicalDevice physDev,
1509 const VkPhysicalDeviceProperties& properties,
1510 VkFormat format) {
1511 VkFormatProperties props;
1512 memset(&props, 0, sizeof(VkFormatProperties));
1513 GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
1514 InitFormatFlags(props.linearTilingFeatures, &fLinearFlags);
1515 InitFormatFlags(props.optimalTilingFeatures, &fOptimalFlags);
1516 if (fOptimalFlags & kRenderable_Flag) {
1517 this->initSampleCounts(contextOptions, interface, physDev, properties, format);
1518 }
1519}
1520
1521// For many checks in caps, we need to know whether the GrBackendFormat is external or not. If it is
1522// external the VkFormat will be VK_NULL_HANDLE which is not handled by our various format
1523// capability checks.
1525 const skgpu::VulkanYcbcrConversionInfo* ycbcrInfo =
1527 SkASSERT(ycbcrInfo);
1528
1529 // All external formats have a valid ycbcrInfo used for sampling and a non zero external format.
1530 if (ycbcrInfo->isValid() && ycbcrInfo->fExternalFormat != 0) {
1531#ifdef SK_DEBUG
1532 VkFormat vkFormat;
1534 SkASSERT(vkFormat == VK_FORMAT_UNDEFINED);
1535#endif
1536 return true;
1537 }
1538 return false;
1539}
1540
1542 VkFormat vkFormat;
1543 if (!GrBackendFormats::AsVkFormat(format, &vkFormat)) {
1544 return false;
1545 }
1547 return false;
1548 }
1549
1550 return format_is_srgb(vkFormat);
1551}
1552
1554 VkFormat vkFormat;
1555 if (!GrBackendFormats::AsVkFormat(format, &vkFormat)) {
1556 return false;
1557 }
1559 // We can always texture from an external format (assuming we have the ycbcr conversion
1560 // info which we require to be passed in).
1561 return true;
1562 }
1563 return this->isVkFormatTexturable(vkFormat);
1564}
1565
1567 const FormatInfo& info = this->getFormatInfo(format);
1568 return SkToBool(FormatInfo::kTexturable_Flag & info.fOptimalFlags);
1569}
1570
1572 int sampleCount) const {
1573 if (!this->isFormatRenderable(format, sampleCount)) {
1574 return false;
1575 }
1576 VkFormat vkFormat;
1577 if (!GrBackendFormats::AsVkFormat(format, &vkFormat)) {
1578 return false;
1579 }
1580 const auto& info = this->getFormatInfo(vkFormat);
1581 if (!SkToBool(info.colorTypeFlags(ct) & ColorTypeInfo::kRenderable_Flag)) {
1582 return false;
1583 }
1584 return true;
1585}
1586
1587bool GrVkCaps::isFormatRenderable(const GrBackendFormat& format, int sampleCount) const {
1588 VkFormat vkFormat;
1589 if (!GrBackendFormats::AsVkFormat(format, &vkFormat)) {
1590 return false;
1591 }
1592 return this->isFormatRenderable(vkFormat, sampleCount);
1593}
1594
1595bool GrVkCaps::isFormatRenderable(VkFormat format, int sampleCount) const {
1596 return sampleCount <= this->maxRenderTargetSampleCount(format);
1597}
1598
1600 const GrBackendFormat& format) const {
1601 VkFormat vkFormat;
1602 if (!GrBackendFormats::AsVkFormat(format, &vkFormat)) {
1603 return 0;
1604 }
1605
1606 return this->getRenderTargetSampleCount(requestedCount, vkFormat);
1607}
1608
1610 requestedCount = std::max(1, requestedCount);
1611
1612 const FormatInfo& info = this->getFormatInfo(format);
1613
1614 int count = info.fColorSampleCounts.size();
1615
1616 if (!count) {
1617 return 0;
1618 }
1619
1620 if (1 == requestedCount) {
1621 SkASSERT(!info.fColorSampleCounts.empty() && info.fColorSampleCounts[0] == 1);
1622 return 1;
1623 }
1624
1625 for (int i = 0; i < count; ++i) {
1626 if (info.fColorSampleCounts[i] >= requestedCount) {
1627 return info.fColorSampleCounts[i];
1628 }
1629 }
1630 return 0;
1631}
1632
1634 VkFormat vkFormat;
1635 if (!GrBackendFormats::AsVkFormat(format, &vkFormat)) {
1636 return 0;
1637 }
1638 return this->maxRenderTargetSampleCount(vkFormat);
1639}
1640
1642 const FormatInfo& info = this->getFormatInfo(format);
1643
1644 const auto& table = info.fColorSampleCounts;
1645 if (table.empty()) {
1646 return 0;
1647 }
1648 return table[table.size() - 1];
1649}
1650
1651static inline size_t align_to_4(size_t v) {
1652 switch (v & 0b11) {
1653 // v is already a multiple of 4.
1654 case 0: return v;
1655 // v is a multiple of 2 but not 4.
1656 case 2: return 2 * v;
1657 // v is not a multiple of 2.
1658 default: return 4 * v;
1659 }
1660}
1661
1663 const GrBackendFormat& surfaceFormat,
1664 GrColorType srcColorType) const {
1665 VkFormat vkFormat;
1666 if (!GrBackendFormats::AsVkFormat(surfaceFormat, &vkFormat)) {
1667 return {GrColorType::kUnknown, 0};
1668 }
1669
1670 // We don't support the ability to upload to external formats or formats that require a ycbcr
1671 // sampler. In general these types of formats are only used for sampling in a shader.
1672 if (backend_format_is_external(surfaceFormat) || skgpu::VkFormatNeedsYcbcrSampler(vkFormat)) {
1673 return {GrColorType::kUnknown, 0};
1674 }
1675
1676 // The VkBufferImageCopy bufferOffset field must be both a multiple of 4 and of a single texel.
1677 size_t offsetAlignment = align_to_4(skgpu::VkFormatBytesPerBlock(vkFormat));
1678
1679 const auto& info = this->getFormatInfo(vkFormat);
1680 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1681 const auto& ctInfo = info.fColorTypeInfos[i];
1682 if (ctInfo.fColorType == surfaceColorType) {
1683 return {ctInfo.fTransferColorType, offsetAlignment};
1684 }
1685 }
1686 return {GrColorType::kUnknown, 0};
1687}
1688
1690 const GrSurface* surface) const {
1691 if (surface->isProtected()) {
1693 }
1694 if (auto tex = static_cast<const GrVkTexture*>(surface->asTexture())) {
1695 auto texImage = tex->textureImage();
1696 if (!texImage) {
1698 }
1699 // We can't directly read from a VkImage that has a ycbcr sampler.
1700 if (texImage->ycbcrConversionInfo().isValid()) {
1702 }
1703 // We can't directly read from a compressed format
1704 if (skgpu::VkFormatIsCompressed(texImage->imageFormat())) {
1706 }
1708 } else if (auto rt = surface->asRenderTarget()) {
1709 if (rt->numSamples() > 1) {
1711 }
1713 }
1715}
1716
1718 const auto& info = this->getFormatInfo(vkFormat);
1719 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1720 if (info.fColorTypeInfos[i].fColorType == surfaceColorType) {
1721 return info.fColorTypeInfos[i].fTransferColorType;
1722 }
1723 }
1724 return GrColorType::kUnknown;
1725}
1726
1727bool GrVkCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
1728 if (auto rt = surface->asRenderTarget()) {
1729 return rt->numSamples() <= 1 && SkToBool(surface->asTexture());
1730 }
1731 // We can't write to a texture that has a ycbcr sampler.
1732 if (auto tex = static_cast<const GrVkTexture*>(surface->asTexture())) {
1733 auto texImage = tex->textureImage();
1734 if (!texImage) {
1735 return false;
1736 }
1737 // We can't directly read from a VkImage that has a ycbcr sampler.
1738 if (texImage->ycbcrConversionInfo().isValid()) {
1739 return false;
1740 }
1741 }
1742 return true;
1743}
1744
1745bool GrVkCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
1746 const GrBackendFormat& format) const {
1747 VkFormat vkFormat;
1748 if (!GrBackendFormats::AsVkFormat(format, &vkFormat)) {
1749 return false;
1750 }
1751 const skgpu::VulkanYcbcrConversionInfo* ycbcrInfo =
1753 SkASSERT(ycbcrInfo);
1754
1755 if (ycbcrInfo->isValid() && !skgpu::VkFormatNeedsYcbcrSampler(vkFormat)) {
1756 // Format may be undefined for external images, which are required to have YCbCr conversion.
1757 if (VK_FORMAT_UNDEFINED == vkFormat && ycbcrInfo->fExternalFormat != 0) {
1758 return true;
1759 }
1760 return false;
1761 }
1762
1763 const auto& info = this->getFormatInfo(vkFormat);
1764 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1765 if (info.fColorTypeInfos[i].fColorType == ct) {
1766 return true;
1767 }
1768 }
1769 return false;
1770}
1771
1772GrBackendFormat GrVkCaps::onGetDefaultBackendFormat(GrColorType ct) const {
1774 if (format == VK_FORMAT_UNDEFINED) {
1775 return {};
1776 }
1778}
1779
1780bool GrVkCaps::onSupportsDynamicMSAA(const GrRenderTargetProxy* rtProxy) const {
1781 // We must be able to use the rtProxy as an input attachment to load into the discardable msaa
1782 // attachment. Also the rtProxy should have a sample count of 1 so that it can be used as a
1783 // resolve attachment.
1784 return this->supportsDiscardableMSAAForDMSAA() &&
1785 rtProxy->supportsVkInputAttachment() &&
1786 rtProxy->numSamples() == 1;
1787}
1788
1790 return rt->resolveAttachment() &&
1792 ((rt->numSamples() > 1 && this->preferDiscardableMSAAAttachment()) ||
1793 (rt->numSamples() == 1 && this->supportsDiscardableMSAAForDMSAA()));
1794}
1795
1797 return programInfo.targetHasVkResolveAttachmentWithInput() &&
1798 programInfo.numSamples() > 1 &&
1799 ((programInfo.targetsNumSamples() > 1 && this->preferDiscardableMSAAAttachment()) ||
1800 (programInfo.targetsNumSamples() == 1 && this->supportsDiscardableMSAAForDMSAA()));
1801}
1802
1804 SkTextureCompressionType compressionType) const {
1805 switch (compressionType) {
1807 return {};
1811 }
1812 return {};
1816 }
1817 return {};
1821 }
1822 return {};
1823 }
1824
1826}
1827
1828skgpu::Swizzle GrVkCaps::onGetReadSwizzle(const GrBackendFormat& format,
1829 GrColorType colorType) const {
1830 VkFormat vkFormat;
1832 const skgpu::VulkanYcbcrConversionInfo* ycbcrInfo =
1834 SkASSERT(ycbcrInfo);
1835 if (ycbcrInfo->isValid() && ycbcrInfo->fExternalFormat != 0) {
1836 // We allow these to work with any color type and never swizzle. See
1837 // onAreColorTypeAndFormatCompatible.
1838 return skgpu::Swizzle{"rgba"};
1839 }
1840
1841 const auto& info = this->getFormatInfo(vkFormat);
1842 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1843 const auto& ctInfo = info.fColorTypeInfos[i];
1844 if (ctInfo.fColorType == colorType) {
1845 return ctInfo.fReadSwizzle;
1846 }
1847 }
1848 SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
1849 (int)colorType, (int)vkFormat);
1850 return {};
1851}
1852
1854 GrColorType colorType) const {
1855 VkFormat vkFormat;
1857 const auto& info = this->getFormatInfo(vkFormat);
1858 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1859 const auto& ctInfo = info.fColorTypeInfos[i];
1860 if (ctInfo.fColorType == colorType) {
1861 return ctInfo.fWriteSwizzle;
1862 }
1863 }
1864 SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
1865 (int)colorType, (int)vkFormat);
1866 return {};
1867}
1868
1869GrDstSampleFlags GrVkCaps::onGetDstSampleFlagsForProxy(const GrRenderTargetProxy* rt) const {
1870 bool isMSAAWithResolve = rt->numSamples() > 1 && rt->asTextureProxy();
1871 // TODO: Currently if we have an msaa rt with a resolve, the supportsVkInputAttachment call
1872 // references whether the resolve is supported as an input attachment. We need to add a check to
1873 // allow checking the color attachment (msaa or not) supports input attachment specifically.
1874 if (!isMSAAWithResolve && rt->supportsVkInputAttachment()) {
1876 }
1878}
1879
1881 VkFormat vkFormat;
1883
1884#ifdef SK_DEBUG
1885 // We should never be trying to compute a key for an external format
1886 const skgpu::VulkanYcbcrConversionInfo* ycbcrInfo =
1888 SkASSERT(ycbcrInfo);
1889 SkASSERT(!ycbcrInfo->isValid() || ycbcrInfo->fExternalFormat == 0);
1890#endif
1891
1892 // A VkFormat has a size of 64 bits.
1893 return (uint64_t)vkFormat;
1894}
1895
1896GrCaps::SupportedRead GrVkCaps::onSupportedReadPixelsColorType(
1897 GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
1898 GrColorType dstColorType) const {
1899 VkFormat vkFormat;
1900 if (!GrBackendFormats::AsVkFormat(srcBackendFormat, &vkFormat)) {
1901 return {GrColorType::kUnknown, 0};
1902 }
1903
1904 if (skgpu::VkFormatNeedsYcbcrSampler(vkFormat)) {
1905 return {GrColorType::kUnknown, 0};
1906 }
1907
1908 SkTextureCompressionType compression = GrBackendFormatToCompressionType(srcBackendFormat);
1909 if (compression != SkTextureCompressionType::kNone) {
1912 }
1913
1914 // The VkBufferImageCopy bufferOffset field must be both a multiple of 4 and of a single texel.
1915 size_t offsetAlignment = align_to_4(skgpu::VkFormatBytesPerBlock(vkFormat));
1916
1917 const auto& info = this->getFormatInfo(vkFormat);
1918 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1919 const auto& ctInfo = info.fColorTypeInfos[i];
1920 if (ctInfo.fColorType == srcColorType) {
1921 return {ctInfo.fTransferColorType, offsetAlignment};
1922 }
1923 }
1924 return {GrColorType::kUnknown, 0};
1925}
1926
1929}
1930
1933}
1934
1936 GrSamplerState samplerState,
1937 const GrBackendFormat& format) const {
1938 const skgpu::VulkanYcbcrConversionInfo* ycbcrInfo =
1940 if (!ycbcrInfo) {
1941 return;
1942 }
1943
1944 GrVkSampler::Key key = GrVkSampler::GenerateKey(samplerState, *ycbcrInfo);
1945
1946 constexpr size_t numInts = (sizeof(key) + 3) / 4;
1947 uint32_t tmp[numInts];
1948 memcpy(tmp, &key, sizeof(key));
1949
1950 for (size_t i = 0; i < numInts; ++i) {
1951 b->add32(tmp[i]);
1952 }
1953}
1954
1955/**
1956 * For Vulkan we want to cache the entire VkPipeline for reuse of draws. The Desc here holds all
1957 * the information needed to differentiate one pipeline from another.
1958 *
1959 * The GrProgramDesc contains all the information need to create the actual shaders for the
1960 * pipeline.
1961 *
1962 * For Vulkan we need to add to the GrProgramDesc to include the rest of the state on the
1963 * pipline. This includes stencil settings, blending information, render pass format, draw face
1964 * information, and primitive type. Note that some state is set dynamically on the pipeline for
1965 * each draw and thus is not included in this descriptor. This includes the viewport, scissor,
1966 * and blend constant.
1967 */
1969 const GrProgramInfo& programInfo,
1970 ProgramDescOverrideFlags overrideFlags) const {
1972 GrProgramDesc::Build(&desc, programInfo, *this);
1973
1974 skgpu::KeyBuilder b(desc.key());
1975
1976 // This will become part of the sheared off key used to persistently cache
1977 // the SPIRV code. It needs to be added right after the base key so that,
1978 // when the base-key is sheared off, the shearing code can include it in the
1979 // reduced key (c.f. the +4s in the SkData::MakeWithCopy calls in
1980 // GrVkPipelineStateBuilder.cpp).
1982
1984 if (programInfo.renderPassBarriers() & GrXferBarrierFlags::kBlend) {
1986 }
1989 }
1990
1991 bool needsResolve = this->programInfoWillUseDiscardableMSAA(programInfo);
1992
1993 bool forceLoadFromResolve =
1995 SkASSERT(!forceLoadFromResolve || needsResolve);
1996
1998 if (needsResolve && (programInfo.colorLoadOp() == GrLoadOp::kLoad || forceLoadFromResolve)) {
2000 }
2001
2002 if (rt) {
2003 GrVkRenderTarget* vkRT = (GrVkRenderTarget*) rt;
2004
2005 SkASSERT(!needsResolve || (vkRT->resolveAttachment() &&
2007
2008 bool needsStencil = programInfo.needsStencil() || programInfo.isStencilEnabled();
2009 // TODO: support failure in getSimpleRenderPass
2010 auto rp = vkRT->getSimpleRenderPass(needsResolve, needsStencil, selfDepFlags,
2011 loadFromResolve);
2012 SkASSERT(rp);
2013 rp->genKey(&b);
2014
2015#ifdef SK_DEBUG
2016 if (!rp->isExternal()) {
2017 // This is to ensure ReconstructAttachmentsDescriptor keeps matching
2018 // getSimpleRenderPass' result
2019 GrVkRenderPass::AttachmentsDescriptor attachmentsDescriptor;
2020 GrVkRenderPass::AttachmentFlags attachmentFlags;
2022 &attachmentsDescriptor,
2023 &attachmentFlags);
2024 SkASSERT(rp->isCompatible(attachmentsDescriptor, attachmentFlags, selfDepFlags,
2025 loadFromResolve));
2026 }
2027#endif
2028 } else {
2029 GrVkRenderPass::AttachmentsDescriptor attachmentsDescriptor;
2030 GrVkRenderPass::AttachmentFlags attachmentFlags;
2032 &attachmentsDescriptor,
2033 &attachmentFlags);
2034
2035 // kExternal_AttachmentFlag is only set for wrapped secondary command buffers - which
2036 // will always go through the above 'rt' path (i.e., we can always pass 0 as the final
2037 // parameter to GenKey).
2038 GrVkRenderPass::GenKey(&b, attachmentFlags, attachmentsDescriptor, selfDepFlags,
2039 loadFromResolve, 0);
2040 }
2041
2042 GrStencilSettings stencil = programInfo.nonGLStencilSettings();
2043 stencil.genKey(&b, true);
2044
2045 programInfo.pipeline().genKey(&b, *this);
2046 b.add32(programInfo.numSamples());
2047
2048 // Vulkan requires the full primitive type as part of its key
2049 b.add32(programInfo.primitiveTypeKey());
2050
2051 b.flush();
2052 return desc;
2053}
2054
2056 // We always create vulkan RT with the input attachment flag;
2058}
2059
2062 return stageFlags;
2063}
2064
2065template <size_t N>
2066static bool intel_deviceID_present(const std::array<uint32_t, N>& array, uint32_t deviceID) {
2067 return std::find(array.begin(), array.end(), deviceID) != array.end();
2068}
2069
2070
2071GrVkCaps::IntelGPUType GrVkCaps::GetIntelGPUType(uint32_t deviceID) {
2072 // Some common Intel GPU models, currently we cover SKL/ICL/RKL/TGL/ADL
2073 // Referenced from the following Mesa source files:
2074 // https://github.com/mesa3d/mesa/blob/master/include/pci_ids/i965_pci_ids.h
2075 // https://github.com/mesa3d/mesa/blob/master/include/pci_ids/iris_pci_ids.h
2076 static constexpr std::array<uint32_t, 25> kSkyLakeIDs = {
2077 {0x1902, 0x1906, 0x190A, 0x190B, 0x190E, 0x1912, 0x1913,
2078 0x1915, 0x1916, 0x1917, 0x191A, 0x191B, 0x191D, 0x191E,
2079 0x1921, 0x1923, 0x1926, 0x1927, 0x192A, 0x192B, 0x192D,
2080 0x1932, 0x193A, 0x193B, 0x193D}};
2081 static constexpr std::array<uint32_t, 14> kIceLakeIDs = {
2082 {0x8A50, 0x8A51, 0x8A52, 0x8A53, 0x8A54, 0x8A56, 0x8A57,
2083 0x8A58, 0x8A59, 0x8A5A, 0x8A5B, 0x8A5C, 0x8A5D, 0x8A71}};
2084 static constexpr std::array<uint32_t, 5> kRocketLakeIDs = {
2085 {0x4c8a, 0x4c8b, 0x4c8c, 0x4c90, 0x4c9a}};
2086 static constexpr std::array<uint32_t, 11> kTigerLakeIDs = {
2087 {0x9A40, 0x9A49, 0x9A59, 0x9A60, 0x9A68, 0x9A70,
2088 0x9A78, 0x9AC0, 0x9AC9, 0x9AD9, 0x9AF8}};
2089 static constexpr std::array<uint32_t, 10> kAlderLakeIDs = {
2090 {0x4680, 0x4681, 0x4682, 0x4683, 0x4690,
2091 0x4691, 0x4692, 0x4693, 0x4698, 0x4699}};
2092
2093 if (intel_deviceID_present(kSkyLakeIDs, deviceID)) {
2094 return IntelGPUType::kSkyLake;
2095 }
2096 if (intel_deviceID_present(kIceLakeIDs, deviceID)) {
2097 return IntelGPUType::kIceLake;
2098 }
2099 if (intel_deviceID_present(kRocketLakeIDs, deviceID)) {
2100 return IntelGPUType::kRocketLake;
2101 }
2102 if (intel_deviceID_present(kTigerLakeIDs, deviceID)) {
2103 return IntelGPUType::kTigerLake;
2104 }
2105 if (intel_deviceID_present(kAlderLakeIDs, deviceID)) {
2106 return IntelGPUType::kAlderLake;
2107 }
2108 return IntelGPUType::kOther;
2109}
2110
2111#if defined(GR_TEST_UTILS)
2112std::vector<GrTest::TestFormatColorTypeCombination> GrVkCaps::getTestingCombinations() const {
2113 std::vector<GrTest::TestFormatColorTypeCombination> combos = {
2138 // These two compressed formats both have an effective colorType of kRGB_888x
2142 };
2143
2144 return combos;
2145}
2146#endif
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
int count
Definition: FontMgrTest.cpp:50
SkTextureCompressionType GrBackendFormatToCompressionType(const GrBackendFormat &format)
GrDstSampleFlags
Definition: GrTypesPriv.h:936
static const int kGrColorTypeCnt
Definition: GrTypesPriv.h:587
GrTextureType
Definition: GrTypesPriv.h:268
GrColorType
Definition: GrTypesPriv.h:540
GrInternalSurfaceFlags
Definition: GrTypesPriv.h:436
static bool format_is_srgb(VkFormat format)
Definition: GrVkCaps.cpp:776
static size_t align_to_4(size_t v)
Definition: GrVkCaps.cpp:1651
bool stencil_format_supported(const skgpu::VulkanInterface *interface, VkPhysicalDevice physDev, VkFormat format)
Definition: GrVkCaps.cpp:755
static bool backend_format_is_external(const GrBackendFormat &format)
Definition: GrVkCaps.cpp:1524
static FormatCompatibilityClass format_compatibility_class(VkFormat format)
Definition: GrVkCaps.cpp:108
static bool intel_deviceID_present(const std::array< uint32_t, N > &array, uint32_t deviceID)
Definition: GrVkCaps.cpp:2066
static constexpr VkFormat kVkFormats[]
Definition: GrVkCaps.cpp:789
bool GrVkFormatIsSupported(VkFormat format)
Definition: GrVkUtil.cpp:21
#define GR_VK_CALL(IFACE, X)
Definition: GrVkUtil.h:24
#define SkUNREACHABLE
Definition: SkAssert.h:135
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkDEBUGFAILF(fmt,...)
Definition: SkAssert.h:119
#define SkASSERT(cond)
Definition: SkAssert.h:116
static constexpr bool SkTextureCompressionTypeIsOpaque(SkTextureCompressionType compression)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
SkTextureCompressionType
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
SI F table(const skcms_Curve *curve, F v)
int find(T *array, int N, T item)
bool fSupportsProtectedContent
Definition: GrCaps.h:648
SurfaceReadPixelsSupport
Definition: GrCaps.h:296
bool fDynamicStateArrayGeometryProcessorTextureSupport
Definition: GrCaps.h:646
int fMaxPreferredRenderTargetSize
Definition: GrCaps.h:658
int fMaxVertexAttributes
Definition: GrCaps.h:659
bool fFinishedProcAsyncCallbackSupport
Definition: GrCaps.h:640
int fMaxRenderTargetSize
Definition: GrCaps.h:657
bool fReadPixelsRowBytesSupport
Definition: GrCaps.h:621
const GrShaderCaps * shaderCaps() const
Definition: GrCaps.h:63
std::unique_ptr< GrShaderCaps > fShaderCaps
Definition: GrCaps.h:584
bool fReuseScratchTextures
Definition: GrCaps.h:589
bool fNativeDrawIndirectSupport
Definition: GrCaps.h:596
bool fAnisoSupport
Definition: GrCaps.h:588
uint32_t fMaxPushConstantsSize
Definition: GrCaps.h:663
bool fTransferFromBufferToBufferSupport
Definition: GrCaps.h:618
bool fTransferFromBufferToTextureSupport
Definition: GrCaps.h:616
bool fTextureBarrierSupport
Definition: GrCaps.h:593
int fBufferMapThreshold
Definition: GrCaps.h:655
bool preferDiscardableMSAAAttachment() const
Definition: GrCaps.h:107
bool fBackendSemaphoreSupport
Definition: GrCaps.h:639
@ kAdvancedCoherent_BlendEquationSupport
Definition: GrCaps.h:154
@ kAdvanced_BlendEquationSupport
Definition: GrCaps.h:152
@ kBasic_BlendEquationSupport
Definition: GrCaps.h:150
bool fHalfFloatVertexAttributeSupport
Definition: GrCaps.h:610
bool fSampleLocationsSupport
Definition: GrCaps.h:594
bool fGpuTracingSupport
Definition: GrCaps.h:591
bool fOversizedStencilSupport
Definition: GrCaps.h:592
bool fSemaphoreSupport
Definition: GrCaps.h:638
bool fMipmapSupport
Definition: GrCaps.h:587
bool fWireframeSupport
Definition: GrCaps.h:599
ProgramDescOverrideFlags
Definition: GrCaps.h:511
uint32_t fMapBufferFlags
Definition: GrCaps.h:654
bool fReuseScratchBuffers
Definition: GrCaps.h:590
bool fWritePixelsRowBytesSupport
Definition: GrCaps.h:619
bool fShouldCollapseSrcOverToSrcWhenAble
Definition: GrCaps.h:622
bool fNPOTTextureTileSupport
Definition: GrCaps.h:586
bool fSupportsAHardwareBufferImages
Definition: GrCaps.h:609
bool fTransferFromSurfaceToBufferSupport
Definition: GrCaps.h:617
void finishInitialization(const GrContextOptions &options)
Definition: GrCaps.cpp:107
@ kCanMap_MapFlag
Definition: GrCaps.h:199
@ kSubset_MapFlag
Definition: GrCaps.h:201
@ kAsyncRead_MapFlag
Definition: GrCaps.h:202
bool fAvoidWritePixelsFastPath
Definition: GrCaps.h:628
BlendEquationSupport fBlendEquationSupport
Definition: GrCaps.h:650
bool fPreferDiscardableMSAAAttachment
Definition: GrCaps.h:601
bool fConservativeRasterSupport
Definition: GrCaps.h:598
bool fDrawInstancedSupport
Definition: GrCaps.h:595
int fMaxTextureSize
Definition: GrCaps.h:660
bool fCrossContextTextureSupport
Definition: GrCaps.h:643
bool fPreferFullscreenClears
Definition: GrCaps.h:604
void genKey(skgpu::KeyBuilder *, const GrCaps &) const
Definition: GrPipeline.cpp:79
static void Build(GrProgramDesc *, const GrProgramInfo &, const GrCaps &)
uint16_t primitiveTypeKey() const
Definition: GrProgramInfo.h:54
int numSamples() const
Definition: GrProgramInfo.h:29
int targetsNumSamples() const
Definition: GrProgramInfo.h:48
const GrPipeline & pipeline() const
Definition: GrProgramInfo.h:39
bool targetHasVkResolveAttachmentWithInput() const
Definition: GrProgramInfo.h:44
bool isStencilEnabled() const
Definition: GrProgramInfo.h:31
GrLoadOp colorLoadOp() const
Definition: GrProgramInfo.h:52
int needsStencil() const
Definition: GrProgramInfo.h:30
GrStencilSettings nonGLStencilSettings() const
GrXferBarrierFlags renderPassBarriers() const
Definition: GrProgramInfo.h:50
bool supportsVkInputAttachment() const
int numSamples() const
void genKey(skgpu::KeyBuilder *b, bool includeRefsAndMasks) const
virtual GrTextureProxy * asTextureProxy()
bool canCopyAsResolve(VkFormat dstConfig, int dstSampleCnt, bool dstHasYcbcr, VkFormat srcConfig, int srcSamplecnt, bool srcHasYcbcr) const
Definition: GrVkCaps.cpp:193
bool isVkFormatTexturable(VkFormat) const
Definition: GrVkCaps.cpp:1566
bool programInfoWillUseDiscardableMSAA(const GrProgramInfo &) const
Definition: GrVkCaps.cpp:1796
bool canCopyAsBlit(VkFormat dstConfig, int dstSampleCnt, bool dstIsLinear, bool dstHasYcbcr, VkFormat srcConfig, int srcSampleCnt, bool srcIsLinear, bool srcHasYcbcr) const
Definition: GrVkCaps.cpp:170
bool formatCanBeDstofBlit(VkFormat format, bool linearTiled) const
Definition: GrVkCaps.h:71
uint64_t computeFormatKey(const GrBackendFormat &) const override
Definition: GrVkCaps.cpp:1880
bool isFormatRenderable(const GrBackendFormat &format, int sampleCount) const override
Definition: GrVkCaps.cpp:1587
SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface *) const override
Definition: GrVkCaps.cpp:1689
int maxRenderTargetSampleCount(const GrBackendFormat &) const override
Definition: GrVkCaps.cpp:1633
VkShaderStageFlags getPushConstantStageFlags() const
Definition: GrVkCaps.cpp:2060
bool renderTargetSupportsDiscardableMSAA(const GrVkRenderTarget *) const
Definition: GrVkCaps.cpp:1789
bool isFormatTexturable(const GrBackendFormat &, GrTextureType) const override
Definition: GrVkCaps.cpp:1553
GrProgramDesc makeDesc(GrRenderTarget *, const GrProgramInfo &, ProgramDescOverrideFlags) const override
Definition: GrVkCaps.cpp:1968
void addExtraSamplerKey(skgpu::KeyBuilder *, GrSamplerState, const GrBackendFormat &) const override
Definition: GrVkCaps.cpp:1935
int getFragmentUniformSet() const
Definition: GrVkCaps.cpp:1931
bool isFormatSRGB(const GrBackendFormat &) const override
Definition: GrVkCaps.cpp:1541
VkFormat getFormatFromColorType(GrColorType colorType) const
Definition: GrVkCaps.h:235
GrColorType transferColorType(VkFormat, GrColorType surfaceColorType) const
Definition: GrVkCaps.cpp:1717
bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat &format, int sampleCount=1) const override
Definition: GrVkCaps.cpp:1571
bool supportsDiscardableMSAAForDMSAA() const
Definition: GrVkCaps.h:262
GrBackendFormat getBackendFormatFromCompressionType(SkTextureCompressionType) const override
Definition: GrVkCaps.cpp:1803
int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat &) const override
Definition: GrVkCaps.cpp:1599
GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const override
Definition: GrVkCaps.cpp:2055
bool formatCanBeSrcofBlit(VkFormat format, bool linearTiled) const
Definition: GrVkCaps.h:77
SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType, const GrBackendFormat &surfaceFormat, GrColorType srcColorType) const override
Definition: GrVkCaps.cpp:1662
bool canCopyImage(VkFormat dstFormat, int dstSampleCnt, bool dstHasYcbcr, VkFormat srcFormat, int srcSamplecnt, bool srcHasYcbcr) const
Definition: GrVkCaps.cpp:155
skgpu::Swizzle getWriteSwizzle(const GrBackendFormat &, GrColorType) const override
Definition: GrVkCaps.cpp:1853
int getFragmentUniformBinding() const
Definition: GrVkCaps.cpp:1927
GrVkCaps(const GrContextOptions &, const skgpu::VulkanInterface *, VkPhysicalDevice, const VkPhysicalDeviceFeatures2 &, uint32_t instanceVersion, uint32_t physicalDeviceVersion, const skgpu::VulkanExtensions &, skgpu::Protected)
Definition: GrVkCaps.cpp:43
@ kShader_PersistentCacheKeyType
Definition: GrVkGpu.h:185
bool supportsInputAttachmentUsage() const
Definition: GrVkImage.h:102
static void GenKey(skgpu::KeyBuilder *, AttachmentFlags, const AttachmentsDescriptor &, SelfDependencyFlags selfDepFlags, LoadFromResolve, uint64_t externalRenderPass)
static void ReconstructAttachmentsDescriptor(const GrVkCaps &vkCaps, const GrProgramInfo &programInfo, GrVkRenderPass::AttachmentsDescriptor *desc, GrVkRenderPass::AttachmentFlags *flags)
GrVkImage * resolveAttachment() const
const GrVkRenderPass * getSimpleRenderPass(bool withResolve, bool withStencil, SelfDependencyFlags selfDepFlags, LoadFromResolve)
static SK_END_REQUIRE_DENSE Key GenerateKey(GrSamplerState, const skgpu::VulkanYcbcrConversionInfo &)
static constexpr Swizzle BGRA()
Definition: Swizzle.h:67
static constexpr Swizzle RGB1()
Definition: Swizzle.h:69
VkSurfaceKHR surface
Definition: main.cc:49
static bool b
FlutterSemanticsFlag flags
uint32_t uint32_t * format
static float max(float r, float g, float b)
Definition: hsl.cpp:49
static float min(float r, float g, float b)
Definition: hsl.cpp:48
SK_API const skgpu::VulkanYcbcrConversionInfo * GetVkYcbcrConversionInfo(const GrBackendFormat &)
SK_API bool AsVkFormat(const GrBackendFormat &, VkFormat *)
SK_API GrBackendFormat MakeVk(VkFormat format, bool willUseDRMFormatModifiers=false)
static bool init()
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
dst
Definition: cp.py:12
static constexpr size_t VkFormatBytesPerBlock(VkFormat vkFormat)
static constexpr bool VkFormatNeedsYcbcrSampler(VkFormat format)
static constexpr bool VkFormatIsCompressed(VkFormat vkFormat)
T * GetExtensionFeatureStruct(const VkPhysicalDeviceFeatures2 &features, VkStructureType type)
Protected
Definition: GpuTypes.h:61
static void usage(char *argv0)
bool fDisableDriverCorrectnessWorkarounds
int fMaxCachedVulkanSecondaryCommandBuffers
bool fHalfIs32Bits
Definition: GrShaderCaps.h:42
bool fBitManipulationSupport
Definition: GrShaderCaps.h:41
int fMaxFragmentSamplers
Definition: GrShaderCaps.h:71
bool fPreferFlatInterpolation
Definition: GrShaderCaps.h:35
bool fVertexIDSupport
Definition: GrShaderCaps.h:36
bool fNonconstantArrayIndexSupport
Definition: GrShaderCaps.h:39
Definition: SkRect.h:32
constexpr SkISize size() const
Definition: SkRect.h:172
bool fSampleMaskSupport
Definition: SkSLUtil.h:98
bool fExplicitTextureLodSupport
Definition: SkSLUtil.h:87
bool fDualSourceBlendingSupport
Definition: SkSLUtil.h:84
bool fMustDeclareFragmentFrontFacing
Definition: SkSLUtil.h:151
bool fInfinitySupport
Definition: SkSLUtil.h:103
@ kAutomatic_AdvBlendEqInteraction
Definition: SkSLUtil.h:33
bool fShaderDerivativeSupport
Definition: SkSLUtil.h:85
bool fFlatInterpolationSupport
Definition: SkSLUtil.h:96
bool fIntegerSupport
Definition: SkSLUtil.h:89
bool fInverseHyperbolicSupport
Definition: SkSLUtil.h:92
const char * fVersionDeclString
Definition: SkSLUtil.h:153
bool fNonsquareMatrixSupport
Definition: SkSLUtil.h:90
bool fFloatIs32Bits
Definition: SkSLUtil.h:100
bool fUsesPrecisionModifiers
Definition: SkSLUtil.h:95
VkFormatFeatureFlags linearTilingFeatures
Definition: vulkan_core.h:3013
VkFormatFeatureFlags optimalTilingFeatures
Definition: vulkan_core.h:3014
VkSampleCountFlags sampleCounts
Definition: vulkan_core.h:3022
VkPhysicalDeviceFeatures features
Definition: vulkan_core.h:5271
VkBool32 standardSampleLocations
Definition: vulkan_core.h:3208
uint32_t maxDescriptorSetInputAttachments
Definition: vulkan_core.h:3134
uint32_t maxPerStageDescriptorSamplers
Definition: vulkan_core.h:3120
uint32_t maxPerStageDescriptorSampledImages
Definition: vulkan_core.h:3123
uint32_t maxVertexInputAttributes
Definition: vulkan_core.h:3135
char deviceName[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE]
Definition: vulkan_core.h:3235
VkPhysicalDeviceLimits limits
Definition: vulkan_core.h:3237
#define VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME
#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME
VkFlags VkSampleCountFlags
Definition: vulkan_core.h:2349
@ VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT
Definition: vulkan_core.h:2271
@ VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT
Definition: vulkan_core.h:2267
@ VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
Definition: vulkan_core.h:2268
@ VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
Definition: vulkan_core.h:2259
@ VK_FORMAT_FEATURE_BLIT_SRC_BIT
Definition: vulkan_core.h:2269
@ VK_FORMAT_FEATURE_BLIT_DST_BIT
Definition: vulkan_core.h:2270
#define VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME
Definition: vulkan_core.h:8673
#define VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME
@ VK_SHADER_STAGE_VERTEX_BIT
Definition: vulkan_core.h:2665
@ VK_SHADER_STAGE_FRAGMENT_BIT
Definition: vulkan_core.h:2669
#define VK_TRUE
Definition: vulkan_core.h:131
VkFlags VkImageUsageFlags
Definition: vulkan_core.h:2382
#define VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME
Definition: vulkan_core.h:9443
@ VK_IMAGE_TILING_OPTIMAL
Definition: vulkan_core.h:1767
#define VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME
Definition: vulkan_core.h:8708
@ VK_IMAGE_USAGE_TRANSFER_DST_BIT
Definition: vulkan_core.h:2353
@ VK_IMAGE_USAGE_SAMPLED_BIT
Definition: vulkan_core.h:2354
@ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
Definition: vulkan_core.h:2356
@ VK_IMAGE_USAGE_TRANSFER_SRC_BIT
Definition: vulkan_core.h:2352
@ VK_SAMPLE_COUNT_8_BIT
Definition: vulkan_core.h:2343
@ VK_SAMPLE_COUNT_2_BIT
Definition: vulkan_core.h:2341
@ VK_SAMPLE_COUNT_1_BIT
Definition: vulkan_core.h:2340
@ VK_SAMPLE_COUNT_4_BIT
Definition: vulkan_core.h:2342
@ VK_SAMPLE_COUNT_16_BIT
Definition: vulkan_core.h:2344
#define VK_EXT_RGBA10X6_FORMATS_EXTENSION_NAME
#define VK_KHR_MAINTENANCE3_EXTENSION_NAME
Definition: vulkan_core.h:9508
VkFlags VkFormatFeatureFlags
Definition: vulkan_core.h:2307
VkFlags VkShaderStageFlags
Definition: vulkan_core.h:2731
#define VK_MAKE_VERSION(major, minor, patch)
Definition: vulkan_core.h:78
#define VK_KHR_MAINTENANCE1_EXTENSION_NAME
Definition: vulkan_core.h:8638
#define VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME
Definition: vulkan_core.h:9396
@ VK_IMAGE_TYPE_2D
Definition: vulkan_core.h:1775
#define VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME
Definition: vulkan_core.h:8511
#define VK_EXT_DEVICE_FAULT_EXTENSION_NAME
#define VK_KHR_BIND_MEMORY_2_EXTENSION_NAME
Definition: vulkan_core.h:9482
#define VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME
VkFormat
Definition: vulkan_core.h:1458
@ VK_FORMAT_R16G16B16A16_UNORM
Definition: vulkan_core.h:1550
@ VK_FORMAT_R8G8B8A8_SRGB
Definition: vulkan_core.h:1502
@ VK_FORMAT_R8G8B8_UNORM
Definition: vulkan_core.h:1482
@ VK_FORMAT_D24_UNORM_S8_UINT
Definition: vulkan_core.h:1588
@ VK_FORMAT_B8G8R8A8_UNORM
Definition: vulkan_core.h:1503
@ VK_FORMAT_R16G16_SFLOAT
Definition: vulkan_core.h:1542
@ VK_FORMAT_B4G4R4A4_UNORM_PACK16
Definition: vulkan_core.h:1462
@ VK_FORMAT_R16_SFLOAT
Definition: vulkan_core.h:1535
@ VK_FORMAT_R8G8_UNORM
Definition: vulkan_core.h:1475
@ VK_FORMAT_S8_UINT
Definition: vulkan_core.h:1586
@ VK_FORMAT_R8_UNORM
Definition: vulkan_core.h:1468
@ VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16
Definition: vulkan_core.h:1657
@ VK_FORMAT_R5G6B5_UNORM_PACK16
Definition: vulkan_core.h:1463
@ VK_FORMAT_R4G4B4A4_UNORM_PACK16
Definition: vulkan_core.h:1461
@ VK_FORMAT_A2B10G10R10_UNORM_PACK32
Definition: vulkan_core.h:1523
@ VK_FORMAT_R8G8B8A8_UNORM
Definition: vulkan_core.h:1496
@ VK_FORMAT_UNDEFINED
Definition: vulkan_core.h:1459
@ VK_FORMAT_BC1_RGB_UNORM_BLOCK
Definition: vulkan_core.h:1590
@ VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16
Definition: vulkan_core.h:1653
@ VK_FORMAT_R16_UNORM
Definition: vulkan_core.h:1529
@ VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM
Definition: vulkan_core.h:1646
@ VK_FORMAT_R16G16B16A16_SFLOAT
Definition: vulkan_core.h:1556
@ VK_FORMAT_R16G16_UNORM
Definition: vulkan_core.h:1536
@ VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK
Definition: vulkan_core.h:1606
@ VK_FORMAT_A2R10G10B10_UNORM_PACK32
Definition: vulkan_core.h:1517
@ VK_FORMAT_BC1_RGBA_UNORM_BLOCK
Definition: vulkan_core.h:1592
@ VK_FORMAT_G8_B8R8_2PLANE_420_UNORM
Definition: vulkan_core.h:1647
@ VK_FORMAT_B5G6R5_UNORM_PACK16
Definition: vulkan_core.h:1464
@ VK_FORMAT_D32_SFLOAT_S8_UINT
Definition: vulkan_core.h:1589
#define VK_KHR_SWAPCHAIN_EXTENSION_NAME
Definition: vulkan_core.h:7707
#define VK_KHR_MAINTENANCE2_EXTENSION_NAME
Definition: vulkan_core.h:9241
@ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2
Definition: vulkan_core.h:272
@ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES
Definition: vulkan_core.h:296
@ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RGBA10X6_FORMATS_FEATURES_EXT
Definition: vulkan_core.h:961
@ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT
Definition: vulkan_core.h:669
@ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT
Definition: vulkan_core.h:670
#define VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME
Definition: vulkan_core.h:9374