From 780e4c8194903a386fd2667b6eb89beb016afc21 Mon Sep 17 00:00:00 2001 From: Jason Macnak Date: Mon, 14 Sep 2026 15:53:16 -0700 Subject: [PATCH] Filter reported device extensions to those supported by codegen With Cuttlefish moving its host tooling to an installed host package being built from github and not from the Android build, it is now possible for the guest gfxstream build from Android to be newer than the gfxstream host build. With this, Gfxstream needs to start worrying about forwards/backward compatability. b/561597187 is the first case where the guest thinks it can send VK_EXT_border_color_swizzle structs (e.g. VkPhysicalDeviceBorderColorSwizzleFeaturesEXT) but then the host gives up when it encounters a struct it does not recognize. Gfxstream should only report extensions that are intersection of guest support and host support. Bug: b/561597187 Test: launch Cuttlefish with a hack to disable the VK_EXT_border_color_swizzle extension on the host and validate that the guest does not report it even though guest codegen could support it Change-Id: If4268ca1c282dcfbd92c7d5969cd45f199235e86 --- host/vulkan/cereal/Android.bp | 1 + host/vulkan/cereal/BUILD.bazel | 3 + host/vulkan/cereal/CMakeLists.txt | 1 + .../goldfish_vk_supported_extensions.cpp | 169 ++++++++++++++++++ .../common/goldfish_vk_supported_extensions.h | 45 +++++ host/vulkan/cereal/meson.build | 1 + host/vulkan/vk_decoder_global_state.cpp | 42 ++--- 7 files changed, 242 insertions(+), 20 deletions(-) create mode 100644 host/vulkan/cereal/common/goldfish_vk_supported_extensions.cpp create mode 100644 host/vulkan/cereal/common/goldfish_vk_supported_extensions.h diff --git a/host/vulkan/cereal/Android.bp b/host/vulkan/cereal/Android.bp index 0febf58cf..4aab67be0 100644 --- a/host/vulkan/cereal/Android.bp +++ b/host/vulkan/cereal/Android.bp @@ -32,6 +32,7 @@ cc_library_static { "common/goldfish_vk_reserved_marshaling.cpp", "common/goldfish_vk_deepcopy.cpp", "common/goldfish_vk_dispatch.cpp", + "common/goldfish_vk_supported_extensions.cpp", "common/goldfish_vk_transform.cpp", ], header_libs: [ diff --git a/host/vulkan/cereal/BUILD.bazel b/host/vulkan/cereal/BUILD.bazel index 378d8f71e..7b491875e 100644 --- a/host/vulkan/cereal/BUILD.bazel +++ b/host/vulkan/cereal/BUILD.bazel @@ -13,6 +13,7 @@ cc_library( "common/goldfish_vk_dispatch.h", "common/goldfish_vk_extension_structs.h", "common/goldfish_vk_private_defs.h", + "common/goldfish_vk_supported_extensions.h", "common/goldfish_vk_transform.h", "common/vk_struct_id.h", ], @@ -37,6 +38,7 @@ cc_library( "common/goldfish_vk_extension_structs.cpp", "common/goldfish_vk_marshaling.cpp", "common/goldfish_vk_reserved_marshaling.cpp", + "common/goldfish_vk_supported_extensions.cpp", "common/goldfish_vk_transform.cpp", ], hdrs = [ @@ -46,6 +48,7 @@ cc_library( "common/goldfish_vk_marshaling.h", "common/goldfish_vk_private_defs.h", "common/goldfish_vk_reserved_marshaling.h", + "common/goldfish_vk_supported_extensions.h", "common/goldfish_vk_transform.h", "common/vk_struct_id.h", ], diff --git a/host/vulkan/cereal/CMakeLists.txt b/host/vulkan/cereal/CMakeLists.txt index 5134a9cf6..136076aa5 100644 --- a/host/vulkan/cereal/CMakeLists.txt +++ b/host/vulkan/cereal/CMakeLists.txt @@ -18,6 +18,7 @@ add_library(OpenglRender_vulkan_cereal common/goldfish_vk_reserved_marshaling.cpp common/goldfish_vk_deepcopy.cpp common/goldfish_vk_dispatch.cpp + common/goldfish_vk_supported_extensions.cpp common/goldfish_vk_transform.cpp ) target_compile_definitions(OpenglRender_vulkan_cereal PRIVATE -DVK_GOOGLE_gfxstream) if (WIN32) diff --git a/host/vulkan/cereal/common/goldfish_vk_supported_extensions.cpp b/host/vulkan/cereal/common/goldfish_vk_supported_extensions.cpp new file mode 100644 index 000000000..4bb33e051 --- /dev/null +++ b/host/vulkan/cereal/common/goldfish_vk_supported_extensions.cpp @@ -0,0 +1,169 @@ +// Copyright (C) 2018 The Android Open Source Project +// Copyright (C) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Autogenerated module goldfish_vk_supported_extensions +// +// (impl) generated by genvk.py +// +// Please do not modify directly; +// re-run mesa3d/src/gfxstream/codegen/generate-gfxstream-vulkan.sh, +// or directly from Python by defining: +// VULKAN_REGISTRY_XML_DIR : Directory containing vk.xml +// VULKAN_REGISTRY_SCRIPTS_DIR : Directory containing genvk.py +// CEREAL_OUTPUT_DIR: Where to put the generated sources. +// +// python3 $VULKAN_REGISTRY_SCRIPTS_DIR/genvk.py -registry $VULKAN_REGISTRY_XML_DIR/vk.xml cereal -o +// $CEREAL_OUTPUT_DIR +// + +#include "goldfish_vk_supported_extensions.h" + +namespace gfxstream { +namespace host { +namespace vk { + +const std::unordered_set& GetInstanceExtensionsSupportedByCodegen() { + static const std::unordered_set* kSupported = []() { + return new std::unordered_set{ + "VK_EXT_debug_report", + "VK_EXT_debug_utils", + "VK_EXT_validation_features", + "VK_KHR_external_fence_capabilities", + "VK_KHR_external_memory_capabilities", + "VK_KHR_external_semaphore_capabilities", + "VK_KHR_get_physical_device_properties2", + }; + }(); + return *kSupported; +} + +const std::unordered_set& GetDeviceExtensionsSupportedByCodegen() { + static const std::unordered_set* kSupported = []() { + return new std::unordered_set{ + "VK_AMD_gpu_shader_half_float", + "VK_ANDROID_external_memory_android_hardware_buffer", + "VK_ANDROID_native_buffer", + "VK_EXT_4444_formats", + "VK_EXT_blend_operation_advanced", + "VK_EXT_border_color_swizzle", + "VK_EXT_color_write_enable", + "VK_EXT_custom_border_color", + "VK_EXT_depth_clip_enable", + "VK_EXT_device_memory_report", + "VK_EXT_extended_dynamic_state", + "VK_EXT_extended_dynamic_state2", + "VK_EXT_external_memory_host", + "VK_EXT_external_memory_metal", + "VK_EXT_fragment_density_map", + "VK_EXT_frame_boundary", + "VK_EXT_graphics_pipeline_library", + "VK_EXT_host_image_copy", + "VK_EXT_image_compression_control", + "VK_EXT_image_compression_control_swapchain", + "VK_EXT_image_drm_format_modifier", + "VK_EXT_image_robustness", + "VK_EXT_index_type_uint8", + "VK_EXT_inline_uniform_block", + "VK_EXT_line_rasterization", + "VK_EXT_load_store_op_none", + "VK_EXT_memory_budget", + "VK_EXT_metal_objects", + "VK_EXT_metal_surface", + "VK_EXT_pipeline_creation_cache_control", + "VK_EXT_pipeline_creation_feedback", + "VK_EXT_pipeline_protected_access", + "VK_EXT_primitive_topology_list_restart", + "VK_EXT_primitives_generated_query", + "VK_EXT_private_data", + "VK_EXT_provoking_vertex", + "VK_EXT_queue_family_foreign", + "VK_EXT_robustness2", + "VK_EXT_scalar_block_layout", + "VK_EXT_shader_demote_to_helper_invocation", + "VK_EXT_shader_stencil_export", + "VK_EXT_subgroup_size_control", + "VK_EXT_swapchain_colorspace", + "VK_EXT_swapchain_maintenance1", + "VK_EXT_texel_buffer_alignment", + "VK_EXT_texture_compression_astc_hdr", + "VK_EXT_tooling_info", + "VK_EXT_transform_feedback", + "VK_EXT_vertex_attribute_divisor", + "VK_EXT_ycbcr_2plane_444_formats", + "VK_GOOGLE_gfxstream", + "VK_KHR_android_surface", + "VK_KHR_bind_memory2", + "VK_KHR_buffer_device_address", + "VK_KHR_copy_commands2", + "VK_KHR_create_renderpass2", + "VK_KHR_dedicated_allocation", + "VK_KHR_descriptor_update_template", + "VK_KHR_dynamic_rendering", + "VK_KHR_external_fence", + "VK_KHR_external_fence_fd", + "VK_KHR_external_memory", + "VK_KHR_external_memory_fd", + "VK_KHR_external_memory_win32", + "VK_KHR_external_semaphore", + "VK_KHR_external_semaphore_fd", + "VK_KHR_external_semaphore_win32", + "VK_KHR_format_feature_flags2", + "VK_KHR_get_memory_requirements2", + "VK_KHR_global_priority", + "VK_KHR_image_format_list", + "VK_KHR_imageless_framebuffer", + "VK_KHR_incremental_present", + "VK_KHR_line_rasterization", + "VK_KHR_maintenance1", + "VK_KHR_maintenance2", + "VK_KHR_maintenance3", + "VK_KHR_maintenance4", + "VK_KHR_maintenance5", + "VK_KHR_maintenance6", + "VK_KHR_maintenance7", + "VK_KHR_maintenance8", + "VK_KHR_maintenance9", + "VK_KHR_multiview", + "VK_KHR_pipeline_executable_properties", + "VK_KHR_pipeline_library", + "VK_KHR_ray_tracing_pipeline", + "VK_KHR_sampler_ycbcr_conversion", + "VK_KHR_shader_float16_int8", + "VK_KHR_shader_integer_dot_product", + "VK_KHR_shader_non_semantic_info", + "VK_KHR_shader_subgroup_extended_types", + "VK_KHR_shader_terminate_invocation", + "VK_KHR_storage_buffer_storage_class", + "VK_KHR_surface", + "VK_KHR_swapchain", + "VK_KHR_swapchain_maintenance1", + "VK_KHR_synchronization2", + "VK_KHR_vulkan_memory_model", + "VK_KHR_win32_surface", + "VK_KHR_xcb_surface", + "VK_KHR_zero_initialize_workgroup_memory", + "VK_MVK_macos_surface", + "VK_NV_device_diagnostic_checkpoints", + "VK_NV_shader_subgroup_partitioned", + "VK_QNX_external_memory_screen_buffer", + "VK_QNX_screen_surface", + }; + }(); + return *kSupported; +} + +} // namespace vk +} // namespace host +} // namespace gfxstream diff --git a/host/vulkan/cereal/common/goldfish_vk_supported_extensions.h b/host/vulkan/cereal/common/goldfish_vk_supported_extensions.h new file mode 100644 index 000000000..5d8a73769 --- /dev/null +++ b/host/vulkan/cereal/common/goldfish_vk_supported_extensions.h @@ -0,0 +1,45 @@ +// Copyright (C) 2018 The Android Open Source Project +// Copyright (C) 2018 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Autogenerated module goldfish_vk_supported_extensions +// +// (header) generated by genvk.py +// +// Please do not modify directly; +// re-run mesa3d/src/gfxstream/codegen/generate-gfxstream-vulkan.sh, +// or directly from Python by defining: +// VULKAN_REGISTRY_XML_DIR : Directory containing vk.xml +// VULKAN_REGISTRY_SCRIPTS_DIR : Directory containing genvk.py +// CEREAL_OUTPUT_DIR: Where to put the generated sources. +// +// python3 $VULKAN_REGISTRY_SCRIPTS_DIR/genvk.py -registry $VULKAN_REGISTRY_XML_DIR/vk.xml cereal -o +// $CEREAL_OUTPUT_DIR +// +#pragma once + +#include +#include + +namespace gfxstream { +namespace host { +namespace vk { + +const std::unordered_set& GetInstanceExtensionsSupportedByCodegen(); + +const std::unordered_set& GetDeviceExtensionsSupportedByCodegen(); + +} // namespace vk +} // namespace host +} // namespace gfxstream diff --git a/host/vulkan/cereal/meson.build b/host/vulkan/cereal/meson.build index 2d03c2081..d1c2b82e0 100644 --- a/host/vulkan/cereal/meson.build +++ b/host/vulkan/cereal/meson.build @@ -7,6 +7,7 @@ files_lib_cereal = files( 'common/goldfish_vk_reserved_marshaling.cpp', 'common/goldfish_vk_deepcopy.cpp', 'common/goldfish_vk_dispatch.cpp', + 'common/goldfish_vk_supported_extensions.cpp', 'common/goldfish_vk_transform.cpp' ) diff --git a/host/vulkan/vk_decoder_global_state.cpp b/host/vulkan/vk_decoder_global_state.cpp index e1fac243a..ffb50b8ca 100644 --- a/host/vulkan/vk_decoder_global_state.cpp +++ b/host/vulkan/vk_decoder_global_state.cpp @@ -42,6 +42,7 @@ #include "common/goldfish_vk_dispatch.h" #include "common/goldfish_vk_marshaling.h" #include "common/goldfish_vk_reserved_marshaling.h" +#include "common/goldfish_vk_supported_extensions.h" #include "emulated_textures/astc_texture.h" #include "emulated_textures/compressed_image_info.h" #include "emulated_textures/gpu_decompression_pipeline.h" @@ -1986,36 +1987,37 @@ class VkDecoderGlobalState::Impl { auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice); auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice); - bool shouldPassthrough = !m_vkEmulation->isYcbcrEmulationEnabled(); -#if defined(__APPLE__) - shouldPassthrough = shouldPassthrough && !(m_vkEmulation->getExternalMemoryMode() == - ExternalMemory::Mode::Metal); -#endif + // Start with host extensions: + std::vector properties; + VkResult result = + enumerateDeviceExtensionProperties(vk, physicalDevice, pLayerName, properties); + if (result != VK_SUCCESS) { + GFXSTREAM_ERROR("Failed to query host device extensions."); + return result; + } + + // Remove all extensions that are not supported by the host codegen to prevent + // guest to host compatibility issues: + const auto& supportedDeviceExtensions = GetDeviceExtensionsSupportedByCodegen(); + properties.erase( + std::remove_if(properties.begin(), properties.end(), + [&](const VkExtensionProperties& extension) { + return supportedDeviceExtensions.find(extension.extensionName) == + supportedDeviceExtensions.end(); + }), + properties.end()); + + // Add in emulated extensions: #if defined(_WIN32) // Temporary fix to get old system images working with lavapipe // TODO(b/409769371): remove this once system images updated or win32 extension is supported const bool advertiseHostAllocAsWin32 = (m_vkEmulation->getExternalMemoryMode() == ExternalMemory::Mode::HostAllocation); - if (advertiseHostAllocAsWin32) { - shouldPassthrough = false; - } #endif - if (shouldPassthrough) { - return vk->vkEnumerateDeviceExtensionProperties(physicalDevice, pLayerName, - pPropertyCount, pProperties); - } - // If MoltenVK is supported on host, we need to ensure that we include // VK_MVK_moltenvk extenstion in returned properties. - std::vector properties; - VkResult result = - enumerateDeviceExtensionProperties(vk, physicalDevice, pLayerName, properties); - if (result != VK_SUCCESS) { - return result; - } - #if defined(__APPLE__) && defined(VK_MVK_moltenvk) // Guest will check for VK_MVK_moltenvk extension for enabling AHB support if ((m_vkEmulation->getExternalMemoryMode() == ExternalMemory::Mode::Metal) &&