Add kRGB_888X_GrPixelConfig

This is needed to support importing of RGBX AHB into skia's vulkan backend.
With this CL we only enable the new pixel config to be textureable.

Bug: skia:
Change-Id: Iba9180c14f3ef633ae846091cf453d68f82ce544
Reviewed-on: https://skia-review.googlesource.com/c/192035
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/vk/GrVkCaps.cpp b/src/gpu/vk/GrVkCaps.cpp
index 1123325..55f632a 100644
--- a/src/gpu/vk/GrVkCaps.cpp
+++ b/src/gpu/vk/GrVkCaps.cpp
@@ -517,6 +517,8 @@
                 // only extra work is the swizzle in the shader for all operations.
                 shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::BGRA();
                 shaderCaps->fConfigOutputSwizzle[i] = GrSwizzle::BGRA();
+            } else if (kRGB_888X_GrPixelConfig == config) {
+                shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGB1();
             } else {
                 shaderCaps->fConfigTextureSwizzle[i] = GrSwizzle::RGBA();
             }
@@ -593,19 +595,27 @@
         VkFormat format;
         if (GrPixelConfigToVkFormat(static_cast<GrPixelConfig>(i), &format)) {
             if (!GrPixelConfigIsSRGB(static_cast<GrPixelConfig>(i)) || fSRGBSupport) {
-                fConfigTable[i].init(interface, physDev, properties, format);
+                bool disableRendering = false;
+                if (static_cast<GrPixelConfig>(i) == kRGB_888X_GrPixelConfig) {
+                    // Currently we don't allow RGB_888X to be renderable because we don't have a
+                    // way to handle blends that reference dst alpha when the values in the dst
+                    // alpha channel are uninitialized.
+                    disableRendering = true;
+                }
+                fConfigTable[i].init(interface, physDev, properties, format, disableRendering);
             }
         }
     }
 }
 
-void GrVkCaps::ConfigInfo::InitConfigFlags(VkFormatFeatureFlags vkFlags, uint16_t* flags) {
+void GrVkCaps::ConfigInfo::InitConfigFlags(VkFormatFeatureFlags vkFlags, uint16_t* flags,
+                                           bool disableRendering) {
     if (SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT & vkFlags) &&
         SkToBool(VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT & vkFlags)) {
         *flags = *flags | kTextureable_Flag;
 
         // Ganesh assumes that all renderable surfaces are also texturable
-        if (SkToBool(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT & vkFlags)) {
+        if (SkToBool(VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT & vkFlags) & !disableRendering) {
             *flags = *flags | kRenderable_Flag;
         }
     }
@@ -666,12 +676,13 @@
 void GrVkCaps::ConfigInfo::init(const GrVkInterface* interface,
                                 VkPhysicalDevice physDev,
                                 const VkPhysicalDeviceProperties& properties,
-                                VkFormat format) {
+                                VkFormat format,
+                                bool disableRendering) {
     VkFormatProperties props;
     memset(&props, 0, sizeof(VkFormatProperties));
     GR_VK_CALL(interface, GetPhysicalDeviceFormatProperties(physDev, format, &props));
-    InitConfigFlags(props.linearTilingFeatures, &fLinearFlags);
-    InitConfigFlags(props.optimalTilingFeatures, &fOptimalFlags);
+    InitConfigFlags(props.linearTilingFeatures, &fLinearFlags, disableRendering);
+    InitConfigFlags(props.optimalTilingFeatures, &fOptimalFlags, disableRendering);
     if (fOptimalFlags & kRenderable_Flag) {
         this->initSampleCounts(interface, physDev, properties, format);
     }
@@ -762,6 +773,9 @@
             if (VK_FORMAT_R8G8B8_UNORM == format) {
                 return kRGB_888_GrPixelConfig;
             }
+            if (VK_FORMAT_R8G8B8A8_UNORM == format) {
+                return kRGB_888X_GrPixelConfig;
+            }
             break;
         case kBGRA_8888_SkColorType:
             if (VK_FORMAT_B8G8R8A8_UNORM == format) {
diff --git a/src/gpu/vk/GrVkCaps.h b/src/gpu/vk/GrVkCaps.h
index 2309541..41c31fb 100644
--- a/src/gpu/vk/GrVkCaps.h
+++ b/src/gpu/vk/GrVkCaps.h
@@ -191,8 +191,8 @@
         ConfigInfo() : fOptimalFlags(0), fLinearFlags(0) {}
 
         void init(const GrVkInterface*, VkPhysicalDevice, const VkPhysicalDeviceProperties&,
-                  VkFormat);
-        static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags);
+                  VkFormat, bool disableRendering);
+        static void InitConfigFlags(VkFormatFeatureFlags, uint16_t* flags, bool disableRendering);
         void initSampleCounts(const GrVkInterface*, VkPhysicalDevice,
                               const VkPhysicalDeviceProperties&, VkFormat);
 
diff --git a/src/gpu/vk/GrVkGpu.cpp b/src/gpu/vk/GrVkGpu.cpp
index 3a820d9..934d858 100644
--- a/src/gpu/vk/GrVkGpu.cpp
+++ b/src/gpu/vk/GrVkGpu.cpp
@@ -611,9 +611,8 @@
 
     // For RGB_888x src data we are uploading it first to an RGBA texture and then copying it to the
     // dst RGB texture. Thus we do not upload mip levels for that.
-    if (dataColorType == GrColorType::kRGB_888x) {
-        SkASSERT(tex->imageFormat() == VK_FORMAT_R8G8B8_UNORM &&
-                 tex->config() == kRGB_888_GrPixelConfig);
+    if (dataColorType == GrColorType::kRGB_888x && tex->imageFormat() == VK_FORMAT_R8G8B8_UNORM) {
+        SkASSERT(tex->config() == kRGB_888_GrPixelConfig);
         // First check that we'll be able to do the copy to the to the R8G8B8 image in the end via a
         // blit or draw.
         if (!this->vkCaps().configCanBeDstofBlit(kRGB_888_GrPixelConfig, tex->isLinearTiled()) &&
@@ -681,7 +680,7 @@
     // For uploading RGB_888x data to an R8G8B8_UNORM texture we must first upload the data to an
     // R8G8B8A8_UNORM image and then copy it.
     sk_sp<GrVkTexture> copyTexture;
-    if (dataColorType == GrColorType::kRGB_888x) {
+    if (dataColorType == GrColorType::kRGB_888x && tex->imageFormat() == VK_FORMAT_R8G8B8_UNORM) {
         GrSurfaceDesc surfDesc;
         surfDesc.fFlags = kRenderTarget_GrSurfaceFlag;
         surfDesc.fWidth = width;
@@ -2066,9 +2065,8 @@
     // 32 bits, but the Vulkan format is only 24. So we first copy the surface into an R8G8B8A8
     // image and then do the read pixels from that.
     sk_sp<GrVkTextureRenderTarget> copySurface;
-    if (dstColorType == GrColorType::kRGB_888x) {
-        SkASSERT(image->imageFormat() == VK_FORMAT_R8G8B8_UNORM &&
-                 surface->config() == kRGB_888_GrPixelConfig);
+    if (dstColorType == GrColorType::kRGB_888x && image->imageFormat() == VK_FORMAT_R8G8B8_UNORM) {
+        SkASSERT(surface->config() == kRGB_888_GrPixelConfig);
 
         // Make a new surface that is RGBA to copy the RGB surface into.
         GrSurfaceDesc surfDesc;
diff --git a/src/gpu/vk/GrVkUtil.cpp b/src/gpu/vk/GrVkUtil.cpp
index 8dffe4c..cf8b9ec 100644
--- a/src/gpu/vk/GrVkUtil.cpp
+++ b/src/gpu/vk/GrVkUtil.cpp
@@ -25,6 +25,9 @@
         case kRGB_888_GrPixelConfig:
             *format = VK_FORMAT_R8G8B8_UNORM;
             return true;
+        case kRGB_888X_GrPixelConfig:
+            *format = VK_FORMAT_R8G8B8A8_UNORM;
+            return true;
         case kRG_88_GrPixelConfig:
             *format = VK_FORMAT_R8G8_UNORM;
             return true;
@@ -86,7 +89,8 @@
 bool GrVkFormatPixelConfigPairIsValid(VkFormat format, GrPixelConfig config) {
     switch (format) {
         case VK_FORMAT_R8G8B8A8_UNORM:
-            return kRGBA_8888_GrPixelConfig == config;
+            return kRGBA_8888_GrPixelConfig == config ||
+                   kRGB_888X_GrPixelConfig == config;
         case VK_FORMAT_B8G8R8A8_UNORM:
             return kBGRA_8888_GrPixelConfig == config;
         case VK_FORMAT_R8G8B8A8_SRGB: