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

Commit 6d20b3b2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "libvulkan: enable promoted instance extensions for 1.0 icd instance"

parents c6a2f3a4 7c0c07c4
Loading
Loading
Loading
Loading
+44 −13
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ class CreateInfoWrapper {
    };

    VkApplicationInfo application_info_;
    uint32_t sanitized_api_version_;

    ExtensionFilter extension_filter_;

@@ -329,6 +330,7 @@ CreateInfoWrapper::CreateInfoWrapper(const VkInstanceCreateInfo& create_info,
      loader_api_version_(VK_API_VERSION_1_1),
      physical_dev_(VK_NULL_HANDLE),
      instance_info_(create_info),
      sanitized_api_version_(loader_api_version_),
      extension_filter_() {}

CreateInfoWrapper::CreateInfoWrapper(VkPhysicalDevice physical_dev,
@@ -385,10 +387,6 @@ VkResult CreateInfoWrapper::SanitizeApiVersion() {
            hal_extensions_.set(i);
        }

        // If pApplicationInfo is NULL, apiVersion is assumed to be 1.0
        if (!instance_info_.pApplicationInfo)
            return VK_SUCCESS;

        uint32_t icd_api_version = VK_API_VERSION_1_0;
        PFN_vkEnumerateInstanceVersion pfn_enumerate_instance_version =
            reinterpret_cast<PFN_vkEnumerateInstanceVersion>(
@@ -409,8 +407,13 @@ VkResult CreateInfoWrapper::SanitizeApiVersion() {
            return VK_SUCCESS;

        if (icd_api_version < loader_api_version_) {
            sanitized_api_version_ = icd_api_version;

            if (!instance_info_.pApplicationInfo)
                return VK_SUCCESS;

            application_info_ = *instance_info_.pApplicationInfo;
            application_info_.apiVersion = icd_api_version;
            application_info_.apiVersion = sanitized_api_version_;
            instance_info_.pApplicationInfo = &application_info_;
        }
    } else {
@@ -498,15 +501,33 @@ VkResult CreateInfoWrapper::SanitizeExtensions() {
                                     : dev_info_.ppEnabledExtensionNames;
    auto& ext_count = (is_instance_) ? instance_info_.enabledExtensionCount
                                     : dev_info_.enabledExtensionCount;
    if (!ext_count)
        return VK_SUCCESS;

    VkResult result = InitExtensionFilter();
    if (result != VK_SUCCESS)
        return result;

    if (is_instance_ && sanitized_api_version_ < loader_api_version_) {
        for (uint32_t i = 0; i < ext_count; i++) {
            // Upon api downgrade, skip the promoted instance extensions in the
            // first pass to avoid duplicate extensions.
            const std::optional<uint32_t> version =
                GetInstanceExtensionPromotedVersion(ext_names[i]);
            if (version && *version > sanitized_api_version_ &&
                *version <= loader_api_version_)
                continue;

            FilterExtension(ext_names[i]);
        }

        // Enable the required extensions to support core functionalities.
        const auto promoted_extensions = GetPromotedInstanceExtensions(
            sanitized_api_version_, loader_api_version_);
        for (const auto& promoted_extension : promoted_extensions)
            FilterExtension(promoted_extension);
    } else {
        for (uint32_t i = 0; i < ext_count; i++)
            FilterExtension(ext_names[i]);
    }

    // Enable device extensions that contain physical-device commands, so that
    // vkGetInstanceProcAddr will return those physical-device commands.
@@ -571,10 +592,20 @@ VkResult CreateInfoWrapper::InitExtensionFilter() {
    filter.ext_count = count;

    // allocate name array
    uint32_t enabled_ext_count = (is_instance_)
                                     ? instance_info_.enabledExtensionCount
                                     : dev_info_.enabledExtensionCount;
    if (is_instance_) {
        uint32_t enabled_ext_count = instance_info_.enabledExtensionCount;

        // It requires enabling additional promoted extensions to downgrade api,
        // so we reserve enough space here.
        if (sanitized_api_version_ < loader_api_version_) {
            enabled_ext_count += CountPromotedInstanceExtensions(
                sanitized_api_version_, loader_api_version_);
        }

        count = std::min(filter.ext_count, enabled_ext_count);
    } else {
        count = std::min(filter.ext_count, dev_info_.enabledExtensionCount);
    }
    filter.names = reinterpret_cast<const char**>(allocator_.pfnAllocation(
        allocator_.pUserData, sizeof(const char*) * count, alignof(const char*),
        VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
+48 −0
Original line number Diff line number Diff line
@@ -577,5 +577,53 @@ bool InitDriverTable(VkDevice dev,
    return success;
}

const std::pair<const char*, uint32_t> g_promoted_instance_extensions[] = {
    // clang-format off
    std::make_pair("VK_KHR_device_group_creation", VK_API_VERSION_1_1),
    std::make_pair("VK_KHR_external_fence_capabilities", VK_API_VERSION_1_1),
    std::make_pair("VK_KHR_external_memory_capabilities", VK_API_VERSION_1_1),
    std::make_pair("VK_KHR_external_semaphore_capabilities", VK_API_VERSION_1_1),
    std::make_pair("VK_KHR_get_physical_device_properties2", VK_API_VERSION_1_1),
    // clang-format on
};

std::optional<uint32_t> GetInstanceExtensionPromotedVersion(const char* name) {
    auto begin = std::cbegin(g_promoted_instance_extensions);
    auto end = std::cend(g_promoted_instance_extensions);
    auto iter =
        std::lower_bound(begin, end, name,
                         [](const std::pair<const char*, uint32_t>& e,
                            const char* n) { return strcmp(e.first, n) < 0; });
    return (iter < end && strcmp(iter->first, name) == 0)
               ? std::optional<uint32_t>(iter->second)
               : std::nullopt;
}

uint32_t CountPromotedInstanceExtensions(uint32_t begin_version,
                                         uint32_t end_version) {
    auto begin = std::cbegin(g_promoted_instance_extensions);
    auto end = std::cend(g_promoted_instance_extensions);
    uint32_t count = 0;

    for (auto iter = begin; iter != end; iter++)
        if (iter->second > begin_version && iter->second <= end_version)
            count++;

    return count;
}

std::vector<const char*> GetPromotedInstanceExtensions(uint32_t begin_version,
                                                       uint32_t end_version) {
    auto begin = std::cbegin(g_promoted_instance_extensions);
    auto end = std::cend(g_promoted_instance_extensions);
    std::vector<const char*> extensions;

    for (auto iter = begin; iter != end; iter++)
        if (iter->second > begin_version && iter->second <= end_version)
            extensions.emplace_back(iter->first);

    return extensions;
}

}  // namespace driver
}  // namespace vulkan
+8 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include <vulkan/vulkan.h>

#include <bitset>
#include <optional>
#include <vector>

namespace vulkan {
namespace driver {
@@ -109,6 +111,12 @@ bool InitDriverTable(VkDevice dev,
                     PFN_vkGetDeviceProcAddr get_proc,
                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);

std::optional<uint32_t> GetInstanceExtensionPromotedVersion(const char* name);
uint32_t CountPromotedInstanceExtensions(uint32_t begin_version,
                                         uint32_t end_version);
std::vector<const char*> GetPromotedInstanceExtensions(uint32_t begin_version,
                                                       uint32_t end_version);

}  // namespace driver
}  // namespace vulkan

+56 −0
Original line number Diff line number Diff line
@@ -162,6 +162,8 @@ def gen_h():
#include <vulkan/vulkan.h>

#include <bitset>
#include <optional>
#include <vector>

namespace vulkan {
namespace driver {
@@ -229,6 +231,12 @@ bool InitDriverTable(VkDevice dev,
                     PFN_vkGetDeviceProcAddr get_proc,
                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);

std::optional<uint32_t> GetInstanceExtensionPromotedVersion(const char* name);
uint32_t CountPromotedInstanceExtensions(uint32_t begin_version,
                                         uint32_t end_version);
std::vector<const char*> GetPromotedInstanceExtensions(uint32_t begin_version,
                                                       uint32_t end_version);

}  // namespace driver
}  // namespace vulkan

@@ -539,6 +547,54 @@ bool InitDriverTable(VkDevice dev,
    return success;
}

const std::pair<const char*, uint32_t> g_promoted_instance_extensions[] = {
    // clang-format off\n""")

    for key, value in sorted(gencom.promoted_inst_ext_dict.items()):
      f.write(gencom.indent(1) + 'std::make_pair("' + key + '", ' + value + '),\n')

    f.write("""\
    // clang-format on
};

std::optional<uint32_t> GetInstanceExtensionPromotedVersion(const char* name) {
    auto begin = std::cbegin(g_promoted_instance_extensions);
    auto end = std::cend(g_promoted_instance_extensions);
    auto iter =
        std::lower_bound(begin, end, name,
                         [](const std::pair<const char*, uint32_t>& e,
                            const char* n) { return strcmp(e.first, n) < 0; });
    return (iter < end && strcmp(iter->first, name) == 0)
               ? std::optional<uint32_t>(iter->second)
               : std::nullopt;
}

uint32_t CountPromotedInstanceExtensions(uint32_t begin_version,
                                         uint32_t end_version) {
    auto begin = std::cbegin(g_promoted_instance_extensions);
    auto end = std::cend(g_promoted_instance_extensions);
    uint32_t count = 0;

    for (auto iter = begin; iter != end; iter++)
        if (iter->second > begin_version && iter->second <= end_version)
            count++;

    return count;
}

std::vector<const char*> GetPromotedInstanceExtensions(uint32_t begin_version,
                                                       uint32_t end_version) {
    auto begin = std::cbegin(g_promoted_instance_extensions);
    auto end = std::cend(g_promoted_instance_extensions);
    std::vector<const char*> extensions;

    for (auto iter = begin; iter != end; iter++)
        if (iter->second > begin_version && iter->second <= end_version)
            extensions.emplace_back(iter->first);

    return extensions;
}

}  // namespace driver
}  // namespace vulkan\n""")

+17 −0
Original line number Diff line number Diff line
@@ -97,6 +97,9 @@ version_code_list = []
# Dict for mapping a function to the core Vulkan API version.
version_dict = {}

# Dict for mapping a promoted instance extension to the core Vulkan API version.
promoted_inst_ext_dict = {}


def indent(num):
  """Returns the requested indents.
@@ -183,6 +186,15 @@ def version_code(version):
  return version[11:]


def version_2_api_version(version):
  """Returns the api version from a version string.

  Args:
    version: Vulkan version string.
  """
  return 'VK_API' + version[2:]


def is_function_supported(cmd):
  """Returns true if a function is core or from a supportable extension.

@@ -327,6 +339,7 @@ def parse_vulkan_registry():
  return_type_dict
  version_code_list
  version_dict
  promoted_inst_ext_dict
  """
  registry = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..',
                          'external', 'vulkan-headers', 'registry', 'vk.xml')
@@ -379,6 +392,10 @@ def parse_vulkan_registry():
      apiversion = ''
      if extension.tag == 'extension':
        extname = extension.get('name')
        if (extension.get('type') == 'instance' and
            extension.get('promotedto') is not None):
          promoted_inst_ext_dict[extname] = \
              version_2_api_version(extension.get('promotedto'))
        for req in extension:
          if req.get('feature') is not None:
            apiversion = req.get('feature')