tools/spec: split the output code into subsections
This commit is contained in:
parent
504cd3946e
commit
05867df536
316
tools/spec.py
316
tools/spec.py
@ -715,6 +715,171 @@ def parse_extensions(reg:registry, root):
|
|||||||
reg.extensions[name] = extension(node)
|
reg.extensions[name] = extension(node)
|
||||||
|
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
def write_header(path:str, q):
|
||||||
|
with open(path, 'w') as dst:
|
||||||
|
dst.write("#pragma once\n")
|
||||||
|
|
||||||
|
# Write the declarations and definitions for all types.
|
||||||
|
for obj in q:
|
||||||
|
dst.write(obj.declare())
|
||||||
|
dst.write('\n')
|
||||||
|
dst.write(obj.define(reg))
|
||||||
|
dst.write('\n')
|
||||||
|
|
||||||
|
|
||||||
|
# Define the default case for device and instance type traits.
|
||||||
|
dst.write("""
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
/// A type trait that tests if a Vulkan type is an instance type
|
||||||
|
template <typename NativeT>
|
||||||
|
struct is_instance:
|
||||||
|
public std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
/// A type trait that tests if a Vulkan type is a device type
|
||||||
|
template <typename NativeT>
|
||||||
|
struct is_device:
|
||||||
|
public std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr auto is_instance_v = is_instance<T>::value;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr auto is_device_v = is_device<T>::value;
|
||||||
|
""")
|
||||||
|
|
||||||
|
# Specialise traits for device and instance types.
|
||||||
|
for obj in q:
|
||||||
|
if not isinstance(obj,handle):
|
||||||
|
continue
|
||||||
|
|
||||||
|
device_value = "true_type" if obj.has_parent("VkDevice", reg) else "false_type"
|
||||||
|
instance_value = "true_type" if obj.has_parent("VkInstance", reg) else "false_type"
|
||||||
|
|
||||||
|
dst.write(f"""
|
||||||
|
template <> struct is_instance<{obj.name}>: public std::{instance_value} {{ }};
|
||||||
|
template <> struct is_device<{obj.name}>: public std::{device_value} {{ }};
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
##-----------------------------------------------------------------------------
|
||||||
|
def write_icd(path:str, q):
|
||||||
|
with open(path, 'w') as icd:
|
||||||
|
commands = [i for i in q if isinstance(i, command)]
|
||||||
|
instance_commands = [i for i in commands if i.is_instance(reg)]
|
||||||
|
device_commands = [i for i in commands if i.is_device(reg)]
|
||||||
|
|
||||||
|
assert len(instance_commands) + len(device_commands) == len(commands)
|
||||||
|
|
||||||
|
icd.write(f"""
|
||||||
|
#include "vk.hpp"
|
||||||
|
|
||||||
|
#include <cruft/util/preprocessor.hpp>
|
||||||
|
|
||||||
|
#define MAP_COMMANDS(FUNC) MAP0(FUNC,{",".join(i.name for i in commands)})
|
||||||
|
#define MAP_INSTANCE_COMMANDS(FUNC) MAP0(FUNC,{",".join(i.name for i in instance_commands)})
|
||||||
|
#define MAP_DEVICE_COMMANDS(FUNC) MAP0(FUNC,{",".join(i.name for i in device_commands)})
|
||||||
|
|
||||||
|
namespace cruft::vk::icd {{
|
||||||
|
class vendor;
|
||||||
|
|
||||||
|
struct func {{
|
||||||
|
void *handle;
|
||||||
|
void const *table;
|
||||||
|
}};
|
||||||
|
|
||||||
|
struct instance_table {{
|
||||||
|
instance_table (vendor &);
|
||||||
|
""")
|
||||||
|
|
||||||
|
for obj in instance_commands:
|
||||||
|
icd.write(f"{obj.result} (*{obj.name}) ({','.join(p.param for p in obj.params)}) = nullptr;\n")
|
||||||
|
|
||||||
|
icd.write("""};
|
||||||
|
|
||||||
|
struct device_table {
|
||||||
|
""")
|
||||||
|
|
||||||
|
for obj in device_commands:
|
||||||
|
icd.write(f"{obj.result} (*{obj.name}) ({','.join(p.param for p in obj.params)}) = nullptr;\n")
|
||||||
|
|
||||||
|
icd.write("""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
##-----------------------------------------------------------------------------
|
||||||
|
def write_dispatch(path:str, q):
|
||||||
|
with open(path, 'w') as dispatch:
|
||||||
|
dispatch.write("""
|
||||||
|
#include "../vk.hpp"
|
||||||
|
#include "vtable.hpp"
|
||||||
|
|
||||||
|
#include "icd/dispatch.hpp"
|
||||||
|
|
||||||
|
#include <cruft/util/debug.hpp>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||||
|
|
||||||
|
static cruft::vk::icd::instance_table const *i_table [[maybe_unused]] = nullptr;
|
||||||
|
static cruft::vk::icd::device_table const *d_table [[maybe_unused]] = nullptr;
|
||||||
|
|
||||||
|
void (*cruft_vk_icdGetInstanceProcAddr) (
|
||||||
|
VkInstance instance,
|
||||||
|
const char* pName
|
||||||
|
) = nullptr;
|
||||||
|
|
||||||
|
void cruft::vk::icd::init (vendor const &impl)
|
||||||
|
{
|
||||||
|
cruft_vk_icdGetInstanceProcAddr = impl.vtable.GetInstanceProc;
|
||||||
|
}
|
||||||
|
|
||||||
|
""")
|
||||||
|
|
||||||
|
for obj in (i for i in q if isinstance(i, command)):
|
||||||
|
first_arg = reg.types[obj.params[0].type]
|
||||||
|
|
||||||
|
if not isinstance(first_arg, handle):
|
||||||
|
dispatch.write(f"""
|
||||||
|
extern "C" {obj.result} {rename(obj.name)} ({", ".join(p.param for p in obj.params)}) noexcept {{
|
||||||
|
unimplemented ();
|
||||||
|
}}""")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if first_arg.has_parent('VkDevice', reg):
|
||||||
|
table = "d_table";
|
||||||
|
elif first_arg.has_parent('VkInstance', reg):
|
||||||
|
table = 'i_table'
|
||||||
|
else:
|
||||||
|
raise Exception("Unknown param type")
|
||||||
|
|
||||||
|
|
||||||
|
dispatch.write(f"""
|
||||||
|
extern "C" {obj.result} {rename(obj.name)} ({", ".join(p.param for p in obj.params)}) noexcept {{
|
||||||
|
using first_arg_t = std::decay_t<decltype({obj.params[0].name})>;
|
||||||
|
|
||||||
|
if constexpr (is_instance_v<first_arg_t>) {{
|
||||||
|
auto const entry = reinterpret_cast<cruft::vk::icd::func const*> ({obj.params[0].name});
|
||||||
|
auto const *table = reinterpret_cast<decltype({table})> (entry->table);
|
||||||
|
|
||||||
|
return (table->{obj.name})(
|
||||||
|
reinterpret_cast<decltype({obj.params[0].name})> (entry->handle)
|
||||||
|
{", ".join([''] + [p.name for p in obj.params[1:]])}
|
||||||
|
);
|
||||||
|
}} else {{
|
||||||
|
unimplemented ();
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
def enqueue_type(name:str, queued:Set[str], types:Dict[str,type]):
|
def enqueue_type(name:str, queued:Set[str], types:Dict[str,type]):
|
||||||
if name in queued:
|
if name in queued:
|
||||||
@ -784,151 +949,6 @@ if __name__ == '__main__':
|
|||||||
extensions = ["VK_KHR_swapchain", "VK_EXT_debug_report", "VK_KHR_external_memory"]
|
extensions = ["VK_KHR_swapchain", "VK_EXT_debug_report", "VK_KHR_external_memory"]
|
||||||
q = reg.serialise(args.platform)
|
q = reg.serialise(args.platform)
|
||||||
|
|
||||||
with open(args.dst, 'w') as dst:
|
write_header(args.dst, q)
|
||||||
dst.write("#pragma once\n")
|
write_icd(args.icd, q)
|
||||||
for obj in q:
|
write_dispatch(args.dispatch, q)
|
||||||
dst.write(obj.declare())
|
|
||||||
dst.write('\n')
|
|
||||||
dst.write(obj.define(reg))
|
|
||||||
dst.write('\n')
|
|
||||||
|
|
||||||
|
|
||||||
dst.write("""
|
|
||||||
#include <type_traits>
|
|
||||||
|
|
||||||
template <typename NativeT>
|
|
||||||
struct is_instance:
|
|
||||||
public std::false_type
|
|
||||||
{};
|
|
||||||
|
|
||||||
template <typename NativeT>
|
|
||||||
struct is_device:
|
|
||||||
public std::false_type
|
|
||||||
{};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
constexpr auto is_instance_v = is_instance<T>::value;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
constexpr auto is_device_v = is_device<T>::value;
|
|
||||||
""")
|
|
||||||
|
|
||||||
for obj in q:
|
|
||||||
if not isinstance(obj,handle):
|
|
||||||
continue
|
|
||||||
|
|
||||||
device_value = "true_type" if obj.has_parent("VkDevice", reg) else "false_type"
|
|
||||||
instance_value = "true_type" if obj.has_parent("VkInstance", reg) else "false_type"
|
|
||||||
|
|
||||||
dst.write(f"""
|
|
||||||
template <> struct is_instance<{obj.name}>: public std::{instance_value} {{ }};
|
|
||||||
template <> struct is_device<{obj.name}>: public std::{device_value} {{ }};
|
|
||||||
""")
|
|
||||||
|
|
||||||
with open(args.icd, 'w') as icd:
|
|
||||||
commands = [i for i in q if isinstance(i, command)]
|
|
||||||
instance_commands = [i for i in commands if i.is_instance(reg)]
|
|
||||||
device_commands = [i for i in commands if i.is_device(reg)]
|
|
||||||
|
|
||||||
assert len(instance_commands) + len(device_commands) == len(commands)
|
|
||||||
|
|
||||||
icd.write(f"""
|
|
||||||
#include "vk.hpp"
|
|
||||||
|
|
||||||
#include <cruft/util/preprocessor.hpp>
|
|
||||||
|
|
||||||
#define MAP_COMMANDS(FUNC) MAP0(FUNC,{",".join(i.name for i in commands)})
|
|
||||||
#define MAP_INSTANCE_COMMANDS(FUNC) MAP0(FUNC,{",".join(i.name for i in instance_commands)})
|
|
||||||
#define MAP_DEVICE_COMMANDS(FUNC) MAP0(FUNC,{",".join(i.name for i in device_commands)})
|
|
||||||
|
|
||||||
namespace cruft::vk::icd {{
|
|
||||||
class vendor;
|
|
||||||
|
|
||||||
struct func {{
|
|
||||||
void *handle;
|
|
||||||
void const *table;
|
|
||||||
}};
|
|
||||||
|
|
||||||
struct instance_table {{
|
|
||||||
instance_table (vendor &);
|
|
||||||
""")
|
|
||||||
|
|
||||||
for obj in instance_commands:
|
|
||||||
icd.write(f"{obj.result} (*{obj.name}) ({','.join(p.param for p in obj.params)}) = nullptr;\n")
|
|
||||||
|
|
||||||
icd.write("""};
|
|
||||||
|
|
||||||
struct device_table {
|
|
||||||
""")
|
|
||||||
|
|
||||||
for obj in device_commands:
|
|
||||||
icd.write(f"{obj.result} (*{obj.name}) ({','.join(p.param for p in obj.params)}) = nullptr;\n")
|
|
||||||
|
|
||||||
icd.write("""
|
|
||||||
};
|
|
||||||
}
|
|
||||||
""")
|
|
||||||
|
|
||||||
|
|
||||||
with open(args.dispatch, 'w') as dispatch:
|
|
||||||
dispatch.write("""
|
|
||||||
#include "../vk.hpp"
|
|
||||||
#include "vtable.hpp"
|
|
||||||
|
|
||||||
#include "icd/dispatch.hpp"
|
|
||||||
|
|
||||||
#include <cruft/util/debug.hpp>
|
|
||||||
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
||||||
|
|
||||||
static cruft::vk::icd::instance_table const *i_table [[maybe_unused]] = nullptr;
|
|
||||||
static cruft::vk::icd::device_table const *d_table [[maybe_unused]] = nullptr;
|
|
||||||
|
|
||||||
void (*cruft_vk_icdGetInstanceProcAddr) (
|
|
||||||
VkInstance instance,
|
|
||||||
const char* pName
|
|
||||||
) = nullptr;
|
|
||||||
|
|
||||||
void cruft::vk::icd::init (vendor const &impl)
|
|
||||||
{
|
|
||||||
cruft_vk_icdGetInstanceProcAddr = impl.vtable.GetInstanceProc;
|
|
||||||
}
|
|
||||||
|
|
||||||
""")
|
|
||||||
|
|
||||||
for obj in commands:
|
|
||||||
first_arg = reg.types[obj.params[0].type]
|
|
||||||
|
|
||||||
if not isinstance(first_arg, handle):
|
|
||||||
dispatch.write(f"""
|
|
||||||
extern "C" {obj.result} {rename(obj.name)} ({", ".join(p.param for p in obj.params)}) noexcept {{
|
|
||||||
unimplemented ();
|
|
||||||
}}""")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if first_arg.has_parent('VkDevice', reg):
|
|
||||||
table = "d_table";
|
|
||||||
elif first_arg.has_parent('VkInstance', reg):
|
|
||||||
table = 'i_table'
|
|
||||||
else:
|
|
||||||
raise Exception("Unknown param type")
|
|
||||||
|
|
||||||
|
|
||||||
dispatch.write(f"""
|
|
||||||
extern "C" {obj.result} {rename(obj.name)} ({", ".join(p.param for p in obj.params)}) noexcept {{
|
|
||||||
using first_arg_t = std::decay_t<decltype({obj.params[0].name})>;
|
|
||||||
|
|
||||||
if constexpr (is_instance_v<first_arg_t>) {{
|
|
||||||
auto const entry = reinterpret_cast<cruft::vk::icd::func const*> ({obj.params[0].name});
|
|
||||||
auto const *table = reinterpret_cast<decltype({table})> (entry->table);
|
|
||||||
|
|
||||||
return (table->{obj.name})(
|
|
||||||
reinterpret_cast<decltype({obj.params[0].name})> (entry->handle)
|
|
||||||
{", ".join([''] + [p.name for p in obj.params[1:]])}
|
|
||||||
);
|
|
||||||
}} else {{
|
|
||||||
unimplemented ();
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
""")
|
|
||||||
|
Loading…
Reference in New Issue
Block a user