• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "include/core/SkAlphaType.h"
9 #include "include/core/SkColor.h"
10 #include "include/core/SkColorSpace.h"
11 #include "include/core/SkColorType.h"
12 #include "include/core/SkImage.h"
13 #include "include/core/SkImageInfo.h"
14 #include "include/core/SkMatrix.h"
15 #include "include/core/SkPixmap.h"
16 #include "include/core/SkRect.h"
17 #include "include/core/SkRefCnt.h"
18 #include "include/core/SkSamplingOptions.h"
19 #include "include/core/SkString.h"
20 #include "include/core/SkSurface.h"
21 #include "include/core/SkTypes.h"
22 #include "include/gpu/GpuTypes.h"
23 #include "include/gpu/GrBackendSurface.h"
24 #include "include/gpu/GrContextOptions.h"
25 #include "include/gpu/GrDirectContext.h"
26 #include "include/gpu/GrTypes.h"
27 #include "include/private/SkColorData.h"
28 #include "include/private/gpu/ganesh/GrTypesPriv.h"
29 #include "src/core/SkAutoPixmapStorage.h"
30 #include "src/gpu/RefCntedCallback.h"
31 #include "src/gpu/Swizzle.h"
32 #include "src/gpu/ganesh/GrCaps.h"
33 #include "src/gpu/ganesh/GrColorInfo.h"
34 #include "src/gpu/ganesh/GrDataUtils.h"
35 #include "src/gpu/ganesh/GrDirectContextPriv.h"
36 #include "src/gpu/ganesh/GrFragmentProcessor.h"
37 #include "src/gpu/ganesh/GrImageInfo.h"
38 #include "src/gpu/ganesh/GrPixmap.h"
39 #include "src/gpu/ganesh/GrProxyProvider.h"
40 #include "src/gpu/ganesh/GrResourceCache.h"
41 #include "src/gpu/ganesh/GrSamplerState.h"
42 #include "src/gpu/ganesh/GrSurfaceProxy.h"
43 #include "src/gpu/ganesh/GrSurfaceProxyView.h"
44 #include "src/gpu/ganesh/GrTextureProxy.h"
45 #include "src/gpu/ganesh/SurfaceContext.h"
46 #include "src/gpu/ganesh/SurfaceFillContext.h"
47 #include "src/gpu/ganesh/effects/GrTextureEffect.h"
48 #include "tests/CtsEnforcement.h"
49 #include "tests/Test.h"
50 #include "tests/TestUtils.h"
51 #include "tools/ToolUtils.h"
52 #include "tools/gpu/ManagedBackendTexture.h"
53 #include "tools/gpu/ProxyUtils.h"
54 
55 #include <array>
56 #include <functional>
57 #include <initializer_list>
58 #include <memory>
59 #include <utility>
60 
61 #if defined(SK_DAWN)
62 #include <dawn/webgpu_cpp.h>
63 #endif
64 
65 #if defined(SK_GL)
66 #include "include/gpu/gl/GrGLInterface.h"
67 #include "include/gpu/gl/GrGLTypes.h"
68 #include "src/gpu/ganesh/gl/GrGLCaps.h"
69 #include "src/gpu/ganesh/gl/GrGLContext.h"
70 #include "src/gpu/ganesh/gl/GrGLDefines_impl.h"
71 #include "src/gpu/ganesh/gl/GrGLGpu.h"
72 #include "tools/gpu/gl/GLTestContext.h"
73 #endif
74 
75 #if defined(SK_METAL)
76 #include "include/gpu/mtl/GrMtlTypes.h"
77 #include "src/gpu/ganesh/mtl/GrMtlCppUtil.h"
78 #endif
79 
80 #if defined(SK_DIRECT3D)
81 #include "include/private/gpu/ganesh/GrD3DTypesMinimal.h"
82 #endif
83 
84 #if defined(SK_VULKAN)
85 #include "include/gpu/vk/GrVkTypes.h"
86 #include "src/gpu/ganesh/vk/GrVkCaps.h"
87 #include <vulkan/vulkan_core.h>
88 #endif
89 
90 using sk_gpu_test::ManagedBackendTexture;
91 
92 // Test wrapping of GrBackendObjects in SkSurfaces and SkImages (non-static since used in Mtl test)
test_wrapping(GrDirectContext * dContext,skiatest::Reporter * reporter,std::function<sk_sp<ManagedBackendTexture> (GrDirectContext *,GrMipmapped,GrRenderable)> create,GrColorType grColorType,GrMipmapped mipmapped,GrRenderable renderable)93 void test_wrapping(GrDirectContext* dContext,
94                    skiatest::Reporter* reporter,
95                    std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
96                                                               GrMipmapped,
97                                                               GrRenderable)> create,
98                    GrColorType grColorType,
99                    GrMipmapped mipmapped,
100                    GrRenderable renderable) {
101     GrResourceCache* cache = dContext->priv().getResourceCache();
102 
103     const int initialCount = cache->getResourceCount();
104 
105     sk_sp<ManagedBackendTexture> mbet = create(dContext, mipmapped, renderable);
106     if (!mbet) {
107         ERRORF(reporter, "Couldn't create backendTexture for grColorType %d renderable %s\n",
108                (int)grColorType,
109                GrRenderable::kYes == renderable ? "yes" : "no");
110         return;
111     }
112 
113     // Skia proper should know nothing about the new backend object
114     REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
115 
116     SkColorType skColorType = GrColorTypeToSkColorType(grColorType);
117 
118     // Wrapping a backendTexture in an SkImage/SkSurface requires an SkColorType
119     if (skColorType == kUnknown_SkColorType) {
120         return;
121     }
122 
123     // As we transition to using attachments instead of GrTextures and GrRenderTargets individual
124     // proxy instansiations may add multiple things to the cache. There would be an entry for the
125     // GrTexture/GrRenderTarget and entries for one or more attachments.
126     int cacheEntriesPerProxy = 1;
127     // We currently only have attachments on the vulkan and metal backends
128     if (dContext->backend() == GrBackend::kVulkan || dContext->backend() == GrBackend::kMetal) {
129         // If we ever make a rt with multisamples this would have an additional
130         // attachment as well.
131         cacheEntriesPerProxy++;
132     }
133 
134     if (GrRenderable::kYes == renderable && dContext->colorTypeSupportedAsSurface(skColorType)) {
135         sk_sp<SkSurface> surf = SkSurface::MakeFromBackendTexture(dContext,
136                                                                   mbet->texture(),
137                                                                   kTopLeft_GrSurfaceOrigin,
138                                                                   0,
139                                                                   skColorType,
140                                                                   nullptr, nullptr);
141         if (!surf) {
142             ERRORF(reporter, "Couldn't make SkSurface from backendTexture for %s\n",
143                    ToolUtils::colortype_name(skColorType));
144         } else {
145             REPORTER_ASSERT(reporter,
146                             initialCount + cacheEntriesPerProxy == cache->getResourceCount());
147         }
148     }
149 
150     {
151         sk_sp<SkImage> img = SkImage::MakeFromTexture(dContext,
152                                                       mbet->texture(),
153                                                       kTopLeft_GrSurfaceOrigin,
154                                                       skColorType,
155                                                       kUnpremul_SkAlphaType,
156                                                       nullptr);
157         if (!img) {
158             ERRORF(reporter, "Couldn't make SkImage from backendTexture for %s\n",
159                    ToolUtils::colortype_name(skColorType));
160         } else {
161             GrTextureProxy* proxy = sk_gpu_test::GetTextureImageProxy(img.get(), dContext);
162             REPORTER_ASSERT(reporter, proxy);
163 
164             REPORTER_ASSERT(reporter, mipmapped == proxy->proxyMipmapped());
165             REPORTER_ASSERT(reporter, proxy->isInstantiated());
166             REPORTER_ASSERT(reporter, mipmapped == proxy->mipmapped());
167 
168             REPORTER_ASSERT(reporter,
169                             initialCount + cacheEntriesPerProxy == cache->getResourceCount());
170         }
171     }
172 
173     REPORTER_ASSERT(reporter, initialCount == cache->getResourceCount());
174 }
175 
isBGRA8(const GrBackendFormat & format)176 static bool isBGRA8(const GrBackendFormat& format) {
177     switch (format.backend()) {
178         case GrBackendApi::kOpenGL:
179 #ifdef SK_GL
180             return format.asGLFormat() == GrGLFormat::kBGRA8;
181 #else
182             return false;
183 #endif
184         case GrBackendApi::kVulkan: {
185 #ifdef SK_VULKAN
186             VkFormat vkFormat;
187             format.asVkFormat(&vkFormat);
188             return vkFormat == VK_FORMAT_B8G8R8A8_UNORM;
189 #else
190             return false;
191 #endif
192         }
193         case GrBackendApi::kMetal:
194 #ifdef SK_METAL
195             return GrMtlFormatIsBGRA8(format.asMtlFormat());
196 #else
197             return false;
198 #endif
199         case GrBackendApi::kDirect3D: {
200 #ifdef SK_DIRECT3D
201             DXGI_FORMAT d3dFormat;
202             format.asDxgiFormat(&d3dFormat);
203             return d3dFormat == DXGI_FORMAT_B8G8R8A8_UNORM;
204 #else
205             return false;
206 #endif
207         }
208         case GrBackendApi::kDawn: {
209 #ifdef SK_DAWN
210             wgpu::TextureFormat dawnFormat;
211             format.asDawnFormat(&dawnFormat);
212             return dawnFormat == wgpu::TextureFormat::BGRA8Unorm;
213 #else
214             return false;
215 #endif
216         }
217         case GrBackendApi::kMock: {
218             SkImage::CompressionType compression = format.asMockCompressionType();
219             if (compression != SkImage::CompressionType::kNone) {
220                 return false; // No compressed formats are BGRA
221             }
222 
223             return format.asMockColorType() == GrColorType::kBGRA_8888;
224         }
225     }
226     SkUNREACHABLE;
227 }
228 
isRGB(const GrBackendFormat & format)229 static bool isRGB(const GrBackendFormat& format) {
230     switch (format.backend()) {
231         case GrBackendApi::kOpenGL:
232 #ifdef SK_GL
233             return format.asGLFormat() == GrGLFormat::kRGB8;
234 #else
235             return false;
236 #endif
237         case GrBackendApi::kVulkan: {
238 #ifdef SK_VULKAN
239             VkFormat vkFormat;
240             format.asVkFormat(&vkFormat);
241             return vkFormat == VK_FORMAT_R8G8B8_UNORM;
242 #else
243             return false;
244 #endif
245         }
246         case GrBackendApi::kMetal:
247             return false;  // Metal doesn't even pretend to support this
248         case GrBackendApi::kDirect3D:
249             return false;  // Not supported in Direct3D 12
250         case GrBackendApi::kDawn:
251             return false;
252         case GrBackendApi::kMock:
253             return format.asMockColorType() == GrColorType::kRGB_888;
254     }
255     SkUNREACHABLE;
256 }
257 
check_solid_pixmap(skiatest::Reporter * reporter,const SkColor4f & expected,const SkPixmap & actual,GrColorType ct,const char * label1,const char * label2)258 static void check_solid_pixmap(skiatest::Reporter* reporter,
259                                const SkColor4f& expected,
260                                const SkPixmap& actual,
261                                GrColorType ct,
262                                const char* label1,
263                                const char* label2) {
264     // we need 0.001f across the board just for noise
265     // we need 0.01f across the board for 1010102
266     const float tols[4] = { 0.01f, 0.01f, 0.01f, 0.01f };
267 
268     auto error = std::function<ComparePixmapsErrorReporter>(
269         [reporter, ct, label1, label2, expected](int x, int y, const float diffs[4]) {
270             SkASSERT(x >= 0 && y >= 0);
271             ERRORF(reporter, "%s %s %s - mismatch at %d, %d "
272                              "expected (%.2f, %.2f, %.2f %.2f) "
273                              "- diffs (%.2f, %.2f, %.2f %.2f)",
274                    GrColorTypeToStr(ct), label1, label2, x, y,
275                    expected.fR, expected.fG, expected.fB, expected.fA,
276                    diffs[0], diffs[1], diffs[2], diffs[3]);
277         });
278 
279     CheckSolidPixels(expected, actual, tols, error);
280 }
281 
282 // Determine what color we expect if we store 'orig' in 'ct' converted back to SkColor4f.
get_expected_color(SkColor4f orig,GrColorType ct)283 static SkColor4f get_expected_color(SkColor4f orig, GrColorType ct) {
284     GrImageInfo ii(ct, kUnpremul_SkAlphaType, nullptr, {1, 1});
285     std::unique_ptr<char[]> data(new char[ii.minRowBytes()]);
286     GrClearImage(ii, data.get(), ii.minRowBytes(), orig.array());
287 
288     // Read back to SkColor4f.
289     SkColor4f result;
290     GrImageInfo resultII(GrColorType::kRGBA_F32, kUnpremul_SkAlphaType, nullptr, {1, 1});
291     GrConvertPixels(GrPixmap(resultII,  &result.fR,   sizeof(result)),
292                     GrPixmap(      ii,  data.get(), ii.minRowBytes()));
293     return result;
294 }
295 
296 static void check_mipmaps(GrDirectContext*,
297                           const GrBackendTexture&,
298                           GrColorType,
299                           const SkColor4f expectedColors[6],
300                           skiatest::Reporter*,
301                           const char* label);
302 
check_base_readbacks(GrDirectContext * dContext,const GrBackendTexture & backendTex,GrColorType colorType,GrRenderable renderableTexture,const SkColor4f & color,skiatest::Reporter * reporter,const char * label)303 static void check_base_readbacks(GrDirectContext* dContext,
304                                  const GrBackendTexture& backendTex,
305                                  GrColorType colorType,
306                                  GrRenderable renderableTexture,
307                                  const SkColor4f& color,
308                                  skiatest::Reporter* reporter,
309                                  const char* label) {
310     if (isRGB(backendTex.getBackendFormat())) {
311         // readPixels is busted for the RGB backend format (skbug.com/8862)
312         // TODO: add a GrColorType::kRGB_888 to fix the situation
313         return;
314     }
315 
316     SkColor4f expectedColor = get_expected_color(color, colorType);
317 
318     SkAutoPixmapStorage actual;
319 
320     {
321         SkImageInfo readBackII = SkImageInfo::Make(32, 32,
322                                                    kRGBA_8888_SkColorType,
323                                                    kUnpremul_SkAlphaType);
324 
325         SkAssertResult(actual.tryAlloc(readBackII));
326     }
327     for (GrRenderable renderableCtx : {GrRenderable::kNo, GrRenderable::kYes}) {
328         if (renderableCtx == GrRenderable::kYes && renderableTexture == GrRenderable::kNo) {
329             continue;
330         }
331         sk_sp<GrSurfaceProxy> proxy;
332         if (renderableCtx == GrRenderable::kYes) {
333             proxy = dContext->priv().proxyProvider()->wrapRenderableBackendTexture(
334                     backendTex, 1, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, nullptr);
335         } else {
336             proxy = dContext->priv().proxyProvider()->wrapBackendTexture(
337                     backendTex, kBorrow_GrWrapOwnership, GrWrapCacheable::kNo, kRW_GrIOType);
338         }
339         if (!proxy) {
340             ERRORF(reporter, "Could not make proxy from backend texture");
341             return;
342         }
343         auto swizzle = dContext->priv().caps()->getReadSwizzle(backendTex.getBackendFormat(),
344                                                                colorType);
345         GrSurfaceProxyView readView(proxy, kTopLeft_GrSurfaceOrigin, swizzle);
346         GrColorInfo info(colorType, kUnpremul_SkAlphaType, nullptr);
347         auto surfaceContext = dContext->priv().makeSC(readView, info);
348         if (!surfaceContext) {
349             ERRORF(reporter, "Could not create surface context for colorType: %d\n",
350                    (int)colorType);
351         }
352 
353         if (!surfaceContext->readPixels(dContext, actual, {0, 0})) {
354             // TODO: we need a better way to tell a priori if readPixels will work for an
355             // arbitrary colorType
356 #if 0
357             ERRORF(reporter, "Couldn't readback from SurfaceContext for colorType: %d\n",
358                    (int)colorType);
359 #endif
360         } else {
361             auto name = SkStringPrintf("%s::readPixels",
362                                        (renderableCtx == GrRenderable::kYes ? "SurfaceFillContext"
363                                                                             : "SurfaceContext"));
364             check_solid_pixmap(reporter, expectedColor, actual, colorType, label, name.c_str());
365         }
366     }
367 }
368 
369 // Test initialization of GrBackendObjects to a specific color (non-static since used in Mtl test)
test_color_init(GrDirectContext * dContext,skiatest::Reporter * reporter,std::function<sk_sp<ManagedBackendTexture> (GrDirectContext *,const SkColor4f &,GrMipmapped,GrRenderable)> create,GrColorType colorType,const SkColor4f & color,GrMipmapped mipmapped,GrRenderable renderable)370 void test_color_init(GrDirectContext* dContext,
371                      skiatest::Reporter* reporter,
372                      std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
373                                                                 const SkColor4f&,
374                                                                 GrMipmapped,
375                                                                 GrRenderable)> create,
376                      GrColorType colorType,
377                      const SkColor4f& color,
378                      GrMipmapped mipmapped,
379                      GrRenderable renderable) {
380     sk_sp<ManagedBackendTexture> mbet = create(dContext, color, mipmapped, renderable);
381     if (!mbet) {
382         // errors here should be reported by the test_wrapping test
383         return;
384     }
385 
386     auto checkBackendTexture = [&](const SkColor4f& testColor) {
387         if (mipmapped == GrMipmapped::kYes) {
388             SkColor4f expectedColor = get_expected_color(testColor, colorType);
389             SkColor4f expectedColors[6] = {expectedColor, expectedColor, expectedColor,
390                                            expectedColor, expectedColor, expectedColor};
391             check_mipmaps(dContext, mbet->texture(), colorType, expectedColors, reporter,
392                           "colorinit");
393         }
394 
395         // The last step in this test will dirty the mipmaps so do it last
396         check_base_readbacks(dContext, mbet->texture(), colorType, renderable, testColor, reporter,
397                              "colorinit");
398     };
399 
400     checkBackendTexture(color);
401 
402     SkColor4f newColor = {color.fB , color.fR, color.fG, color.fA };
403 
404     SkColorType skColorType = GrColorTypeToSkColorType(colorType);
405     // Our update method only works with SkColorTypes.
406     if (skColorType != kUnknown_SkColorType) {
407         dContext->updateBackendTexture(mbet->texture(),
408                                        skColorType,
409                                        newColor,
410                                        ManagedBackendTexture::ReleaseProc,
411                                        mbet->releaseContext());
412         checkBackendTexture(newColor);
413     }
414 }
415 
416 // Draw the backend texture into an RGBA surface fill context, attempting to access all the mipMap
417 // levels.
check_mipmaps(GrDirectContext * dContext,const GrBackendTexture & backendTex,GrColorType colorType,const SkColor4f expectedColors[6],skiatest::Reporter * reporter,const char * label)418 static void check_mipmaps(GrDirectContext* dContext,
419                           const GrBackendTexture& backendTex,
420                           GrColorType colorType,
421                           const SkColor4f expectedColors[6],
422                           skiatest::Reporter* reporter,
423                           const char* label) {
424 #ifdef SK_GL
425     // skbug.com/9141 (RGBA_F32 mipmaps appear to be broken on some Mali devices)
426     if (GrBackendApi::kOpenGL == dContext->backend()) {
427         GrGLGpu* glGPU = static_cast<GrGLGpu*>(dContext->priv().getGpu());
428 
429         if (colorType == GrColorType::kRGBA_F32 &&
430             glGPU->ctxInfo().standard() == kGLES_GrGLStandard) {
431             return;
432         }
433     }
434 #endif
435 
436     if (isRGB(backendTex.getBackendFormat())) {
437         // readPixels is busted for the RGB backend format (skbug.com/8862)
438         // TODO: add a GrColorType::kRGB_888 to fix the situation
439         return;
440     }
441 
442     GrImageInfo info(GrColorType::kRGBA_8888, kUnpremul_SkAlphaType, nullptr, {32, 32});
443     auto dstFillContext = dContext->priv().makeSFC(info, /*label=*/{});
444     if (!dstFillContext) {
445         ERRORF(reporter, "Could not make dst fill context.");
446         return;
447     }
448 
449     constexpr int kNumMipLevels = 6;
450 
451     auto proxy = dContext->priv().proxyProvider()->wrapBackendTexture(backendTex,
452                                                                       kBorrow_GrWrapOwnership,
453                                                                       GrWrapCacheable::kNo,
454                                                                       kRW_GrIOType);
455     if (!proxy) {
456         ERRORF(reporter, "Could not make proxy from backend texture");
457         return;
458     }
459     auto swizzle = dContext->priv().caps()->getReadSwizzle(backendTex.getBackendFormat(),
460                                                            colorType);
461     GrSurfaceProxyView readView(proxy, kTopLeft_GrSurfaceOrigin, swizzle);
462 
463     for (int i = 0, rectSize = 32; i < kNumMipLevels; ++i, rectSize /= 2) {
464         SkASSERT(rectSize >= 1);
465         dstFillContext->clear(SK_PMColor4fTRANSPARENT);
466 
467         SkMatrix texMatrix;
468         texMatrix.setScale(1 << i, 1 << i);
469         static constexpr GrSamplerState kNearestNearest(GrSamplerState::Filter::kNearest,
470                                                         GrSamplerState::MipmapMode::kNearest);
471         auto fp = GrTextureEffect::Make(readView,
472                                         kUnpremul_SkAlphaType,
473                                         texMatrix,
474                                         kNearestNearest,
475                                         *dstFillContext->caps());
476         dstFillContext->fillRectWithFP(SkIRect::MakeWH(rectSize, rectSize), std::move(fp));
477 
478         SkImageInfo readbackII = SkImageInfo::Make(rectSize, rectSize,
479                                                    kRGBA_8888_SkColorType,
480                                                    kUnpremul_SkAlphaType);
481         SkAutoPixmapStorage actual;
482         SkAssertResult(actual.tryAlloc(readbackII));
483         actual.erase(SkColors::kTransparent);
484 
485         bool result = dstFillContext->readPixels(dContext, actual, {0, 0});
486         REPORTER_ASSERT(reporter, result);
487 
488         SkString str;
489         str.appendf("mip-level %d", i);
490 
491         check_solid_pixmap(reporter, expectedColors[i], actual, colorType, label, str.c_str());
492     }
493 }
494 
495 // Test initialization of GrBackendObjects using SkPixmaps (non-static since used in Mtl test)
test_pixmap_init(GrDirectContext * dContext,skiatest::Reporter * reporter,std::function<sk_sp<ManagedBackendTexture> (GrDirectContext *,const SkPixmap srcData[],int numLevels,GrSurfaceOrigin,GrRenderable)> create,SkColorType skColorType,GrSurfaceOrigin origin,GrMipmapped mipmapped,GrRenderable renderable)496 void test_pixmap_init(GrDirectContext* dContext,
497                       skiatest::Reporter* reporter,
498                       std::function<sk_sp<ManagedBackendTexture>(GrDirectContext*,
499                                                                  const SkPixmap srcData[],
500                                                                  int numLevels,
501                                                                  GrSurfaceOrigin,
502                                                                  GrRenderable)> create,
503                       SkColorType skColorType,
504                       GrSurfaceOrigin origin,
505                       GrMipmapped mipmapped,
506                       GrRenderable renderable) {
507     SkPixmap pixmaps[6];
508     std::unique_ptr<char[]> memForPixmaps;
509     constexpr SkColor4f kColors[6] = {
510         { 1.0f, 0.0f, 0.0f, 1.0f }, // R
511         { 0.0f, 1.0f, 0.0f, 0.9f }, // G
512         { 0.0f, 0.0f, 1.0f, 0.7f }, // B
513         { 0.0f, 1.0f, 1.0f, 0.5f }, // C
514         { 1.0f, 0.0f, 1.0f, 0.3f }, // M
515         { 1.0f, 1.0f, 0.0f, 0.2f }, // Y
516     };
517 
518     int numMipLevels = ToolUtils::make_pixmaps(skColorType, kUnpremul_SkAlphaType,
519                                                mipmapped == GrMipmapped::kYes,
520                                                kColors, pixmaps, &memForPixmaps);
521     SkASSERT(numMipLevels);
522 
523     sk_sp<ManagedBackendTexture> mbet = create(dContext, pixmaps, numMipLevels, origin, renderable);
524     if (!mbet) {
525         // errors here should be reported by the test_wrapping test
526         return;
527     }
528 
529     if (skColorType == kBGRA_8888_SkColorType && !isBGRA8(mbet->texture().getBackendFormat())) {
530         // When kBGRA is backed by an RGBA something goes wrong in the swizzling
531         return;
532     }
533 
534     auto checkBackendTexture = [&](const SkColor4f colors[6]) {
535         GrColorType grColorType = SkColorTypeToGrColorType(skColorType);
536         if (mipmapped == GrMipmapped::kYes) {
537             SkColor4f expectedColors[6] = {
538                     get_expected_color(colors[0], grColorType),
539                     get_expected_color(colors[1], grColorType),
540                     get_expected_color(colors[2], grColorType),
541                     get_expected_color(colors[3], grColorType),
542                     get_expected_color(colors[4], grColorType),
543                     get_expected_color(colors[5], grColorType),
544             };
545 
546             check_mipmaps(dContext, mbet->texture(), grColorType, expectedColors, reporter,
547                           "pixmap");
548         }
549 
550         // The last step in this test will dirty the mipmaps so do it last
551         check_base_readbacks(dContext, mbet->texture(), grColorType, renderable, colors[0],
552                              reporter, "pixmap");
553     };
554 
555     checkBackendTexture(kColors);
556 
557     constexpr SkColor4f kColorsNew[6] = {
558         {1.0f, 1.0f, 0.0f, 0.2f},  // Y
559         {1.0f, 0.0f, 0.0f, 1.0f},  // R
560         {0.0f, 1.0f, 0.0f, 0.9f},  // G
561         {0.0f, 0.0f, 1.0f, 0.7f},  // B
562         {0.0f, 1.0f, 1.0f, 0.5f},  // C
563         {1.0f, 0.0f, 1.0f, 0.3f},  // M
564     };
565     ToolUtils::make_pixmaps(skColorType, kUnpremul_SkAlphaType, mipmapped == GrMipmapped::kYes,
566                             kColorsNew, pixmaps, &memForPixmaps);
567 
568     // Upload new data and make sure everything still works
569     dContext->updateBackendTexture(mbet->texture(),
570                                    pixmaps,
571                                    numMipLevels,
572                                    origin,
573                                    ManagedBackendTexture::ReleaseProc,
574                                    mbet->releaseContext());
575 
576     checkBackendTexture(kColorsNew);
577 }
578 
579 enum class VkLayout {
580     kUndefined,
581     kReadOnlyOptimal,
582 };
583 
check_vk_tiling(const GrBackendTexture & backendTex)584 void check_vk_tiling(const GrBackendTexture& backendTex) {
585 #if defined(SK_VULKAN) && defined(SK_DEBUG)
586     GrVkImageInfo vkII;
587     if (backendTex.getVkImageInfo(&vkII)) {
588         SkASSERT(VK_IMAGE_TILING_OPTIMAL == vkII.fImageTiling);
589     }
590 #endif
591 }
592 
593 ///////////////////////////////////////////////////////////////////////////////
color_type_backend_allocation_test(const sk_gpu_test::ContextInfo & ctxInfo,skiatest::Reporter * reporter)594 void color_type_backend_allocation_test(const sk_gpu_test::ContextInfo& ctxInfo,
595                                         skiatest::Reporter* reporter) {
596     auto context = ctxInfo.directContext();
597     const GrCaps* caps = context->priv().caps();
598 
599     constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
600     constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 0.75f };
601 
602     struct {
603         SkColorType   fColorType;
604         SkColor4f     fColor;
605     } combinations[] = {
606         { kAlpha_8_SkColorType,           kTransCol                },
607         { kRGB_565_SkColorType,           SkColors::kRed           },
608         { kARGB_4444_SkColorType,         SkColors::kGreen         },
609         { kRGBA_8888_SkColorType,         SkColors::kBlue          },
610         { kSRGBA_8888_SkColorType,        { 0.25f, 0.5f, 0.75f, 1.0f}},
611         { kRGB_888x_SkColorType,          SkColors::kCyan          },
612         // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
613         { kBGRA_8888_SkColorType,         { 1, 0, 0, 1.0f }        },
614         // TODO: readback is busted for *10A2 when alpha = 0.5f (perhaps premul vs. unpremul)
615         { kRGBA_1010102_SkColorType,      { 0.25f, 0.5f, 0.75f, 1.0f }},
616         { kBGRA_1010102_SkColorType,      { 0.25f, 0.5f, 0.75f, 1.0f }},
617         // RGB/BGR 101010x have no Ganesh correlate
618         { kRGB_101010x_SkColorType,       { 0, 0.5f, 0, 0.5f }     },
619         { kBGR_101010x_SkColorType,       { 0, 0.5f, 0, 0.5f }     },
620         { kBGR_101010x_XR_SkColorType,    { 0, 0.5f, 0, 0.5f }     },
621         { kGray_8_SkColorType,            kGrayCol                 },
622         { kRGBA_F16Norm_SkColorType,      SkColors::kLtGray        },
623         { kRGBA_F16_SkColorType,          SkColors::kYellow        },
624         { kRGBA_F32_SkColorType,          SkColors::kGray          },
625         { kR8G8_unorm_SkColorType,        { .25f, .75f, 0, 1 }     },
626         { kR16G16_unorm_SkColorType,      SkColors::kGreen         },
627         { kA16_unorm_SkColorType,         kTransCol                },
628         { kA16_float_SkColorType,         kTransCol                },
629         { kR16G16_float_SkColorType,      { .25f, .75f, 0, 1 }     },
630         { kR16G16B16A16_unorm_SkColorType,{ .25f, .5f, .75f, 1 }   },
631         { kR8_unorm_SkColorType,          { .25f, 0, 0, 1 }        },
632     };
633 
634     static_assert(kLastEnum_SkColorType == std::size(combinations));
635 
636     for (auto combo : combinations) {
637         SkColorType colorType = combo.fColorType;
638 
639         if (GrBackendApi::kMetal == context->backend()) {
640             // skbug.com/9086 (Metal caps may not be handling RGBA32 correctly)
641             if (kRGBA_F32_SkColorType == combo.fColorType) {
642                 continue;
643             }
644         }
645 
646         if (colorType == kBGR_101010x_XR_SkColorType) {
647             // Creating a texture with kBGR_101010x_XR_SkColorType is not
648             // implemented.
649             continue;
650         }
651 
652         for (auto mipmapped : {GrMipmapped::kNo, GrMipmapped::kYes}) {
653             if (GrMipmapped::kYes == mipmapped && !caps->mipmapSupport()) {
654                 continue;
655             }
656 
657             for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
658                 if (!caps->getDefaultBackendFormat(SkColorTypeToGrColorType(colorType),
659                                                    renderable).isValid()) {
660                     continue;
661                 }
662 
663                 if (GrRenderable::kYes == renderable) {
664                     if (kRGB_888x_SkColorType == combo.fColorType) {
665                         // Ganesh can't perform the blends correctly when rendering this format
666                         continue;
667                     }
668                 }
669 
670                 {
671                     auto uninitCreateMtd = [colorType](GrDirectContext* dContext,
672                                                        GrMipmapped mipmapped,
673                                                        GrRenderable renderable) {
674                         auto mbet = ManagedBackendTexture::MakeWithoutData(dContext,
675                                                                            32, 32,
676                                                                            colorType,
677                                                                            mipmapped,
678                                                                            renderable,
679                                                                            GrProtected::kNo);
680                         check_vk_tiling(mbet->texture());
681 #ifdef SK_DEBUG
682                         {
683                             GrBackendFormat format = dContext->defaultBackendFormat(colorType,
684                                                                                     renderable);
685                             SkASSERT(format == mbet->texture().getBackendFormat());
686                         }
687 #endif
688 
689                         return mbet;
690                     };
691 
692                     test_wrapping(context, reporter, uninitCreateMtd,
693                                   SkColorTypeToGrColorType(colorType), mipmapped, renderable);
694                 }
695 
696                 {
697                     auto createWithColorMtd = [colorType](GrDirectContext* dContext,
698                                                           const SkColor4f& color,
699                                                           GrMipmapped mipmapped,
700                                                           GrRenderable renderable) {
701                         auto mbet = ManagedBackendTexture::MakeWithData(dContext,
702                                                                         32, 32,
703                                                                         colorType,
704                                                                         color,
705                                                                         mipmapped,
706                                                                         renderable,
707                                                                         GrProtected::kNo);
708                         check_vk_tiling(mbet->texture());
709 
710 #ifdef SK_DEBUG
711                         {
712                             GrBackendFormat format = dContext->defaultBackendFormat(colorType,
713                                                                                    renderable);
714                             SkASSERT(format == mbet->texture().getBackendFormat());
715                         }
716 #endif
717 
718                         return mbet;
719                     };
720                     test_color_init(context, reporter, createWithColorMtd,
721                                     SkColorTypeToGrColorType(colorType), combo.fColor, mipmapped,
722                                     renderable);
723                 }
724 
725                 for (auto origin : {kTopLeft_GrSurfaceOrigin, kBottomLeft_GrSurfaceOrigin}) {
726                     auto createWithSrcDataMtd = [](GrDirectContext* dContext,
727                                                    const SkPixmap srcData[],
728                                                    int numLevels,
729                                                    GrSurfaceOrigin origin,
730                                                    GrRenderable renderable) {
731                         SkASSERT(srcData && numLevels);
732                         auto mbet = ManagedBackendTexture::MakeWithData(dContext,
733                                                                         srcData,
734                                                                         numLevels,
735                                                                         origin,
736                                                                         renderable,
737                                                                         GrProtected::kNo);
738                         check_vk_tiling(mbet->texture());
739 #ifdef SK_DEBUG
740                         {
741                             auto format = dContext->defaultBackendFormat(srcData[0].colorType(),
742                                                                          renderable);
743                             SkASSERT(format == mbet->texture().getBackendFormat());
744                         }
745 #endif
746                         return mbet;
747                     };
748 
749                     test_pixmap_init(context,
750                                      reporter,
751                                      createWithSrcDataMtd,
752                                      colorType,
753                                      origin,
754                                      mipmapped,
755                                      renderable);
756                 }
757             }
758         }
759     }
760 }
761 
DEF_GANESH_TEST(ColorTypeBackendAllocationTest,reporter,options,CtsEnforcement::kApiLevel_T)762 DEF_GANESH_TEST(ColorTypeBackendAllocationTest, reporter, options, CtsEnforcement::kApiLevel_T) {
763     for (int t = 0; t < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++t) {
764         auto type = static_cast<sk_gpu_test::GrContextFactory::ContextType>(t);
765         if (!sk_gpu_test::GrContextFactory::IsRenderingContext(type)) {
766             continue;
767         }
768         sk_gpu_test::GrContextFactory factory(options);
769         sk_gpu_test::ContextInfo info = factory.getContextInfo(type);
770         if (!info.directContext()) {
771             continue;
772         }
773         color_type_backend_allocation_test(info, reporter);
774         // The GL backend must support contexts that don't allow GL_UNPACK_ROW_LENGTH. Other
775         // backends are not required to work with this cap disabled.
776         if (info.directContext()->priv().caps()->writePixelsRowBytesSupport() &&
777             info.directContext()->backend() == GrBackendApi::kOpenGL) {
778             GrContextOptions overrideOptions = options;
779             overrideOptions.fDisallowWriteAndTransferPixelRowBytes = true;
780             sk_gpu_test::GrContextFactory overrideFactory(overrideOptions);
781             info = overrideFactory.getContextInfo(type);
782             color_type_backend_allocation_test(info, reporter);
783         }
784     }
785 }
786 
787 ///////////////////////////////////////////////////////////////////////////////
788 #ifdef SK_GL
789 
DEF_GANESH_TEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)790 DEF_GANESH_TEST_FOR_ALL_GL_CONTEXTS(GLBackendAllocationTest,
791                                     reporter,
792                                     ctxInfo,
793                                     CtsEnforcement::kApiLevel_T) {
794     sk_gpu_test::GLTestContext* glCtx = ctxInfo.glContext();
795     GrGLStandard standard = glCtx->gl()->fStandard;
796     auto context = ctxInfo.directContext();
797     const GrGLCaps* glCaps = static_cast<const GrGLCaps*>(context->priv().caps());
798 
799     constexpr SkColor4f kTransCol     { 0,     0.25f, 0.75f, 0.5f };
800     constexpr SkColor4f kGrayCol      { 0.75f, 0.75f, 0.75f, 1.f  };
801     constexpr SkColor4f kTransGrayCol { 0.5f,  0.5f,  0.5f,  .8f  };
802 
803     struct {
804         GrColorType   fColorType;
805         GrGLenum      fFormat;
806         SkColor4f     fColor;
807     } combinations[] = {
808         { GrColorType::kRGBA_8888,        GR_GL_RGBA8,                SkColors::kRed       },
809         { GrColorType::kRGBA_8888_SRGB,   GR_GL_SRGB8_ALPHA8,         SkColors::kRed       },
810 
811         { GrColorType::kRGB_888x,         GR_GL_RGBA8,                SkColors::kYellow    },
812         { GrColorType::kRGB_888x,         GR_GL_RGB8,                 SkColors::kCyan      },
813         { GrColorType::kRGB_888x,         GR_GL_RGBX8,                SkColors::kCyan      },
814 
815         { GrColorType::kBGRA_8888,        GR_GL_RGBA8,                SkColors::kBlue      },
816         { GrColorType::kBGRA_8888,        GR_GL_BGRA8,                SkColors::kBlue      },
817         // TODO: readback is busted when alpha = 0.5f (perhaps premul vs. unpremul)
818         { GrColorType::kRGBA_1010102,     GR_GL_RGB10_A2,             { 0.25f, 0.5f, 0.75f, 1.f }},
819         { GrColorType::kBGRA_1010102,     GR_GL_RGB10_A2,             { 0.25f, 0.5f, 0.75f, 1.f }},
820         { GrColorType::kBGR_565,          GR_GL_RGB565,               SkColors::kRed       },
821         { GrColorType::kABGR_4444,        GR_GL_RGBA4,                SkColors::kGreen     },
822 
823         { GrColorType::kAlpha_8,          GR_GL_ALPHA8,               kTransCol            },
824         { GrColorType::kAlpha_8,          GR_GL_R8,                   kTransCol            },
825 
826         { GrColorType::kGray_8,           GR_GL_LUMINANCE8,           kGrayCol             },
827         { GrColorType::kGray_8,           GR_GL_R8,                   kGrayCol             },
828 
829         { GrColorType::kGrayAlpha_88,     GR_GL_LUMINANCE8_ALPHA8,    kTransGrayCol        },
830 
831         { GrColorType::kRGBA_F32,         GR_GL_RGBA32F,              SkColors::kRed       },
832 
833         { GrColorType::kRGBA_F16_Clamped, GR_GL_RGBA16F,              SkColors::kLtGray    },
834         { GrColorType::kRGBA_F16,         GR_GL_RGBA16F,              SkColors::kYellow    },
835 
836         { GrColorType::kRG_88,            GR_GL_RG8,                  { 1, 0.5f, 0, 1 }    },
837         { GrColorType::kAlpha_F16,        GR_GL_R16F,                 { 1.0f, 0, 0, 0.5f } },
838         { GrColorType::kAlpha_F16,        GR_GL_LUMINANCE16F,         kGrayCol             },
839 
840         { GrColorType::kAlpha_16,         GR_GL_R16,                  kTransCol            },
841         { GrColorType::kRG_1616,          GR_GL_RG16,                 SkColors::kYellow    },
842 
843         { GrColorType::kRGBA_16161616,    GR_GL_RGBA16,               SkColors::kLtGray    },
844         { GrColorType::kRG_F16,           GR_GL_RG16F,                SkColors::kYellow    },
845     };
846 
847     for (auto combo : combinations) {
848         for (GrTextureType textureType : {GrTextureType::k2D, GrTextureType::kRectangle}) {
849             GrGLenum target = textureType == GrTextureType::k2D ? GR_GL_TEXTURE_2D
850                                                                 : GR_GL_TEXTURE_RECTANGLE;
851             GrBackendFormat format = GrBackendFormat::MakeGL(combo.fFormat, target);
852             if (!glCaps->isFormatTexturable(format, textureType)) {
853                 continue;
854             }
855 
856             if (GrColorType::kBGRA_8888 == combo.fColorType ||
857                 GrColorType::kBGRA_1010102 == combo.fColorType) {
858                 // We allow using a GL_RGBA8 or GR_GL_RGB10_A2 texture as BGRA on desktop GL but not
859                 // ES
860                 if (kGL_GrGLStandard != standard &&
861                     (GR_GL_RGBA8 == combo.fFormat || GR_GL_RGB10_A2 == combo.fFormat)) {
862                     continue;
863                 }
864             }
865 
866             for (auto mipmapped : {GrMipmapped::kNo, GrMipmapped::kYes}) {
867                 if (GrMipmapped::kYes == mipmapped &&
868                     (!glCaps->mipmapSupport() || target == GR_GL_TEXTURE_RECTANGLE)) {
869                     continue;
870                 }
871 
872                 for (auto renderable : {GrRenderable::kNo, GrRenderable::kYes}) {
873                     if (GrRenderable::kYes == renderable) {
874                         if (!glCaps->isFormatAsColorTypeRenderable(combo.fColorType, format)) {
875                             continue;
876                         }
877                     }
878 
879                     {
880                         auto uninitCreateMtd = [format](GrDirectContext* dContext,
881                                                         GrMipmapped mipmapped,
882                                                         GrRenderable renderable) {
883                             return ManagedBackendTexture::MakeWithoutData(dContext,
884                                                                           32, 32,
885                                                                           format,
886                                                                           mipmapped,
887                                                                           renderable,
888                                                                           GrProtected::kNo);
889                         };
890 
891                         test_wrapping(context, reporter, uninitCreateMtd, combo.fColorType,
892                                       mipmapped, renderable);
893                     }
894 
895                     {
896                         // We're creating backend textures without specifying a color type "view" of
897                         // them at the public API level. Therefore, Ganesh will not apply any
898                         // swizzles before writing the color to the texture. However, our validation
899                         // code does rely on interpreting the texture contents via a SkColorType and
900                         // therefore swizzles may be applied during the read step. Ideally we'd
901                         // update our validation code to use a "raw" read that doesn't impose a
902                         // color type but for now we just munge the data we upload to match the
903                         // expectation.
904                         skgpu::Swizzle swizzle;
905                         switch (combo.fColorType) {
906                             case GrColorType::kAlpha_8:
907                                 swizzle = skgpu::Swizzle("aaaa");
908                                 break;
909                             case GrColorType::kAlpha_16:
910                                 swizzle = skgpu::Swizzle("aaaa");
911                                 break;
912                             case GrColorType::kAlpha_F16:
913                                 swizzle = skgpu::Swizzle("aaaa");
914                                 break;
915                             default:
916                                 break;
917                         }
918                         auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
919                                                                     const SkColor4f& color,
920                                                                     GrMipmapped mipmapped,
921                                                                     GrRenderable renderable) {
922                             auto swizzledColor = swizzle.applyTo(color);
923                             return ManagedBackendTexture::MakeWithData(dContext,
924                                                                        32, 32,
925                                                                        format,
926                                                                        swizzledColor,
927                                                                        mipmapped,
928                                                                        renderable,
929                                                                        GrProtected::kNo);
930                         };
931                         test_color_init(context, reporter, createWithColorMtd, combo.fColorType,
932                                         combo.fColor, mipmapped, renderable);
933                     }
934                 }
935             }
936         }
937     }
938 }
939 
940 #endif
941 
942 ///////////////////////////////////////////////////////////////////////////////
943 
944 #ifdef SK_VULKAN
945 
DEF_GANESH_TEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest,reporter,ctxInfo,CtsEnforcement::kApiLevel_T)946 DEF_GANESH_TEST_FOR_VULKAN_CONTEXT(VkBackendAllocationTest,
947                                    reporter,
948                                    ctxInfo,
949                                    CtsEnforcement::kApiLevel_T) {
950     auto context = ctxInfo.directContext();
951     const GrVkCaps* vkCaps = static_cast<const GrVkCaps*>(context->priv().caps());
952 
953     constexpr SkColor4f kTransCol { 0, 0.25f, 0.75f, 0.5f };
954     constexpr SkColor4f kGrayCol { 0.75f, 0.75f, 0.75f, 1 };
955 
956     struct {
957         GrColorType fColorType;
958         VkFormat    fFormat;
959         SkColor4f   fColor;
960     } combinations[] = {
961         { GrColorType::kRGBA_8888,        VK_FORMAT_R8G8B8A8_UNORM,           SkColors::kRed      },
962         { GrColorType::kRGBA_8888_SRGB,   VK_FORMAT_R8G8B8A8_SRGB,            SkColors::kRed      },
963 
964         // In this configuration (i.e., an RGB_888x colortype with an RGBA8 backing format),
965         // there is nothing to tell Skia to make the provided color opaque. Clients will need
966         // to provide an opaque initialization color in this case.
967         { GrColorType::kRGB_888x,         VK_FORMAT_R8G8B8A8_UNORM,           SkColors::kYellow   },
968         { GrColorType::kRGB_888x,         VK_FORMAT_R8G8B8_UNORM,             SkColors::kCyan     },
969 
970         { GrColorType::kBGRA_8888,        VK_FORMAT_B8G8R8A8_UNORM,           SkColors::kBlue     },
971 
972         { GrColorType::kRGBA_1010102,     VK_FORMAT_A2B10G10R10_UNORM_PACK32,
973                                                                       { 0.25f, 0.5f, 0.75f, 1.0f }},
974         { GrColorType::kBGRA_1010102,     VK_FORMAT_A2R10G10B10_UNORM_PACK32,
975                                                                       { 0.25f, 0.5f, 0.75f, 1.0f }},
976         { GrColorType::kBGR_565,          VK_FORMAT_R5G6B5_UNORM_PACK16,      SkColors::kRed      },
977 
978         { GrColorType::kABGR_4444,        VK_FORMAT_R4G4B4A4_UNORM_PACK16,    SkColors::kCyan     },
979         { GrColorType::kABGR_4444,        VK_FORMAT_B4G4R4A4_UNORM_PACK16,    SkColors::kYellow   },
980 
981         { GrColorType::kAlpha_8,          VK_FORMAT_R8_UNORM,                 kTransCol           },
982         // In this config (i.e., a Gray8 color type with an R8 backing format), there is nothing
983         // to tell Skia this isn't an Alpha8 color type (so it will initialize the texture with
984         // the alpha channel of the color). Clients should, in general, fill all the channels
985         // of the provided color with the same value in such cases.
986         { GrColorType::kGray_8,           VK_FORMAT_R8_UNORM,                 kGrayCol            },
987 
988         { GrColorType::kRGBA_F16_Clamped, VK_FORMAT_R16G16B16A16_SFLOAT,      SkColors::kLtGray   },
989         { GrColorType::kRGBA_F16,         VK_FORMAT_R16G16B16A16_SFLOAT,      SkColors::kYellow   },
990 
991         { GrColorType::kRG_88,            VK_FORMAT_R8G8_UNORM,               { 1, 0.5f, 0, 1 }   },
992         { GrColorType::kAlpha_F16,        VK_FORMAT_R16_SFLOAT,               { 1.0f, 0, 0, 0.5f }},
993 
994         { GrColorType::kAlpha_16,         VK_FORMAT_R16_UNORM,                kTransCol           },
995         { GrColorType::kRG_1616,          VK_FORMAT_R16G16_UNORM,             SkColors::kYellow   },
996         { GrColorType::kRGBA_16161616,    VK_FORMAT_R16G16B16A16_UNORM,       SkColors::kLtGray   },
997         { GrColorType::kRG_F16,           VK_FORMAT_R16G16_SFLOAT,            SkColors::kYellow   },
998     };
999 
1000     for (auto combo : combinations) {
1001         if (!vkCaps->isVkFormatTexturable(combo.fFormat)) {
1002             continue;
1003         }
1004 
1005         GrBackendFormat format = GrBackendFormat::MakeVk(combo.fFormat);
1006 
1007         for (auto mipmapped : { GrMipmapped::kNo, GrMipmapped::kYes }) {
1008             if (GrMipmapped::kYes == mipmapped && !vkCaps->mipmapSupport()) {
1009                 continue;
1010             }
1011 
1012             for (auto renderable : { GrRenderable::kNo, GrRenderable::kYes }) {
1013 
1014                 if (GrRenderable::kYes == renderable) {
1015                     // We must also check whether we allow rendering to the format using the
1016                     // color type.
1017                     if (!vkCaps->isFormatAsColorTypeRenderable(
1018                             combo.fColorType, GrBackendFormat::MakeVk(combo.fFormat), 1)) {
1019                         continue;
1020                     }
1021                 }
1022 
1023                 {
1024                     auto uninitCreateMtd = [format](GrDirectContext* dContext,
1025                                                     GrMipmapped mipmapped,
1026                                                     GrRenderable renderable) {
1027                         auto mbet = ManagedBackendTexture::MakeWithoutData(dContext,
1028                                                                            32, 32,
1029                                                                            format,
1030                                                                            mipmapped,
1031                                                                            renderable,
1032                                                                            GrProtected::kNo);
1033                         check_vk_tiling(mbet->texture());
1034                         return mbet;
1035                     };
1036 
1037                     test_wrapping(context, reporter, uninitCreateMtd, combo.fColorType, mipmapped,
1038                                   renderable);
1039                 }
1040 
1041                 {
1042                     // We're creating backend textures without specifying a color type "view" of
1043                     // them at the public API level. Therefore, Ganesh will not apply any swizzles
1044                     // before writing the color to the texture. However, our validation code does
1045                     // rely on interpreting the texture contents via a SkColorType and therefore
1046                     // swizzles may be applied during the read step.
1047                     // Ideally we'd update our validation code to use a "raw" read that doesn't
1048                     // impose a color type but for now we just munge the data we upload to match the
1049                     // expectation.
1050                     skgpu::Swizzle swizzle;
1051                     switch (combo.fColorType) {
1052                         case GrColorType::kAlpha_8:
1053                             SkASSERT(combo.fFormat == VK_FORMAT_R8_UNORM);
1054                             swizzle = skgpu::Swizzle("aaaa");
1055                             break;
1056                         case GrColorType::kAlpha_16:
1057                             SkASSERT(combo.fFormat == VK_FORMAT_R16_UNORM);
1058                             swizzle = skgpu::Swizzle("aaaa");
1059                             break;
1060                         case GrColorType::kAlpha_F16:
1061                             SkASSERT(combo.fFormat == VK_FORMAT_R16_SFLOAT);
1062                             swizzle = skgpu::Swizzle("aaaa");
1063                             break;
1064                         case GrColorType::kABGR_4444:
1065                             if (combo.fFormat == VK_FORMAT_B4G4R4A4_UNORM_PACK16) {
1066                                 swizzle = skgpu::Swizzle("bgra");
1067                             }
1068                             break;
1069                         default:
1070                             swizzle = skgpu::Swizzle("rgba");
1071                             break;
1072                     }
1073 
1074                     auto createWithColorMtd = [format, swizzle](GrDirectContext* dContext,
1075                                                                 const SkColor4f& color,
1076                                                                 GrMipmapped mipmapped,
1077                                                                 GrRenderable renderable) {
1078                         auto swizzledColor = swizzle.applyTo(color);
1079                         auto mbet = ManagedBackendTexture::MakeWithData(dContext,
1080                                                                         32, 32,
1081                                                                         format,
1082                                                                         swizzledColor,
1083                                                                         mipmapped,
1084                                                                         renderable,
1085                                                                         GrProtected::kNo);
1086                         check_vk_tiling(mbet->texture());
1087                         return mbet;
1088                     };
1089                     test_color_init(context, reporter, createWithColorMtd, combo.fColorType,
1090                                     combo.fColor, mipmapped, renderable);
1091                 }
1092             }
1093         }
1094     }
1095 }
1096 
1097 #endif
1098