mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Impeller] If validations are enabled but not found, still create the VK context. (flutter/engine#45674)
Fixes https://github.com/flutter/flutter/issues/131714
This commit is contained in:
parent
f49eb6e0aa
commit
cf31c43c78
@ -14,11 +14,7 @@ namespace impeller {
|
||||
|
||||
static constexpr const char* kInstanceLayer = "ImpellerInstance";
|
||||
|
||||
CapabilitiesVK::CapabilitiesVK(bool enable_validations)
|
||||
: enable_validations_(enable_validations) {
|
||||
if (enable_validations_) {
|
||||
FML_LOG(INFO) << "Vulkan validations are enabled.";
|
||||
}
|
||||
CapabilitiesVK::CapabilitiesVK(bool enable_validations) {
|
||||
auto extensions = vk::enumerateInstanceExtensionProperties();
|
||||
auto layers = vk::enumerateInstanceLayerProperties();
|
||||
|
||||
@ -42,6 +38,17 @@ CapabilitiesVK::CapabilitiesVK(bool enable_validations)
|
||||
}
|
||||
}
|
||||
|
||||
validations_enabled_ =
|
||||
enable_validations && HasLayer("VK_LAYER_KHRONOS_validation");
|
||||
if (enable_validations && !validations_enabled_) {
|
||||
FML_LOG(ERROR)
|
||||
<< "Requested Impeller context creation with validations but the "
|
||||
"validation layers could not be found. Expect no Vulkan validation "
|
||||
"checks!";
|
||||
}
|
||||
if (validations_enabled_) {
|
||||
FML_LOG(INFO) << "Vulkan validations are enabled.";
|
||||
}
|
||||
is_valid_ = true;
|
||||
}
|
||||
|
||||
@ -52,19 +59,15 @@ bool CapabilitiesVK::IsValid() const {
|
||||
}
|
||||
|
||||
bool CapabilitiesVK::AreValidationsEnabled() const {
|
||||
return enable_validations_;
|
||||
return validations_enabled_;
|
||||
}
|
||||
|
||||
std::optional<std::vector<std::string>> CapabilitiesVK::GetEnabledLayers()
|
||||
const {
|
||||
std::vector<std::string> required;
|
||||
|
||||
if (enable_validations_) {
|
||||
if (!HasLayer("VK_LAYER_KHRONOS_validation")) {
|
||||
VALIDATION_LOG
|
||||
<< "Requested validations but the validation layer was not found.";
|
||||
return std::nullopt;
|
||||
}
|
||||
if (validations_enabled_) {
|
||||
// The presence of this layer is already checked in the ctor.
|
||||
required.push_back("VK_LAYER_KHRONOS_validation");
|
||||
}
|
||||
|
||||
@ -131,7 +134,7 @@ CapabilitiesVK::GetEnabledInstanceExtensions() const {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if (enable_validations_) {
|
||||
if (validations_enabled_) {
|
||||
if (!HasExtension("VK_EXT_debug_utils")) {
|
||||
VALIDATION_LOG << "Requested validations but could not find the "
|
||||
"VK_EXT_debug_utils extension.";
|
||||
|
||||
@ -100,7 +100,7 @@ class CapabilitiesVK final : public Capabilities,
|
||||
PixelFormat GetDefaultDepthStencilFormat() const override;
|
||||
|
||||
private:
|
||||
const bool enable_validations_;
|
||||
bool validations_enabled_ = false;
|
||||
std::map<std::string, std::set<std::string>> exts_;
|
||||
std::set<OptionalDeviceExtensionVK> optional_device_extensions_;
|
||||
mutable PixelFormat default_color_format_ = PixelFormat::kUnknown;
|
||||
|
||||
@ -83,5 +83,13 @@ TEST(ContextVKTest, DeletePipelineLibraryAfterContext) {
|
||||
"vkDestroyDevice") != functions->end());
|
||||
}
|
||||
|
||||
TEST(ContextVKTest, CanCreateContextInAbsenceOfValidationLayers) {
|
||||
// The mocked methods don't report the presence of a validation layer but we
|
||||
// explicitly ask for validation. Context creation should continue anyway.
|
||||
auto context = CreateMockVulkanContext(
|
||||
[](auto& settings) { settings.enable_validation = true; });
|
||||
ASSERT_NE(context, nullptr);
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
||||
|
||||
@ -513,10 +513,14 @@ PFN_vkVoidFunction GetMockVulkanProcAddress(VkInstance instance,
|
||||
|
||||
} // namespace
|
||||
|
||||
std::shared_ptr<ContextVK> CreateMockVulkanContext(void) {
|
||||
ContextVK::Settings settings;
|
||||
std::shared_ptr<ContextVK> CreateMockVulkanContext(
|
||||
const std::function<void(ContextVK::Settings&)>& settings_callback) {
|
||||
auto message_loop = fml::ConcurrentMessageLoop::Create();
|
||||
ContextVK::Settings settings;
|
||||
settings.proc_address_callback = GetMockVulkanProcAddress;
|
||||
if (settings_callback) {
|
||||
settings_callback(settings);
|
||||
}
|
||||
return ContextVK::Create(std::move(settings));
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -15,7 +16,18 @@ namespace testing {
|
||||
std::shared_ptr<std::vector<std::string>> GetMockVulkanFunctions(
|
||||
VkDevice device);
|
||||
|
||||
std::shared_ptr<ContextVK> CreateMockVulkanContext(void);
|
||||
//------------------------------------------------------------------------------
|
||||
/// @brief Create a Vulkan context with Vulkan functions mocked. The caller
|
||||
/// is given a chance to tinker on the settings right before a
|
||||
/// context is created.
|
||||
///
|
||||
/// @param[in] settings_callback The settings callback
|
||||
///
|
||||
/// @return A context if one can be created.
|
||||
///
|
||||
std::shared_ptr<ContextVK> CreateMockVulkanContext(
|
||||
const std::function<void(ContextVK::Settings&)>& settings_callback =
|
||||
nullptr);
|
||||
|
||||
} // namespace testing
|
||||
} // namespace impeller
|
||||
|
||||
@ -38,14 +38,17 @@ static std::shared_ptr<impeller::Context> CreateImpellerContext(
|
||||
settings.cache_directory = fml::paths::GetCachesDirectory();
|
||||
settings.enable_validation = enable_vulkan_validation;
|
||||
|
||||
if (settings.enable_validation) {
|
||||
auto context = impeller::ContextVK::Create(std::move(settings));
|
||||
|
||||
if (context && impeller::CapabilitiesVK::Cast(*context->GetCapabilities())
|
||||
.AreValidationsEnabled()) {
|
||||
FML_LOG(ERROR) << "Using the Impeller rendering backend (Vulkan with "
|
||||
"Validation Layers).";
|
||||
} else {
|
||||
FML_LOG(ERROR) << "Using the Impeller rendering backend (Vulkan).";
|
||||
}
|
||||
|
||||
return impeller::ContextVK::Create(std::move(settings));
|
||||
return context;
|
||||
}
|
||||
|
||||
AndroidContextVulkanImpeller::AndroidContextVulkanImpeller(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user