Do not create YcbcrConversion for RGB565 passed as external format

Since we don't support external formats (we replace
them to internal ones and cut off VkExternalFormatANDROID
from struct chains), a vkCreateSampler call with
a conversion based on an external format with
another external format provided does not make sence.

This change returns a predefined value
(VK_YCBCR_CONVERSION_DO_NOTHING of type
VkSamplerYcbcrConversion) for CreateSamplerYcbcrConversion
when RGB565 is passed as an external format.

This special value (VK_YCBCR_CONVERSION_DO_NOTHING) is
checked later in vkCreateSampler and the whole
VkSamplerYcbcrConversionInfo is discarded.

Bug: 134771579
Test: CtsGraphicsTestCases android.graphics.cts.BasicVulkanGpuTest
Change-Id: I6c0a085866178391eb330b0005a687914be5e865
Signed-off-by: Roman Kiryanov <[email protected]>
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 9cd8a79..e03e143 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -2274,7 +2274,15 @@
         const VkExternalFormatANDROID* extFormatAndroidPtr =
             vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
         if (extFormatAndroidPtr) {
-            if (extFormatAndroidPtr->externalFormat) {
+            if (extFormatAndroidPtr->externalFormat == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) {
+                // We don't support external formats on host and it causes RGB565
+                // to fail in CtsGraphicsTestCases android.graphics.cts.BasicVulkanGpuTest
+                // when passed as an external format.
+                // We may consider doing this for all external formats.
+                // See b/134771579.
+                *pYcbcrConversion = VK_YCBCR_CONVERSION_DO_NOTHING;
+                return VK_SUCCESS;
+            } else if (extFormatAndroidPtr->externalFormat) {
                 localCreateInfo.format =
                     vk_format_from_android(extFormatAndroidPtr->externalFormat);
             }
@@ -2282,8 +2290,25 @@
 #endif
 
         VkEncoder* enc = (VkEncoder*)context;
-        return enc->vkCreateSamplerYcbcrConversion(
+        VkResult res = enc->vkCreateSamplerYcbcrConversion(
             device, &localCreateInfo, pAllocator, pYcbcrConversion);
+
+        if (*pYcbcrConversion == VK_YCBCR_CONVERSION_DO_NOTHING) {
+            ALOGE("FATAL: vkCreateSamplerYcbcrConversion returned a reserved value (VK_YCBCR_CONVERSION_DO_NOTHING)");
+            abort();
+        }
+        return res;
+    }
+
+    void on_vkDestroySamplerYcbcrConversion(
+        void* context,
+        VkDevice device,
+        VkSamplerYcbcrConversion ycbcrConversion,
+        const VkAllocationCallbacks* pAllocator) {
+        VkEncoder* enc = (VkEncoder*)context;
+        if (ycbcrConversion != VK_YCBCR_CONVERSION_DO_NOTHING) {
+            enc->vkDestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator);
+        }
     }
 
     VkResult on_vkCreateSamplerYcbcrConversionKHR(
@@ -2299,7 +2324,15 @@
         const VkExternalFormatANDROID* extFormatAndroidPtr =
             vk_find_struct<VkExternalFormatANDROID>(pCreateInfo);
         if (extFormatAndroidPtr) {
-            if (extFormatAndroidPtr->externalFormat) {
+            if (extFormatAndroidPtr->externalFormat == AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM) {
+                // We don't support external formats on host and it causes RGB565
+                // to fail in CtsGraphicsTestCases android.graphics.cts.BasicVulkanGpuTest
+                // when passed as an external format.
+                // We may consider doing this for all external formats.
+                // See b/134771579.
+                *pYcbcrConversion = VK_YCBCR_CONVERSION_DO_NOTHING;
+                return VK_SUCCESS;
+            } else if (extFormatAndroidPtr->externalFormat) {
                 localCreateInfo.format =
                     vk_format_from_android(extFormatAndroidPtr->externalFormat);
             }
@@ -2307,8 +2340,51 @@
 #endif
 
         VkEncoder* enc = (VkEncoder*)context;
-        return enc->vkCreateSamplerYcbcrConversionKHR(
+        VkResult res = enc->vkCreateSamplerYcbcrConversionKHR(
             device, &localCreateInfo, pAllocator, pYcbcrConversion);
+
+        if (*pYcbcrConversion == VK_YCBCR_CONVERSION_DO_NOTHING) {
+            ALOGE("FATAL: vkCreateSamplerYcbcrConversionKHR returned a reserved value (VK_YCBCR_CONVERSION_DO_NOTHING)");
+            abort();
+        }
+        return res;
+    }
+
+    void on_vkDestroySamplerYcbcrConversionKHR(
+        void* context,
+        VkDevice device,
+        VkSamplerYcbcrConversion ycbcrConversion,
+        const VkAllocationCallbacks* pAllocator) {
+        VkEncoder* enc = (VkEncoder*)context;
+        if (ycbcrConversion != VK_YCBCR_CONVERSION_DO_NOTHING) {
+            enc->vkDestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator);
+        }
+    }
+
+    VkResult on_vkCreateSampler(
+        void* context, VkResult,
+        VkDevice device,
+        const VkSamplerCreateInfo* pCreateInfo,
+        const VkAllocationCallbacks* pAllocator,
+        VkSampler* pSampler) {
+
+        VkSamplerCreateInfo localCreateInfo = vk_make_orphan_copy(*pCreateInfo);
+        vk_struct_chain_iterator structChainIter = vk_make_chain_iterator(&localCreateInfo);
+
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+        VkSamplerYcbcrConversionInfo localVkSamplerYcbcrConversionInfo;
+        const VkSamplerYcbcrConversionInfo* samplerYcbcrConversionInfo =
+            vk_find_struct<VkSamplerYcbcrConversionInfo>(pCreateInfo);
+        if (samplerYcbcrConversionInfo) {
+            if (samplerYcbcrConversionInfo->conversion != VK_YCBCR_CONVERSION_DO_NOTHING) {
+                localVkSamplerYcbcrConversionInfo = vk_make_orphan_copy(*samplerYcbcrConversionInfo);
+                vk_append_struct(&structChainIter, &localVkSamplerYcbcrConversionInfo);
+            }
+        }
+#endif
+
+        VkEncoder* enc = (VkEncoder*)context;
+        return enc->vkCreateSampler(device, &localCreateInfo, pAllocator, pSampler);
     }
 
     void on_vkDestroyImage(
@@ -3738,6 +3814,15 @@
         context, input_result, device, pCreateInfo, pAllocator, pYcbcrConversion);
 }
 
+void ResourceTracker::on_vkDestroySamplerYcbcrConversion(
+    void* context,
+    VkDevice device,
+    VkSamplerYcbcrConversion ycbcrConversion,
+    const VkAllocationCallbacks* pAllocator) {
+    mImpl->on_vkDestroySamplerYcbcrConversion(
+        context, device, ycbcrConversion, pAllocator);
+}
+
 VkResult ResourceTracker::on_vkCreateSamplerYcbcrConversionKHR(
     void* context, VkResult input_result,
     VkDevice device,
@@ -3748,6 +3833,25 @@
         context, input_result, device, pCreateInfo, pAllocator, pYcbcrConversion);
 }
 
+void ResourceTracker::on_vkDestroySamplerYcbcrConversionKHR(
+    void* context,
+    VkDevice device,
+    VkSamplerYcbcrConversion ycbcrConversion,
+    const VkAllocationCallbacks* pAllocator) {
+    mImpl->on_vkDestroySamplerYcbcrConversionKHR(
+        context, device, ycbcrConversion, pAllocator);
+}
+
+VkResult ResourceTracker::on_vkCreateSampler(
+    void* context, VkResult input_result,
+    VkDevice device,
+    const VkSamplerCreateInfo* pCreateInfo,
+    const VkAllocationCallbacks* pAllocator,
+    VkSampler* pSampler) {
+    return mImpl->on_vkCreateSampler(
+        context, input_result, device, pCreateInfo, pAllocator, pSampler);
+}
+
 VkResult ResourceTracker::on_vkMapMemoryIntoAddressSpaceGOOGLE_pre(
     void* context,
     VkResult input_result,