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

Commit d2aa3ab0 authored by Cody Northrop's avatar Cody Northrop
Browse files

Rootless GPU Debug

Add the ability to load GPU debug layers from the base
directory of debuggable applications.

This update concides with changes to framework/base to
control the enabling logic in GraphicsEnvironment.

This commit changes the Vulkan loader to:
* Scan an additional location for debug layers.
* Use the provided order of layers from GraphicsEnvironment,
  overriding system properties.
* Use the first instance of a layer found, in the case of duplicates.
* Move layers paths and namespace to GraphicsEnv, removing vulkan_loader_data

Bug: 63708377
Test: Manual, CTS tests to follow

Change-Id: I38dc91bbc26671f5093ee1b12454fc024c0b5892
parent 81be9993
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@

#include <log/log.h>
#include <nativeloader/dlext_namespaces.h>
#include <nativeloader/native_loader.h>

// TODO(b/37049319) Get this from a header once one exists
extern "C" {
@@ -45,6 +46,32 @@ void GraphicsEnv::setDriverPath(const std::string path) {
    mDriverPath = path;
}

void GraphicsEnv::setLayerPaths(android_namespace_t* appNamespace, const std::string layerPaths) {
    if (mLayerPaths.empty()) {
        mLayerPaths = layerPaths;
        mAppNamespace = appNamespace;
    } else {
        ALOGV("Vulkan layer search path already set, not clobbering with '%s' for namespace %p'",
                layerPaths.c_str(), appNamespace);
    }
}

android_namespace_t* GraphicsEnv::getAppNamespace() {
    return mAppNamespace;
}

const std::string GraphicsEnv::getLayerPaths(){
    return mLayerPaths;
}

const std::string GraphicsEnv::getDebugLayers() {
    return mDebugLayers;
}

void GraphicsEnv::setDebugLayers(const std::string layers) {
    mDebugLayers = layers;
}

android_namespace_t* GraphicsEnv::getDriverNamespace() {
    static std::once_flag once;
    std::call_once(once, [this]() {
+10 −0
Original line number Diff line number Diff line
@@ -35,10 +35,20 @@ public:
    void setDriverPath(const std::string path);
    android_namespace_t* getDriverNamespace();

    void setLayerPaths(android_namespace_t* appNamespace, const std::string layerPaths);
    android_namespace_t* getAppNamespace();
    const std::string getLayerPaths();

    void setDebugLayers(const std::string layers);
    const std::string getDebugLayers();

private:
    GraphicsEnv() = default;
    std::string mDriverPath;
    std::string mDebugLayers;
    std::string mLayerPaths;
    android_namespace_t* mDriverNamespace = nullptr;
    android_namespace_t* mAppNamespace = nullptr;
};

} // namespace android
+0 −33
Original line number Diff line number Diff line
/*
 * Copyright 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef VULKAN_VULKAN_LOADER_DATA_H
#define VULKAN_VULKAN_LOADER_DATA_H

#include <string>

struct android_namespace_t;

namespace vulkan {
    struct LoaderData {
        std::string layer_path;
        android_namespace_t* app_namespace;

        __attribute__((visibility("default"))) static LoaderData& GetInstance();
    };
}

#endif
+0 −1
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@ cc_library_shared {
        "layers_extensions.cpp",
        "stubhal.cpp",
        "swapchain.cpp",
        "vulkan_loader_data.cpp",
    ],

    export_header_lib_headers: ["vulkan_headers"],
+29 −8
Original line number Diff line number Diff line
@@ -29,14 +29,17 @@
#include <new>
#include <utility>

#include <android-base/strings.h>
#include <cutils/properties.h>
#include <log/log.h>

#include <vulkan/vk_layer_interface.h>
#include <graphicsenv/GraphicsEnv.h>
#include "api.h"
#include "driver.h"
#include "layers_extensions.h"


namespace vulkan {
namespace api {

@@ -121,6 +124,10 @@ class OverrideLayerNames {
        if (!is_instance_ || !driver::Debuggable())
            return;

        GetLayersFromSettings();

        // If no layers specified via Settings, check legacy properties
        if (implicit_layers_.count <= 0) {
            ParseDebugVulkanLayers();
            property_list(ParseDebugVulkanLayer, this);

@@ -131,6 +138,20 @@ class OverrideLayerNames {
                          return (a.priority < b.priority);
                      });
        }
    }

    void GetLayersFromSettings() {
        // These will only be available if conditions are met in GraphicsEnvironemnt
        // gpu_debug_layers = layer1:layer2:layerN
        const std::string layers = android::GraphicsEnv::getInstance().getDebugLayers();
        if (!layers.empty()) {
            ALOGV("Debug layer list: %s", layers.c_str());
            std::vector<std::string> paths = android::base::Split(layers, ":");
            for (uint32_t i = 0; i < paths.size(); i++) {
                AddImplicitLayer(int(i), paths[i].c_str(), paths[i].length());
            }
        }
    }

    void ParseDebugVulkanLayers() {
        // debug.vulkan.layers specifies colon-separated layer names
Loading