Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2901c9e authored by Serdar Kocdemir's avatar Serdar Kocdemir
Browse files

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
parent 615c1f39
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -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;
}

+58 −2
Original line number Diff line number Diff line
@@ -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);
    }
}

+8 −0
Original line number Diff line number Diff line
@@ -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());
+17 −0
Original line number Diff line number Diff line
@@ -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;
+9 −0
Original line number Diff line number Diff line
@@ -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
Loading