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

Commit 7cc36a50 authored by Yiwei Zhang's avatar Yiwei Zhang
Browse files

Vulkan: correctly expose Vulkan entry points

This change fixes the advertisement of core Vulkan entry points as below:
1. GIPA returns a valid checked_proc for 1.1 core device APIs.
2. GDPA returns NULL for 1.1 core device APIs on a 1.0 physical device.

Bug: 134185757
Bug: 142266108
Test: dEQP-VK.memory.binding on 1.1 loader and 1.0 device ICD
Test: dEQP-VK.api.info.instance on 1.1 loader and 1.0 instance ICD
Change-Id: I0a3e06dc04bade4f36a7e68ee2f53979c656ee4e
parent aeaa867b
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -519,7 +519,11 @@ LayerChain::LayerChain(bool is_instance,
      get_device_proc_addr_(nullptr),
      driver_extensions_(nullptr),
      driver_extension_count_(0) {
    enabled_extensions_.set(driver::ProcHook::EXTENSION_CORE);
    // advertise the loader supported core Vulkan API version at vulkan::api
    for (uint32_t i = driver::ProcHook::EXTENSION_CORE_1_0;
         i != driver::ProcHook::EXTENSION_COUNT; ++i) {
        enabled_extensions_.set(i);
    }
}

LayerChain::~LayerChain() {
+47 −13
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ class CreateInfoWrapper {

    VkResult Validate();
    void DowngradeApiVersion();
    void UpgradeDeviceCoreApiVersion(uint32_t api_version);

    const std::bitset<ProcHook::EXTENSION_COUNT>& GetHookExtensions() const;
    const std::bitset<ProcHook::EXTENSION_COUNT>& GetHalExtensions() const;
@@ -328,8 +329,12 @@ CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
      physical_dev_(VK_NULL_HANDLE),
      instance_info_(create_info),
      extension_filter_() {
    hook_extensions_.set(ProcHook::EXTENSION_CORE);
    hal_extensions_.set(ProcHook::EXTENSION_CORE);
    // instance core versions need to match the loader api version
    for (uint32_t i = ProcHook::EXTENSION_CORE_1_0;
         i != ProcHook::EXTENSION_COUNT; ++i) {
        hook_extensions_.set(i);
        hal_extensions_.set(i);
    }
}

CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
@@ -340,8 +345,9 @@ CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
      physical_dev_(physical_dev),
      dev_info_(create_info),
      extension_filter_() {
    hook_extensions_.set(ProcHook::EXTENSION_CORE);
    hal_extensions_.set(ProcHook::EXTENSION_CORE);
    // initialize with baseline core API version
    hook_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
    hal_extensions_.set(ProcHook::EXTENSION_CORE_1_0);
}

CreateInfoWrapper::~CreateInfoWrapper() {
@@ -540,7 +546,8 @@ void CreateInfoWrapper::FilterExtension(const char* name) {
            case ProcHook::ANDROID_external_memory_android_hardware_buffer:
            case ProcHook::ANDROID_native_buffer:
            case ProcHook::GOOGLE_display_timing:
            case ProcHook::EXTENSION_CORE:
            case ProcHook::EXTENSION_CORE_1_0:
            case ProcHook::EXTENSION_CORE_1_1:
            case ProcHook::EXTENSION_COUNT:
                // Device and meta extensions. If we ever get here it's a bug in
                // our code. But enumerating them lets us avoid having a default
@@ -588,7 +595,8 @@ void CreateInfoWrapper::FilterExtension(const char* name) {
            case ProcHook::EXT_debug_report:
            case ProcHook::EXT_swapchain_colorspace:
            case ProcHook::ANDROID_native_buffer:
            case ProcHook::EXTENSION_CORE:
            case ProcHook::EXTENSION_CORE_1_0:
            case ProcHook::EXTENSION_CORE_1_1:
            case ProcHook::EXTENSION_COUNT:
                // Instance and meta extensions. If we ever get here it's a bug
                // in our code. But enumerating them lets us avoid having a
@@ -636,6 +644,31 @@ void CreateInfoWrapper::DowngradeApiVersion() {
    }
}

void CreateInfoWrapper::UpgradeDeviceCoreApiVersion(uint32_t api_version) {
    ALOG_ASSERT(!is_instance_, "Device only API called by instance wrapper.");

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wold-style-cast"
    api_version ^= VK_VERSION_PATCH(api_version);
#pragma clang diagnostic pop

    // cap the API version to the loader supported highest version
    if (api_version > VK_API_VERSION_1_1)
        api_version = VK_API_VERSION_1_1;

    switch (api_version) {
        case VK_API_VERSION_1_1:
            hook_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
            hal_extensions_.set(ProcHook::EXTENSION_CORE_1_1);
            [[clang::fallthrough]];
        case VK_API_VERSION_1_0:
            break;
        default:
            ALOGD("Unknown upgrade API version[%u]", api_version);
            break;
    }
}

VKAPI_ATTR void* DefaultAllocate(void*,
                                 size_t size,
                                 size_t alignment,
@@ -771,7 +804,7 @@ PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance, const char* pName) {
                       : nullptr;
            break;
        case ProcHook::DEVICE:
            proc = (hook->extension == ProcHook::EXTENSION_CORE)
            proc = (hook->extension == ProcHook::EXTENSION_CORE_1_0)
                       ? hook->proc
                       : hook->checked_proc;
            break;
@@ -1117,6 +1150,13 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice,
    if (!data)
        return VK_ERROR_OUT_OF_HOST_MEMORY;

    VkPhysicalDeviceProperties properties;
    ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
    instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
                                                     &properties);
    ATRACE_END();

    wrapper.UpgradeDeviceCoreApiVersion(properties.apiVersion);
    data->hook_extensions |= wrapper.GetHookExtensions();

    // call into the driver
@@ -1161,12 +1201,6 @@ VkResult CreateDevice(VkPhysicalDevice physicalDevice,
        return VK_ERROR_INCOMPATIBLE_DRIVER;
    }

    VkPhysicalDeviceProperties properties;
    ATRACE_BEGIN("driver.GetPhysicalDeviceProperties");
    instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
                                                     &properties);
    ATRACE_END();

    if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU) {
        // Log that the app is hitting software Vulkan implementation
        android::GraphicsEnv::getInstance().setTargetStats(
+2 −6
Original line number Diff line number Diff line
@@ -67,9 +67,7 @@ struct InstanceData {
        : opaque_api_data(),
          allocator(alloc),
          driver(),
          get_device_proc_addr(nullptr) {
        hook_extensions.set(ProcHook::EXTENSION_CORE);
    }
          get_device_proc_addr(nullptr) {}

    api::InstanceData opaque_api_data;

@@ -89,9 +87,7 @@ struct DeviceData {
        : opaque_api_data(),
          allocator(alloc),
          debug_report_callbacks(debug_report_callbacks_),
          driver() {
        hook_extensions.set(ProcHook::EXTENSION_CORE);
    }
          driver() {}

    api::DeviceData opaque_api_data;

+34 −17
Original line number Diff line number Diff line
@@ -74,6 +74,15 @@ VKAPI_ATTR VkResult checkedQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR
    }
}

VKAPI_ATTR VkResult checkedBindImageMemory2(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) {
    if (GetData(device).hook_extensions[ProcHook::EXTENSION_CORE_1_1]) {
        return BindImageMemory2(device, bindInfoCount, pBindInfos);
    } else {
        Logger(device).Err(device, "VK_VERSION_1_1 not enabled. vkBindImageMemory2 not executed.");
        return VK_SUCCESS;
    }
}

VKAPI_ATTR VkResult checkedBindImageMemory2KHR(VkDevice device, uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) {
    if (GetData(device).hook_extensions[ProcHook::KHR_bind_memory2]) {
        return BindImageMemory2KHR(device, bindInfoCount, pBindInfos);
@@ -145,6 +154,14 @@ VKAPI_ATTR VkResult checkedGetPastPresentationTimingGOOGLE(VkDevice device, VkSw
    }
}

VKAPI_ATTR void checkedGetDeviceQueue2(VkDevice device, const VkDeviceQueueInfo2* pQueueInfo, VkQueue* pQueue) {
    if (GetData(device).hook_extensions[ProcHook::EXTENSION_CORE_1_1]) {
        GetDeviceQueue2(device, pQueueInfo, pQueue);
    } else {
        Logger(device).Err(device, "VK_VERSION_1_1 not enabled. vkGetDeviceQueue2 not executed.");
    }
}

// clang-format on

const ProcHook g_proc_hooks[] = {
@@ -173,16 +190,16 @@ const ProcHook g_proc_hooks[] = {
    {
        "vkAllocateCommandBuffers",
        ProcHook::DEVICE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(AllocateCommandBuffers),
        nullptr,
    },
    {
        "vkBindImageMemory2",
        ProcHook::DEVICE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_1,
        reinterpret_cast<PFN_vkVoidFunction>(BindImageMemory2),
        nullptr,
        reinterpret_cast<PFN_vkVoidFunction>(checkedBindImageMemory2),
    },
    {
        "vkBindImageMemory2KHR",
@@ -208,14 +225,14 @@ const ProcHook g_proc_hooks[] = {
    {
        "vkCreateDevice",
        ProcHook::INSTANCE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(CreateDevice),
        nullptr,
    },
    {
        "vkCreateInstance",
        ProcHook::GLOBAL,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(CreateInstance),
        nullptr,
    },
@@ -243,14 +260,14 @@ const ProcHook g_proc_hooks[] = {
    {
        "vkDestroyDevice",
        ProcHook::DEVICE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice),
        nullptr,
    },
    {
        "vkDestroyInstance",
        ProcHook::INSTANCE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance),
        nullptr,
    },
@@ -271,28 +288,28 @@ const ProcHook g_proc_hooks[] = {
    {
        "vkEnumerateDeviceExtensionProperties",
        ProcHook::INSTANCE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties),
        nullptr,
    },
    {
        "vkEnumerateInstanceExtensionProperties",
        ProcHook::GLOBAL,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties),
        nullptr,
    },
    {
        "vkEnumeratePhysicalDeviceGroups",
        ProcHook::INSTANCE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_1,
        reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDeviceGroups),
        nullptr,
    },
    {
        "vkEnumeratePhysicalDevices",
        ProcHook::INSTANCE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(EnumeratePhysicalDevices),
        nullptr,
    },
@@ -313,28 +330,28 @@ const ProcHook g_proc_hooks[] = {
    {
        "vkGetDeviceProcAddr",
        ProcHook::DEVICE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr),
        nullptr,
    },
    {
        "vkGetDeviceQueue",
        ProcHook::DEVICE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue),
        nullptr,
    },
    {
        "vkGetDeviceQueue2",
        ProcHook::DEVICE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_1,
        reinterpret_cast<PFN_vkVoidFunction>(GetDeviceQueue2),
        nullptr,
        reinterpret_cast<PFN_vkVoidFunction>(checkedGetDeviceQueue2),
    },
    {
        "vkGetInstanceProcAddr",
        ProcHook::INSTANCE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr),
        nullptr,
    },
@@ -446,7 +463,7 @@ const ProcHook g_proc_hooks[] = {
    {
        "vkQueueSubmit",
        ProcHook::DEVICE,
        ProcHook::EXTENSION_CORE,
        ProcHook::EXTENSION_CORE_1_0,
        reinterpret_cast<PFN_vkVoidFunction>(QueueSubmit),
        nullptr,
    },
+2 −1
Original line number Diff line number Diff line
@@ -49,7 +49,8 @@ struct ProcHook {
        KHR_bind_memory2,
        KHR_get_physical_device_properties2,

        EXTENSION_CORE,  // valid bit
        EXTENSION_CORE_1_0,
        EXTENSION_CORE_1_1,
        EXTENSION_COUNT,
        EXTENSION_UNKNOWN,
    };
Loading