[Impeller] allow newer powervr gpu to use Vulkan. (#165520)

Not to be landed until https://github.com/flutter/flutter/pull/165497
lands.

We don't both to parse the model number until CXT and DXT as all prior
models shouldn't be used.
This commit is contained in:
Jonah Williams 2025-03-28 11:08:08 -07:00 committed by GitHub
parent 7cfaf04fa9
commit 5e18e591dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 84 additions and 15 deletions

View File

@ -345,13 +345,13 @@ TEST(ContextVKTest, BatchSubmitCommandBuffersOnNonArm) {
EXPECT_TRUE(context->EnqueueCommandBuffer(context->CreateCommandBuffer()));
EXPECT_TRUE(context->EnqueueCommandBuffer(context->CreateCommandBuffer()));
// If command buffers are batch not submitted, we should have created them and
// a corresponding fence immediately.
// If command buffers are batched and not submitted, we should have created
// them and a corresponding fence immediately.
auto functions = GetMockVulkanFunctions(context->GetDevice());
EXPECT_TRUE(std::find(functions->begin(), functions->end(),
"vkAllocateCommandBuffers") != functions->end());
EXPECT_TRUE(std::find(functions->begin(), functions->end(),
"vkCreateFence") != functions->end());
EXPECT_FALSE(std::find(functions->begin(), functions->end(),
"vkCreateFence") != functions->end());
}
TEST(ContextVKTest, AHBSwapchainCapabilitiesCanBeMissing) {

View File

@ -119,6 +119,17 @@ AdrenoGPU GetAdrenoVersion(std::string_view version) {
return result->second;
}
PowerVRGPU GetPowerVRVersion(std::string_view version) {
// We don't really care about the specific model, just the series.
if (version.find("DXT") != std::string::npos) {
return PowerVRGPU::kDXT;
}
if (version.find("CXT") != std::string::npos) {
return PowerVRGPU::kCXT;
}
return PowerVRGPU::kUnknown;
}
MaliGPU GetMaliVersion(std::string_view version) {
// These names are usually Mali-VERSION or Mali-Version-EXTRA_CRAP.
auto dash_pos = version.find("Mali-");
@ -264,6 +275,9 @@ DriverInfoVK::DriverInfoVK(const vk::PhysicalDevice& device) {
case VendorVK::kARM:
mali_gpu_ = GetMaliVersion(driver_name_);
break;
case VendorVK::kPowerVR:
powervr_gpu_ = GetPowerVRVersion(driver_name_);
break;
default:
break;
}
@ -356,7 +370,7 @@ bool DriverInfoVK::IsKnownBadDriver() const {
// https://github.com/flutter/flutter/issues/160866
// https://github.com/flutter/flutter/issues/160804
// https://github.com/flutter/flutter/issues/160406
if (vendor_ == VendorVK::kImgTec) {
if (powervr_gpu_.has_value() && powervr_gpu_.value() < PowerVRGPU::kCXT) {
return true;
}
return false;
@ -370,4 +384,8 @@ std::optional<AdrenoGPU> DriverInfoVK::GetAdrenoGPUInfo() const {
return adreno_gpu_;
}
std::optional<PowerVRGPU> DriverInfoVK::GetPowerVRGPUInfo() const {
return powervr_gpu_;
}
} // namespace impeller

View File

@ -108,6 +108,26 @@ enum class MaliGPU {
kUnknown,
};
// Ordered by approximate release date. We currently don't attempt to
// parse the exact power VR GPU variant so newer names will fall back
// to OpenGL. This is acceptable for now.
enum class PowerVRGPU {
kUnknown,
// Not good.
kRogue,
// Vulkan may work, but not tested.
kAXE,
kAXM,
kAXT,
kBXE,
kBXM,
kBXS,
kBXT,
// First good vulkan drivers.
kCXT,
kDXT,
};
enum class VendorVK {
kUnknown,
//----------------------------------------------------------------------------
@ -251,6 +271,12 @@ class DriverInfoVK {
///
std::optional<AdrenoGPU> GetAdrenoGPUInfo() const;
//----------------------------------------------------------------------------
/// @brief Returns PowerVR GPU info if this is a PowerVR GPU, otherwise
/// std::nullopt.
///
std::optional<PowerVRGPU> GetPowerVRGPUInfo() const;
private:
bool is_valid_ = false;
Version api_version_;
@ -260,6 +286,7 @@ class DriverInfoVK {
// identified Adreno GPU.
std::optional<AdrenoGPU> adreno_gpu_ = std::nullopt;
std::optional<MaliGPU> mali_gpu_ = std::nullopt;
std::optional<PowerVRGPU> powervr_gpu_ = std::nullopt;
std::string driver_name_;
};

View File

@ -7,6 +7,7 @@
#include "impeller/renderer/backend/vulkan/driver_info_vk.h"
#include "impeller/renderer/backend/vulkan/surface_context_vk.h"
#include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"
#include "impeller/renderer/backend/vulkan/workarounds_vk.h"
namespace impeller::testing {
@ -250,15 +251,40 @@ TEST(DriverInfoVKTest, DisableOldXclipseDriver) {
EXPECT_FALSE(context->GetDriverInfo()->IsKnownBadDriver());
}
TEST(DriverInfoVKTest, AllPowerVRDisabled) {
auto const context =
TEST(DriverInfoVKTest, OldPowerVRDisabled) {
std::shared_ptr<ContextVK> context =
MockVulkanContextBuilder()
.SetPhysicalPropertiesCallback(
[](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
prop->vendorID = 0x1010;
prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
std::string name = "PowerVR Rogue GE8320";
name.copy(prop->deviceName, name.size());
})
.Build();
EXPECT_TRUE(context->GetDriverInfo()->IsKnownBadDriver());
EXPECT_EQ(context->GetDriverInfo()->GetPowerVRGPUInfo(),
std::optional<PowerVRGPU>(PowerVRGPU::kUnknown));
}
TEST(DriverInfoVKTest, NewPowerVREnabled) {
std::shared_ptr<ContextVK> context =
MockVulkanContextBuilder()
.SetPhysicalPropertiesCallback(
[](VkPhysicalDevice device, VkPhysicalDeviceProperties* prop) {
prop->vendorID = 0x1010;
prop->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
std::string name = "PowerVR DXT 123";
name.copy(prop->deviceName, name.size());
})
.Build();
EXPECT_FALSE(context->GetDriverInfo()->IsKnownBadDriver());
EXPECT_EQ(context->GetDriverInfo()->GetPowerVRGPUInfo(),
std::optional<PowerVRGPU>(PowerVRGPU::kDXT));
EXPECT_TRUE(GetWorkaroundsFromDriverInfo(*context->GetDriverInfo())
.input_attachment_self_dependency_broken);
}
} // namespace impeller::testing

View File

@ -11,22 +11,18 @@ WorkaroundsVK GetWorkaroundsFromDriverInfo(DriverInfoVK& driver_info) {
WorkaroundsVK workarounds;
const auto& adreno_gpu = driver_info.GetAdrenoGPUInfo();
const auto& mali_gpu = driver_info.GetMaliGPUInfo();
const auto& powervr_gpu = driver_info.GetPowerVRGPUInfo();
workarounds.batch_submit_command_buffer_timeout = true;
if (adreno_gpu.has_value()) {
workarounds.slow_primitive_restart_performance = true;
workarounds.broken_mipmap_generation = true;
if (adreno_gpu.value() <= AdrenoGPU::kAdreno630) {
workarounds.input_attachment_self_dependency_broken = true;
workarounds.batch_submit_command_buffer_timeout = true;
}
if (adreno_gpu.value() >= AdrenoGPU::kAdreno702) {
workarounds.batch_submit_command_buffer_timeout = false;
}
} else if (mali_gpu.has_value()) {
workarounds.batch_submit_command_buffer_timeout = false;
} else if (powervr_gpu.has_value()) {
workarounds.input_attachment_self_dependency_broken = true;
}
return workarounds;
}

View File

@ -25,6 +25,8 @@ struct WorkaroundsVK {
/// On older 600 Series Adreno the input attachment / self dependency
/// cycle for programmable blending is broken.
///
/// Also broken on newer PowerVR.
bool input_attachment_self_dependency_broken = false;
/// Almost all Adreno series GPU (from 600 up to 800) have problems