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,