diff options
author | 2022-11-17 00:39:05 +0000 | |
---|---|---|
committer | 2022-12-12 17:21:14 +0000 | |
commit | b2901c9ec5b6e131623170b3ca3b9bd79bb25545 (patch) | |
tree | 9e501b718617a405ffee7fde6e0ac37ed61a1439 | |
parent | 615c1f396ed1f7104f76f249991ef286e53039a8 (diff) |
Adding new Vulkan metrics to GPU Stats
Following fields are added into GpuStatsAppInfo for tracking:
bool createdGlesContext = false;
bool createdVulkanDevice = false;
bool createdVulkanSwapchain = false;
uint32_t vulkanApiVersion = 0;
uint64_t vulkanDeviceFeaturesEnabled = 0;
std::vector<int32_t> vulkanInstanceExtensions = {};
std::vector<int32_t> vulkanDeviceExtensions = {};
Extensions are tracked as 32-bit hashes.
setTargetStatsArray GPU service function added to provide
an array of stat values, used for reporting list of extensions.
Bug: b/244286661
Test: adb shell dumpsys gpu
Test: atest GpuStatsTest
Change-Id: I4ae4e3b687cd6274a9b4127a336dd0f91f5f9e39
-rw-r--r-- | libs/graphicsenv/GpuStatsInfo.cpp | 32 | ||||
-rw-r--r-- | libs/graphicsenv/GraphicsEnv.cpp | 60 | ||||
-rw-r--r-- | libs/graphicsenv/IGpuService.cpp | 8 | ||||
-rw-r--r-- | libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h | 17 | ||||
-rw-r--r-- | libs/graphicsenv/include/graphicsenv/GraphicsEnv.h | 9 | ||||
-rw-r--r-- | libs/graphicsenv/include/graphicsenv/IGpuService.h | 4 | ||||
-rw-r--r-- | opengl/libs/EGL/egl_platform_entries.cpp | 2 | ||||
-rw-r--r-- | services/gpuservice/GpuService.cpp | 6 | ||||
-rw-r--r-- | services/gpuservice/GpuService.h | 3 | ||||
-rw-r--r-- | services/gpuservice/gpustats/GpuStats.cpp | 91 | ||||
-rw-r--r-- | services/gpuservice/gpustats/include/gpustats/GpuStats.h | 5 | ||||
-rw-r--r-- | services/gpuservice/tests/unittests/GpuStatsTest.cpp | 107 | ||||
-rw-r--r-- | vulkan/libvulkan/driver.cpp | 80 | ||||
-rw-r--r-- | vulkan/libvulkan/swapchain.cpp | 4 |
14 files changed, 410 insertions, 18 deletions
diff --git a/libs/graphicsenv/GpuStatsInfo.cpp b/libs/graphicsenv/GpuStatsInfo.cpp index 858739c9dd..7b7421424d 100644 --- a/libs/graphicsenv/GpuStatsInfo.cpp +++ b/libs/graphicsenv/GpuStatsInfo.cpp @@ -89,6 +89,14 @@ status_t GpuStatsAppInfo::writeToParcel(Parcel* parcel) const { if ((status = parcel->writeBool(falsePrerotation)) != OK) return status; if ((status = parcel->writeBool(gles1InUse)) != OK) return status; if ((status = parcel->writeBool(angleInUse)) != OK) return status; + if ((status = parcel->writeBool(createdGlesContext)) != OK) return status; + if ((status = parcel->writeBool(createdVulkanDevice)) != OK) return status; + if ((status = parcel->writeBool(createdVulkanSwapchain)) != OK) return status; + if ((status = parcel->writeUint32(vulkanApiVersion)) != OK) return status; + if ((status = parcel->writeUint64(vulkanDeviceFeaturesEnabled)) != OK) return status; + if ((status = parcel->writeInt32Vector(vulkanInstanceExtensions)) != OK) return status; + if ((status = parcel->writeInt32Vector(vulkanDeviceExtensions)) != OK) return status; + return OK; } @@ -103,6 +111,14 @@ status_t GpuStatsAppInfo::readFromParcel(const Parcel* parcel) { if ((status = parcel->readBool(&falsePrerotation)) != OK) return status; if ((status = parcel->readBool(&gles1InUse)) != OK) return status; if ((status = parcel->readBool(&angleInUse)) != OK) return status; + if ((status = parcel->readBool(&createdGlesContext)) != OK) return status; + if ((status = parcel->readBool(&createdVulkanDevice)) != OK) return status; + if ((status = parcel->readBool(&createdVulkanSwapchain)) != OK) return status; + if ((status = parcel->readUint32(&vulkanApiVersion)) != OK) return status; + if ((status = parcel->readUint64(&vulkanDeviceFeaturesEnabled)) != OK) return status; + if ((status = parcel->readInt32Vector(&vulkanInstanceExtensions)) != OK) return status; + if ((status = parcel->readInt32Vector(&vulkanDeviceExtensions)) != OK) return status; + return OK; } @@ -114,6 +130,12 @@ std::string GpuStatsAppInfo::toString() const { StringAppendF(&result, "falsePrerotation = %d\n", falsePrerotation); StringAppendF(&result, "gles1InUse = %d\n", gles1InUse); StringAppendF(&result, "angleInUse = %d\n", angleInUse); + StringAppendF(&result, "createdGlesContext = %d\n", createdGlesContext); + StringAppendF(&result, "createdVulkanDevice = %d\n", createdVulkanDevice); + StringAppendF(&result, "createdVulkanSwapchain = %d\n", createdVulkanSwapchain); + StringAppendF(&result, "vulkanApiVersion = 0x%" PRIx32 "\n", vulkanApiVersion); + StringAppendF(&result, "vulkanDeviceFeaturesEnabled = 0x%" PRIx64 "\n", + vulkanDeviceFeaturesEnabled); result.append("glDriverLoadingTime:"); for (int32_t loadingTime : glDriverLoadingTime) { StringAppendF(&result, " %d", loadingTime); @@ -129,6 +151,16 @@ std::string GpuStatsAppInfo::toString() const { StringAppendF(&result, " %d", loadingTime); } result.append("\n"); + result.append("vulkanInstanceExtensions:"); + for (int32_t extension : vulkanInstanceExtensions) { + StringAppendF(&result, " 0x%x", extension); + } + result.append("\n"); + result.append("vulkanDeviceExtensions:"); + for (int32_t extension : vulkanDeviceExtensions) { + StringAppendF(&result, " 0x%x", extension); + } + result.append("\n"); return result; } diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp index 5f5f85a2ad..46dd62d3bf 100644 --- a/libs/graphicsenv/GraphicsEnv.cpp +++ b/libs/graphicsenv/GraphicsEnv.cpp @@ -259,6 +259,57 @@ void GraphicsEnv::setDriverLoaded(GpuStatsInfo::Api api, bool isDriverLoaded, sendGpuStatsLocked(api, isDriverLoaded, driverLoadingTime); } +// Hash function to calculate hash for null-terminated Vulkan extension names +// We store hash values of the extensions, rather than the actual names or +// indices to be able to support new extensions easily, avoid creating +// a table of 'known' extensions inside Android and reduce the runtime overhead. +static uint64_t calculateExtensionHash(const char* word) { + if (!word) { + return 0; + } + const size_t wordLen = strlen(word); + const uint32_t seed = 167; + uint64_t hash = 0; + for (size_t i = 0; i < wordLen; i++) { + hash = (hash * seed) + word[i]; + } + return hash; +} + +void GraphicsEnv::setVulkanInstanceExtensions(uint32_t enabledExtensionCount, + const char* const* ppEnabledExtensionNames) { + ATRACE_CALL(); + if (enabledExtensionCount == 0 || ppEnabledExtensionNames == nullptr) { + return; + } + + const uint32_t maxNumStats = android::GpuStatsAppInfo::MAX_NUM_EXTENSIONS; + uint64_t extensionHashes[maxNumStats]; + const uint32_t numStats = std::min(enabledExtensionCount, maxNumStats); + for(uint32_t i = 0; i < numStats; i++) { + extensionHashes[i] = calculateExtensionHash(ppEnabledExtensionNames[i]); + } + setTargetStatsArray(android::GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION, + extensionHashes, numStats); +} + +void GraphicsEnv::setVulkanDeviceExtensions(uint32_t enabledExtensionCount, + const char* const* ppEnabledExtensionNames) { + ATRACE_CALL(); + if (enabledExtensionCount == 0 || ppEnabledExtensionNames == nullptr) { + return; + } + + const uint32_t maxNumStats = android::GpuStatsAppInfo::MAX_NUM_EXTENSIONS; + uint64_t extensionHashes[maxNumStats]; + const uint32_t numStats = std::min(enabledExtensionCount, maxNumStats); + for(uint32_t i = 0; i < numStats; i++) { + extensionHashes[i] = calculateExtensionHash(ppEnabledExtensionNames[i]); + } + setTargetStatsArray(android::GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION, + extensionHashes, numStats); +} + static sp<IGpuService> getGpuService() { static const sp<IBinder> binder = defaultServiceManager()->checkService(String16("gpu")); if (!binder) { @@ -276,6 +327,11 @@ bool GraphicsEnv::readyToSendGpuStatsLocked() { } void GraphicsEnv::setTargetStats(const GpuStatsInfo::Stats stats, const uint64_t value) { + return setTargetStatsArray(stats, &value, 1); +} + +void GraphicsEnv::setTargetStatsArray(const GpuStatsInfo::Stats stats, const uint64_t* values, + const uint32_t valueCount) { ATRACE_CALL(); std::lock_guard<std::mutex> lock(mStatsLock); @@ -283,8 +339,8 @@ void GraphicsEnv::setTargetStats(const GpuStatsInfo::Stats stats, const uint64_t const sp<IGpuService> gpuService = getGpuService(); if (gpuService) { - gpuService->setTargetStats(mGpuStats.appPackageName, mGpuStats.driverVersionCode, stats, - value); + gpuService->setTargetStatsArray(mGpuStats.appPackageName, mGpuStats.driverVersionCode, + stats, values, valueCount); } } diff --git a/libs/graphicsenv/IGpuService.cpp b/libs/graphicsenv/IGpuService.cpp index fa25c5516d..ceb52f71d8 100644 --- a/libs/graphicsenv/IGpuService.cpp +++ b/libs/graphicsenv/IGpuService.cpp @@ -61,6 +61,14 @@ public: remote()->transact(BnGpuService::SET_TARGET_STATS, data, &reply, IBinder::FLAG_ONEWAY); } + void setTargetStatsArray(const std::string& appPackageName, const uint64_t driverVersionCode, + const GpuStatsInfo::Stats stats, const uint64_t* values, + const uint32_t valueCount) override { + for (uint32_t i = 0; i < valueCount; i++) { + setTargetStats(appPackageName, driverVersionCode, stats, values[i]); + } + } + void setUpdatableDriverPath(const std::string& driverPath) override { Parcel data, reply; data.writeInterfaceToken(IGpuService::getInterfaceDescriptor()); diff --git a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h index 5b513d2a79..47607a0ab9 100644 --- a/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h +++ b/libs/graphicsenv/include/graphicsenv/GpuStatsInfo.h @@ -58,6 +58,9 @@ public: */ class GpuStatsAppInfo : public Parcelable { public: + // This limits the worst case number of extensions to be tracked. + static const uint32_t MAX_NUM_EXTENSIONS = 100; + GpuStatsAppInfo() = default; GpuStatsAppInfo(const GpuStatsAppInfo&) = default; virtual ~GpuStatsAppInfo() = default; @@ -74,6 +77,13 @@ public: bool falsePrerotation = false; bool gles1InUse = false; bool angleInUse = false; + bool createdGlesContext = false; + bool createdVulkanDevice = false; + bool createdVulkanSwapchain = false; + uint32_t vulkanApiVersion = 0; + uint64_t vulkanDeviceFeaturesEnabled = 0; + std::vector<int32_t> vulkanInstanceExtensions = {}; + std::vector<int32_t> vulkanDeviceExtensions = {}; std::chrono::time_point<std::chrono::system_clock> lastAccessTime; }; @@ -101,6 +111,13 @@ public: CPU_VULKAN_IN_USE = 0, FALSE_PREROTATION = 1, GLES_1_IN_USE = 2, + CREATED_GLES_CONTEXT = 3, + CREATED_VULKAN_API_VERSION = 4, + CREATED_VULKAN_DEVICE = 5, + CREATED_VULKAN_SWAPCHAIN = 6, + VULKAN_DEVICE_FEATURES_ENABLED = 7, + VULKAN_INSTANCE_EXTENSION = 8, + VULKAN_DEVICE_EXTENSION = 9, }; GpuStatsInfo() = default; diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h index 73d3196948..b58a6d90fe 100644 --- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h +++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h @@ -71,10 +71,19 @@ public: const std::string& appPackageName, const int32_t vulkanVersion); // Set stats for target GpuStatsInfo::Stats type. void setTargetStats(const GpuStatsInfo::Stats stats, const uint64_t value = 0); + // Set array of stats for target GpuStatsInfo::Stats type. + void setTargetStatsArray(const GpuStatsInfo::Stats stats, const uint64_t* values, + const uint32_t valueCount); // Set which driver is intended to load. void setDriverToLoad(GpuStatsInfo::Driver driver); // Set which driver is actually loaded. void setDriverLoaded(GpuStatsInfo::Api api, bool isDriverLoaded, int64_t driverLoadingTime); + // Set which instance extensions are enabled for the app. + void setVulkanInstanceExtensions(uint32_t enabledExtensionCount, + const char* const* ppEnabledExtensionNames); + // Set which device extensions are enabled for the app. + void setVulkanDeviceExtensions(uint32_t enabledExtensionCount, + const char* const* ppEnabledExtensionNames); /* * Api for Vk/GL layer injection. Presently, drivers enable certain diff --git a/libs/graphicsenv/include/graphicsenv/IGpuService.h b/libs/graphicsenv/include/graphicsenv/IGpuService.h index 2d59fa0165..b708b0fec0 100644 --- a/libs/graphicsenv/include/graphicsenv/IGpuService.h +++ b/libs/graphicsenv/include/graphicsenv/IGpuService.h @@ -42,6 +42,10 @@ public: // set target stats. virtual void setTargetStats(const std::string& appPackageName, const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats, const uint64_t value = 0) = 0; + virtual void setTargetStatsArray(const std::string& appPackageName, + const uint64_t driverVersionCode, + const GpuStatsInfo::Stats stats, const uint64_t* values, + const uint32_t valueCount) = 0; // setter and getter for updatable driver path. virtual void setUpdatableDriverPath(const std::string& driverPath) = 0; diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp index 7619a5071c..0527c8a45a 100644 --- a/opengl/libs/EGL/egl_platform_entries.cpp +++ b/opengl/libs/EGL/egl_platform_entries.cpp @@ -937,6 +937,8 @@ EGLContext eglCreateContextImpl(EGLDisplay dpy, EGLConfig config, EGLContext sha android::GraphicsEnv::getInstance().setTargetStats( android::GpuStatsInfo::Stats::GLES_1_IN_USE); } + android::GraphicsEnv::getInstance().setTargetStats( + android::GpuStatsInfo::Stats::CREATED_GLES_CONTEXT); egl_context_t* c = new egl_context_t(dpy, context, config, cnx, version); return c; } diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp index 7b9782f4e8..aaa8c18508 100644 --- a/services/gpuservice/GpuService.cpp +++ b/services/gpuservice/GpuService.cpp @@ -82,6 +82,12 @@ void GpuService::setTargetStats(const std::string& appPackageName, const uint64_ mGpuStats->insertTargetStats(appPackageName, driverVersionCode, stats, value); } +void GpuService::setTargetStatsArray(const std::string& appPackageName, + const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats, + const uint64_t* values, const uint32_t valueCount) { + mGpuStats->insertTargetStatsArray(appPackageName, driverVersionCode, stats, values, valueCount); +} + void GpuService::setUpdatableDriverPath(const std::string& driverPath) { IPCThreadState* ipc = IPCThreadState::self(); const int pid = ipc->getCallingPid(); diff --git a/services/gpuservice/GpuService.h b/services/gpuservice/GpuService.h index d7313d165e..e7e0cba689 100644 --- a/services/gpuservice/GpuService.h +++ b/services/gpuservice/GpuService.h @@ -56,6 +56,9 @@ private: int64_t driverLoadingTime) override; void setTargetStats(const std::string& appPackageName, const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats, const uint64_t value) override; + void setTargetStatsArray(const std::string& appPackageName, + const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats, + const uint64_t* values, const uint32_t valueCount) override; void setUpdatableDriverPath(const std::string& driverPath) override; std::string getUpdatableDriverPath() override; diff --git a/services/gpuservice/gpustats/GpuStats.cpp b/services/gpuservice/gpustats/GpuStats.cpp index d033453dd7..f06a0457d3 100644 --- a/services/gpuservice/gpustats/GpuStats.cpp +++ b/services/gpuservice/gpustats/GpuStats.cpp @@ -175,29 +175,83 @@ void GpuStats::insertDriverStats(const std::string& driverPackageName, void GpuStats::insertTargetStats(const std::string& appPackageName, const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats, - const uint64_t /*value*/) { + const uint64_t value) { + return insertTargetStatsArray(appPackageName, driverVersionCode, stats, &value, 1); +} + +void GpuStats::insertTargetStatsArray(const std::string& appPackageName, + const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats, + const uint64_t* values, const uint32_t valueCount) { ATRACE_CALL(); const std::string appStatsKey = appPackageName + std::to_string(driverVersionCode); std::lock_guard<std::mutex> lock(mLock); registerStatsdCallbacksIfNeeded(); - if (!mAppStats.count(appStatsKey)) { + + const auto foundApp = mAppStats.find(appStatsKey); + if (foundApp == mAppStats.end()) { return; } - switch (stats) { - case GpuStatsInfo::Stats::CPU_VULKAN_IN_USE: - mAppStats[appStatsKey].cpuVulkanInUse = true; - break; - case GpuStatsInfo::Stats::FALSE_PREROTATION: - mAppStats[appStatsKey].falsePrerotation = true; - break; - case GpuStatsInfo::Stats::GLES_1_IN_USE: - mAppStats[appStatsKey].gles1InUse = true; - break; - default: - break; + GpuStatsAppInfo& targetAppStats = foundApp->second; + + if (stats == GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION + || stats == GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION) { + // Handle extension arrays separately as we need to store a unique set of them + // in the stats vector. Storing in std::set<> is not efficient for serialization tasks. + std::vector<int32_t>& targetVec = + (stats == GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION) ? + targetAppStats.vulkanInstanceExtensions : + targetAppStats.vulkanDeviceExtensions; + const bool addAll = (targetVec.size() == 0); + targetVec.reserve(valueCount); + + // Add new extensions into the set + for(uint32_t i = 0; + (i < valueCount) && (targetVec.size() < GpuStatsAppInfo::MAX_NUM_EXTENSIONS); + i++) { + const int32_t extVal = int32_t(values[i] & 0xFFFFFFFF); + if (addAll + || std::find(targetVec.cbegin(), targetVec.cend(), extVal) == targetVec.cend()) { + targetVec.push_back(extVal); + } + } + } + else { + // Handle other type of stats info events + for(uint32_t i = 0; i < valueCount; i++) { + const uint64_t value = values[i]; + switch (stats) { + case GpuStatsInfo::Stats::CPU_VULKAN_IN_USE: + targetAppStats.cpuVulkanInUse = true; + break; + case GpuStatsInfo::Stats::FALSE_PREROTATION: + targetAppStats.falsePrerotation = true; + break; + case GpuStatsInfo::Stats::GLES_1_IN_USE: + targetAppStats.gles1InUse = true; + break; + case GpuStatsInfo::Stats::CREATED_GLES_CONTEXT: + targetAppStats.createdGlesContext = true; + break; + case GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE: + targetAppStats.createdVulkanDevice = true; + break; + case GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION: + targetAppStats.vulkanApiVersion = uint32_t(value & 0xffffffff); + break; + case GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN: + targetAppStats.createdVulkanSwapchain = true; + break; + case GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED: + // Merge all requested feature bits together for this app + targetAppStats.vulkanDeviceFeaturesEnabled |= value; + break; + default: + break; + } + } } } @@ -347,7 +401,14 @@ AStatsManager_PullAtomCallbackReturn GpuStats::pullAppInfoAtom(AStatsEventList* ele.second.cpuVulkanInUse, ele.second.falsePrerotation, ele.second.gles1InUse, - ele.second.angleInUse); + ele.second.angleInUse, + ele.second.createdGlesContext, + ele.second.createdVulkanDevice, + ele.second.createdVulkanSwapchain, + ele.second.vulkanApiVersion, + ele.second.vulkanDeviceFeaturesEnabled, + ele.second.vulkanInstanceExtensions, + ele.second.vulkanDeviceExtensions); } } diff --git a/services/gpuservice/gpustats/include/gpustats/GpuStats.h b/services/gpuservice/gpustats/include/gpustats/GpuStats.h index 2aba651af9..22c64dbc02 100644 --- a/services/gpuservice/gpustats/include/gpustats/GpuStats.h +++ b/services/gpuservice/gpustats/include/gpustats/GpuStats.h @@ -41,11 +41,14 @@ public: // Insert target stats into app stats or potentially global stats as well. void insertTargetStats(const std::string& appPackageName, const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats, const uint64_t value); + void insertTargetStatsArray(const std::string& appPackageName, + const uint64_t driverVersionCode, const GpuStatsInfo::Stats stats, + const uint64_t* values, const uint32_t valueCount); // dumpsys interface void dump(const Vector<String16>& args, std::string* result); // This limits the worst case number of loading times tracked. - static const size_t MAX_NUM_LOADING_TIMES = 50; + static const size_t MAX_NUM_LOADING_TIMES = 16; // Below limits the memory usage of GpuStats to be less than 10KB. This is // the preferred number for statsd while maintaining nice data quality. static const size_t MAX_NUM_APP_RECORDS = 100; diff --git a/services/gpuservice/tests/unittests/GpuStatsTest.cpp b/services/gpuservice/tests/unittests/GpuStatsTest.cpp index 7ea22888f8..4ce533ff7c 100644 --- a/services/gpuservice/tests/unittests/GpuStatsTest.cpp +++ b/services/gpuservice/tests/unittests/GpuStatsTest.cpp @@ -52,6 +52,13 @@ using testing::HasSubstr; #define DRIVER_LOADING_TIME_2 789 #define DRIVER_LOADING_TIME_3 891 +constexpr uint64_t VULKAN_FEATURES_MASK = 0x600D; +constexpr uint32_t VULKAN_API_VERSION = 0x400000; +constexpr int32_t VULKAN_INSTANCE_EXTENSION_1 = 0x1234; +constexpr int32_t VULKAN_INSTANCE_EXTENSION_2 = 0x8765; +constexpr int32_t VULKAN_DEVICE_EXTENSION_1 = 0x9012; +constexpr int32_t VULKAN_DEVICE_EXTENSION_2 = 0x3456; + enum InputCommand : int32_t { DUMP_ALL = 0, DUMP_GLOBAL = 1, @@ -218,6 +225,24 @@ TEST_F(GpuStatsTest, canNotInsertTargetStatsBeforeProperSetup) { GpuStatsInfo::Stats::FALSE_PREROTATION, 0); mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, GpuStatsInfo::Stats::GLES_1_IN_USE, 0); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_GLES_CONTEXT, 0); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION, + VULKAN_API_VERSION); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE, 0); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN, 0); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED, + VULKAN_FEATURES_MASK); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION, + VULKAN_INSTANCE_EXTENSION_1); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION, + VULKAN_DEVICE_EXTENSION_1); EXPECT_TRUE(inputCommand(InputCommand::DUMP_APP).empty()); } @@ -233,10 +258,51 @@ TEST_F(GpuStatsTest, canInsertTargetStatsAfterProperSetup) { GpuStatsInfo::Stats::FALSE_PREROTATION, 0); mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, GpuStatsInfo::Stats::GLES_1_IN_USE, 0); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_GLES_CONTEXT, 0); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION, + VULKAN_API_VERSION); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE, 0); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN, 0); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED, + VULKAN_FEATURES_MASK); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION, + VULKAN_INSTANCE_EXTENSION_1); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION, + VULKAN_INSTANCE_EXTENSION_2); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION, + VULKAN_DEVICE_EXTENSION_1); + mGpuStats->insertTargetStats(APP_PKG_NAME_1, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION, + VULKAN_DEVICE_EXTENSION_2); EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("cpuVulkanInUse = 1")); EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("falsePrerotation = 1")); EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("gles1InUse = 1")); + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdGlesContext = 1")); + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdVulkanDevice = 1")); + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdVulkanSwapchain = 1")); + std::stringstream expectedResult; + expectedResult << "vulkanApiVersion = 0x" << std::hex << VULKAN_API_VERSION; + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str())); + expectedResult.str(""); + expectedResult << "vulkanDeviceFeaturesEnabled = 0x" << std::hex << VULKAN_FEATURES_MASK; + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str())); + expectedResult.str(""); + expectedResult << "vulkanInstanceExtensions: 0x" << std::hex << VULKAN_INSTANCE_EXTENSION_1 + << " 0x" << std::hex << VULKAN_INSTANCE_EXTENSION_2; + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str())); + expectedResult.str(""); + expectedResult << "vulkanDeviceExtensions: 0x" << std::hex << VULKAN_DEVICE_EXTENSION_1 + << " 0x" << std::hex << VULKAN_DEVICE_EXTENSION_2; + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str())); } // Verify we always have the most recently used apps in mAppStats, even when we fill it. @@ -260,11 +326,52 @@ TEST_F(GpuStatsTest, canInsertMoreThanMaxNumAppRecords) { GpuStatsInfo::Stats::FALSE_PREROTATION, 0); mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, GpuStatsInfo::Stats::GLES_1_IN_USE, 0); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_GLES_CONTEXT, 0); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION, + VULKAN_API_VERSION); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE, 0); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN, 0); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED, + VULKAN_FEATURES_MASK); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION, + VULKAN_INSTANCE_EXTENSION_1); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_INSTANCE_EXTENSION, + VULKAN_INSTANCE_EXTENSION_2); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION, + VULKAN_DEVICE_EXTENSION_1); + mGpuStats->insertTargetStats(fullPkgName, BUILTIN_DRIVER_VER_CODE, + GpuStatsInfo::Stats::VULKAN_DEVICE_EXTENSION, + VULKAN_DEVICE_EXTENSION_2); EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(fullPkgName.c_str())); EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("cpuVulkanInUse = 1")); EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("falsePrerotation = 1")); EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("gles1InUse = 1")); + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdGlesContext = 1")); + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdVulkanDevice = 1")); + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr("createdVulkanSwapchain = 1")); + std::stringstream expectedResult; + expectedResult << "vulkanApiVersion = 0x" << std::hex << VULKAN_API_VERSION; + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str())); + expectedResult.str(""); + expectedResult << "vulkanDeviceFeaturesEnabled = 0x" << std::hex << VULKAN_FEATURES_MASK; + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str())); + expectedResult.str(""); + expectedResult << "vulkanInstanceExtensions: 0x" << std::hex << VULKAN_INSTANCE_EXTENSION_1 + << " 0x" << std::hex << VULKAN_INSTANCE_EXTENSION_2; + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str())); + expectedResult.str(""); + expectedResult << "vulkanDeviceExtensions: 0x" << std::hex << VULKAN_DEVICE_EXTENSION_1 + << " 0x" << std::hex << VULKAN_DEVICE_EXTENSION_2; + EXPECT_THAT(inputCommand(InputCommand::DUMP_APP), HasSubstr(expectedResult.str())); } // mAppStats purges GpuStats::APP_RECORD_HEADROOM apps removed everytime it's filled up. diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp index 766451824a..15b637cf17 100644 --- a/vulkan/libvulkan/driver.cpp +++ b/vulkan/libvulkan/driver.cpp @@ -1178,6 +1178,27 @@ VkResult CreateInstance(const VkInstanceCreateInfo* pCreateInfo, return VK_ERROR_INCOMPATIBLE_DRIVER; } + // TODO(b/259516419) avoid getting stats from hwui + // const bool reportStats = (pCreateInfo->pApplicationInfo == nullptr ) + // || (strcmp("android framework", + // pCreateInfo->pApplicationInfo->pEngineName) != 0); + const bool reportStats = true; + if (reportStats) { + // Set stats for Vulkan api version requested with application info + if (pCreateInfo->pApplicationInfo) { + const uint32_t vulkanApiVersion = + pCreateInfo->pApplicationInfo->apiVersion; + android::GraphicsEnv::getInstance().setTargetStats( + android::GpuStatsInfo::Stats::CREATED_VULKAN_API_VERSION, + vulkanApiVersion); + } + + // Update stats for the extensions requested + android::GraphicsEnv::getInstance().setVulkanInstanceExtensions( + pCreateInfo->enabledExtensionCount, + pCreateInfo->ppEnabledExtensionNames); + } + *pInstance = instance; return VK_SUCCESS; @@ -1280,6 +1301,65 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice, *pDevice = dev; + // TODO(b/259516419) avoid getting stats from hwui + const bool reportStats = true; + if (reportStats) { + android::GraphicsEnv::getInstance().setTargetStats( + android::GpuStatsInfo::Stats::CREATED_VULKAN_DEVICE); + + // Set stats for creating a Vulkan device and report features in use + const VkPhysicalDeviceFeatures* pEnabledFeatures = + pCreateInfo->pEnabledFeatures; + if (!pEnabledFeatures) { + // Use features from the chained VkPhysicalDeviceFeatures2 + // structure, if given + const VkPhysicalDeviceFeatures2* features2 = + reinterpret_cast<const VkPhysicalDeviceFeatures2*>( + pCreateInfo->pNext); + while (features2 && + features2->sType != + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2) { + features2 = reinterpret_cast<const VkPhysicalDeviceFeatures2*>( + features2->pNext); + } + if (features2) { + pEnabledFeatures = &features2->features; + } + } + const VkBool32* pFeatures = + reinterpret_cast<const VkBool32*>(pEnabledFeatures); + if (pFeatures) { + // VkPhysicalDeviceFeatures consists of VkBool32 values, go over all + // of them using pointer arithmetic here and save the features in a + // 64-bit bitfield + static_assert( + (sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32)) <= 64, + "VkPhysicalDeviceFeatures has too many elements for bitfield " + "packing"); + static_assert( + (sizeof(VkPhysicalDeviceFeatures) % sizeof(VkBool32)) == 0, + "VkPhysicalDeviceFeatures has invalid size for bitfield " + "packing"); + const int numFeatures = + sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32); + + uint64_t enableFeatureBits = 0; + for (int i = 0; i < numFeatures; i++) { + if (pFeatures[i] != VK_FALSE) { + enableFeatureBits |= (uint64_t(1) << i); + } + } + android::GraphicsEnv::getInstance().setTargetStats( + android::GpuStatsInfo::Stats::VULKAN_DEVICE_FEATURES_ENABLED, + enableFeatureBits); + } + + // Update stats for the extensions requested + android::GraphicsEnv::getInstance().setVulkanDeviceExtensions( + pCreateInfo->enabledExtensionCount, + pCreateInfo->ppEnabledExtensionNames); + } + return VK_SUCCESS; } diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 87b3a89cce..07b6dce26e 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -1533,6 +1533,10 @@ VkResult CreateSwapchainKHR(VkDevice device, android::GpuStatsInfo::Stats::FALSE_PREROTATION); } + // Set stats for creating a Vulkan swapchain + android::GraphicsEnv::getInstance().setTargetStats( + android::GpuStatsInfo::Stats::CREATED_VULKAN_SWAPCHAIN); + surface.swapchain_handle = HandleFromSwapchain(swapchain); *swapchain_handle = surface.swapchain_handle; return VK_SUCCESS; |