Skip to content

Commit 588d429

Browse files
authored
fix: swap app and engine version in vk::ApplicationInfo (flutter#181432)
The driver on PIxel 10 requires Flutter to set the `engine` version to something higher than 1.0. We had previous set the application version without effect. With this change, I see we can get a valid vulkan context. - ran some testing against reported errors (saw none) - compiled and ran wonderous with validation layers (runs) - still researching towards: flutter#179812 > On a pixel 10, the Vulkan engine version must be bumped up past 1.0 and any other additional checks gating Vulkan removed. It must be confirmed that Impeller is able to create a Vulkan context. Pixel 10 gets a Vulkan context with just the engine version bump. > The usual sample applications must render accurately. wonderous and failing code passes and renders correctly > The reduced test cases in the internal doc must be tested. it does. > If testing is successful, the engine version update may be committed. This is necessary for enabling Vulkan on Pixel 10 but not sufficient to ensure stability of newer Vulkan enabled Impeller applications on Pixel 10 devices that have not yet been updated. This PR does that. > Impeller must detect the driver version and self-reject Vulkan on device older than the current Pixel 10 GPU driver version. The IHV reports that a safe conservative driver version is >= 25.1 and any verification must happen on versions past this. Impeller should still base its checks on the driver version that we verify correctness on. What we have today works well and it is not advised to introduce instability for the sake of enabling Vulkan on this device. Done - driver_version appears to be a build number, so monotonically increasing.
1 parent 0c2d316 commit 588d429

3 files changed

Lines changed: 40 additions & 5 deletions

File tree

engine/src/flutter/impeller/renderer/backend/vulkan/context_vk.cc

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@ Context::BackendType ContextVK::GetBackendType() const {
141141
return Context::BackendType::kVulkan;
142142
}
143143

144+
/* version 2.0.0 */
145+
static constexpr uint32_t kImpellerEngineVersion =
146+
VK_MAKE_API_VERSION(0, 2, 0, 0);
147+
144148
void ContextVK::Setup(Settings settings) {
145149
TRACE_EVENT0("impeller", "ContextVK::Setup");
146150

@@ -206,19 +210,18 @@ void ContextVK::Setup(Settings settings) {
206210

207211
vk::ApplicationInfo application_info;
208212

209-
// Use the same encoding macro as vulkan versions, but otherwise application
213+
// Use the same encoding macro as vulkan versions, but otherwise engine
210214
// version is intended to be the version of the Impeller engine. This version
211215
// information, along with the application name below is provided to allow
212216
// IHVs to make optimizations and/or disable functionality based on knowledge
213217
// of the engine version (for example, to work around bugs). We don't tie this
214218
// to the overall Flutter version as that version is not yet defined when the
215-
// engine is compiled. Instead we can manually bump it occassionally.
219+
// engine is compiled. Instead we can manually bump it occasionally.
216220
//
217221
// variant, major, minor, patch
218-
application_info.setApplicationVersion(
219-
VK_MAKE_API_VERSION(0, 2, 0, 0) /*version 2.0.0*/);
222+
application_info.setApplicationVersion(VK_API_VERSION_1_0);
220223
application_info.setApiVersion(VK_API_VERSION_1_1);
221-
application_info.setEngineVersion(VK_API_VERSION_1_0);
224+
application_info.setEngineVersion(kImpellerEngineVersion);
222225
application_info.setPEngineName("Impeller");
223226
application_info.setPApplicationName("Impeller");
224227

engine/src/flutter/impeller/renderer/backend/vulkan/driver_info_vk.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111

1212
#include "flutter/fml/build_config.h"
1313

14+
#ifdef FML_OS_ANDROID
15+
#include <sys/system_properties.h>
16+
#endif // FML_OS_ANDROID
17+
1418
namespace impeller {
1519

1620
namespace {
@@ -117,6 +121,16 @@ constexpr std::array<std::pair<std::string_view, PowerVRGPU>, 6> kGpuSeriesMap =
117121
}};
118122
} // namespace
119123

124+
// Pixel 10 device ID from ANGLE/Chromium source code.
125+
// https://chromium.googlesource.com/chromium/src/+/main/testing/buildbot/buildbot_json_magic_substitutions.py#51
126+
// https://source.chromium.org/chromium/chromium/src/+/main:content/test/gpu/gpu_tests/gpu_integration_test.py;l=1396;drc=6cce000efb9f288a9d51d42c7ab38b38beb5d77c
127+
const uint32_t kPixel10DeviceID = 0x71061212;
128+
// PowerVR 25.1@6794074 - the device_driver_version_ is a packed version number
129+
// which is vendor specific. This appears to be the PowerVR DDK build number.
130+
// https://www.khronos.org/conformance/adopters/conformant-products/opencl#submission_466
131+
// https://vulkan.gpuinfo.org/listreports.php?devicename=Google+Pixel+10&platform=android
132+
const uint32_t kPixel10MinDriverVersion = 6794074; // Corresponds to 25.1
133+
120134
AdrenoGPU GetAdrenoVersion(std::string_view version) {
121135
/// The format that Adreno names follow is "Adreno (TM) VERSION".
122136
auto paren_pos = version.find("Adreno (TM) ");
@@ -269,6 +283,8 @@ DriverInfoVK::DriverInfoVK(const vk::PhysicalDevice& device) {
269283
api_version_ = Version{VK_API_VERSION_MAJOR(props.apiVersion),
270284
VK_API_VERSION_MINOR(props.apiVersion),
271285
VK_API_VERSION_PATCH(props.apiVersion)};
286+
driver_version_ = props.driverVersion;
287+
device_id_ = props.deviceID;
272288
vendor_ = IdentifyVendor(props.vendorID);
273289
if (vendor_ == VendorVK::kUnknown) {
274290
FML_LOG(WARNING) << "Unknown GPU Driver Vendor: " << props.vendorID
@@ -316,6 +332,7 @@ void DriverInfoVK::DumpToLog() const {
316332
std::vector<std::pair<std::string, std::string>> items;
317333
items.emplace_back("Name", driver_name_);
318334
items.emplace_back("API Version", api_version_.ToString());
335+
items.emplace_back("Driver Version", std::to_string(driver_version_));
319336
items.emplace_back("Vendor", VendorToString(vendor_));
320337
items.emplace_back("Device Type", DeviceTypeToString(type_));
321338
items.emplace_back("Is Emulator", std::to_string(IsEmulator()));
@@ -358,6 +375,19 @@ bool DriverInfoVK::IsEmulator() const {
358375
}
359376

360377
bool DriverInfoVK::IsKnownBadDriver() const {
378+
#if FML_OS_ANDROID
379+
// Pixel 10 is identified by the PowerVR vendor and device ID 0x71061212.
380+
// The driver version 25.1 or greater is required - which is device specific
381+
// to 6794074 or greater.
382+
if (vendor_ == VendorVK::kPowerVR && device_id_ == kPixel10DeviceID &&
383+
driver_version_ < kPixel10MinDriverVersion) {
384+
FML_LOG(WARNING) << "Pixel 10 driver version "
385+
<< std::to_string(driver_version_)
386+
<< " is less than 25.1. Blocking Vulkan initialization.";
387+
return true;
388+
}
389+
#endif // FML_OS_ANDROID
390+
361391
// Fall back to OpenGL ES on older Adreno devices that require additional
362392
// workarounds in the Impeller Vulkan back end such as disabling framebuffer
363393
// fetch.

engine/src/flutter/impeller/renderer/backend/vulkan/driver_info_vk.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ class DriverInfoVK {
280280
private:
281281
bool is_valid_ = false;
282282
Version api_version_;
283+
uint32_t driver_version_;
284+
uint32_t device_id_ = 0;
283285
VendorVK vendor_ = VendorVK::kUnknown;
284286
DeviceTypeVK type_ = DeviceTypeVK::kUnknown;
285287
// If the VendorVK is VendorVK::kQualcomm, this will be populated with the

0 commit comments

Comments
 (0)