[Impeller] make swapchain related external fence/semaphore extensions optional. (#162205)
Fixes https://github.com/flutter/flutter/issues/162088 Since we will always support a fallback to the KHR swapchain on Android, we can make the external fence/semaphore extensions optional.
This commit is contained in:
parent
abd0d16232
commit
95811bd82a
@ -193,20 +193,27 @@ static const char* GetExtensionName(RequiredAndroidDeviceExtensionVK ext) {
|
||||
return VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME;
|
||||
case RequiredAndroidDeviceExtensionVK::kKHRDedicatedAllocation:
|
||||
return VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME;
|
||||
case RequiredAndroidDeviceExtensionVK::kKHRExternalFenceFd:
|
||||
return VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
|
||||
case RequiredAndroidDeviceExtensionVK::kKHRExternalFence:
|
||||
return VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME;
|
||||
case RequiredAndroidDeviceExtensionVK::kKHRExternalSemaphoreFd:
|
||||
return VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
|
||||
case RequiredAndroidDeviceExtensionVK::kKHRExternalSemaphore:
|
||||
return VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME;
|
||||
case RequiredAndroidDeviceExtensionVK::kLast:
|
||||
return "Unknown";
|
||||
}
|
||||
FML_UNREACHABLE();
|
||||
}
|
||||
|
||||
static const char* GetExtensionName(OptionalAndroidDeviceExtensionVK ext) {
|
||||
switch (ext) {
|
||||
case OptionalAndroidDeviceExtensionVK::kKHRExternalFenceFd:
|
||||
return VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME;
|
||||
case OptionalAndroidDeviceExtensionVK::kKHRExternalFence:
|
||||
return VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME;
|
||||
case OptionalAndroidDeviceExtensionVK::kKHRExternalSemaphoreFd:
|
||||
return VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME;
|
||||
case OptionalAndroidDeviceExtensionVK::kKHRExternalSemaphore:
|
||||
return VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME;
|
||||
case OptionalAndroidDeviceExtensionVK::kLast:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static const char* GetExtensionName(OptionalDeviceExtensionVK ext) {
|
||||
switch (ext) {
|
||||
case OptionalDeviceExtensionVK::kEXTPipelineCreationFeedback:
|
||||
@ -549,6 +556,7 @@ bool CapabilitiesVK::SetPhysicalDevice(
|
||||
required_common_device_extensions_.clear();
|
||||
required_android_device_extensions_.clear();
|
||||
optional_device_extensions_.clear();
|
||||
optional_android_device_extensions_.clear();
|
||||
|
||||
std::set<std::string> exts;
|
||||
if (!use_embedder_extensions_) {
|
||||
@ -583,6 +591,14 @@ bool CapabilitiesVK::SetPhysicalDevice(
|
||||
}
|
||||
return true;
|
||||
});
|
||||
IterateExtensions<OptionalAndroidDeviceExtensionVK>(
|
||||
[&](OptionalAndroidDeviceExtensionVK ext) {
|
||||
auto name = GetExtensionName(ext);
|
||||
if (exts.find(name) != exts.end()) {
|
||||
optional_android_device_extensions_.insert(ext);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
supports_texture_fixed_rate_compression_ =
|
||||
@ -602,6 +618,14 @@ bool CapabilitiesVK::SetPhysicalDevice(
|
||||
has_triangle_fans_ =
|
||||
!HasExtension(OptionalDeviceExtensionVK::kVKKHRPortabilitySubset);
|
||||
|
||||
// External Fence/Semaphore for AHB swapchain
|
||||
if (HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalFenceFd) &&
|
||||
HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalFence) &&
|
||||
HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalSemaphore) &&
|
||||
HasExtension(OptionalAndroidDeviceExtensionVK::kKHRExternalSemaphoreFd)) {
|
||||
supports_external_fence_and_semaphore_ = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -695,6 +719,11 @@ bool CapabilitiesVK::HasExtension(OptionalDeviceExtensionVK ext) const {
|
||||
optional_device_extensions_.end();
|
||||
}
|
||||
|
||||
bool CapabilitiesVK::HasExtension(OptionalAndroidDeviceExtensionVK ext) const {
|
||||
return optional_android_device_extensions_.find(ext) !=
|
||||
optional_android_device_extensions_.end();
|
||||
}
|
||||
|
||||
bool CapabilitiesVK::SupportsTextureFixedRateCompression() const {
|
||||
return supports_texture_fixed_rate_compression_;
|
||||
}
|
||||
@ -765,4 +794,8 @@ void CapabilitiesVK::ApplyWorkarounds(const WorkaroundsVK& workarounds) {
|
||||
has_framebuffer_fetch_ = !workarounds.input_attachment_self_dependency_broken;
|
||||
}
|
||||
|
||||
bool CapabilitiesVK::SupportsExternalSemaphoreExtensions() const {
|
||||
return supports_external_fence_and_semaphore_;
|
||||
}
|
||||
|
||||
} // namespace impeller
|
||||
|
@ -81,6 +81,16 @@ enum class RequiredAndroidDeviceExtensionVK : uint32_t {
|
||||
///
|
||||
kKHRDedicatedAllocation,
|
||||
|
||||
kLast,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// @brief A device extension available on some Android platforms.
|
||||
///
|
||||
/// Platform agnostic code can still check if these Android
|
||||
/// extensions are present.
|
||||
///
|
||||
enum class OptionalAndroidDeviceExtensionVK : uint32_t {
|
||||
//----------------------------------------------------------------------------
|
||||
/// For exporting file descriptors from fences to interact with platform APIs.
|
||||
///
|
||||
@ -188,6 +198,8 @@ class CapabilitiesVK final : public Capabilities,
|
||||
|
||||
bool HasExtension(OptionalDeviceExtensionVK ext) const;
|
||||
|
||||
bool HasExtension(OptionalAndroidDeviceExtensionVK ext) const;
|
||||
|
||||
std::optional<std::vector<std::string>> GetEnabledLayers() const;
|
||||
|
||||
std::optional<std::vector<std::string>> GetEnabledInstanceExtensions() const;
|
||||
@ -269,6 +281,10 @@ class CapabilitiesVK final : public Capabilities,
|
||||
///
|
||||
bool SupportsTextureFixedRateCompression() const;
|
||||
|
||||
/// Whether the external fence and semaphore extensions used for AHB support
|
||||
/// are available.
|
||||
bool SupportsExternalSemaphoreExtensions() const;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
/// @brief Get the fixed compression rate supported by the context for
|
||||
/// the given format and usage.
|
||||
@ -292,6 +308,8 @@ class CapabilitiesVK final : public Capabilities,
|
||||
std::set<RequiredCommonDeviceExtensionVK> required_common_device_extensions_;
|
||||
std::set<RequiredAndroidDeviceExtensionVK>
|
||||
required_android_device_extensions_;
|
||||
std::set<OptionalAndroidDeviceExtensionVK>
|
||||
optional_android_device_extensions_;
|
||||
std::set<OptionalDeviceExtensionVK> optional_device_extensions_;
|
||||
mutable PixelFormat default_color_format_ = PixelFormat::kUnknown;
|
||||
PixelFormat default_stencil_format_ = PixelFormat::kUnknown;
|
||||
@ -305,6 +323,7 @@ class CapabilitiesVK final : public Capabilities,
|
||||
bool has_triangle_fans_ = true;
|
||||
bool has_primitive_restart_ = true;
|
||||
bool has_framebuffer_fetch_ = true;
|
||||
bool supports_external_fence_and_semaphore_ = false;
|
||||
bool is_valid_ = false;
|
||||
|
||||
// The embedder.h API is responsible for providing the instance and device
|
||||
|
@ -731,7 +731,9 @@ const std::unique_ptr<DriverInfoVK>& ContextVK::GetDriverInfo() const {
|
||||
}
|
||||
|
||||
bool ContextVK::GetShouldEnableSurfaceControlSwapchain() const {
|
||||
return should_enable_surface_control_;
|
||||
return should_enable_surface_control_ &&
|
||||
CapabilitiesVK::Cast(*device_capabilities_)
|
||||
.SupportsExternalSemaphoreExtensions();
|
||||
}
|
||||
|
||||
RuntimeStageBackend ContextVK::GetRuntimeStageBackend() const {
|
||||
|
@ -354,5 +354,43 @@ TEST(ContextVKTest, BatchSubmitCommandBuffersOnNonArm) {
|
||||
"vkCreateFence") != functions->end());
|
||||
}
|
||||
|
||||
TEST(ContextVKTest, AHBSwapchainCapabilitiesCanBeMissing) {
|
||||
{
|
||||
std::shared_ptr<ContextVK> context =
|
||||
MockVulkanContextBuilder()
|
||||
.SetSettingsCallback([](ContextVK::Settings& settings) {
|
||||
settings.enable_surface_control = true;
|
||||
})
|
||||
.Build();
|
||||
|
||||
EXPECT_FALSE(context->GetShouldEnableSurfaceControlSwapchain());
|
||||
}
|
||||
|
||||
ContextVK::EmbedderData data;
|
||||
auto other_context = MockVulkanContextBuilder().Build();
|
||||
|
||||
data.instance = other_context->GetInstance();
|
||||
data.device = other_context->GetDevice();
|
||||
data.physical_device = other_context->GetPhysicalDevice();
|
||||
data.queue = VkQueue{};
|
||||
data.queue_family_index = 0;
|
||||
data.instance_extensions = {"VK_KHR_surface", "VK_KHR_android_surface"};
|
||||
data.device_extensions = {"VK_KHR_swapchain",
|
||||
VK_KHR_EXTERNAL_FENCE_FD_EXTENSION_NAME,
|
||||
VK_KHR_EXTERNAL_FENCE_EXTENSION_NAME,
|
||||
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
|
||||
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME};
|
||||
|
||||
auto context = MockVulkanContextBuilder()
|
||||
.SetSettingsCallback([](ContextVK::Settings& settings) {
|
||||
settings.enable_surface_control = true;
|
||||
})
|
||||
.SetEmbedderData(data)
|
||||
.Build();
|
||||
|
||||
EXPECT_TRUE(context->GetShouldEnableSurfaceControlSwapchain());
|
||||
|
||||
} // namespace impeller
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
||||
|
Loading…
x
Reference in New Issue
Block a user