def gen_h():
    """Generates the null_driver_gen.h file.
  """
    genfile = os.path.join(os.path.dirname(__file__), '..', 'nulldrv',
                           'null_driver_gen.h')

    with open(genfile, 'w') as f:
        f.write(gencom.copyright_and_warning(2015))

        f.write("""\
#ifndef NULLDRV_NULL_DRIVER_H
#define NULLDRV_NULL_DRIVER_H 1

#include <vulkan/vk_android_native_buffer.h>
#include <vulkan/vulkan.h>

namespace null_driver {

PFN_vkVoidFunction GetGlobalProcAddr(const char* name);
PFN_vkVoidFunction GetInstanceProcAddr(const char* name);

// clang-format off\n""")

        for cmd in gencom.command_list:
            if _is_driver_function(cmd):
                param_list = [''.join(i) for i in gencom.param_dict[cmd]]
                f.write('VKAPI_ATTR ' + gencom.return_type_dict[cmd] + ' ' +
                        gencom.base_name(cmd) + '(' + ', '.join(param_list) +
                        ');\n')

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

}  // namespace null_driver

#endif  // NULLDRV_NULL_DRIVER_H\n""")

        f.close()
    gencom.run_clang_format(genfile)
예제 #2
0
def gen_cpp():
    """Generates the driver_gen.cpp file.
  """
    genfile = os.path.join(os.path.dirname(__file__), '..', 'libvulkan',
                           'driver_gen.cpp')

    with open(genfile, 'w') as f:
        f.write(gencom.copyright_and_warning(2016))
        f.write("""\
#include <log/log.h>
#include <string.h>

#include <algorithm>

#include "driver.h"

namespace vulkan {
namespace driver {

namespace {

// clang-format off\n\n""")

        for cmd in gencom.command_list:
            _define_proc_hook_stub(cmd, f)

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

const ProcHook g_proc_hooks[] = {
    // clang-format off\n""")

        sorted_command_list = sorted(gencom.command_list)
        for cmd in sorted_command_list:
            if _is_intercepted(cmd):
                if gencom.is_globally_dispatched(cmd):
                    _define_global_proc_hook(cmd, f)
                elif gencom.is_instance_dispatched(cmd):
                    _define_instance_proc_hook(cmd, f)
                elif gencom.is_device_dispatched(cmd):
                    _define_device_proc_hook(cmd, f)

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

}  // namespace

const ProcHook* GetProcHook(const char* name) {
    const auto& begin = g_proc_hooks;
    const auto& end =
        g_proc_hooks + sizeof(g_proc_hooks) / sizeof(g_proc_hooks[0]);
    const auto hook = std::lower_bound(
        begin, end, name,
        [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
    return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
}

ProcHook::Extension GetProcHookExtension(const char* name) {
    // clang-format off\n""")

        for ext in _KNOWN_EXTENSIONS:
            f.write(
                gencom.indent(1) + 'if (strcmp(name, \"' + ext +
                '\") == 0) return ProcHook::' + gencom.base_ext_name(ext) +
                ';\n')

        f.write("""\
    // clang-format on
    return ProcHook::EXTENSION_UNKNOWN;
}

#define UNLIKELY(expr) __builtin_expect((expr), 0)

#define INIT_PROC(required, obj, proc)                                 \\
    do {                                                               \\
        data.driver.proc =                                             \\
            reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \\
        if (UNLIKELY(required && !data.driver.proc)) {                 \\
            ALOGE("missing " #obj " proc: vk" #proc);                  \\
            success = false;                                           \\
        }                                                              \\
    } while (0)

#define INIT_PROC_EXT(ext, required, obj, proc) \\
    do {                                        \\
        if (extensions[ProcHook::ext])          \\
            INIT_PROC(required, obj, proc);     \\
    } while (0)

bool InitDriverTable(VkInstance instance,
                     PFN_vkGetInstanceProcAddr get_proc,
                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
    auto& data = GetData(instance);
    bool success = true;

    // clang-format off\n""")

        for cmd in gencom.command_list:
            if _is_instance_driver_table_entry(cmd):
                gencom.init_proc(cmd, f)

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

    return success;
}

bool InitDriverTable(VkDevice dev,
                     PFN_vkGetDeviceProcAddr get_proc,
                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
    auto& data = GetData(dev);
    bool success = true;

    // clang-format off\n""")

        for cmd in gencom.command_list:
            if _is_device_driver_table_entry(cmd):
                gencom.init_proc(cmd, f)

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

    return success;
}

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

        f.close()
    gencom.run_clang_format(genfile)
예제 #3
0
def gen_h():
    """Generates the driver_gen.h file.
  """
    genfile = os.path.join(os.path.dirname(__file__), '..', 'libvulkan',
                           'driver_gen.h')

    with open(genfile, 'w') as f:
        f.write(gencom.copyright_and_warning(2016))

        f.write("""\
#ifndef LIBVULKAN_DRIVER_GEN_H
#define LIBVULKAN_DRIVER_GEN_H

#include <vulkan/vk_android_native_buffer.h>
#include <vulkan/vulkan.h>

#include <bitset>

namespace vulkan {
namespace driver {

struct ProcHook {
    enum Type {
        GLOBAL,
        INSTANCE,
        DEVICE,
    };
    enum Extension {\n""")

        for ext in _KNOWN_EXTENSIONS:
            f.write(gencom.indent(2) + gencom.base_ext_name(ext) + ',\n')

        f.write('\n')
        for version in gencom.version_code_list:
            f.write(gencom.indent(2) + 'EXTENSION_CORE_' + version + ',\n')

        # EXTENSION_COUNT must be the next enum after the highest API version.
        f.write("""\
        EXTENSION_COUNT,
        EXTENSION_UNKNOWN,
    };

    const char* name;
    Type type;
    Extension extension;

    PFN_vkVoidFunction proc;
    PFN_vkVoidFunction checked_proc;  // always nullptr for non-device hooks
};

struct InstanceDriverTable {
    // clang-format off\n""")

        for cmd in gencom.command_list:
            if _is_instance_driver_table_entry(cmd):
                f.write(
                    gencom.indent(1) + 'PFN_' + cmd + ' ' +
                    gencom.base_name(cmd) + ';\n')

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

struct DeviceDriverTable {
    // clang-format off\n""")

        for cmd in gencom.command_list:
            if _is_device_driver_table_entry(cmd):
                f.write(
                    gencom.indent(1) + 'PFN_' + cmd + ' ' +
                    gencom.base_name(cmd) + ';\n')

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

const ProcHook* GetProcHook(const char* name);
ProcHook::Extension GetProcHookExtension(const char* name);

bool InitDriverTable(VkInstance instance,
                     PFN_vkGetInstanceProcAddr get_proc,
                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);
bool InitDriverTable(VkDevice dev,
                     PFN_vkGetDeviceProcAddr get_proc,
                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions);

}  // namespace driver
}  // namespace vulkan

#endif  // LIBVULKAN_DRIVER_TABLE_H\n""")

        f.close()
    gencom.run_clang_format(genfile)
def gen_cpp():
    """Generates the driver_gen.cpp file.
  """
    genfile = os.path.join(os.path.dirname(__file__), '..', 'libvulkan',
                           'driver_gen.cpp')

    with open(genfile, 'w') as f:
        f.write(gencom.copyright_and_warning(2016))
        f.write("""\
#include <log/log.h>
#include <string.h>

#include <algorithm>

#include "driver.h"

namespace vulkan {
namespace driver {

namespace {

// clang-format off\n\n""")

        for cmd in gencom.command_list:
            _define_proc_hook_stub(cmd, f)

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

const ProcHook g_proc_hooks[] = {
    // clang-format off\n""")

        sorted_command_list = sorted(gencom.command_list)
        for cmd in sorted_command_list:
            if _is_intercepted(cmd):
                if gencom.is_globally_dispatched(cmd):
                    _define_global_proc_hook(cmd, f)
                elif gencom.is_instance_dispatched(cmd):
                    _define_instance_proc_hook(cmd, f)
                elif gencom.is_device_dispatched(cmd):
                    _define_device_proc_hook(cmd, f)

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

}  // namespace

const ProcHook* GetProcHook(const char* name) {
    auto begin = std::cbegin(g_proc_hooks);
    auto end = std::cend(g_proc_hooks);
    auto hook = std::lower_bound(
        begin, end, name,
        [](const ProcHook& e, const char* n) { return strcmp(e.name, n) < 0; });
    return (hook < end && strcmp(hook->name, name) == 0) ? hook : nullptr;
}

ProcHook::Extension GetProcHookExtension(const char* name) {
    // clang-format off\n""")

        for ext in _KNOWN_EXTENSIONS:
            f.write(
                gencom.indent(1) + 'if (strcmp(name, \"' + ext +
                '\") == 0) return ProcHook::' + gencom.base_ext_name(ext) +
                ';\n')

        f.write("""\
    // clang-format on
    return ProcHook::EXTENSION_UNKNOWN;
}

#define UNLIKELY(expr) __builtin_expect((expr), 0)

#define INIT_PROC(required, obj, proc)                                 \\
    do {                                                               \\
        data.driver.proc =                                             \\
            reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \\
        if (UNLIKELY(required && !data.driver.proc)) {                 \\
            ALOGE("missing " #obj " proc: vk" #proc);                  \\
            success = false;                                           \\
        }                                                              \\
    } while (0)

#define INIT_PROC_EXT(ext, required, obj, proc) \\
    do {                                        \\
        if (extensions[ProcHook::ext])          \\
            INIT_PROC(required, obj, proc);     \\
    } while (0)

bool InitDriverTable(VkInstance instance,
                     PFN_vkGetInstanceProcAddr get_proc,
                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
    auto& data = GetData(instance);
    bool success = true;

    // clang-format off\n""")

        for cmd in gencom.command_list:
            if _is_instance_driver_table_entry(cmd):
                gencom.init_proc(cmd, f)

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

    return success;
}

bool InitDriverTable(VkDevice dev,
                     PFN_vkGetDeviceProcAddr get_proc,
                     const std::bitset<ProcHook::EXTENSION_COUNT>& extensions) {
    auto& data = GetData(dev);
    bool success = true;

    // clang-format off\n""")

        for cmd in gencom.command_list:
            if _is_device_driver_table_entry(cmd):
                gencom.init_proc(cmd, f)

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

    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""")

        f.close()
    gencom.run_clang_format(genfile)
def gen_cpp():
    """Generates the null_driver_gen.cpp file.
  """
    genfile = os.path.join(os.path.dirname(__file__), '..', 'nulldrv',
                           'null_driver_gen.cpp')

    with open(genfile, 'w') as f:
        f.write(gencom.copyright_and_warning(2015))

        f.write("""\
#include <algorithm>

#include "null_driver_gen.h"

using namespace null_driver;

namespace {

struct NameProc {
    const char* name;
    PFN_vkVoidFunction proc;
};

PFN_vkVoidFunction Lookup(const char* name,
                          const NameProc* begin,
                          const NameProc* end) {
    const auto& entry = std::lower_bound(
        begin, end, name,
        [](const NameProc& e, const char* n) { return strcmp(e.name, n) < 0; });
    if (entry == end || strcmp(entry->name, name) != 0)
        return nullptr;
    return entry->proc;
}

template <size_t N>
PFN_vkVoidFunction Lookup(const char* name, const NameProc (&procs)[N]) {
    return Lookup(name, procs, procs + N);
}

const NameProc kGlobalProcs[] = {
    // clang-format off\n""")

        sorted_command_list = sorted(gencom.command_list)
        for cmd in sorted_command_list:
            if (_is_driver_function(cmd)
                    and gencom.get_dispatch_table_type(cmd) == 'Global'):
                f.write(
                    gencom.indent(1) + '{\"' + cmd +
                    '\", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_'
                    + cmd + '>(' + gencom.base_name(cmd) + '))},\n')

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

const NameProc kInstanceProcs[] = {
    // clang-format off\n""")

        for cmd in sorted_command_list:
            if _is_driver_function(cmd):
                f.write(
                    gencom.indent(1) + '{\"' + cmd +
                    '\", reinterpret_cast<PFN_vkVoidFunction>(static_cast<PFN_'
                    + cmd + '>(' + gencom.base_name(cmd) + '))},\n')

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

}  // namespace

namespace null_driver {

PFN_vkVoidFunction GetGlobalProcAddr(const char* name) {
    return Lookup(name, kGlobalProcs);
}

PFN_vkVoidFunction GetInstanceProcAddr(const char* name) {
    return Lookup(name, kInstanceProcs);
}

}  // namespace null_driver\n""")

        f.close()
    gencom.run_clang_format(genfile)
def gen_h():
    """Generates the api_gen.h file.
  """
    genfile = os.path.join(os.path.dirname(__file__), '..', 'libvulkan',
                           'api_gen.h')

    with open(genfile, 'w') as f:
        instance_dispatch_table_entries = []
        device_dispatch_table_entries = []

        for cmd in gencom.command_list:
            if cmd not in gencom.alias_dict:
                if gencom.is_instance_dispatch_table_entry(cmd):
                    instance_dispatch_table_entries.append(
                        'PFN_' + cmd + ' ' + gencom.base_name(cmd) + ';')
                elif gencom.is_device_dispatch_table_entry(cmd):
                    device_dispatch_table_entries.append(
                        'PFN_' + cmd + ' ' + gencom.base_name(cmd) + ';')

        f.write(gencom.copyright_and_warning(2016))

        f.write("""\
#ifndef LIBVULKAN_API_GEN_H
#define LIBVULKAN_API_GEN_H

#include <vulkan/vulkan.h>

#include <bitset>

#include "driver_gen.h"

namespace vulkan {
namespace api {

struct InstanceDispatchTable {
    // clang-format off\n""")

        for entry in instance_dispatch_table_entries:
            f.write(gencom.indent(1) + entry + '\n')

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

struct DeviceDispatchTable {
    // clang-format off\n""")

        for entry in device_dispatch_table_entries:
            f.write(gencom.indent(1) + entry + '\n')

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

bool InitDispatchTable(
    VkInstance instance,
    PFN_vkGetInstanceProcAddr get_proc,
    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions);
bool InitDispatchTable(
    VkDevice dev,
    PFN_vkGetDeviceProcAddr get_proc,
    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions);

}  // namespace api
}  // namespace vulkan

#endif  // LIBVULKAN_API_GEN_H\n""")

        f.close()
    gencom.run_clang_format(genfile)
def gen_cpp():
    """Generates the api_gen.cpp file.
  """
    genfile = os.path.join(os.path.dirname(__file__), '..', 'libvulkan',
                           'api_gen.cpp')

    with open(genfile, 'w') as f:
        f.write(gencom.copyright_and_warning(2016))

        f.write("""\
#include <log/log.h>
#include <string.h>

#include <algorithm>

// to catch mismatches between vulkan.h and this file
#undef VK_NO_PROTOTYPES
#include "api.h"

namespace vulkan {
namespace api {

#define UNLIKELY(expr) __builtin_expect((expr), 0)

#define INIT_PROC(required, obj, proc)                                 \\
    do {                                                               \\
        data.dispatch.proc =                                           \\
            reinterpret_cast<PFN_vk##proc>(get_proc(obj, "vk" #proc)); \\
        if (UNLIKELY(required && !data.dispatch.proc)) {               \\
            ALOGE("missing " #obj " proc: vk" #proc);                  \\
            success = false;                                           \\
        }                                                              \\
    } while (0)

// Exported extension functions may be invoked even when their extensions
// are disabled.  Dispatch to stubs when that happens.
#define INIT_PROC_EXT(ext, required, obj, proc)  \\
    do {                                         \\
        if (extensions[driver::ProcHook::ext])   \\
            INIT_PROC(required, obj, proc);      \\
        else                                     \\
            data.dispatch.proc = disabled##proc; \\
    } while (0)

namespace {

// clang-format off\n\n""")

        for cmd in gencom.command_list:
            _define_extension_stub(cmd, f)

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

}  // namespace

bool InitDispatchTable(
    VkInstance instance,
    PFN_vkGetInstanceProcAddr get_proc,
    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions) {
    auto& data = GetData(instance);
    bool success = true;

    // clang-format off\n""")

        for cmd in gencom.command_list:
            if gencom.is_instance_dispatch_table_entry(cmd):
                gencom.init_proc(cmd, f)

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

    return success;
}

bool InitDispatchTable(
    VkDevice dev,
    PFN_vkGetDeviceProcAddr get_proc,
    const std::bitset<driver::ProcHook::EXTENSION_COUNT>& extensions) {
    auto& data = GetData(dev);
    bool success = true;

    // clang-format off\n""")

        for cmd in gencom.command_list:
            if gencom.is_device_dispatch_table_entry(cmd):
                gencom.init_proc(cmd, f)

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

    return success;
}

// clang-format off

namespace {

// forward declarations needed by GetInstanceProcAddr and GetDeviceProcAddr
""")

        for cmd in gencom.command_list:
            if gencom.is_function_exported(cmd) and not _is_intercepted(cmd):
                param_list = [''.join(i) for i in gencom.param_dict[cmd]]
                f.write('VKAPI_ATTR ' + gencom.return_type_dict[cmd] + ' ' +
                        gencom.base_name(cmd) + '(' + ', '.join(param_list) +
                        ');\n')

        f.write('\n')
        for cmd in gencom.command_list:
            if gencom.is_function_exported(cmd) and not _is_intercepted(cmd):
                param_list = [''.join(i) for i in gencom.param_dict[cmd]]
                f.write('VKAPI_ATTR ' + gencom.return_type_dict[cmd] + ' ' +
                        gencom.base_name(cmd) + '(' + ', '.join(param_list) +
                        ') {\n')
                if cmd == 'vkGetInstanceProcAddr':
                    _intercept_instance_proc_addr(f)
                elif cmd == 'vkGetDeviceProcAddr':
                    _intercept_device_proc_addr(f)
                _api_dispatch(cmd, f)
                f.write('}\n\n')

        f.write("""
}  // anonymous namespace

// clang-format on

}  // namespace api
}  // namespace vulkan

// clang-format off\n\n""")

        for cmd in gencom.command_list:
            if gencom.is_function_exported(cmd):
                param_list = [''.join(i) for i in gencom.param_dict[cmd]]
                f.write('__attribute__((visibility("default")))\n')
                f.write('VKAPI_ATTR ' + gencom.return_type_dict[cmd] + ' ' +
                        cmd + '(' + ', '.join(param_list) + ') {\n')
                f.write(gencom.indent(1))
                if gencom.return_type_dict[cmd] != 'void':
                    f.write('return ')
                param_list = gencom.param_dict[cmd]
                f.write('vulkan::api::' + gencom.base_name(cmd) + '(' +
                        ', '.join(i[1] for i in param_list) + ');\n}\n\n')

        f.write('// clang-format on\n')
        f.close()
    gencom.run_clang_format(genfile)