blob: 9215dde80f041bd57f78e20d74d2cd00e02f33eb [file] [log] [blame]
Greg Daniel164a9f02016-02-22 09:56:40 -05001/*
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
John Stilesfbd050b2020-08-03 13:21:46 -04008#include "src/gpu/vk/GrVkCaps.h"
9
10#include <memory>
11
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/gpu/GrBackendSurface.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/gpu/vk/GrVkBackendContext.h"
14#include "include/gpu/vk/GrVkExtensions.h"
Robert Phillips99dead92020-01-27 16:11:57 -050015#include "src/core/SkCompressedDataUtils.h"
Greg Daniel01f278c2020-06-12 16:58:17 -040016#include "src/gpu/GrBackendUtils.h"
Robert Phillips03e4c952019-11-26 16:20:22 -050017#include "src/gpu/GrProgramDesc.h"
Brian Salomon201cdbb2019-08-14 17:00:30 -040018#include "src/gpu/GrRenderTarget.h"
Greg Danielf91aeb22019-06-18 09:58:02 -040019#include "src/gpu/GrRenderTargetProxy.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050020#include "src/gpu/GrShaderCaps.h"
Robert Phillips03e4c952019-11-26 16:20:22 -050021#include "src/gpu/GrStencilSettings.h"
Brian Osman7fbb3632019-07-19 11:38:57 -040022#include "src/gpu/GrUtil.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050023#include "src/gpu/SkGr.h"
Robert Phillips03e4c952019-11-26 16:20:22 -050024#include "src/gpu/vk/GrVkGpu.h"
Greg Daniel2bc96d62021-09-13 13:08:02 -040025#include "src/gpu/vk/GrVkImage.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050026#include "src/gpu/vk/GrVkInterface.h"
Robert Phillips03e4c952019-11-26 16:20:22 -050027#include "src/gpu/vk/GrVkRenderTarget.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050028#include "src/gpu/vk/GrVkTexture.h"
Ethan Nicholas0be34802019-08-15 12:36:58 -040029#include "src/gpu/vk/GrVkUniformHandler.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050030#include "src/gpu/vk/GrVkUtil.h"
Greg Daniel164a9f02016-02-22 09:56:40 -050031
Emircan Uysaler23ca4e72019-06-24 10:53:09 -040032#ifdef SK_BUILD_FOR_ANDROID
33#include <sys/system_properties.h>
34#endif
35
Greg Daniel164a9f02016-02-22 09:56:40 -050036GrVkCaps::GrVkCaps(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
Greg Daniela0651ac2018-08-08 09:23:18 -040037 VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures2& features,
Greg Daniel41f0e282019-01-28 13:15:05 -050038 uint32_t instanceVersion, uint32_t physicalDeviceVersion,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -040039 const GrVkExtensions& extensions, GrProtected isProtected)
40 : INHERITED(contextOptions) {
Greg Daniel164a9f02016-02-22 09:56:40 -050041 /**************************************************************************
Brian Salomonf7232642018-09-19 08:58:08 -040042 * GrCaps fields
43 **************************************************************************/
Brian Salomon69100f02020-07-21 10:49:25 -040044 fMipmapSupport = true; // always available in Vulkan
brianosman88791862016-05-23 10:15:27 -070045 fNPOTTextureTileSupport = true; // always available in Vulkan
Greg Daniel164a9f02016-02-22 09:56:40 -050046 fReuseScratchTextures = true; //TODO: figure this out
47 fGpuTracingSupport = false; //TODO: figure this out
Greg Daniel28bea442021-06-25 15:06:15 +000048 fOversizedStencilSupport = false; //TODO: figure this out
Chris Daltona77cdee2020-04-03 14:50:43 -060049 fDrawInstancedSupport = true;
Greg Daniel164a9f02016-02-22 09:56:40 -050050
Brian Salomon9ff5acb2019-05-08 09:04:47 -040051 fSemaphoreSupport = true; // always available in Vulkan
jvanverth84741b32016-09-30 08:39:02 -070052 fFenceSyncSupport = true; // always available in Vulkan
Greg Daniel691f5e72018-02-28 14:21:34 -050053 fCrossContextTextureSupport = true;
Brian Osman499bf1a2018-09-17 11:32:42 -040054 fHalfFloatVertexAttributeSupport = true;
Greg Daniel164a9f02016-02-22 09:56:40 -050055
Brian Salomon1047a492019-07-02 12:25:21 -040056 // We always copy in/out of a transfer buffer so it's trivial to support row bytes.
57 fReadPixelsRowBytesSupport = true;
58 fWritePixelsRowBytesSupport = true;
59
Brian Salomonfb28c6f2020-01-10 13:04:45 -050060 fTransferFromBufferToTextureSupport = true;
61 fTransferFromSurfaceToBufferSupport = true;
Greg Daniel164a9f02016-02-22 09:56:40 -050062
63 fMaxRenderTargetSize = 4096; // minimum required by spec
64 fMaxTextureSize = 4096; // minimum required by spec
Greg Daniel164a9f02016-02-22 09:56:40 -050065
Brian Salomonf7232642018-09-19 08:58:08 -040066 fDynamicStateArrayGeometryProcessorTextureSupport = true;
67
Greg Daniel37fd6582020-09-14 12:36:09 -040068 fTextureBarrierSupport = true;
69
Brian Salomon94efbf52016-11-29 13:43:05 -050070 fShaderCaps.reset(new GrShaderCaps(contextOptions));
Greg Daniel164a9f02016-02-22 09:56:40 -050071
Emircan Uysaler23ca4e72019-06-24 10:53:09 -040072 this->init(contextOptions, vkInterface, physDev, features, physicalDeviceVersion, extensions,
73 isProtected);
Greg Daniel164a9f02016-02-22 09:56:40 -050074}
75
Brian Salomon1c53a9f2019-08-12 14:10:12 -040076namespace {
77/**
78 * This comes from section 37.1.6 of the Vulkan spec. Format is
79 * (<bits>|<tag>)_<block_size>_<texels_per_block>.
80 */
81enum class FormatCompatibilityClass {
82 k8_1_1,
83 k16_2_1,
84 k24_3_1,
85 k32_4_1,
86 k64_8_1,
Robert Phillipsb0855272020-01-15 12:56:52 -050087 kBC1_RGB_8_16_1,
88 kBC1_RGBA_8_16,
Brian Salomon1c53a9f2019-08-12 14:10:12 -040089 kETC2_RGB_8_16,
90};
91} // anonymous namespace
Robert Phillips66a46032019-06-18 08:00:42 -040092
Brian Salomon1c53a9f2019-08-12 14:10:12 -040093static FormatCompatibilityClass format_compatibility_class(VkFormat format) {
94 switch (format) {
95 case VK_FORMAT_B8G8R8A8_UNORM:
96 case VK_FORMAT_R8G8B8A8_UNORM:
97 case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
Robert Phillips9a30ee02020-04-29 08:58:39 -040098 case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
Brian Salomon1c53a9f2019-08-12 14:10:12 -040099 case VK_FORMAT_R8G8B8A8_SRGB:
100 case VK_FORMAT_R16G16_UNORM:
101 case VK_FORMAT_R16G16_SFLOAT:
102 return FormatCompatibilityClass::k32_4_1;
103
104 case VK_FORMAT_R8_UNORM:
105 return FormatCompatibilityClass::k8_1_1;
106
107 case VK_FORMAT_R5G6B5_UNORM_PACK16:
108 case VK_FORMAT_R16_SFLOAT:
109 case VK_FORMAT_R8G8_UNORM:
110 case VK_FORMAT_B4G4R4A4_UNORM_PACK16:
111 case VK_FORMAT_R4G4B4A4_UNORM_PACK16:
112 case VK_FORMAT_R16_UNORM:
113 return FormatCompatibilityClass::k16_2_1;
114
115 case VK_FORMAT_R16G16B16A16_SFLOAT:
116 case VK_FORMAT_R16G16B16A16_UNORM:
117 return FormatCompatibilityClass::k64_8_1;
118
119 case VK_FORMAT_R8G8B8_UNORM:
120 return FormatCompatibilityClass::k24_3_1;
121
Brian Salomon1c53a9f2019-08-12 14:10:12 -0400122 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
123 return FormatCompatibilityClass::kETC2_RGB_8_16;
124
Robert Phillips8f259a02019-12-20 11:32:27 -0500125 case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
Robert Phillipsb0855272020-01-15 12:56:52 -0500126 return FormatCompatibilityClass::kBC1_RGB_8_16_1;
127
128 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
129 return FormatCompatibilityClass::kBC1_RGBA_8_16;
Robert Phillips8f259a02019-12-20 11:32:27 -0500130
Brian Salomon1c53a9f2019-08-12 14:10:12 -0400131 default:
132 SK_ABORT("Unsupported VkFormat");
Greg Daniel5c7b5412019-05-10 11:39:55 -0400133 }
Greg Daniel5c7b5412019-05-10 11:39:55 -0400134}
135
Brian Salomon1c53a9f2019-08-12 14:10:12 -0400136bool GrVkCaps::canCopyImage(VkFormat dstFormat, int dstSampleCnt, bool dstHasYcbcr,
137 VkFormat srcFormat, int srcSampleCnt, bool srcHasYcbcr) const {
Greg Daniel25af6712018-04-25 10:44:38 -0400138 if ((dstSampleCnt > 1 || srcSampleCnt > 1) && dstSampleCnt != srcSampleCnt) {
139 return false;
140 }
141
Greg Daniela51e93c2019-03-25 12:30:45 -0400142 if (dstHasYcbcr || srcHasYcbcr) {
143 return false;
144 }
145
Brian Salomon1c53a9f2019-08-12 14:10:12 -0400146 // We require that all Vulkan GrSurfaces have been created with transfer_dst and transfer_src
Greg Daniel25af6712018-04-25 10:44:38 -0400147 // as image usage flags.
Brian Salomon1c53a9f2019-08-12 14:10:12 -0400148 return format_compatibility_class(srcFormat) == format_compatibility_class(dstFormat);
Greg Daniel25af6712018-04-25 10:44:38 -0400149}
150
Brian Salomon1c53a9f2019-08-12 14:10:12 -0400151bool GrVkCaps::canCopyAsBlit(VkFormat dstFormat, int dstSampleCnt, bool dstIsLinear,
152 bool dstHasYcbcr, VkFormat srcFormat, int srcSampleCnt,
Greg Daniela51e93c2019-03-25 12:30:45 -0400153 bool srcIsLinear, bool srcHasYcbcr) const {
Greg Daniel25af6712018-04-25 10:44:38 -0400154 // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src
155 // as image usage flags.
Greg Danielcaa795f2019-05-14 11:54:25 -0400156 if (!this->formatCanBeDstofBlit(dstFormat, dstIsLinear) ||
157 !this->formatCanBeSrcofBlit(srcFormat, srcIsLinear)) {
Greg Daniel25af6712018-04-25 10:44:38 -0400158 return false;
159 }
160
Greg Daniel25af6712018-04-25 10:44:38 -0400161 // We cannot blit images that are multisampled. Will need to figure out if we can blit the
162 // resolved msaa though.
163 if (dstSampleCnt > 1 || srcSampleCnt > 1) {
164 return false;
165 }
166
Greg Daniela51e93c2019-03-25 12:30:45 -0400167 if (dstHasYcbcr || srcHasYcbcr) {
168 return false;
169 }
170
Greg Daniel25af6712018-04-25 10:44:38 -0400171 return true;
172}
173
Brian Salomon1c53a9f2019-08-12 14:10:12 -0400174bool GrVkCaps::canCopyAsResolve(VkFormat dstFormat, int dstSampleCnt, bool dstHasYcbcr,
175 VkFormat srcFormat, int srcSampleCnt, bool srcHasYcbcr) const {
Greg Daniel25af6712018-04-25 10:44:38 -0400176 // The src surface must be multisampled.
177 if (srcSampleCnt <= 1) {
178 return false;
179 }
180
181 // The dst must not be multisampled.
182 if (dstSampleCnt > 1) {
183 return false;
184 }
185
186 // Surfaces must have the same format.
Brian Salomon1c53a9f2019-08-12 14:10:12 -0400187 if (srcFormat != dstFormat) {
Greg Daniel25af6712018-04-25 10:44:38 -0400188 return false;
189 }
190
Greg Daniela51e93c2019-03-25 12:30:45 -0400191 if (dstHasYcbcr || srcHasYcbcr) {
192 return false;
193 }
194
Greg Daniel25af6712018-04-25 10:44:38 -0400195 return true;
196}
197
Brian Salomonc67c31c2018-12-06 10:00:03 -0500198bool GrVkCaps::onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src,
199 const SkIRect& srcRect, const SkIPoint& dstPoint) const {
Greg Danielca9dbe22020-01-02 13:44:30 -0500200 if (src->isProtected() == GrProtected::kYes && dst->isProtected() != GrProtected::kYes) {
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400201 return false;
202 }
203
Greg Daniel25af6712018-04-25 10:44:38 -0400204 // TODO: Figure out a way to track if we've wrapped a linear texture in a proxy (e.g.
205 // PromiseImage which won't get instantiated right away. Does this need a similar thing like the
206 // tracking of external or rectangle textures in GL? For now we don't create linear textures
207 // internally, and I don't believe anyone is wrapping them.
208 bool srcIsLinear = false;
209 bool dstIsLinear = false;
210
211 int dstSampleCnt = 0;
212 int srcSampleCnt = 0;
213 if (const GrRenderTargetProxy* rtProxy = dst->asRenderTargetProxy()) {
Greg Danielbe7fc462019-01-03 16:40:42 -0500214 // Copying to or from render targets that wrap a secondary command buffer is not allowed
215 // since they would require us to know the VkImage, which we don't have, as well as need us
216 // to stop and start the VkRenderPass which we don't have access to.
217 if (rtProxy->wrapsVkSecondaryCB()) {
218 return false;
219 }
Greg Danielaacc9f72020-12-17 10:42:57 -0500220 if (this->preferDiscardableMSAAAttachment() && dst->asTextureProxy() &&
221 rtProxy->supportsVkInputAttachment()) {
222 dstSampleCnt = 1;
223 } else {
224 dstSampleCnt = rtProxy->numSamples();
225 }
Greg Daniel25af6712018-04-25 10:44:38 -0400226 }
227 if (const GrRenderTargetProxy* rtProxy = src->asRenderTargetProxy()) {
Greg Danielbe7fc462019-01-03 16:40:42 -0500228 // Copying to or from render targets that wrap a secondary command buffer is not allowed
229 // since they would require us to know the VkImage, which we don't have, as well as need us
230 // to stop and start the VkRenderPass which we don't have access to.
231 if (rtProxy->wrapsVkSecondaryCB()) {
232 return false;
233 }
Greg Danielaacc9f72020-12-17 10:42:57 -0500234 if (this->preferDiscardableMSAAAttachment() && src->asTextureProxy() &&
235 rtProxy->supportsVkInputAttachment()) {
236 srcSampleCnt = 1;
237 } else {
238 srcSampleCnt = rtProxy->numSamples();
239 }
Greg Daniel25af6712018-04-25 10:44:38 -0400240 }
241 SkASSERT((dstSampleCnt > 0) == SkToBool(dst->asRenderTargetProxy()));
242 SkASSERT((srcSampleCnt > 0) == SkToBool(src->asRenderTargetProxy()));
243
Greg Daniela51e93c2019-03-25 12:30:45 -0400244 bool dstHasYcbcr = false;
245 if (auto ycbcr = dst->backendFormat().getVkYcbcrConversionInfo()) {
246 if (ycbcr->isValid()) {
247 dstHasYcbcr = true;
248 }
249 }
250
251 bool srcHasYcbcr = false;
252 if (auto ycbcr = src->backendFormat().getVkYcbcrConversionInfo()) {
253 if (ycbcr->isValid()) {
254 srcHasYcbcr = true;
255 }
256 }
257
Brian Salomon1c53a9f2019-08-12 14:10:12 -0400258 VkFormat dstFormat, srcFormat;
259 SkAssertResult(dst->backendFormat().asVkFormat(&dstFormat));
260 SkAssertResult(src->backendFormat().asVkFormat(&srcFormat));
261
262 return this->canCopyImage(dstFormat, dstSampleCnt, dstHasYcbcr,
263 srcFormat, srcSampleCnt, srcHasYcbcr) ||
264 this->canCopyAsBlit(dstFormat, dstSampleCnt, dstIsLinear, dstHasYcbcr,
265 srcFormat, srcSampleCnt, srcIsLinear, srcHasYcbcr) ||
266 this->canCopyAsResolve(dstFormat, dstSampleCnt, dstHasYcbcr,
267 srcFormat, srcSampleCnt, srcHasYcbcr);
Greg Daniel25af6712018-04-25 10:44:38 -0400268}
269
Greg Daniel7e000222018-12-03 10:08:21 -0500270template<typename T> T* get_extension_feature_struct(const VkPhysicalDeviceFeatures2& features,
271 VkStructureType type) {
272 // All Vulkan structs that could be part of the features chain will start with the
273 // structure type followed by the pNext pointer. We cast to the CommonVulkanHeader
274 // so we can get access to the pNext for the next struct.
275 struct CommonVulkanHeader {
276 VkStructureType sType;
277 void* pNext;
278 };
279
280 void* pNext = features.pNext;
281 while (pNext) {
282 CommonVulkanHeader* header = static_cast<CommonVulkanHeader*>(pNext);
283 if (header->sType == type) {
284 return static_cast<T*>(pNext);
285 }
286 pNext = header->pNext;
287 }
288 return nullptr;
289}
290
Greg Daniel164a9f02016-02-22 09:56:40 -0500291void GrVkCaps::init(const GrContextOptions& contextOptions, const GrVkInterface* vkInterface,
Greg Daniela0651ac2018-08-08 09:23:18 -0400292 VkPhysicalDevice physDev, const VkPhysicalDeviceFeatures2& features,
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400293 uint32_t physicalDeviceVersion, const GrVkExtensions& extensions,
294 GrProtected isProtected) {
Jim Van Verth6a40abc2017-11-02 16:56:09 +0000295 VkPhysicalDeviceProperties properties;
296 GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties(physDev, &properties));
egdanield5e3b9e2016-03-08 12:19:54 -0800297
egdanield5e3b9e2016-03-08 12:19:54 -0800298 VkPhysicalDeviceMemoryProperties memoryProperties;
299 GR_VK_CALL(vkInterface, GetPhysicalDeviceMemoryProperties(physDev, &memoryProperties));
300
Greg Daniel41f0e282019-01-28 13:15:05 -0500301 SkASSERT(physicalDeviceVersion <= properties.apiVersion);
Greg Danielc0b03d82018-08-03 14:41:15 -0400302
Greg Danielcb324152019-02-25 11:36:53 -0500303 if (extensions.hasExtension(VK_KHR_SWAPCHAIN_EXTENSION_NAME, 1)) {
304 fSupportsSwapchain = true;
305 }
306
Greg Danielc0b03d82018-08-03 14:41:15 -0400307 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
308 extensions.hasExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, 1)) {
309 fSupportsPhysicalDeviceProperties2 = true;
310 }
311
312 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
313 extensions.hasExtension(VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, 1)) {
314 fSupportsMemoryRequirements2 = true;
315 }
316
317 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
Greg Daniel637c06a2018-09-12 09:44:25 -0400318 extensions.hasExtension(VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, 1)) {
319 fSupportsBindMemory2 = true;
320 }
321
322 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
Greg Danielc0b03d82018-08-03 14:41:15 -0400323 extensions.hasExtension(VK_KHR_MAINTENANCE1_EXTENSION_NAME, 1)) {
324 fSupportsMaintenance1 = true;
325 }
326
327 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
328 extensions.hasExtension(VK_KHR_MAINTENANCE2_EXTENSION_NAME, 1)) {
329 fSupportsMaintenance2 = true;
330 }
331
332 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
333 extensions.hasExtension(VK_KHR_MAINTENANCE3_EXTENSION_NAME, 1)) {
334 fSupportsMaintenance3 = true;
335 }
336
Greg Daniela9979d12018-08-27 15:56:46 -0400337 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
Greg Daniel637c06a2018-09-12 09:44:25 -0400338 (extensions.hasExtension(VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, 1) &&
Greg Daniela9979d12018-08-27 15:56:46 -0400339 this->supportsMemoryRequirements2())) {
340 fSupportsDedicatedAllocation = true;
341 }
342
343 if (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
344 (extensions.hasExtension(VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME, 1) &&
345 this->supportsPhysicalDeviceProperties2() &&
346 extensions.hasExtension(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, 1) &&
347 this->supportsDedicatedAllocation())) {
348 fSupportsExternalMemory = true;
349 }
350
351#ifdef SK_BUILD_FOR_ANDROID
Greg Daniel637c06a2018-09-12 09:44:25 -0400352 // Currently Adreno devices are not supporting the QUEUE_FAMILY_FOREIGN_EXTENSION, so until they
353 // do we don't explicitly require it here even the spec says it is required.
Greg Daniela9979d12018-08-27 15:56:46 -0400354 if (extensions.hasExtension(
Greg Daniel637c06a2018-09-12 09:44:25 -0400355 VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME, 2) &&
356 /* extensions.hasExtension(VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME, 1) &&*/
357 this->supportsExternalMemory() &&
358 this->supportsBindMemory2()) {
Greg Daniela9979d12018-08-27 15:56:46 -0400359 fSupportsAndroidHWBExternalMemory = true;
Greg Daniel637c06a2018-09-12 09:44:25 -0400360 fSupportsAHardwareBufferImages = true;
Greg Daniela9979d12018-08-27 15:56:46 -0400361 }
362#endif
363
Greg Daniel7e000222018-12-03 10:08:21 -0500364 auto ycbcrFeatures =
365 get_extension_feature_struct<VkPhysicalDeviceSamplerYcbcrConversionFeatures>(
Sergey Ulanov2739fd22019-08-11 22:46:33 -0700366 features, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES);
Greg Daniel7e000222018-12-03 10:08:21 -0500367 if (ycbcrFeatures && ycbcrFeatures->samplerYcbcrConversion &&
Greg Daniel7e000222018-12-03 10:08:21 -0500368 (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0) ||
369 (extensions.hasExtension(VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME, 1) &&
Sergey Ulanov2739fd22019-08-11 22:46:33 -0700370 this->supportsMaintenance1() && this->supportsBindMemory2() &&
371 this->supportsMemoryRequirements2() && this->supportsPhysicalDeviceProperties2()))) {
Greg Daniel7e000222018-12-03 10:08:21 -0500372 fSupportsYcbcrConversion = true;
373 }
Sergey Ulanov2739fd22019-08-11 22:46:33 -0700374
Greg Daniel7e000222018-12-03 10:08:21 -0500375 // We always push back the default GrVkYcbcrConversionInfo so that the case of no conversion
376 // will return a key of 0.
377 fYcbcrInfos.push_back(GrVkYcbcrConversionInfo());
378
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400379 if ((isProtected == GrProtected::kYes) &&
380 (physicalDeviceVersion >= VK_MAKE_VERSION(1, 1, 0))) {
381 fSupportsProtectedMemory = true;
382 fAvoidUpdateBuffers = true;
383 fShouldAlwaysUseDedicatedImageMemory = true;
384 }
385
Greg Danieled629c12020-08-14 13:11:18 -0400386 fMaxInputAttachmentDescriptors = properties.limits.maxDescriptorSetInputAttachments;
387
Greg Daniel52a7eca2021-01-11 11:24:40 -0500388 // On desktop GPUs we have found that this does not provide much benefit. The perf results show
389 // a mix of regressions, some improvements, and lots of no changes. Thus it is no worth enabling
390 // this (especially with the rendering artifacts) on desktop.
391 //
392 // On Adreno devices we were expecting to see perf gains. But instead there were actually a lot
393 // of perf regressions and only a few perf wins. This needs some follow up with qualcomm since
394 // we do expect this to be a big win on tilers.
395 //
396 // On ARM devices we are seeing an average perf win of around 50%-60% across the board.
397 if (kARM_VkVendor == properties.vendorID) {
398 fPreferDiscardableMSAAAttachment = true;
399 }
Greg Danield8d9cf12021-01-07 09:46:39 -0500400
Greg Daniel313c6952018-08-08 09:24:08 -0400401 this->initGrCaps(vkInterface, physDev, properties, memoryProperties, features, extensions);
Greg Daniel36443602018-08-02 12:51:52 -0400402 this->initShaderCaps(properties, features);
Greg Danielf3b11622018-03-01 15:01:27 -0500403
Chris Dalton8e738a22018-10-05 16:41:44 -0600404 if (kQualcomm_VkVendor == properties.vendorID) {
Chris Dalton685e09b2021-06-19 11:50:17 -0600405 // A "clear" load for atlases runs faster on QC than a "discard" load followed by a
Chris Dalton8e738a22018-10-05 16:41:44 -0600406 // scissored clear.
407 // On NVIDIA and Intel, the discard load followed by clear is faster.
408 // TODO: Evaluate on ARM, Imagination, and ATI.
409 fPreferFullscreenClears = true;
410 }
411
Greg Daniel5af72c12021-02-08 13:52:08 -0500412 if (properties.vendorID == kNvidia_VkVendor || properties.vendorID == kAMD_VkVendor) {
413 // On discrete GPUs it can be faster to read gpu only memory compared to memory that is also
414 // mappable on the host.
415 fGpuOnlyBuffersMorePerformant = true;
Greg Danield2a39122021-02-17 16:12:54 -0500416
417 // On discrete GPUs we try to use special DEVICE_LOCAL and HOST_VISIBLE memory for our
418 // cpu write, gpu read buffers. This memory is not ideal to be kept persistently mapped.
419 // Some discrete GPUs do not expose this special memory, however we still disable
420 // persistently mapped buffers for all of them since most GPUs with updated drivers do
421 // expose it. If this becomes an issue we can try to be more fine grained.
422 fShouldPersistentlyMapCpuToGpuBuffers = false;
Greg Daniel5af72c12021-02-08 13:52:08 -0500423 }
424
Greg Daniel78e6a4c2019-03-19 14:13:36 -0400425 if (kQualcomm_VkVendor == properties.vendorID) {
426 // On Qualcomm it looks like using vkCmdUpdateBuffer is slower than using a transfer buffer
427 // even for small sizes.
428 fAvoidUpdateBuffers = true;
429 }
430
Jim Van Verth4b3d1f32020-10-08 15:46:36 -0400431 if (kQualcomm_VkVendor == properties.vendorID) {
432 // Adreno devices don't support push constants well
433 fMaxPushConstantsSize = 0;
434 }
435
Greg Daniel70ea0d92021-01-14 13:08:13 -0500436 fNativeDrawIndirectSupport = features.features.drawIndirectFirstInstance;
437 if (properties.vendorID == kQualcomm_VkVendor) {
Chris Dalton8f282f52021-01-06 11:47:58 -0700438 // Indirect draws seem slow on QC. Disable until we can investigate. http://skbug.com/11139
439 fNativeDrawIndirectSupport = false;
440 }
441
Greg Daniel70ea0d92021-01-14 13:08:13 -0500442 if (fNativeDrawIndirectSupport) {
443 fMaxDrawIndirectDrawCount = properties.limits.maxDrawIndirectCount;
444 SkASSERT(fMaxDrawIndirectDrawCount == 1 || features.features.multiDrawIndirect);
445 }
446
Greg Daniel569afe12020-09-14 10:25:36 -0400447#ifdef SK_BUILD_FOR_UNIX
448 if (kNvidia_VkVendor == properties.vendorID) {
449 // On nvidia linux we see a big perf regression when not using dedicated image allocations.
450 fShouldAlwaysUseDedicatedImageMemory = true;
451 }
452#endif
453
Greg Danielcaa795f2019-05-14 11:54:25 -0400454 this->initFormatTable(vkInterface, physDev, properties);
egdaniel8f1dcaa2016-04-01 10:10:45 -0700455 this->initStencilFormat(vkInterface, physDev);
Greg Daniel164a9f02016-02-22 09:56:40 -0500456
Greg Daniel43833b02020-07-14 09:21:48 -0400457 if (contextOptions.fMaxCachedVulkanSecondaryCommandBuffers >= 0) {
458 fMaxPerPoolCachedSecondaryCommandBuffers =
459 contextOptions.fMaxCachedVulkanSecondaryCommandBuffers;
460 }
461
Greg Daniel691f5e72018-02-28 14:21:34 -0500462 if (!contextOptions.fDisableDriverCorrectnessWorkarounds) {
Robert Phillips9233e0c2019-11-20 15:20:05 +0000463 this->applyDriverCorrectnessWorkarounds(properties);
egdanielc5ec1402016-03-28 12:14:42 -0700464 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500465
Chris Dalton8367e112019-11-13 12:43:21 -0700466 this->finishInitialization(contextOptions);
Greg Daniel691f5e72018-02-28 14:21:34 -0500467}
468
Robert Phillips9233e0c2019-11-20 15:20:05 +0000469void GrVkCaps::applyDriverCorrectnessWorkarounds(const VkPhysicalDeviceProperties& properties) {
Greg Daniel80a08dd2017-01-20 10:45:49 -0500470#if defined(SK_BUILD_FOR_WIN)
Greg Daniel900e5c82018-08-28 10:59:24 -0400471 if (kNvidia_VkVendor == properties.vendorID || kIntel_VkVendor == properties.vendorID) {
Greg Danielfda45862021-02-09 17:55:07 -0500472 fMustSyncCommandBuffersWithQueue = true;
Greg Daniel80a08dd2017-01-20 10:45:49 -0500473 }
474#elif defined(SK_BUILD_FOR_ANDROID)
475 if (kImagination_VkVendor == properties.vendorID) {
Greg Danielfda45862021-02-09 17:55:07 -0500476 fMustSyncCommandBuffersWithQueue = true;
Greg Daniel80a08dd2017-01-20 10:45:49 -0500477 }
478#endif
Greg Danielbce5eb92018-03-01 13:13:44 -0500479
Greg Daniel6ed2dcc2020-09-02 16:38:43 -0400480 // Defaults to zero since all our workaround checks that use this consider things "fixed" once
481 // above a certain api level. So this will just default to it being less which will enable
482 // workarounds.
483 int androidAPIVersion = 0;
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400484#if defined(SK_BUILD_FOR_ANDROID)
Greg Daniel6ed2dcc2020-09-02 16:38:43 -0400485 char androidAPIVersionStr[PROP_VALUE_MAX];
486 int strLength = __system_property_get("ro.build.version.sdk", androidAPIVersionStr);
487 // Defaults to zero since most checks care if it is greater than a specific value. So this will
488 // just default to it being less.
489 androidAPIVersion = (strLength == 0) ? 0 : atoi(androidAPIVersionStr);
490#endif
491
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400492 // Protected memory features have problems in Android P and earlier.
493 if (fSupportsProtectedMemory && (kQualcomm_VkVendor == properties.vendorID)) {
Greg Daniel6ed2dcc2020-09-02 16:38:43 -0400494 if (androidAPIVersion <= 28) {
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400495 fSupportsProtectedMemory = false;
496 }
497 }
Emircan Uysaler23ca4e72019-06-24 10:53:09 -0400498
Greg Danielddc0c602018-06-18 11:26:30 -0400499 // On Mali galaxy s7 we see lots of rendering issues when we suballocate VkImages.
Greg Daniel98df2912020-09-11 11:08:10 -0400500 if (kARM_VkVendor == properties.vendorID && androidAPIVersion <= 28) {
Greg Danielddc0c602018-06-18 11:26:30 -0400501 fShouldAlwaysUseDedicatedImageMemory = true;
502 }
503
Greg Daniela718a612019-10-07 16:25:41 -0400504 // On Mali galaxy s7 and s9 we see lots of rendering issues with image filters dropping out when
Greg Daniel6ed2dcc2020-09-02 16:38:43 -0400505 // using only primary command buffers. We also see issues on the P30 running android 28.
506 if (kARM_VkVendor == properties.vendorID && androidAPIVersion <= 28) {
Greg Daniela718a612019-10-07 16:25:41 -0400507 fPreferPrimaryOverSecondaryCommandBuffers = false;
Greg Daniel70ea0d92021-01-14 13:08:13 -0500508 // If we are using secondary command buffers our code isn't setup to insert barriers into
509 // the secondary cb so we need to disable support for them.
510 fTextureBarrierSupport = false;
511 fBlendEquationSupport = kBasic_BlendEquationSupport;
Greg Daniela718a612019-10-07 16:25:41 -0400512 }
513
Greg Danield8d9cf12021-01-07 09:46:39 -0500514 // We've seen numerous driver bugs on qualcomm devices running on android P (api 28) or earlier
515 // when trying to using discardable msaa attachments and loading from resolve. So we disable the
516 // feature for those devices.
517 if (properties.vendorID == kQualcomm_VkVendor && androidAPIVersion <= 28) {
518 fPreferDiscardableMSAAAttachment = false;
Greg Danielf8a96582021-08-29 16:25:50 -0400519 fSupportsDiscardableMSAAForDMSAA = false;
Greg Danield8d9cf12021-01-07 09:46:39 -0500520 }
521
Brian Osman76f635c2020-03-25 16:23:11 -0400522 // On Mali G series GPUs, applying transfer functions in the fragment shader with half-floats
523 // produces answers that are much less accurate than expected/required. This forces full floats
524 // for some intermediate values to get acceptable results.
525 if (kARM_VkVendor == properties.vendorID) {
526 fShaderCaps->fColorSpaceMathNeedsFloat = true;
527 }
528
Greg Daniela718a612019-10-07 16:25:41 -0400529 // On various devices, when calling vkCmdClearAttachments on a primary command buffer, it
530 // corrupts the bound buffers on the command buffer. As a workaround we invalidate our knowledge
531 // of bound buffers so that we will rebind them on the next draw.
532 if (kQualcomm_VkVendor == properties.vendorID || kAMD_VkVendor == properties.vendorID) {
533 fMustInvalidatePrimaryCmdBufferStateAfterClearAttachments = true;
534 }
535
Greg Daniel417743f2021-01-06 09:24:09 -0500536 // On Qualcomm and Arm the gpu resolves an area larger than the render pass bounds when using
537 // discardable msaa attachments. This causes the resolve to resolve uninitialized data from the
538 // msaa image into the resolve image.
539 if (kQualcomm_VkVendor == properties.vendorID || kARM_VkVendor == properties.vendorID) {
540 fMustLoadFullImageWithDiscardableMSAA = true;
541 }
542
Greg Daniel815ec0d2021-01-25 14:09:27 -0500543#ifdef SK_BUILD_FOR_UNIX
544 if (kIntel_VkVendor == properties.vendorID) {
545 // At least on our linux Debug Intel HD405 bot we are seeing issues doing read pixels with
546 // non-conherent memory. It seems like the device is not properly honoring the
547 // vkInvalidateMappedMemoryRanges calls correctly. Other linux intel devices seem to work
548 // okay. However, since I'm not sure how to target a specific intel devices or driver
549 // version I am going to stop all intel linux from using non-coherent memory. Currently we
550 // are not shipping anything on these platforms and the only real thing that will regress is
551 // read backs. If we find later we do care about this performance we can come back to figure
552 // out how to do a more narrow workaround.
553 fMustUseCoherentHostVisibleMemory = true;
554 }
555#endif
556
Greg Danielbce5eb92018-03-01 13:13:44 -0500557 ////////////////////////////////////////////////////////////////////////////
558 // GrCaps workarounds
559 ////////////////////////////////////////////////////////////////////////////
560
Chris Daltond53853d2019-11-25 12:54:55 -0700561#ifdef SK_BUILD_FOR_ANDROID
Chris Dalton94310792021-03-12 11:10:24 -0700562 // MSAA CCPR was slow on Android. http://skbug.com/9676
563 fDriverDisableMSAAClipAtlas = true;
Chris Daltond53853d2019-11-25 12:54:55 -0700564#endif
Chris Dalton78fa08b2019-11-16 02:53:52 +0000565
Greg Danielbce5eb92018-03-01 13:13:44 -0500566 if (kARM_VkVendor == properties.vendorID) {
Greg Daniel4374e962018-09-28 15:09:47 -0400567 fAvoidWritePixelsFastPath = true; // bugs.skia.org/8064
Greg Danielbce5eb92018-03-01 13:13:44 -0500568 }
569
570 // AMD advertises support for MAX_UINT vertex input attributes, but in reality only supports 32.
571 if (kAMD_VkVendor == properties.vendorID) {
Brian Osman788b9162020-02-07 10:36:46 -0500572 fMaxVertexAttributes = std::min(fMaxVertexAttributes, 32);
Greg Danielbce5eb92018-03-01 13:13:44 -0500573 }
574
Greg Daniel37fd6582020-09-14 12:36:09 -0400575 // Adreno devices fail when trying to read the dest using an input attachment and texture
576 // barriers.
577 if (kQualcomm_VkVendor == properties.vendorID) {
578 fTextureBarrierSupport = false;
579 }
580
Greg Daniel70ea0d92021-01-14 13:08:13 -0500581 // On ARM indirect draws are broken on Android 9 and earlier. This was tested on a P30 and
582 // Mate 20x running android 9.
583 if (properties.vendorID == kARM_VkVendor && androidAPIVersion <= 28) {
584 fNativeDrawIndirectSupport = false;
585 }
586
Greg Danielbce5eb92018-03-01 13:13:44 -0500587 ////////////////////////////////////////////////////////////////////////////
588 // GrShaderCaps workarounds
589 ////////////////////////////////////////////////////////////////////////////
590
Greg Danielbce5eb92018-03-01 13:13:44 -0500591 if (kImagination_VkVendor == properties.vendorID) {
592 fShaderCaps->fAtan2ImplementedAsAtanYOverX = true;
593 }
Greg Daniel164a9f02016-02-22 09:56:40 -0500594}
595
Greg Daniel313c6952018-08-08 09:24:08 -0400596void GrVkCaps::initGrCaps(const GrVkInterface* vkInterface,
597 VkPhysicalDevice physDev,
598 const VkPhysicalDeviceProperties& properties,
jvanverthfd7bd452016-03-25 06:29:52 -0700599 const VkPhysicalDeviceMemoryProperties& memoryProperties,
Greg Daniel313c6952018-08-08 09:24:08 -0400600 const VkPhysicalDeviceFeatures2& features,
601 const GrVkExtensions& extensions) {
Greg Danielc5cc2de2017-03-20 11:40:58 -0400602 // So GPUs, like AMD, are reporting MAX_INT support vertex attributes. In general, there is no
603 // need for us ever to support that amount, and it makes tests which tests all the vertex
604 // attribs timeout looping over that many. For now, we'll cap this at 64 max and can raise it if
605 // we ever find that need.
606 static const uint32_t kMaxVertexAttributes = 64;
Brian Osman788b9162020-02-07 10:36:46 -0500607 fMaxVertexAttributes = std::min(properties.limits.maxVertexInputAttributes, kMaxVertexAttributes);
Greg Danielc5cc2de2017-03-20 11:40:58 -0400608
Chris Dalton1c3a77e2020-06-09 18:51:40 -0600609 // GrCaps::fSampleLocationsSupport refers to the ability to *query* the sample locations (not
610 // program them). For now we just set this to true if the device uses standard locations, and
611 // return the standard locations back when queried.
612 if (properties.limits.standardSampleLocations) {
Chris Dalton2284aab2019-11-15 11:02:24 -0700613 fSampleLocationsSupport = true;
614 }
615
Chris Daltonce425af2019-12-16 10:39:03 -0700616 if (extensions.hasExtension(VK_EXT_CONSERVATIVE_RASTERIZATION_EXTENSION_NAME, 1)) {
617 fConservativeRasterSupport = true;
618 }
619
Chris Dalton1215cda2019-12-17 21:44:04 -0700620 fWireframeSupport = true;
621
egdanield5e3b9e2016-03-08 12:19:54 -0800622 // We could actually query and get a max size for each config, however maxImageDimension2D will
623 // give the minimum max size across all configs. So for simplicity we will use that for now.
Brian Osman788b9162020-02-07 10:36:46 -0500624 fMaxRenderTargetSize = std::min(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX);
625 fMaxTextureSize = std::min(properties.limits.maxImageDimension2D, (uint32_t)INT_MAX);
Robert Phillips9233e0c2019-11-20 15:20:05 +0000626 if (fDriverBugWorkarounds.max_texture_size_limit_4096) {
Brian Osman788b9162020-02-07 10:36:46 -0500627 fMaxTextureSize = std::min(fMaxTextureSize, 4096);
Robert Phillips9233e0c2019-11-20 15:20:05 +0000628 }
egdanield5e3b9e2016-03-08 12:19:54 -0800629
Chris Dalton2612bae2018-02-22 13:41:37 -0700630 // TODO: check if RT's larger than 4k incur a performance cost on ARM.
631 fMaxPreferredRenderTargetSize = fMaxRenderTargetSize;
632
Jim Van Verth4b3d1f32020-10-08 15:46:36 -0400633 fMaxPushConstantsSize = std::min(properties.limits.maxPushConstantsSize, (uint32_t)INT_MAX);
634
egdanield5e3b9e2016-03-08 12:19:54 -0800635 // Assuming since we will always map in the end to upload the data we might as well just map
636 // from the get go. There is no hard data to suggest this is faster or slower.
cdalton397536c2016-03-25 12:15:03 -0700637 fBufferMapThreshold = 0;
egdanield5e3b9e2016-03-08 12:19:54 -0800638
Brian Salomon105d7c22019-04-16 13:46:14 -0400639 fMapBufferFlags = kCanMap_MapFlag | kSubset_MapFlag | kAsyncRead_MapFlag;
egdanield5e3b9e2016-03-08 12:19:54 -0800640
Greg Daniel28bea442021-06-25 15:06:15 +0000641 fOversizedStencilSupport = true;
Greg Daniel313c6952018-08-08 09:24:08 -0400642
643 if (extensions.hasExtension(VK_EXT_BLEND_OPERATION_ADVANCED_EXTENSION_NAME, 2) &&
644 this->supportsPhysicalDeviceProperties2()) {
645
646 VkPhysicalDeviceBlendOperationAdvancedPropertiesEXT blendProps;
647 blendProps.sType =
648 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT;
649 blendProps.pNext = nullptr;
650
651 VkPhysicalDeviceProperties2 props;
652 props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
653 props.pNext = &blendProps;
654
655 GR_VK_CALL(vkInterface, GetPhysicalDeviceProperties2(physDev, &props));
656
657 if (blendProps.advancedBlendAllOperations == VK_TRUE) {
658 fShaderCaps->fAdvBlendEqInteraction = GrShaderCaps::kAutomatic_AdvBlendEqInteraction;
659
660 auto blendFeatures =
661 get_extension_feature_struct<VkPhysicalDeviceBlendOperationAdvancedFeaturesEXT>(
662 features,
663 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT);
664 if (blendFeatures && blendFeatures->advancedBlendCoherentOperations == VK_TRUE) {
665 fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport;
666 } else {
Greg Daniel9a18b082020-08-14 14:03:50 -0400667 fBlendEquationSupport = kAdvanced_BlendEquationSupport;
Greg Daniel313c6952018-08-08 09:24:08 -0400668 }
669 }
670 }
Greg Danielf6d60d32020-01-08 13:39:16 -0500671
672 if (kARM_VkVendor == properties.vendorID) {
673 fShouldCollapseSrcOverToSrcWhenAble = true;
674 }
Greg Daniel95ab83f2020-11-24 15:48:22 -0500675
676 // We're seeing vkCmdClearAttachments take a lot of cpu time when clearing the color attachment.
677 // We really should only be getting in there for partial clears. So instead we will do all
678 // partial clears as draws.
679 if (kQualcomm_VkVendor == properties.vendorID) {
680 fPerformPartialClearsAsDraws = true;
681 }
egdanield5e3b9e2016-03-08 12:19:54 -0800682}
683
Greg Daniel36443602018-08-02 12:51:52 -0400684void GrVkCaps::initShaderCaps(const VkPhysicalDeviceProperties& properties,
Greg Daniela0651ac2018-08-08 09:23:18 -0400685 const VkPhysicalDeviceFeatures2& features) {
Brian Salomon1edc5b92016-11-29 13:43:46 -0500686 GrShaderCaps* shaderCaps = fShaderCaps.get();
687 shaderCaps->fVersionDeclString = "#version 330\n";
egdaniel3a15fd42016-04-05 11:00:29 -0700688
egdanield5e3b9e2016-03-08 12:19:54 -0800689 // Vulkan is based off ES 3.0 so the following should all be supported
Brian Salomon1edc5b92016-11-29 13:43:46 -0500690 shaderCaps->fUsesPrecisionModifiers = true;
691 shaderCaps->fFlatInterpolationSupport = true;
Brian Salomon41274562017-09-15 09:40:03 -0700692 // Flat interpolation appears to be slow on Qualcomm GPUs. This was tested in GL and is assumed
693 // to be true with Vulkan as well.
694 shaderCaps->fPreferFlatInterpolation = kQualcomm_VkVendor != properties.vendorID;
egdanield5e3b9e2016-03-08 12:19:54 -0800695
Chris Dalton2284aab2019-11-15 11:02:24 -0700696 shaderCaps->fSampleMaskSupport = true;
egdanield5e3b9e2016-03-08 12:19:54 -0800697
Brian Salomon1edc5b92016-11-29 13:43:46 -0500698 shaderCaps->fShaderDerivativeSupport = true;
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600699
John Stiles85749c02021-03-23 17:12:03 -0400700 // ARM GPUs calculate `matrix * vector` in SPIR-V at full precision, even when the inputs are
701 // RelaxedPrecision. Rewriting the multiply as a sum of vector*scalar fixes this. (skia:11769)
702 shaderCaps->fRewriteMatrixVectorMultiply = (kARM_VkVendor == properties.vendorID);
703
Greg Daniela0651ac2018-08-08 09:23:18 -0400704 shaderCaps->fDualSourceBlendingSupport = features.features.dualSrcBlend;
egdanield632bb42016-03-30 12:06:48 -0700705
Brian Salomon1edc5b92016-11-29 13:43:46 -0500706 shaderCaps->fIntegerSupport = true;
John Stilesec793492021-05-03 09:21:12 -0400707 shaderCaps->fNonsquareMatrixSupport = true;
John Stilesbc9222b2021-08-17 15:58:03 -0400708 shaderCaps->fInverseHyperbolicSupport = true;
Chris Dalton1d616352017-05-31 12:51:23 -0600709 shaderCaps->fVertexIDSupport = true;
Chris Dalton69043032021-07-01 11:17:53 -0600710 shaderCaps->fInfinitySupport = true;
Chris Dalton489fa0b2021-05-14 17:41:17 -0600711 shaderCaps->fBitManipulationSupport = true;
cdalton9c3f1432016-03-11 10:07:37 -0800712
cdaltona6b92ad2016-04-11 12:03:08 -0700713 // Assume the minimum precisions mandated by the SPIR-V spec.
Chris Dalton47c8ed32017-11-15 18:27:09 -0700714 shaderCaps->fFloatIs32Bits = true;
715 shaderCaps->fHalfIs32Bits = false;
cdaltona6b92ad2016-04-11 12:03:08 -0700716
Brian Osman788b9162020-02-07 10:36:46 -0500717 shaderCaps->fMaxFragmentSamplers = std::min(
718 std::min(properties.limits.maxPerStageDescriptorSampledImages,
Brian Salomon1edc5b92016-11-29 13:43:46 -0500719 properties.limits.maxPerStageDescriptorSamplers),
720 (uint32_t)INT_MAX);
Greg Daniel164a9f02016-02-22 09:56:40 -0500721}
722
egdaniel8f1dcaa2016-04-01 10:10:45 -0700723bool stencil_format_supported(const GrVkInterface* interface,
724 VkPhysicalDevice physDev,
725 VkFormat format) {
Greg Daniel164a9f02016-02-22 09:56:40 -0500726 VkFormatProperties props;
727 memset(&props, 0, sizeof(VkFormatProperties));
728 GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
egdaniel8f1dcaa2016-04-01 10:10:45 -0700729 return SkToBool(VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT & props.optimalTilingFeatures);
Greg Daniel164a9f02016-02-22 09:56:40 -0500730}
731
egdaniel8f1dcaa2016-04-01 10:10:45 -0700732void GrVkCaps::initStencilFormat(const GrVkInterface* interface, VkPhysicalDevice physDev) {
egdaniel8f1dcaa2016-04-01 10:10:45 -0700733 if (stencil_format_supported(interface, physDev, VK_FORMAT_S8_UINT)) {
Greg Daniel8ade5e82020-10-07 13:09:48 -0400734 fPreferredStencilFormat = VK_FORMAT_S8_UINT;
egdaniel8f1dcaa2016-04-01 10:10:45 -0700735 } else if (stencil_format_supported(interface, physDev, VK_FORMAT_D24_UNORM_S8_UINT)) {
Greg Daniel8ade5e82020-10-07 13:09:48 -0400736 fPreferredStencilFormat = VK_FORMAT_D24_UNORM_S8_UINT;
egdaniel8f1dcaa2016-04-01 10:10:45 -0700737 } else {
738 SkASSERT(stencil_format_supported(interface, physDev, VK_FORMAT_D32_SFLOAT_S8_UINT));
Greg Daniel8ade5e82020-10-07 13:09:48 -0400739 fPreferredStencilFormat = VK_FORMAT_D32_SFLOAT_S8_UINT;
egdaniel8f1dcaa2016-04-01 10:10:45 -0700740 }
741}
742
Greg Danielcaa795f2019-05-14 11:54:25 -0400743static bool format_is_srgb(VkFormat format) {
Robert Phillipsf209e882019-06-25 15:59:50 -0400744 SkASSERT(GrVkFormatIsSupported(format));
745
Greg Danielcaa795f2019-05-14 11:54:25 -0400746 switch (format) {
747 case VK_FORMAT_R8G8B8A8_SRGB:
Greg Danielcaa795f2019-05-14 11:54:25 -0400748 return true;
Greg Danielcaa795f2019-05-14 11:54:25 -0400749 default:
Greg Danielcaa795f2019-05-14 11:54:25 -0400750 return false;
751 }
752}
753
Greg Daniel2c19e7f2019-06-18 13:29:21 -0400754// These are all the valid VkFormats that we support in Skia. They are roughly ordered from most
Greg Danielcaa795f2019-05-14 11:54:25 -0400755// frequently used to least to improve look up times in arrays.
756static constexpr VkFormat kVkFormats[] = {
757 VK_FORMAT_R8G8B8A8_UNORM,
758 VK_FORMAT_R8_UNORM,
759 VK_FORMAT_B8G8R8A8_UNORM,
760 VK_FORMAT_R5G6B5_UNORM_PACK16,
761 VK_FORMAT_R16G16B16A16_SFLOAT,
762 VK_FORMAT_R16_SFLOAT,
Greg Danielcaa795f2019-05-14 11:54:25 -0400763 VK_FORMAT_R8G8B8_UNORM,
764 VK_FORMAT_R8G8_UNORM,
765 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
Robert Phillips9a30ee02020-04-29 08:58:39 -0400766 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
Greg Danielcaa795f2019-05-14 11:54:25 -0400767 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
Greg Danieleb4a8272019-05-16 16:52:55 -0400768 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
Greg Danielcaa795f2019-05-14 11:54:25 -0400769 VK_FORMAT_R8G8B8A8_SRGB,
Robert Phillipsfe18de52019-06-06 17:21:50 -0400770 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
Robert Phillips8f259a02019-12-20 11:32:27 -0500771 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
Robert Phillipsb0855272020-01-15 12:56:52 -0500772 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
Robert Phillipsfe18de52019-06-06 17:21:50 -0400773 VK_FORMAT_R16_UNORM,
774 VK_FORMAT_R16G16_UNORM,
Sergey Ulanov2739fd22019-08-11 22:46:33 -0700775 VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM,
776 VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
Robert Phillips66a46032019-06-18 08:00:42 -0400777 VK_FORMAT_R16G16B16A16_UNORM,
778 VK_FORMAT_R16G16_SFLOAT,
Greg Danielcaa795f2019-05-14 11:54:25 -0400779};
780
Greg Daniel0fac8692019-08-16 13:13:17 -0400781void GrVkCaps::setColorType(GrColorType colorType, std::initializer_list<VkFormat> formats) {
782#ifdef SK_DEBUG
783 for (size_t i = 0; i < kNumVkFormats; ++i) {
784 const auto& formatInfo = fFormatTable[i];
785 for (int j = 0; j < formatInfo.fColorTypeInfoCount; ++j) {
786 const auto& ctInfo = formatInfo.fColorTypeInfos[j];
787 if (ctInfo.fColorType == colorType &&
788 !SkToBool(ctInfo.fFlags & ColorTypeInfo::kWrappedOnly_Flag)) {
789 bool found = false;
790 for (auto it = formats.begin(); it != formats.end(); ++it) {
791 if (kVkFormats[i] == *it) {
792 found = true;
793 }
794 }
795 SkASSERT(found);
796 }
797 }
798 }
799#endif
800 int idx = static_cast<int>(colorType);
801 for (auto it = formats.begin(); it != formats.end(); ++it) {
802 const auto& info = this->getFormatInfo(*it);
803 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
804 if (info.fColorTypeInfos[i].fColorType == colorType) {
805 fColorTypeToFormatTable[idx] = *it;
806 return;
807 }
808 }
809 }
810}
811
Greg Danielcaa795f2019-05-14 11:54:25 -0400812const GrVkCaps::FormatInfo& GrVkCaps::getFormatInfo(VkFormat format) const {
Greg Daniel1ff50212019-08-02 15:54:08 -0400813 GrVkCaps* nonConstThis = const_cast<GrVkCaps*>(this);
814 return nonConstThis->getFormatInfo(format);
815}
816
817GrVkCaps::FormatInfo& GrVkCaps::getFormatInfo(VkFormat format) {
Greg Danielcaa795f2019-05-14 11:54:25 -0400818 static_assert(SK_ARRAY_COUNT(kVkFormats) == GrVkCaps::kNumVkFormats,
819 "Size of VkFormats array must match static value in header");
820 for (size_t i = 0; i < SK_ARRAY_COUNT(kVkFormats); ++i) {
821 if (kVkFormats[i] == format) {
822 return fFormatTable[i];
823 }
824 }
Greg Daniel1ff50212019-08-02 15:54:08 -0400825 static FormatInfo kInvalidFormat;
Greg Daniel52ee5f62019-06-20 13:38:18 -0400826 return kInvalidFormat;
Greg Danielcaa795f2019-05-14 11:54:25 -0400827}
828
829void GrVkCaps::initFormatTable(const GrVkInterface* interface, VkPhysicalDevice physDev,
Greg Daniel2bb6ecc2017-07-20 13:11:14 +0000830 const VkPhysicalDeviceProperties& properties) {
Greg Danielcaa795f2019-05-14 11:54:25 -0400831 static_assert(SK_ARRAY_COUNT(kVkFormats) == GrVkCaps::kNumVkFormats,
832 "Size of VkFormats array must match static value in header");
Greg Daniel1ff50212019-08-02 15:54:08 -0400833
Greg Daniel0fac8692019-08-16 13:13:17 -0400834 std::fill_n(fColorTypeToFormatTable, kGrColorTypeCnt, VK_FORMAT_UNDEFINED);
Greg Daniel1ff50212019-08-02 15:54:08 -0400835
Greg Daniel0fac8692019-08-16 13:13:17 -0400836 // Go through all the formats and init their support surface and data GrColorTypes.
Greg Daniel1ff50212019-08-02 15:54:08 -0400837 // Format: VK_FORMAT_R8G8B8A8_UNORM
838 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400839 constexpr VkFormat format = VK_FORMAT_R8G8B8A8_UNORM;
840 auto& info = this->getFormatInfo(format);
841 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -0400842 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -0400843 info.fColorTypeInfoCount = 2;
John Stilesfbd050b2020-08-03 13:21:46 -0400844 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -0400845 int ctIdx = 0;
846 // Format: VK_FORMAT_R8G8B8A8_UNORM, Surface: kRGBA_8888
847 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400848 constexpr GrColorType ct = GrColorType::kRGBA_8888;
Greg Daniel1ff50212019-08-02 15:54:08 -0400849 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -0400850 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -0400851 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -0400852 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
853 }
854 // Format: VK_FORMAT_R8G8B8A8_UNORM, Surface: kRGB_888x
855 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400856 constexpr GrColorType ct = GrColorType::kRGB_888x;
Greg Daniel1ff50212019-08-02 15:54:08 -0400857 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -0400858 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -0400859 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -0400860 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
Greg Daniel14b57212019-12-17 16:18:06 -0500861 ctInfo.fReadSwizzle = GrSwizzle::RGB1();
Greg Daniel1ff50212019-08-02 15:54:08 -0400862 }
863 }
864 }
865
866 // Format: VK_FORMAT_R8_UNORM
867 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400868 constexpr VkFormat format = VK_FORMAT_R8_UNORM;
869 auto& info = this->getFormatInfo(format);
870 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -0400871 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -0400872 info.fColorTypeInfoCount = 2;
John Stilesfbd050b2020-08-03 13:21:46 -0400873 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -0400874 int ctIdx = 0;
875 // Format: VK_FORMAT_R8_UNORM, Surface: kAlpha_8
876 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400877 constexpr GrColorType ct = GrColorType::kAlpha_8;
Greg Daniel1ff50212019-08-02 15:54:08 -0400878 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -0400879 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -0400880 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -0400881 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
Brian Salomonb43d6992021-01-05 14:37:40 -0500882 ctInfo.fReadSwizzle = GrSwizzle("000r");
883 ctInfo.fWriteSwizzle = GrSwizzle("a000");
Greg Daniel1ff50212019-08-02 15:54:08 -0400884 }
885 // Format: VK_FORMAT_R8_UNORM, Surface: kGray_8
886 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400887 constexpr GrColorType ct = GrColorType::kGray_8;
Greg Daniel1ff50212019-08-02 15:54:08 -0400888 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -0400889 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -0400890 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -0400891 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
Greg Daniel14b57212019-12-17 16:18:06 -0500892 ctInfo.fReadSwizzle = GrSwizzle("rrr1");
Greg Daniel1ff50212019-08-02 15:54:08 -0400893 }
894 }
895 }
896 // Format: VK_FORMAT_B8G8R8A8_UNORM
897 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400898 constexpr VkFormat format = VK_FORMAT_B8G8R8A8_UNORM;
899 auto& info = this->getFormatInfo(format);
900 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -0400901 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -0400902 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -0400903 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -0400904 int ctIdx = 0;
905 // Format: VK_FORMAT_B8G8R8A8_UNORM, Surface: kBGRA_8888
906 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400907 constexpr GrColorType ct = GrColorType::kBGRA_8888;
Greg Daniel1ff50212019-08-02 15:54:08 -0400908 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -0400909 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -0400910 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -0400911 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
912 }
913 }
914 }
915 // Format: VK_FORMAT_R5G6B5_UNORM_PACK16
916 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400917 constexpr VkFormat format = VK_FORMAT_R5G6B5_UNORM_PACK16;
918 auto& info = this->getFormatInfo(format);
919 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -0400920 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -0400921 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -0400922 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -0400923 int ctIdx = 0;
924 // Format: VK_FORMAT_R5G6B5_UNORM_PACK16, Surface: kBGR_565
925 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400926 constexpr GrColorType ct = GrColorType::kBGR_565;
Greg Daniel1ff50212019-08-02 15:54:08 -0400927 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -0400928 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -0400929 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -0400930 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
931 }
932 }
933 }
934 // Format: VK_FORMAT_R16G16B16A16_SFLOAT
935 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400936 constexpr VkFormat format = VK_FORMAT_R16G16B16A16_SFLOAT;
937 auto& info = this->getFormatInfo(format);
938 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -0400939 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -0400940 info.fColorTypeInfoCount = 2;
John Stilesfbd050b2020-08-03 13:21:46 -0400941 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -0400942 int ctIdx = 0;
943 // Format: VK_FORMAT_R16G16B16A16_SFLOAT, Surface: GrColorType::kRGBA_F16
944 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400945 constexpr GrColorType ct = GrColorType::kRGBA_F16;
Greg Daniel1ff50212019-08-02 15:54:08 -0400946 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -0400947 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -0400948 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -0400949 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
950 }
951 // Format: VK_FORMAT_R16G16B16A16_SFLOAT, Surface: GrColorType::kRGBA_F16_Clamped
952 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400953 constexpr GrColorType ct = GrColorType::kRGBA_F16_Clamped;
Greg Daniel1ff50212019-08-02 15:54:08 -0400954 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -0400955 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -0400956 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -0400957 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
958 }
959 }
960 }
961 // Format: VK_FORMAT_R16_SFLOAT
962 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400963 constexpr VkFormat format = VK_FORMAT_R16_SFLOAT;
964 auto& info = this->getFormatInfo(format);
965 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -0400966 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -0400967 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -0400968 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -0400969 int ctIdx = 0;
970 // Format: VK_FORMAT_R16_SFLOAT, Surface: kAlpha_F16
971 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400972 constexpr GrColorType ct = GrColorType::kAlpha_F16;
Greg Daniel1ff50212019-08-02 15:54:08 -0400973 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -0400974 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -0400975 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -0400976 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
Brian Salomonb43d6992021-01-05 14:37:40 -0500977 ctInfo.fReadSwizzle = GrSwizzle("000r");
978 ctInfo.fWriteSwizzle = GrSwizzle("a000");
Greg Daniel1ff50212019-08-02 15:54:08 -0400979 }
980 }
981 }
982 // Format: VK_FORMAT_R8G8B8_UNORM
983 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400984 constexpr VkFormat format = VK_FORMAT_R8G8B8_UNORM;
985 auto& info = this->getFormatInfo(format);
986 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -0400987 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -0400988 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -0400989 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -0400990 int ctIdx = 0;
991 // Format: VK_FORMAT_R8G8B8_UNORM, Surface: kRGB_888x
992 {
Greg Daniel0fac8692019-08-16 13:13:17 -0400993 constexpr GrColorType ct = GrColorType::kRGB_888x;
Greg Daniel1ff50212019-08-02 15:54:08 -0400994 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -0400995 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -0400996 // The Vulkan format is 3 bpp so we must convert to/from that when transferring.
997 ctInfo.fTransferColorType = GrColorType::kRGB_888;
Greg Daniel1ff50212019-08-02 15:54:08 -0400998 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
999 }
1000 }
1001 }
1002 // Format: VK_FORMAT_R8G8_UNORM
1003 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001004 constexpr VkFormat format = VK_FORMAT_R8G8_UNORM;
1005 auto& info = this->getFormatInfo(format);
1006 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -04001007 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -04001008 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001009 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -04001010 int ctIdx = 0;
1011 // Format: VK_FORMAT_R8G8_UNORM, Surface: kRG_88
1012 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001013 constexpr GrColorType ct = GrColorType::kRG_88;
Greg Daniel1ff50212019-08-02 15:54:08 -04001014 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001015 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001016 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -04001017 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1018 }
1019 }
1020 }
1021 // Format: VK_FORMAT_A2B10G10R10_UNORM_PACK32
1022 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001023 constexpr VkFormat format = VK_FORMAT_A2B10G10R10_UNORM_PACK32;
1024 auto& info = this->getFormatInfo(format);
1025 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -04001026 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -04001027 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001028 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -04001029 int ctIdx = 0;
1030 // Format: VK_FORMAT_A2B10G10R10_UNORM_PACK32, Surface: kRGBA_1010102
1031 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001032 constexpr GrColorType ct = GrColorType::kRGBA_1010102;
Greg Daniel1ff50212019-08-02 15:54:08 -04001033 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001034 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001035 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -04001036 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1037 }
1038 }
1039 }
Robert Phillips9a30ee02020-04-29 08:58:39 -04001040 // Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32
1041 {
1042 constexpr VkFormat format = VK_FORMAT_A2R10G10B10_UNORM_PACK32;
1043 auto& info = this->getFormatInfo(format);
1044 info.init(interface, physDev, properties, format);
Robert Phillips9a30ee02020-04-29 08:58:39 -04001045 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
1046 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001047 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Robert Phillips9a30ee02020-04-29 08:58:39 -04001048 int ctIdx = 0;
1049 // Format: VK_FORMAT_A2R10G10B10_UNORM_PACK32, Surface: kBGRA_1010102
1050 {
1051 constexpr GrColorType ct = GrColorType::kBGRA_1010102;
1052 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
1053 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001054 ctInfo.fTransferColorType = ct;
Robert Phillips9a30ee02020-04-29 08:58:39 -04001055 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1056 }
1057 }
1058 }
Greg Daniel1ff50212019-08-02 15:54:08 -04001059 // Format: VK_FORMAT_B4G4R4A4_UNORM_PACK16
1060 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001061 constexpr VkFormat format = VK_FORMAT_B4G4R4A4_UNORM_PACK16;
1062 auto& info = this->getFormatInfo(format);
1063 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -04001064 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -04001065 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001066 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -04001067 int ctIdx = 0;
1068 // Format: VK_FORMAT_B4G4R4A4_UNORM_PACK16, Surface: kABGR_4444
1069 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001070 constexpr GrColorType ct = GrColorType::kABGR_4444;
Greg Daniel1ff50212019-08-02 15:54:08 -04001071 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001072 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001073 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -04001074 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
Greg Daniel14b57212019-12-17 16:18:06 -05001075 ctInfo.fReadSwizzle = GrSwizzle::BGRA();
Brian Salomon982f5462020-03-30 12:52:33 -04001076 ctInfo.fWriteSwizzle = GrSwizzle::BGRA();
Greg Daniel1ff50212019-08-02 15:54:08 -04001077 }
1078 }
1079 }
Greg Daniel373d7dd2020-07-21 10:41:50 -04001080
Greg Daniel1ff50212019-08-02 15:54:08 -04001081 // Format: VK_FORMAT_R4G4B4A4_UNORM_PACK16
1082 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001083 constexpr VkFormat format = VK_FORMAT_R4G4B4A4_UNORM_PACK16;
1084 auto& info = this->getFormatInfo(format);
1085 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -04001086 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -04001087 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001088 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -04001089 int ctIdx = 0;
1090 // Format: VK_FORMAT_R4G4B4A4_UNORM_PACK16, Surface: kABGR_4444
1091 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001092 constexpr GrColorType ct = GrColorType::kABGR_4444;
Greg Daniel1ff50212019-08-02 15:54:08 -04001093 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001094 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001095 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -04001096 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1097 }
1098 }
1099 }
Greg Daniel1ff50212019-08-02 15:54:08 -04001100 // Format: VK_FORMAT_R8G8B8A8_SRGB
1101 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001102 constexpr VkFormat format = VK_FORMAT_R8G8B8A8_SRGB;
1103 auto& info = this->getFormatInfo(format);
Brian Salomon14c514d2019-09-26 12:30:15 -04001104 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -04001105 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -04001106 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001107 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -04001108 int ctIdx = 0;
1109 // Format: VK_FORMAT_R8G8B8A8_SRGB, Surface: kRGBA_8888_SRGB
1110 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001111 constexpr GrColorType ct = GrColorType::kRGBA_8888_SRGB;
Greg Daniel1ff50212019-08-02 15:54:08 -04001112 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001113 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001114 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -04001115 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1116 }
1117 }
1118 }
1119 // Format: VK_FORMAT_R16_UNORM
1120 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001121 constexpr VkFormat format = VK_FORMAT_R16_UNORM;
1122 auto& info = this->getFormatInfo(format);
1123 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -04001124 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -04001125 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001126 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -04001127 int ctIdx = 0;
Robert Phillips429f0d32019-09-11 17:03:28 -04001128 // Format: VK_FORMAT_R16_UNORM, Surface: kAlpha_16
Greg Daniel1ff50212019-08-02 15:54:08 -04001129 {
Robert Phillips429f0d32019-09-11 17:03:28 -04001130 constexpr GrColorType ct = GrColorType::kAlpha_16;
Greg Daniel1ff50212019-08-02 15:54:08 -04001131 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001132 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001133 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -04001134 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
Brian Salomonb43d6992021-01-05 14:37:40 -05001135 ctInfo.fReadSwizzle = GrSwizzle("000r");
1136 ctInfo.fWriteSwizzle = GrSwizzle("a000");
Greg Daniel1ff50212019-08-02 15:54:08 -04001137 }
1138 }
1139 }
1140 // Format: VK_FORMAT_R16G16_UNORM
1141 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001142 constexpr VkFormat format = VK_FORMAT_R16G16_UNORM;
1143 auto& info = this->getFormatInfo(format);
1144 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -04001145 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -04001146 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001147 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -04001148 int ctIdx = 0;
1149 // Format: VK_FORMAT_R16G16_UNORM, Surface: kRG_1616
1150 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001151 constexpr GrColorType ct = GrColorType::kRG_1616;
Greg Daniel1ff50212019-08-02 15:54:08 -04001152 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001153 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001154 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -04001155 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1156 }
1157 }
1158 }
1159 // Format: VK_FORMAT_R16G16B16A16_UNORM
1160 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001161 constexpr VkFormat format = VK_FORMAT_R16G16B16A16_UNORM;
1162 auto& info = this->getFormatInfo(format);
1163 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -04001164 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -04001165 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001166 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -04001167 int ctIdx = 0;
1168 // Format: VK_FORMAT_R16G16B16A16_UNORM, Surface: kRGBA_16161616
1169 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001170 constexpr GrColorType ct = GrColorType::kRGBA_16161616;
Greg Daniel1ff50212019-08-02 15:54:08 -04001171 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001172 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001173 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -04001174 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1175 }
1176 }
1177 }
1178 // Format: VK_FORMAT_R16G16_SFLOAT
1179 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001180 constexpr VkFormat format = VK_FORMAT_R16G16_SFLOAT;
1181 auto& info = this->getFormatInfo(format);
1182 info.init(interface, physDev, properties, format);
Greg Daniel7bfc9132019-08-14 14:23:53 -04001183 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Greg Daniel1ff50212019-08-02 15:54:08 -04001184 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001185 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Greg Daniel1ff50212019-08-02 15:54:08 -04001186 int ctIdx = 0;
1187 // Format: VK_FORMAT_R16G16_SFLOAT, Surface: kRG_F16
1188 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001189 constexpr GrColorType ct = GrColorType::kRG_F16;
Greg Daniel1ff50212019-08-02 15:54:08 -04001190 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001191 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001192 ctInfo.fTransferColorType = ct;
Greg Daniel1ff50212019-08-02 15:54:08 -04001193 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
1194 }
1195 }
1196 }
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001197 // Format: VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM
1198 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001199 constexpr VkFormat format = VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM;
1200 auto& info = this->getFormatInfo(format);
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001201 if (fSupportsYcbcrConversion) {
Greg Daniel0fac8692019-08-16 13:13:17 -04001202 info.init(interface, physDev, properties, format);
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001203 }
Greg Daniel7bfc9132019-08-14 14:23:53 -04001204 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001205 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001206 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001207 int ctIdx = 0;
1208 // Format: VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, Surface: kRGB_888x
1209 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001210 constexpr GrColorType ct = GrColorType::kRGB_888x;
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001211 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001212 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001213 ctInfo.fTransferColorType = ct;
Greg Daniel0fac8692019-08-16 13:13:17 -04001214 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kWrappedOnly_Flag;
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001215 }
1216 }
1217 }
1218 // Format: VK_FORMAT_G8_B8R8_2PLANE_420_UNORM
1219 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001220 constexpr VkFormat format = VK_FORMAT_G8_B8R8_2PLANE_420_UNORM;
1221 auto& info = this->getFormatInfo(format);
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001222 if (fSupportsYcbcrConversion) {
Greg Daniel0fac8692019-08-16 13:13:17 -04001223 info.init(interface, physDev, properties, format);
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001224 }
Greg Daniel7bfc9132019-08-14 14:23:53 -04001225 if (SkToBool(info.fOptimalFlags & FormatInfo::kTexturable_Flag)) {
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001226 info.fColorTypeInfoCount = 1;
John Stilesfbd050b2020-08-03 13:21:46 -04001227 info.fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info.fColorTypeInfoCount);
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001228 int ctIdx = 0;
1229 // Format: VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, Surface: kRGB_888x
1230 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001231 constexpr GrColorType ct = GrColorType::kRGB_888x;
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001232 auto& ctInfo = info.fColorTypeInfos[ctIdx++];
Greg Daniel0fac8692019-08-16 13:13:17 -04001233 ctInfo.fColorType = ct;
Brian Salomon974c8212021-04-05 16:24:00 -04001234 ctInfo.fTransferColorType = ct;
Greg Daniel0fac8692019-08-16 13:13:17 -04001235 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kWrappedOnly_Flag;
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001236 }
1237 }
1238 }
Greg Daniel1ff50212019-08-02 15:54:08 -04001239 // Format: VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK
1240 {
Greg Daniel0fac8692019-08-16 13:13:17 -04001241 constexpr VkFormat format = VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK;
1242 auto& info = this->getFormatInfo(format);
1243 info.init(interface, physDev, properties, format);
Greg Daniel9d02a4c2020-07-15 14:26:08 -04001244 // Setting this to texel block size
Greg Daniel1ff50212019-08-02 15:54:08 -04001245 // No supported GrColorTypes.
1246 }
Greg Daniel0fac8692019-08-16 13:13:17 -04001247
Robert Phillips8f259a02019-12-20 11:32:27 -05001248 // Format: VK_FORMAT_BC1_RGB_UNORM_BLOCK
1249 {
1250 constexpr VkFormat format = VK_FORMAT_BC1_RGB_UNORM_BLOCK;
1251 auto& info = this->getFormatInfo(format);
1252 info.init(interface, physDev, properties, format);
Greg Daniel9d02a4c2020-07-15 14:26:08 -04001253 // Setting this to texel block size
Robert Phillips8f259a02019-12-20 11:32:27 -05001254 // No supported GrColorTypes.
1255 }
1256
Robert Phillipsb0855272020-01-15 12:56:52 -05001257 // Format: VK_FORMAT_BC1_RGBA_UNORM_BLOCK
1258 {
1259 constexpr VkFormat format = VK_FORMAT_BC1_RGBA_UNORM_BLOCK;
1260 auto& info = this->getFormatInfo(format);
1261 info.init(interface, physDev, properties, format);
Greg Daniel9d02a4c2020-07-15 14:26:08 -04001262 // Setting this to texel block size
Robert Phillipsb0855272020-01-15 12:56:52 -05001263 // No supported GrColorTypes.
1264 }
1265
Greg Daniel0fac8692019-08-16 13:13:17 -04001266 ////////////////////////////////////////////////////////////////////////////
1267 // Map GrColorTypes (used for creating GrSurfaces) to VkFormats. The order in which the formats
1268 // are passed into the setColorType function indicates the priority in selecting which format
1269 // we use for a given GrcolorType.
1270
1271 this->setColorType(GrColorType::kAlpha_8, { VK_FORMAT_R8_UNORM });
1272 this->setColorType(GrColorType::kBGR_565, { VK_FORMAT_R5G6B5_UNORM_PACK16 });
1273 this->setColorType(GrColorType::kABGR_4444, { VK_FORMAT_R4G4B4A4_UNORM_PACK16,
1274 VK_FORMAT_B4G4R4A4_UNORM_PACK16 });
1275 this->setColorType(GrColorType::kRGBA_8888, { VK_FORMAT_R8G8B8A8_UNORM });
1276 this->setColorType(GrColorType::kRGBA_8888_SRGB, { VK_FORMAT_R8G8B8A8_SRGB });
1277 this->setColorType(GrColorType::kRGB_888x, { VK_FORMAT_R8G8B8_UNORM,
1278 VK_FORMAT_R8G8B8A8_UNORM });
1279 this->setColorType(GrColorType::kRG_88, { VK_FORMAT_R8G8_UNORM });
1280 this->setColorType(GrColorType::kBGRA_8888, { VK_FORMAT_B8G8R8A8_UNORM });
1281 this->setColorType(GrColorType::kRGBA_1010102, { VK_FORMAT_A2B10G10R10_UNORM_PACK32 });
Robert Phillips9a30ee02020-04-29 08:58:39 -04001282 this->setColorType(GrColorType::kBGRA_1010102, { VK_FORMAT_A2R10G10B10_UNORM_PACK32 });
Greg Daniel0fac8692019-08-16 13:13:17 -04001283 this->setColorType(GrColorType::kGray_8, { VK_FORMAT_R8_UNORM });
1284 this->setColorType(GrColorType::kAlpha_F16, { VK_FORMAT_R16_SFLOAT });
1285 this->setColorType(GrColorType::kRGBA_F16, { VK_FORMAT_R16G16B16A16_SFLOAT });
1286 this->setColorType(GrColorType::kRGBA_F16_Clamped, { VK_FORMAT_R16G16B16A16_SFLOAT });
Robert Phillips429f0d32019-09-11 17:03:28 -04001287 this->setColorType(GrColorType::kAlpha_16, { VK_FORMAT_R16_UNORM });
Greg Daniel0fac8692019-08-16 13:13:17 -04001288 this->setColorType(GrColorType::kRG_1616, { VK_FORMAT_R16G16_UNORM });
1289 this->setColorType(GrColorType::kRGBA_16161616, { VK_FORMAT_R16G16B16A16_UNORM });
1290 this->setColorType(GrColorType::kRG_F16, { VK_FORMAT_R16G16_SFLOAT });
egdaniel8f1dcaa2016-04-01 10:10:45 -07001291}
1292
Greg Daniel1ff50212019-08-02 15:54:08 -04001293void GrVkCaps::FormatInfo::InitFormatFlags(VkFormatFeatureFlags vkFlags, uint16_t* flags) {
egdaniel8f1dcaa2016-04-01 10:10:45 -07001294 if (SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT & vkFlags) &&
1295 SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT & vkFlags)) {
Greg Daniel7bfc9132019-08-14 14:23:53 -04001296 *flags = *flags | kTexturable_Flag;
egdaniel8f1dcaa2016-04-01 10:10:45 -07001297
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001298 // Ganesh assumes that all renderable surfaces are also texturable
Greg Danielcaa795f2019-05-14 11:54:25 -04001299 if (SkToBool(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT & vkFlags)) {
Robert Phillipsb7b7e5f2017-05-22 13:23:19 -04001300 *flags = *flags | kRenderable_Flag;
1301 }
egdaniel8f1dcaa2016-04-01 10:10:45 -07001302 }
Greg Daniel7b62dca2020-08-21 11:26:12 -04001303 // TODO: For Vk w/ VK_KHR_maintenance1 extension support, check
1304 // VK_FORMAT_FEATURE_TRANSFER_[SRC|DST]_BIT_KHR explicitly to set copy flags
1305 // Can do similar check for VK_KHR_sampler_ycbcr_conversion added bits
egdaniel8f1dcaa2016-04-01 10:10:45 -07001306
1307 if (SkToBool(VK_FORMAT_FEATURE_BLIT_SRC_BIT & vkFlags)) {
1308 *flags = *flags | kBlitSrc_Flag;
1309 }
1310
1311 if (SkToBool(VK_FORMAT_FEATURE_BLIT_DST_BIT & vkFlags)) {
1312 *flags = *flags | kBlitDst_Flag;
1313 }
1314}
1315
Greg Danielcaa795f2019-05-14 11:54:25 -04001316void GrVkCaps::FormatInfo::initSampleCounts(const GrVkInterface* interface,
Greg Daniel81e7bf82017-07-19 14:47:42 -04001317 VkPhysicalDevice physDev,
Greg Daniel2bb6ecc2017-07-20 13:11:14 +00001318 const VkPhysicalDeviceProperties& physProps,
Greg Daniel81e7bf82017-07-19 14:47:42 -04001319 VkFormat format) {
1320 VkImageUsageFlags usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1321 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1322 VK_IMAGE_USAGE_SAMPLED_BIT |
1323 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
Greg Daniel81e7bf82017-07-19 14:47:42 -04001324 VkImageFormatProperties properties;
1325 GR_VK_CALL(interface, GetPhysicalDeviceImageFormatProperties(physDev,
1326 format,
1327 VK_IMAGE_TYPE_2D,
1328 VK_IMAGE_TILING_OPTIMAL,
1329 usage,
Brian Osman2b23c4b2018-06-01 12:25:08 -04001330 0, // createFlags
Greg Daniel81e7bf82017-07-19 14:47:42 -04001331 &properties));
1332 VkSampleCountFlags flags = properties.sampleCounts;
1333 if (flags & VK_SAMPLE_COUNT_1_BIT) {
Mike Reedb5475792018-08-08 16:17:42 -04001334 fColorSampleCounts.push_back(1);
Greg Daniel81e7bf82017-07-19 14:47:42 -04001335 }
Greg Daniel2bb6ecc2017-07-20 13:11:14 +00001336 if (kImagination_VkVendor == physProps.vendorID) {
1337 // MSAA does not work on imagination
1338 return;
1339 }
Brian Osman7fbb3632019-07-19 11:38:57 -04001340 if (kIntel_VkVendor == physProps.vendorID) {
Brian Osmanb5391bf2019-08-15 14:52:52 -04001341 // MSAA doesn't work well on Intel GPUs chromium:527565, chromium:983926
1342 return;
Brian Osman7fbb3632019-07-19 11:38:57 -04001343 }
Greg Daniel81e7bf82017-07-19 14:47:42 -04001344 if (flags & VK_SAMPLE_COUNT_2_BIT) {
Mike Reedb5475792018-08-08 16:17:42 -04001345 fColorSampleCounts.push_back(2);
Greg Daniel81e7bf82017-07-19 14:47:42 -04001346 }
1347 if (flags & VK_SAMPLE_COUNT_4_BIT) {
Mike Reedb5475792018-08-08 16:17:42 -04001348 fColorSampleCounts.push_back(4);
Greg Daniel81e7bf82017-07-19 14:47:42 -04001349 }
1350 if (flags & VK_SAMPLE_COUNT_8_BIT) {
Mike Reedb5475792018-08-08 16:17:42 -04001351 fColorSampleCounts.push_back(8);
Greg Daniel81e7bf82017-07-19 14:47:42 -04001352 }
1353 if (flags & VK_SAMPLE_COUNT_16_BIT) {
Mike Reedb5475792018-08-08 16:17:42 -04001354 fColorSampleCounts.push_back(16);
Greg Daniel81e7bf82017-07-19 14:47:42 -04001355 }
Chris Daltonb204e4c2019-11-07 12:43:13 -07001356 // Standard sample locations are not defined for more than 16 samples, and we don't need more
1357 // than 16. Omit 32 and 64.
Greg Daniel81e7bf82017-07-19 14:47:42 -04001358}
1359
Greg Danielcaa795f2019-05-14 11:54:25 -04001360void GrVkCaps::FormatInfo::init(const GrVkInterface* interface,
egdaniel8f1dcaa2016-04-01 10:10:45 -07001361 VkPhysicalDevice physDev,
Greg Daniel2bb6ecc2017-07-20 13:11:14 +00001362 const VkPhysicalDeviceProperties& properties,
Greg Danielcaa795f2019-05-14 11:54:25 -04001363 VkFormat format) {
egdaniel8f1dcaa2016-04-01 10:10:45 -07001364 VkFormatProperties props;
1365 memset(&props, 0, sizeof(VkFormatProperties));
1366 GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
Greg Daniel1ff50212019-08-02 15:54:08 -04001367 InitFormatFlags(props.linearTilingFeatures, &fLinearFlags);
1368 InitFormatFlags(props.optimalTilingFeatures, &fOptimalFlags);
Greg Daniel81e7bf82017-07-19 14:47:42 -04001369 if (fOptimalFlags & kRenderable_Flag) {
Greg Daniel2bb6ecc2017-07-20 13:11:14 +00001370 this->initSampleCounts(interface, physDev, properties, format);
Greg Daniel81e7bf82017-07-19 14:47:42 -04001371 }
Greg Daniel164a9f02016-02-22 09:56:40 -05001372}
Greg Daniel81e7bf82017-07-19 14:47:42 -04001373
Greg Daniela7b7fe02019-09-26 15:18:32 -04001374// For many checks in caps, we need to know whether the GrBackendFormat is external or not. If it is
1375// external the VkFormat will be VK_NULL_HANDLE which is not handled by our various format
1376// capability checks.
1377static bool backend_format_is_external(const GrBackendFormat& format) {
1378 const GrVkYcbcrConversionInfo* ycbcrInfo = format.getVkYcbcrConversionInfo();
1379 SkASSERT(ycbcrInfo);
1380
1381 // All external formats have a valid ycbcrInfo used for sampling and a non zero external format.
1382 if (ycbcrInfo->isValid() && ycbcrInfo->fExternalFormat != 0) {
1383#ifdef SK_DEBUG
1384 VkFormat vkFormat;
1385 SkAssertResult(format.asVkFormat(&vkFormat));
Greg Danielf4e176b2021-08-11 18:31:17 -04001386 SkASSERT(vkFormat == VK_FORMAT_UNDEFINED);
Greg Daniela7b7fe02019-09-26 15:18:32 -04001387#endif
1388 return true;
1389 }
1390 return false;
1391}
1392
Robert Phillipsf209e882019-06-25 15:59:50 -04001393bool GrVkCaps::isFormatSRGB(const GrBackendFormat& format) const {
Brian Salomond4764a12019-08-08 12:08:24 -04001394 VkFormat vkFormat;
1395 if (!format.asVkFormat(&vkFormat)) {
Robert Phillipsf209e882019-06-25 15:59:50 -04001396 return false;
1397 }
Greg Daniela7b7fe02019-09-26 15:18:32 -04001398 if (backend_format_is_external(format)) {
1399 return false;
1400 }
Robert Phillipsf209e882019-06-25 15:59:50 -04001401
Brian Salomond4764a12019-08-08 12:08:24 -04001402 return format_is_srgb(vkFormat);
Robert Phillipsf209e882019-06-25 15:59:50 -04001403}
1404
Greg Daniel0e9d34d2021-08-13 16:20:18 -04001405bool GrVkCaps::isFormatTexturable(const GrBackendFormat& format, GrTextureType) const {
Greg Daniel7bfc9132019-08-14 14:23:53 -04001406 VkFormat vkFormat;
1407 if (!format.asVkFormat(&vkFormat)) {
Greg Danielcaa795f2019-05-14 11:54:25 -04001408 return false;
1409 }
Greg Daniela7b7fe02019-09-26 15:18:32 -04001410 if (backend_format_is_external(format)) {
1411 // We can always texture from an external format (assuming we have the ycbcr conversion
1412 // info which we require to be passed in).
1413 return true;
1414 }
Greg Daniel7bfc9132019-08-14 14:23:53 -04001415 return this->isVkFormatTexturable(vkFormat);
1416}
1417
1418bool GrVkCaps::isVkFormatTexturable(VkFormat format) const {
1419 const FormatInfo& info = this->getFormatInfo(format);
1420 return SkToBool(FormatInfo::kTexturable_Flag & info.fOptimalFlags);
Robert Phillips39ef2ef2019-05-15 08:45:53 -04001421}
1422
Greg Daniel900583a2019-08-06 12:05:31 -04001423bool GrVkCaps::isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format,
1424 int sampleCount) const {
1425 if (!this->isFormatRenderable(format, sampleCount)) {
Greg Danieleadfac92019-08-02 09:03:53 -04001426 return false;
1427 }
Brian Salomond4764a12019-08-08 12:08:24 -04001428 VkFormat vkFormat;
1429 if (!format.asVkFormat(&vkFormat)) {
1430 return false;
1431 }
Greg Daniel1ff50212019-08-02 15:54:08 -04001432 const auto& info = this->getFormatInfo(vkFormat);
1433 if (!SkToBool(info.colorTypeFlags(ct) & ColorTypeInfo::kRenderable_Flag)) {
Greg Danieleadfac92019-08-02 09:03:53 -04001434 return false;
1435 }
Greg Daniel900583a2019-08-06 12:05:31 -04001436 return true;
Greg Danieleadfac92019-08-02 09:03:53 -04001437}
1438
Greg Daniel900583a2019-08-06 12:05:31 -04001439bool GrVkCaps::isFormatRenderable(const GrBackendFormat& format, int sampleCount) const {
Brian Salomond4764a12019-08-08 12:08:24 -04001440 VkFormat vkFormat;
1441 if (!format.asVkFormat(&vkFormat)) {
Greg Daniel900583a2019-08-06 12:05:31 -04001442 return false;
1443 }
Greg Daniel900583a2019-08-06 12:05:31 -04001444 return this->isFormatRenderable(vkFormat, sampleCount);
1445}
1446
1447bool GrVkCaps::isFormatRenderable(VkFormat format, int sampleCount) const {
1448 return sampleCount <= this->maxRenderTargetSampleCount(format);
Greg Danielcaa795f2019-05-14 11:54:25 -04001449}
1450
Robert Phillipsd8f79a22019-06-24 13:25:42 -04001451int GrVkCaps::getRenderTargetSampleCount(int requestedCount,
Brian Salomon4eb38b72019-08-05 12:58:39 -04001452 const GrBackendFormat& format) const {
1453 VkFormat vkFormat;
Brian Salomond4764a12019-08-08 12:08:24 -04001454 if (!format.asVkFormat(&vkFormat)) {
Brian Salomon4eb38b72019-08-05 12:58:39 -04001455 return 0;
1456 }
1457
Brian Salomond4764a12019-08-08 12:08:24 -04001458 return this->getRenderTargetSampleCount(requestedCount, vkFormat);
Robert Phillipsd8f79a22019-06-24 13:25:42 -04001459}
1460
Greg Danielcaa795f2019-05-14 11:54:25 -04001461int GrVkCaps::getRenderTargetSampleCount(int requestedCount, VkFormat format) const {
Brian Osman788b9162020-02-07 10:36:46 -05001462 requestedCount = std::max(1, requestedCount);
Greg Danielcaa795f2019-05-14 11:54:25 -04001463
1464 const FormatInfo& info = this->getFormatInfo(format);
1465
1466 int count = info.fColorSampleCounts.count();
Brian Salomonbdecacf2018-02-02 20:32:49 -05001467
1468 if (!count) {
Greg Daniel81e7bf82017-07-19 14:47:42 -04001469 return 0;
1470 }
1471
Brian Salomonbdecacf2018-02-02 20:32:49 -05001472 if (1 == requestedCount) {
Greg Danielcaa795f2019-05-14 11:54:25 -04001473 SkASSERT(info.fColorSampleCounts.count() && info.fColorSampleCounts[0] == 1);
Brian Salomonbdecacf2018-02-02 20:32:49 -05001474 return 1;
1475 }
1476
Greg Daniel81e7bf82017-07-19 14:47:42 -04001477 for (int i = 0; i < count; ++i) {
Greg Danielcaa795f2019-05-14 11:54:25 -04001478 if (info.fColorSampleCounts[i] >= requestedCount) {
1479 return info.fColorSampleCounts[i];
Greg Daniel81e7bf82017-07-19 14:47:42 -04001480 }
1481 }
Brian Salomonbdecacf2018-02-02 20:32:49 -05001482 return 0;
1483}
1484
Greg Danieleadfac92019-08-02 09:03:53 -04001485int GrVkCaps::maxRenderTargetSampleCount(const GrBackendFormat& format) const {
Brian Salomond4764a12019-08-08 12:08:24 -04001486 VkFormat vkFormat;
1487 if (!format.asVkFormat(&vkFormat)) {
Robert Phillipsd8f79a22019-06-24 13:25:42 -04001488 return 0;
1489 }
Brian Salomond4764a12019-08-08 12:08:24 -04001490 return this->maxRenderTargetSampleCount(vkFormat);
Greg Danielcaa795f2019-05-14 11:54:25 -04001491}
1492
1493int GrVkCaps::maxRenderTargetSampleCount(VkFormat format) const {
1494 const FormatInfo& info = this->getFormatInfo(format);
1495
1496 const auto& table = info.fColorSampleCounts;
Brian Salomonbdecacf2018-02-02 20:32:49 -05001497 if (!table.count()) {
1498 return 0;
1499 }
1500 return table[table.count() - 1];
Brian Salomond653cac2018-02-01 13:58:00 -05001501}
1502
Brian Salomon42be09d2019-07-26 12:12:26 -04001503static inline size_t align_to_4(size_t v) {
1504 switch (v & 0b11) {
1505 // v is already a multiple of 4.
1506 case 0: return v;
1507 // v is a multiple of 2 but not 4.
1508 case 2: return 2 * v;
1509 // v is not a multiple of 2.
1510 default: return 4 * v;
1511 }
1512}
1513
Brian Salomon01915c02019-08-02 09:57:21 -04001514GrCaps::SupportedWrite GrVkCaps::supportedWritePixelsColorType(GrColorType surfaceColorType,
1515 const GrBackendFormat& surfaceFormat,
Brian Salomon42be09d2019-07-26 12:12:26 -04001516 GrColorType srcColorType) const {
Brian Salomond4764a12019-08-08 12:08:24 -04001517 VkFormat vkFormat;
1518 if (!surfaceFormat.asVkFormat(&vkFormat)) {
Greg Daniel1ff50212019-08-02 15:54:08 -04001519 return {GrColorType::kUnknown, 0};
1520 }
1521
Greg Daniela7b7fe02019-09-26 15:18:32 -04001522 // We don't support the ability to upload to external formats or formats that require a ycbcr
1523 // sampler. In general these types of formats are only used for sampling in a shader.
1524 if (backend_format_is_external(surfaceFormat) || GrVkFormatNeedsYcbcrSampler(vkFormat)) {
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001525 return {GrColorType::kUnknown, 0};
1526 }
1527
Greg Daniel1ff50212019-08-02 15:54:08 -04001528 // The VkBufferImageCopy bufferOffset field must be both a multiple of 4 and of a single texel.
Greg Daniel0eca74c2020-10-01 13:46:00 -04001529 size_t offsetAlignment = align_to_4(GrVkFormatBytesPerBlock(vkFormat));
Greg Daniel1ff50212019-08-02 15:54:08 -04001530
Brian Salomond4764a12019-08-08 12:08:24 -04001531 const auto& info = this->getFormatInfo(vkFormat);
Greg Daniel1ff50212019-08-02 15:54:08 -04001532 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1533 const auto& ctInfo = info.fColorTypeInfos[i];
1534 if (ctInfo.fColorType == surfaceColorType) {
Brian Salomon974c8212021-04-05 16:24:00 -04001535 return {ctInfo.fTransferColorType, offsetAlignment};
Greg Daniel1ff50212019-08-02 15:54:08 -04001536 }
1537 }
1538 return {GrColorType::kUnknown, 0};
Brian Salomon42be09d2019-07-26 12:12:26 -04001539}
1540
Brian Salomondc0710f2019-07-01 14:59:32 -04001541GrCaps::SurfaceReadPixelsSupport GrVkCaps::surfaceSupportsReadPixels(
1542 const GrSurface* surface) const {
Emircan Uysaler23ca4e72019-06-24 10:53:09 -04001543 if (surface->isProtected()) {
Brian Salomondc0710f2019-07-01 14:59:32 -04001544 return SurfaceReadPixelsSupport::kUnsupported;
Emircan Uysaler23ca4e72019-06-24 10:53:09 -04001545 }
Greg Daniela51e93c2019-03-25 12:30:45 -04001546 if (auto tex = static_cast<const GrVkTexture*>(surface->asTexture())) {
Greg Daniel2bc96d62021-09-13 13:08:02 -04001547 auto texImage = tex->textureImage();
1548 if (!texImage) {
Greg Danielc2656572021-08-16 16:24:18 -04001549 return SurfaceReadPixelsSupport::kUnsupported;
1550 }
Greg Daniela51e93c2019-03-25 12:30:45 -04001551 // We can't directly read from a VkImage that has a ycbcr sampler.
Greg Daniel2bc96d62021-09-13 13:08:02 -04001552 if (texImage->ycbcrConversionInfo().isValid()) {
Brian Salomondc0710f2019-07-01 14:59:32 -04001553 return SurfaceReadPixelsSupport::kCopyToTexture2D;
Greg Daniela51e93c2019-03-25 12:30:45 -04001554 }
Greg Daniel00fb7242019-07-18 14:28:01 -04001555 // We can't directly read from a compressed format
Greg Daniel2bc96d62021-09-13 13:08:02 -04001556 if (GrVkFormatIsCompressed(texImage->imageFormat())) {
Greg Daniel00fb7242019-07-18 14:28:01 -04001557 return SurfaceReadPixelsSupport::kCopyToTexture2D;
1558 }
Brian Salomon72c7b982020-10-06 10:07:38 -04001559 return SurfaceReadPixelsSupport::kSupported;
1560 } else if (auto rt = surface->asRenderTarget()) {
1561 if (rt->numSamples() > 1) {
1562 return SurfaceReadPixelsSupport::kCopyToTexture2D;
1563 }
1564 return SurfaceReadPixelsSupport::kSupported;
Greg Daniela51e93c2019-03-25 12:30:45 -04001565 }
Brian Salomon72c7b982020-10-06 10:07:38 -04001566 return SurfaceReadPixelsSupport::kUnsupported;
Greg Daniela51e93c2019-03-25 12:30:45 -04001567}
1568
Brian Salomon974c8212021-04-05 16:24:00 -04001569GrColorType GrVkCaps::transferColorType(VkFormat vkFormat, GrColorType surfaceColorType) const {
1570 const auto& info = this->getFormatInfo(vkFormat);
1571 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1572 if (info.fColorTypeInfos[i].fColorType == surfaceColorType) {
1573 return info.fColorTypeInfos[i].fTransferColorType;
1574 }
1575 }
1576 return GrColorType::kUnknown;
1577}
1578
Brian Salomonc67c31c2018-12-06 10:00:03 -05001579bool GrVkCaps::onSurfaceSupportsWritePixels(const GrSurface* surface) const {
Brian Salomon3d86a192018-02-27 16:46:11 -05001580 if (auto rt = surface->asRenderTarget()) {
Chris Dalton6ce447a2019-06-23 18:07:38 -06001581 return rt->numSamples() <= 1 && SkToBool(surface->asTexture());
Brian Salomon3d86a192018-02-27 16:46:11 -05001582 }
Greg Daniela51e93c2019-03-25 12:30:45 -04001583 // We can't write to a texture that has a ycbcr sampler.
1584 if (auto tex = static_cast<const GrVkTexture*>(surface->asTexture())) {
Greg Daniel2bc96d62021-09-13 13:08:02 -04001585 auto texImage = tex->textureImage();
1586 if (!texImage) {
Greg Danielc2656572021-08-16 16:24:18 -04001587 return false;
1588 }
Greg Daniela51e93c2019-03-25 12:30:45 -04001589 // We can't directly read from a VkImage that has a ycbcr sampler.
Greg Daniel2bc96d62021-09-13 13:08:02 -04001590 if (texImage->ycbcrConversionInfo().isValid()) {
Greg Daniela51e93c2019-03-25 12:30:45 -04001591 return false;
1592 }
1593 }
Brian Salomon3d86a192018-02-27 16:46:11 -05001594 return true;
1595}
1596
Greg Daniel0fac8692019-08-16 13:13:17 -04001597bool GrVkCaps::onAreColorTypeAndFormatCompatible(GrColorType ct,
1598 const GrBackendFormat& format) const {
1599 VkFormat vkFormat;
1600 if (!format.asVkFormat(&vkFormat)) {
1601 return false;
1602 }
1603 const GrVkYcbcrConversionInfo* ycbcrInfo = format.getVkYcbcrConversionInfo();
1604 SkASSERT(ycbcrInfo);
1605
1606 if (ycbcrInfo->isValid() && !GrVkFormatNeedsYcbcrSampler(vkFormat)) {
1607 // Format may be undefined for external images, which are required to have YCbCr conversion.
Greg Daniela7b7fe02019-09-26 15:18:32 -04001608 if (VK_FORMAT_UNDEFINED == vkFormat && ycbcrInfo->fExternalFormat != 0) {
Greg Daniel0fac8692019-08-16 13:13:17 -04001609 return true;
1610 }
1611 return false;
1612 }
1613
1614 const auto& info = this->getFormatInfo(vkFormat);
1615 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1616 if (info.fColorTypeInfos[i].fColorType == ct) {
1617 return true;
1618 }
1619 }
1620 return false;
1621}
1622
Brian Salomon469046c2020-03-30 14:21:04 -04001623GrBackendFormat GrVkCaps::onGetDefaultBackendFormat(GrColorType ct) const {
Greg Daniel0fac8692019-08-16 13:13:17 -04001624 VkFormat format = this->getFormatFromColorType(ct);
1625 if (format == VK_FORMAT_UNDEFINED) {
Brian Salomon469046c2020-03-30 14:21:04 -04001626 return {};
Greg Daniel4065d452018-11-16 15:43:41 -05001627 }
1628 return GrBackendFormat::MakeVk(format);
1629}
Timothy Liang036fdfe2018-06-28 15:50:36 -04001630
Greg Daniel1e169372021-08-24 15:44:15 -04001631bool GrVkCaps::onSupportsDynamicMSAA(const GrRenderTargetProxy* rtProxy) const {
Greg Daniel1e169372021-08-24 15:44:15 -04001632 // We must be able to use the rtProxy as an input attachment to load into the discardable msaa
1633 // attachment. Also the rtProxy should have a sample count of 1 so that it can be used as a
1634 // resolve attachment.
1635 return this->supportsDiscardableMSAAForDMSAA() &&
1636 rtProxy->supportsVkInputAttachment() &&
1637 rtProxy->numSamples() == 1;
Greg Daniel1e169372021-08-24 15:44:15 -04001638}
1639
1640bool GrVkCaps::renderTargetSupportsDiscardableMSAA(const GrVkRenderTarget* rt) const {
1641 return rt->resolveAttachment() &&
1642 rt->resolveAttachment()->supportsInputAttachmentUsage() &&
1643 ((rt->numSamples() > 1 && this->preferDiscardableMSAAAttachment()) ||
1644 (rt->numSamples() == 1 && this->supportsDiscardableMSAAForDMSAA()));
1645}
1646
1647bool GrVkCaps::programInfoWillUseDiscardableMSAA(const GrProgramInfo& programInfo) const {
1648 return programInfo.targetHasVkResolveAttachmentWithInput() &&
1649 programInfo.numSamples() > 1 &&
1650 ((programInfo.targetsNumSamples() > 1 && this->preferDiscardableMSAAAttachment()) ||
1651 (programInfo.targetsNumSamples() == 1 && this->supportsDiscardableMSAAForDMSAA()));
1652}
1653
Brian Salomonbb8dde82019-06-27 10:52:13 -04001654GrBackendFormat GrVkCaps::getBackendFormatFromCompressionType(
1655 SkImage::CompressionType compressionType) const {
1656 switch (compressionType) {
Robert Phillipsab2b7222019-12-10 10:05:06 -05001657 case SkImage::CompressionType::kNone:
1658 return {};
Robert Phillipsc558f722020-01-13 13:02:26 -05001659 case SkImage::CompressionType::kETC2_RGB8_UNORM:
Robert Phillipsee946932019-12-18 11:16:17 -05001660 if (this->isVkFormatTexturable(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK)) {
1661 return GrBackendFormat::MakeVk(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK);
1662 }
1663 return {};
Robert Phillips8f259a02019-12-20 11:32:27 -05001664 case SkImage::CompressionType::kBC1_RGB8_UNORM:
1665 if (this->isVkFormatTexturable(VK_FORMAT_BC1_RGB_UNORM_BLOCK)) {
1666 return GrBackendFormat::MakeVk(VK_FORMAT_BC1_RGB_UNORM_BLOCK);
1667 }
1668 return {};
Robert Phillipsb0855272020-01-15 12:56:52 -05001669 case SkImage::CompressionType::kBC1_RGBA8_UNORM:
1670 if (this->isVkFormatTexturable(VK_FORMAT_BC1_RGBA_UNORM_BLOCK)) {
1671 return GrBackendFormat::MakeVk(VK_FORMAT_BC1_RGBA_UNORM_BLOCK);
1672 }
1673 return {};
Brian Salomonbb8dde82019-06-27 10:52:13 -04001674 }
Robert Phillipsab2b7222019-12-10 10:05:06 -05001675
1676 SkUNREACHABLE;
Brian Salomonbb8dde82019-06-27 10:52:13 -04001677}
1678
Greg Daniel01f278c2020-06-12 16:58:17 -04001679GrSwizzle GrVkCaps::onGetReadSwizzle(const GrBackendFormat& format, GrColorType colorType) const {
Brian Salomond4764a12019-08-08 12:08:24 -04001680 VkFormat vkFormat;
1681 SkAssertResult(format.asVkFormat(&vkFormat));
Brian Salomond005b692020-04-01 15:47:05 -04001682 const auto* ycbcrInfo = format.getVkYcbcrConversionInfo();
1683 SkASSERT(ycbcrInfo);
1684 if (ycbcrInfo->isValid() && ycbcrInfo->fExternalFormat != 0) {
1685 // We allow these to work with any color type and never swizzle. See
1686 // onAreColorTypeAndFormatCompatible.
1687 return GrSwizzle{"rgba"};
1688 }
Greg Daniel01f278c2020-06-12 16:58:17 -04001689
Greg Daniel1ff50212019-08-02 15:54:08 -04001690 const auto& info = this->getFormatInfo(vkFormat);
1691 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1692 const auto& ctInfo = info.fColorTypeInfos[i];
1693 if (ctInfo.fColorType == colorType) {
Greg Daniel14b57212019-12-17 16:18:06 -05001694 return ctInfo.fReadSwizzle;
Greg Daniel1ff50212019-08-02 15:54:08 -04001695 }
Greg Danieleb4a8272019-05-16 16:52:55 -04001696 }
John Stiles7bf79992021-06-25 11:05:20 -04001697 SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
1698 (int)colorType, (int)vkFormat);
Brian Salomond005b692020-04-01 15:47:05 -04001699 return {};
Greg Danieleb4a8272019-05-16 16:52:55 -04001700}
1701
Brian Salomon982f5462020-03-30 12:52:33 -04001702GrSwizzle GrVkCaps::getWriteSwizzle(const GrBackendFormat& format, GrColorType colorType) const {
Brian Salomond4764a12019-08-08 12:08:24 -04001703 VkFormat vkFormat;
1704 SkAssertResult(format.asVkFormat(&vkFormat));
Greg Daniel1ff50212019-08-02 15:54:08 -04001705 const auto& info = this->getFormatInfo(vkFormat);
1706 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1707 const auto& ctInfo = info.fColorTypeInfos[i];
1708 if (ctInfo.fColorType == colorType) {
Brian Salomon982f5462020-03-30 12:52:33 -04001709 return ctInfo.fWriteSwizzle;
Greg Daniel1ff50212019-08-02 15:54:08 -04001710 }
1711 }
John Stiles7bf79992021-06-25 11:05:20 -04001712 SkDEBUGFAILF("Illegal color type (%d) and format (%d) combination.",
1713 (int)colorType, (int)vkFormat);
Brian Salomond005b692020-04-01 15:47:05 -04001714 return {};
Greg Danieleb4a8272019-05-16 16:52:55 -04001715}
1716
Greg Daniel87fab9f2021-06-07 15:18:23 -04001717GrDstSampleFlags GrVkCaps::onGetDstSampleFlagsForProxy(const GrRenderTargetProxy* rt) const {
Greg Danielaacc9f72020-12-17 10:42:57 -05001718 bool isMSAAWithResolve = rt->numSamples() > 1 && rt->asTextureProxy();
1719 // TODO: Currently if we have an msaa rt with a resolve, the supportsVkInputAttachment call
1720 // references whether the resolve is supported as an input attachment. We need to add a check to
1721 // allow checking the color attachment (msaa or not) supports input attachment specifically.
1722 if (!isMSAAWithResolve && rt->supportsVkInputAttachment()) {
Greg Daniel87fab9f2021-06-07 15:18:23 -04001723 return GrDstSampleFlags::kRequiresTextureBarrier | GrDstSampleFlags::kAsInputAttachment;
Greg Danield358cbe2020-09-11 09:33:54 -04001724 }
Greg Daniel87fab9f2021-06-07 15:18:23 -04001725 return GrDstSampleFlags::kNone;
Greg Danield358cbe2020-09-11 09:33:54 -04001726}
1727
Greg Danield51fa2f2020-01-22 16:53:38 -05001728uint64_t GrVkCaps::computeFormatKey(const GrBackendFormat& format) const {
1729 VkFormat vkFormat;
1730 SkAssertResult(format.asVkFormat(&vkFormat));
1731
1732#ifdef SK_DEBUG
1733 // We should never be trying to compute a key for an external format
1734 const GrVkYcbcrConversionInfo* ycbcrInfo = format.getVkYcbcrConversionInfo();
1735 SkASSERT(ycbcrInfo);
1736 SkASSERT(!ycbcrInfo->isValid() || ycbcrInfo->fExternalFormat == 0);
1737#endif
1738
1739 // A VkFormat has a size of 64 bits.
1740 return (uint64_t)vkFormat;
1741}
1742
Greg Danielba88ab62019-07-26 09:14:01 -04001743GrCaps::SupportedRead GrVkCaps::onSupportedReadPixelsColorType(
Greg Daniel00fb7242019-07-18 14:28:01 -04001744 GrColorType srcColorType, const GrBackendFormat& srcBackendFormat,
1745 GrColorType dstColorType) const {
Brian Salomond4764a12019-08-08 12:08:24 -04001746 VkFormat vkFormat;
1747 if (!srcBackendFormat.asVkFormat(&vkFormat)) {
Brian Salomon8f8354a2019-07-31 20:12:02 -04001748 return {GrColorType::kUnknown, 0};
Greg Danielba88ab62019-07-26 09:14:01 -04001749 }
1750
Sergey Ulanov2739fd22019-08-11 22:46:33 -07001751 if (GrVkFormatNeedsYcbcrSampler(vkFormat)) {
1752 return {GrColorType::kUnknown, 0};
1753 }
1754
Greg Daniel01f278c2020-06-12 16:58:17 -04001755 SkImage::CompressionType compression = GrBackendFormatToCompressionType(srcBackendFormat);
Robert Phillips07f0e412020-01-17 15:20:00 -05001756 if (compression != SkImage::CompressionType::kNone) {
Robert Phillips99dead92020-01-27 16:11:57 -05001757 return { SkCompressionTypeIsOpaque(compression) ? GrColorType::kRGB_888x
Robert Phillips07f0e412020-01-17 15:20:00 -05001758 : GrColorType::kRGBA_8888, 0 };
1759 }
1760
Greg Danielba88ab62019-07-26 09:14:01 -04001761 // The VkBufferImageCopy bufferOffset field must be both a multiple of 4 and of a single texel.
Greg Daniel0eca74c2020-10-01 13:46:00 -04001762 size_t offsetAlignment = align_to_4(GrVkFormatBytesPerBlock(vkFormat));
Greg Daniel00fb7242019-07-18 14:28:01 -04001763
Brian Salomond4764a12019-08-08 12:08:24 -04001764 const auto& info = this->getFormatInfo(vkFormat);
Greg Daniel1ff50212019-08-02 15:54:08 -04001765 for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
1766 const auto& ctInfo = info.fColorTypeInfos[i];
1767 if (ctInfo.fColorType == srcColorType) {
Brian Salomon974c8212021-04-05 16:24:00 -04001768 return {ctInfo.fTransferColorType, offsetAlignment};
Greg Daniel1ff50212019-08-02 15:54:08 -04001769 }
Greg Daniel00fb7242019-07-18 14:28:01 -04001770 }
Greg Daniel1ff50212019-08-02 15:54:08 -04001771 return {GrColorType::kUnknown, 0};
Greg Daniel00fb7242019-07-18 14:28:01 -04001772}
Robert Phillipsffe27292019-08-01 10:08:07 -04001773
Ethan Nicholas0be34802019-08-15 12:36:58 -04001774int GrVkCaps::getFragmentUniformBinding() const {
1775 return GrVkUniformHandler::kUniformBinding;
1776}
1777
1778int GrVkCaps::getFragmentUniformSet() const {
1779 return GrVkUniformHandler::kUniformBufferDescSet;
1780}
1781
Robert Phillips323471e2019-11-11 11:33:37 -05001782void GrVkCaps::addExtraSamplerKey(GrProcessorKeyBuilder* b,
Brian Salomonccb61422020-01-09 10:46:36 -05001783 GrSamplerState samplerState,
Robert Phillips323471e2019-11-11 11:33:37 -05001784 const GrBackendFormat& format) const {
1785 const GrVkYcbcrConversionInfo* ycbcrInfo = format.getVkYcbcrConversionInfo();
1786 if (!ycbcrInfo) {
1787 return;
1788 }
1789
1790 GrVkSampler::Key key = GrVkSampler::GenerateKey(samplerState, *ycbcrInfo);
1791
Brian Osmanf0de96f2021-02-26 13:54:11 -05001792 constexpr size_t numInts = (sizeof(key) + 3) / 4;
1793 uint32_t tmp[numInts];
Brian Osmanacf26502021-03-03 13:35:04 +00001794 memcpy(tmp, &key, sizeof(key));
Brian Osmanf0de96f2021-02-26 13:54:11 -05001795
1796 for (size_t i = 0; i < numInts; ++i) {
1797 b->add32(tmp[i]);
1798 }
Robert Phillips323471e2019-11-11 11:33:37 -05001799}
1800
Robert Phillips03e4c952019-11-26 16:20:22 -05001801/**
1802 * For Vulkan we want to cache the entire VkPipeline for reuse of draws. The Desc here holds all
1803 * the information needed to differentiate one pipeline from another.
1804 *
1805 * The GrProgramDesc contains all the information need to create the actual shaders for the
1806 * pipeline.
1807 *
1808 * For Vulkan we need to add to the GrProgramDesc to include the rest of the state on the
1809 * pipline. This includes stencil settings, blending information, render pass format, draw face
1810 * information, and primitive type. Note that some state is set dynamically on the pipeline for
1811 * each draw and thus is not included in this descriptor. This includes the viewport, scissor,
1812 * and blend constant.
1813 */
Greg Daniel91b37b12021-01-05 15:40:54 -05001814GrProgramDesc GrVkCaps::makeDesc(GrRenderTarget* rt,
1815 const GrProgramInfo& programInfo,
1816 ProgramDescOverrideFlags overrideFlags) const {
Robert Phillips03e4c952019-11-26 16:20:22 -05001817 GrProgramDesc desc;
Robert Phillipsced5e832021-03-23 09:36:53 -04001818 GrProgramDesc::Build(&desc, programInfo, *this);
Robert Phillips03e4c952019-11-26 16:20:22 -05001819
Brian Osmane23c03d2021-03-05 14:58:25 -05001820 GrProcessorKeyBuilder b(desc.key());
Robert Phillips03e4c952019-11-26 16:20:22 -05001821
1822 // This will become part of the sheared off key used to persistently cache
1823 // the SPIRV code. It needs to be added right after the base key so that,
1824 // when the base-key is sheared off, the shearing code can include it in the
1825 // reduced key (c.f. the +4s in the SkData::MakeWithCopy calls in
1826 // GrVkPipelineStateBuilder.cpp).
Brian Osmane23c03d2021-03-05 14:58:25 -05001827 b.add32(GrVkGpu::kShader_PersistentCacheKeyType);
Robert Phillips03e4c952019-11-26 16:20:22 -05001828
Greg Daniel21774362020-09-14 10:36:43 -04001829 GrVkRenderPass::SelfDependencyFlags selfDepFlags = GrVkRenderPass::SelfDependencyFlags::kNone;
1830 if (programInfo.renderPassBarriers() & GrXferBarrierFlags::kBlend) {
1831 selfDepFlags |= GrVkRenderPass::SelfDependencyFlags::kForNonCoherentAdvBlend;
1832 }
1833 if (programInfo.renderPassBarriers() & GrXferBarrierFlags::kTexture) {
1834 selfDepFlags |= GrVkRenderPass::SelfDependencyFlags::kForInputAttachment;
1835 }
Greg Danielb4189212020-08-10 11:46:30 -04001836
Greg Daniel1e169372021-08-24 15:44:15 -04001837 bool needsResolve = this->programInfoWillUseDiscardableMSAA(programInfo);
Greg Daniela1b5d7e2020-12-17 10:36:58 -05001838
Greg Daniel91b37b12021-01-05 15:40:54 -05001839 bool forceLoadFromResolve =
1840 overrideFlags & GrCaps::ProgramDescOverrideFlags::kVulkanHasResolveLoadSubpass;
1841 SkASSERT(!forceLoadFromResolve || needsResolve);
1842
Greg Daniel7acddf52020-12-16 15:15:51 -05001843 GrVkRenderPass::LoadFromResolve loadFromResolve = GrVkRenderPass::LoadFromResolve::kNo;
Greg Daniel91b37b12021-01-05 15:40:54 -05001844 if (needsResolve && (programInfo.colorLoadOp() == GrLoadOp::kLoad || forceLoadFromResolve)) {
Greg Daniela1b5d7e2020-12-17 10:36:58 -05001845 loadFromResolve = GrVkRenderPass::LoadFromResolve::kLoad;
1846 }
Greg Daniel7acddf52020-12-16 15:15:51 -05001847
Robert Phillips24e2f6e2020-06-26 08:30:07 -04001848 if (rt) {
1849 GrVkRenderTarget* vkRT = (GrVkRenderTarget*) rt;
Robert Phillips96f22372020-05-20 12:31:18 -04001850
Greg Daniel00d6cf42021-03-05 22:50:08 +00001851 SkASSERT(!needsResolve || (vkRT->resolveAttachment() &&
1852 vkRT->resolveAttachment()->supportsInputAttachmentUsage()));
Greg Daniela1b5d7e2020-12-17 10:36:58 -05001853
Chris Dalton57ab06c2021-04-22 12:57:28 -06001854 bool needsStencil = programInfo.needsStencil() || programInfo.isStencilEnabled();
Robert Phillips24e2f6e2020-06-26 08:30:07 -04001855 // TODO: support failure in getSimpleRenderPass
Greg Daniel805c6222021-04-20 12:44:48 -04001856 auto rp = vkRT->getSimpleRenderPass(needsResolve, needsStencil, selfDepFlags,
1857 loadFromResolve);
Robert Phillips24e2f6e2020-06-26 08:30:07 -04001858 SkASSERT(rp);
Brian Osmane23c03d2021-03-05 14:58:25 -05001859 rp->genKey(&b);
Robert Phillips24e2f6e2020-06-26 08:30:07 -04001860
1861#ifdef SK_DEBUG
1862 if (!rp->isExternal()) {
1863 // This is to ensure ReconstructAttachmentsDescriptor keeps matching
1864 // getSimpleRenderPass' result
1865 GrVkRenderPass::AttachmentsDescriptor attachmentsDescriptor;
1866 GrVkRenderPass::AttachmentFlags attachmentFlags;
1867 GrVkRenderTarget::ReconstructAttachmentsDescriptor(*this, programInfo,
1868 &attachmentsDescriptor,
1869 &attachmentFlags);
Greg Daniel7acddf52020-12-16 15:15:51 -05001870 SkASSERT(rp->isCompatible(attachmentsDescriptor, attachmentFlags, selfDepFlags,
1871 loadFromResolve));
Robert Phillips24e2f6e2020-06-26 08:30:07 -04001872 }
1873#endif
1874 } else {
1875 GrVkRenderPass::AttachmentsDescriptor attachmentsDescriptor;
1876 GrVkRenderPass::AttachmentFlags attachmentFlags;
1877 GrVkRenderTarget::ReconstructAttachmentsDescriptor(*this, programInfo,
1878 &attachmentsDescriptor,
1879 &attachmentFlags);
1880
1881 // kExternal_AttachmentFlag is only set for wrapped secondary command buffers - which
1882 // will always go through the above 'rt' path (i.e., we can always pass 0 as the final
1883 // parameter to GenKey).
Brian Osmane23c03d2021-03-05 14:58:25 -05001884 GrVkRenderPass::GenKey(&b, attachmentFlags, attachmentsDescriptor, selfDepFlags,
Greg Daniel7acddf52020-12-16 15:15:51 -05001885 loadFromResolve, 0);
Robert Phillips24e2f6e2020-06-26 08:30:07 -04001886 }
Robert Phillips03e4c952019-11-26 16:20:22 -05001887
1888 GrStencilSettings stencil = programInfo.nonGLStencilSettings();
Brian Osmane23c03d2021-03-05 14:58:25 -05001889 stencil.genKey(&b, true);
Robert Phillips03e4c952019-11-26 16:20:22 -05001890
Brian Osmane23c03d2021-03-05 14:58:25 -05001891 programInfo.pipeline().genKey(&b, *this);
Chris Dalton57ab06c2021-04-22 12:57:28 -06001892 b.add32(programInfo.numSamples());
Robert Phillips03e4c952019-11-26 16:20:22 -05001893
1894 // Vulkan requires the full primitive type as part of its key
Brian Osmane23c03d2021-03-05 14:58:25 -05001895 b.add32(programInfo.primitiveTypeKey());
Robert Phillips03e4c952019-11-26 16:20:22 -05001896
Brian Osmane23c03d2021-03-05 14:58:25 -05001897 b.flush();
Robert Phillips03e4c952019-11-26 16:20:22 -05001898 return desc;
1899}
1900
Greg Daniel638b2e82020-08-27 14:29:00 -04001901GrInternalSurfaceFlags GrVkCaps::getExtraSurfaceFlagsForDeferredRT() const {
1902 // We always create vulkan RT with the input attachment flag;
1903 return GrInternalSurfaceFlags::kVkRTSupportsInputAttachment;
1904}
1905
Jim Van Verth7d338c22021-02-03 12:54:30 -05001906VkShaderStageFlags GrVkCaps::getPushConstantStageFlags() const {
1907 VkShaderStageFlags stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
Jim Van Verth7d338c22021-02-03 12:54:30 -05001908 return stageFlags;
1909}
1910
Robert Phillipsffe27292019-08-01 10:08:07 -04001911#if GR_TEST_UTILS
1912std::vector<GrCaps::TestFormatColorTypeCombination> GrVkCaps::getTestingCombinations() const {
1913 std::vector<GrCaps::TestFormatColorTypeCombination> combos = {
1914 { GrColorType::kAlpha_8, GrBackendFormat::MakeVk(VK_FORMAT_R8_UNORM) },
1915 { GrColorType::kBGR_565, GrBackendFormat::MakeVk(VK_FORMAT_R5G6B5_UNORM_PACK16) },
1916 { GrColorType::kABGR_4444, GrBackendFormat::MakeVk(VK_FORMAT_R4G4B4A4_UNORM_PACK16)},
1917 { GrColorType::kABGR_4444, GrBackendFormat::MakeVk(VK_FORMAT_B4G4R4A4_UNORM_PACK16)},
1918 { GrColorType::kRGBA_8888, GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_UNORM) },
1919 { GrColorType::kRGBA_8888_SRGB, GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_SRGB) },
1920 { GrColorType::kRGB_888x, GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8A8_UNORM) },
1921 { GrColorType::kRGB_888x, GrBackendFormat::MakeVk(VK_FORMAT_R8G8B8_UNORM) },
Robert Phillipsffe27292019-08-01 10:08:07 -04001922 { GrColorType::kRG_88, GrBackendFormat::MakeVk(VK_FORMAT_R8G8_UNORM) },
1923 { GrColorType::kBGRA_8888, GrBackendFormat::MakeVk(VK_FORMAT_B8G8R8A8_UNORM) },
Robert Phillips9a30ee02020-04-29 08:58:39 -04001924 { GrColorType::kRGBA_1010102, GrBackendFormat::MakeVk(VK_FORMAT_A2B10G10R10_UNORM_PACK32)},
1925 { GrColorType::kBGRA_1010102, GrBackendFormat::MakeVk(VK_FORMAT_A2R10G10B10_UNORM_PACK32)},
Robert Phillipsffe27292019-08-01 10:08:07 -04001926 { GrColorType::kGray_8, GrBackendFormat::MakeVk(VK_FORMAT_R8_UNORM) },
1927 { GrColorType::kAlpha_F16, GrBackendFormat::MakeVk(VK_FORMAT_R16_SFLOAT) },
1928 { GrColorType::kRGBA_F16, GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_SFLOAT) },
1929 { GrColorType::kRGBA_F16_Clamped, GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_SFLOAT) },
Robert Phillips429f0d32019-09-11 17:03:28 -04001930 { GrColorType::kAlpha_16, GrBackendFormat::MakeVk(VK_FORMAT_R16_UNORM) },
Robert Phillipsffe27292019-08-01 10:08:07 -04001931 { GrColorType::kRG_1616, GrBackendFormat::MakeVk(VK_FORMAT_R16G16_UNORM) },
1932 { GrColorType::kRGBA_16161616, GrBackendFormat::MakeVk(VK_FORMAT_R16G16B16A16_UNORM) },
1933 { GrColorType::kRG_F16, GrBackendFormat::MakeVk(VK_FORMAT_R16G16_SFLOAT) },
Robert Phillips8f259a02019-12-20 11:32:27 -05001934 // These two compressed formats both have an effective colorType of kRGB_888x
1935 { GrColorType::kRGB_888x, GrBackendFormat::MakeVk(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK)},
1936 { GrColorType::kRGB_888x, GrBackendFormat::MakeVk(VK_FORMAT_BC1_RGB_UNORM_BLOCK) },
Robert Phillipsb0855272020-01-15 12:56:52 -05001937 { GrColorType::kRGBA_8888, GrBackendFormat::MakeVk(VK_FORMAT_BC1_RGBA_UNORM_BLOCK) },
Robert Phillipsffe27292019-08-01 10:08:07 -04001938 };
1939
Robert Phillipsffe27292019-08-01 10:08:07 -04001940 return combos;
1941}
1942#endif