Fix compatible format check for vkCmdCopyImage.

No-Tree-Checks: true
No-Presubmit: true
Change-Id: I4553bbdb7be5f5bd9e6efc12f4e3aba7557c4549
Reviewed-On: https://skia-review.googlesource.com/c/skia/+/213133
Reviewed-By: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
Cherry-Pick: 5c7b54112bca7eb770f29f422b90792cec6a780b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/215383
Reviewed-by: Hal Canary <halcanary@google.com>
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index a720e72..dabdda7 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -74,6 +74,44 @@
     return true;
 }
 
+static int get_compatible_format_class(GrPixelConfig config) {
+    switch (config) {
+        case kAlpha_8_GrPixelConfig:
+        case kAlpha_8_as_Red_GrPixelConfig:
+        case kGray_8_GrPixelConfig:
+        case kGray_8_as_Red_GrPixelConfig:
+            return 1;
+        case kRGB_565_GrPixelConfig:
+        case kRGBA_4444_GrPixelConfig:
+        case kRG_88_GrPixelConfig:
+        case kAlpha_half_GrPixelConfig:
+        case kAlpha_half_as_Red_GrPixelConfig:
+            return 2;
+        case kRGB_888_GrPixelConfig:
+            return 3;
+        case kRGBA_8888_GrPixelConfig:
+        case kBGRA_8888_GrPixelConfig:
+        case kSRGBA_8888_GrPixelConfig:
+        case kSBGRA_8888_GrPixelConfig:
+        case kRGBA_1010102_GrPixelConfig:
+            return 4;
+        case kRGBA_half_GrPixelConfig:
+        case kRG_float_GrPixelConfig:
+            return 5;
+        case kRGBA_float_GrPixelConfig:
+            return 6;
+        case kRGB_ETC1_GrPixelConfig:
+            return 7;
+        case kUnknown_GrPixelConfig:
+        case kAlpha_8_as_Alpha_GrPixelConfig:
+        case kGray_8_as_Lum_GrPixelConfig:
+            SK_ABORT("Unsupported Vulkan pixel config");
+            return 0;
+    }
+    SK_ABORT("Invalid pixel config");
+    return 0;
+}
+
 bool GrVkCaps::canCopyImage(GrPixelConfig dstConfig, int dstSampleCnt, GrSurfaceOrigin dstOrigin,
                             GrPixelConfig srcConfig, int srcSampleCnt,
                             GrSurfaceOrigin srcOrigin) const {
@@ -83,7 +121,8 @@
 
     // We require that all vulkan GrSurfaces have been created with transfer_dst and transfer_src
     // as image usage flags.
-    if (srcOrigin != dstOrigin || GrBytesPerPixel(srcConfig) != GrBytesPerPixel(dstConfig)) {
+    if (srcOrigin != dstOrigin ||
+        get_compatible_format_class(srcConfig) != get_compatible_format_class(dstConfig)) {
         return false;
     }
 
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 2f66805..ede31df 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -712,6 +712,14 @@
         if (!copyTexture) {
             return false;
         }
+
+        if (!this->vkCaps().canCopyAsBlit(tex->config(), 1, false,
+                                          copyTexture->config(), 1, false) &&
+            !this->vkCaps().canCopyAsDraw(tex->config(), SkToBool(tex->asRenderTarget()),
+                                          copyTexture->config(), true)) {
+            return false;
+        }
+
         uploadTexture = copyTexture.get();
         uploadLeft = 0;
         uploadTop = 0;
@@ -2107,14 +2115,15 @@
         if (rt) {
             srcSampleCount = rt->numColorSamples();
         }
-        static const GrSurfaceOrigin kOrigin = kTopLeft_GrSurfaceOrigin;
-        if (!this->vkCaps().canCopyAsBlit(copySurface->config(), 1, kOrigin,
-                                          surface->config(), srcSampleCount, kOrigin) &&
+        if (!this->vkCaps().canCopyAsBlit(copySurface->config(), 1, false,
+                                          surface->config(), srcSampleCount,
+                                          image->isLinearTiled()) &&
             !this->vkCaps().canCopyAsDraw(copySurface->config(), false,
                                           surface->config(), SkToBool(surface->asTexture()))) {
             return false;
         }
         SkIRect srcRect = SkIRect::MakeXYWH(left, top, width, height);
+        static const GrSurfaceOrigin kOrigin = kTopLeft_GrSurfaceOrigin;
         if (!this->copySurface(copySurface.get(), kOrigin, surface, kOrigin,
                                srcRect, SkIPoint::Make(0,0))) {
             return false;