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 <rkir@google.com>
diff --git a/system/vulkan/func_table.cpp b/system/vulkan/func_table.cpp
index f0ed982..a5227ec 100644
--- a/system/vulkan/func_table.cpp
+++ b/system/vulkan/func_table.cpp
@@ -812,7 +812,8 @@
AEMU_SCOPED_TRACE("vkCreateSampler");
auto vkEnc = HostConnection::get()->vkEncoder();
VkResult vkCreateSampler_VkResult_return = (VkResult)0;
- vkCreateSampler_VkResult_return = vkEnc->vkCreateSampler(device, pCreateInfo, pAllocator, pSampler);
+ auto resources = ResourceTracker::get();
+ vkCreateSampler_VkResult_return = resources->on_vkCreateSampler(vkEnc, VK_SUCCESS, device, pCreateInfo, pAllocator, pSampler);
return vkCreateSampler_VkResult_return;
}
static void entry_vkDestroySampler(
@@ -1777,7 +1778,8 @@
{
AEMU_SCOPED_TRACE("vkDestroySamplerYcbcrConversion");
auto vkEnc = HostConnection::get()->vkEncoder();
- vkEnc->vkDestroySamplerYcbcrConversion(device, ycbcrConversion, pAllocator);
+ auto resources = ResourceTracker::get();
+ resources->on_vkDestroySamplerYcbcrConversion(vkEnc, device, ycbcrConversion, pAllocator);
}
static VkResult entry_vkCreateDescriptorUpdateTemplate(
VkDevice device,
@@ -2822,7 +2824,8 @@
{
AEMU_SCOPED_TRACE("vkDestroySamplerYcbcrConversionKHR");
auto vkEnc = HostConnection::get()->vkEncoder();
- vkEnc->vkDestroySamplerYcbcrConversionKHR(device, ycbcrConversion, pAllocator);
+ auto resources = ResourceTracker::get();
+ resources->on_vkDestroySamplerYcbcrConversionKHR(vkEnc, device, ycbcrConversion, pAllocator);
}
#endif
#ifdef VK_KHR_bind_memory2
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,
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index 8daf979..f8e3270 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -271,12 +271,29 @@
const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSamplerYcbcrConversion* pYcbcrConversion);
+ void on_vkDestroySamplerYcbcrConversion(
+ void* context,
+ VkDevice device,
+ VkSamplerYcbcrConversion ycbcrConversion,
+ const VkAllocationCallbacks* pAllocator);
VkResult on_vkCreateSamplerYcbcrConversionKHR(
void* context, VkResult input_result,
VkDevice device,
const VkSamplerYcbcrConversionCreateInfo* pCreateInfo,
const VkAllocationCallbacks* pAllocator,
VkSamplerYcbcrConversion* pYcbcrConversion);
+ void on_vkDestroySamplerYcbcrConversionKHR(
+ void* context,
+ VkDevice device,
+ VkSamplerYcbcrConversion ycbcrConversion,
+ const VkAllocationCallbacks* pAllocator);
+
+ VkResult on_vkCreateSampler(
+ void* context, VkResult input_result,
+ VkDevice device,
+ const VkSamplerCreateInfo* pCreateInfo,
+ const VkAllocationCallbacks* pAllocator,
+ VkSampler* pSampler);
VkResult on_vkMapMemoryIntoAddressSpaceGOOGLE_pre(
void* context,
diff --git a/system/vulkan_enc/goldfish_vk_private_defs.h b/system/vulkan_enc/goldfish_vk_private_defs.h
index 662b8f0..8c08a44 100644
--- a/system/vulkan_enc/goldfish_vk_private_defs.h
+++ b/system/vulkan_enc/goldfish_vk_private_defs.h
@@ -530,6 +530,8 @@
// VulkanStream features
#define VULKAN_STREAM_FEATURE_NULL_OPTIONAL_STRINGS_BIT (1 << 0)
+#define VK_YCBCR_CONVERSION_DO_NOTHING ((VkSamplerYcbcrConversion)0x1111111111111111)
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/system/vulkan_enc/vk_struct_id.h b/system/vulkan_enc/vk_struct_id.h
index 561b430..9721900 100644
--- a/system/vulkan_enc/vk_struct_id.h
+++ b/system/vulkan_enc/vk_struct_id.h
@@ -46,5 +46,7 @@
REGISTER_VK_STRUCT_ID(VkImportMemoryBufferCollectionFUCHSIA, VK_STRUCTURE_TYPE_IMPORT_MEMORY_BUFFER_COLLECTION_FUCHSIA);
REGISTER_VK_STRUCT_ID(VkImportMemoryZirconHandleInfoFUCHSIA, VK_STRUCTURE_TYPE_TEMP_IMPORT_MEMORY_ZIRCON_HANDLE_INFO_FUCHSIA);
REGISTER_VK_STRUCT_ID(VkBufferCollectionImageCreateInfoFUCHSIA, VK_STRUCTURE_TYPE_BUFFER_COLLECTION_IMAGE_CREATE_INFO_FUCHSIA);
+REGISTER_VK_STRUCT_ID(VkSamplerCreateInfo, VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
+REGISTER_VK_STRUCT_ID(VkSamplerYcbcrConversionInfo, VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO);
#undef REGISTER_VK_STRUCT_ID