tools/spec: redirect to appended device/instance vtables
This commit is contained in:
parent
b8f405c134
commit
7e6e5dc1b1
104
tools/spec.py
104
tools/spec.py
@ -220,6 +220,9 @@ class bitmask(type):
|
|||||||
|
|
||||||
|
|
||||||
class handle(type):
|
class handle(type):
|
||||||
|
parents: List[str]
|
||||||
|
type: str
|
||||||
|
|
||||||
def __init__(self, node):
|
def __init__(self, node):
|
||||||
assert node.tag == 'type'
|
assert node.tag == 'type'
|
||||||
assert node.attrib['category'] == 'handle'
|
assert node.attrib['category'] == 'handle'
|
||||||
@ -229,7 +232,11 @@ class handle(type):
|
|||||||
|
|
||||||
super().__init__(name, depends=[type])
|
super().__init__(name, depends=[type])
|
||||||
self.type = type
|
self.type = type
|
||||||
self.parent = node.attrib.get('parent', None)
|
|
||||||
|
parents = node.attrib.get('parent', None)
|
||||||
|
self.parents = parents.split(',') if parents else []
|
||||||
|
|
||||||
|
assert type
|
||||||
|
|
||||||
def declare(self):
|
def declare(self):
|
||||||
return "struct %(name)s_t; using %(name)s = %(name)s_t*;" % {
|
return "struct %(name)s_t; using %(name)s = %(name)s_t*;" % {
|
||||||
@ -244,12 +251,18 @@ class handle(type):
|
|||||||
assert name
|
assert name
|
||||||
assert reg
|
assert reg
|
||||||
|
|
||||||
if not self.parent:
|
if self.name == name:
|
||||||
return False
|
|
||||||
if self.parent == name:
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return reg.types[self.parent].has_parent(name, reg)
|
if not self.parents:
|
||||||
|
return False
|
||||||
|
if name in self.parents:
|
||||||
|
return True
|
||||||
|
|
||||||
|
for p in self.parents:
|
||||||
|
if reg.types[p].has_parent(name, reg):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class enum(type):
|
class enum(type):
|
||||||
@ -432,7 +445,7 @@ class command(type):
|
|||||||
self.depends += p.depends
|
self.depends += p.depends
|
||||||
|
|
||||||
def declare(self):
|
def declare(self):
|
||||||
return "%(result)s %(name)s (%(params)s) noexcept;" % {
|
return 'extern "C" %(result)s %(name)s (%(params)s) noexcept;' % {
|
||||||
'name': rename(self.name),
|
'name': rename(self.name),
|
||||||
'result': self.result,
|
'result': self.result,
|
||||||
'params': ", ".join(p.param for p in self.params)
|
'params': ", ".join(p.param for p in self.params)
|
||||||
@ -773,13 +786,45 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
with open(args.dst, 'w') as dst:
|
with open(args.dst, 'w') as dst:
|
||||||
dst.write("#pragma once\n")
|
dst.write("#pragma once\n")
|
||||||
dst.write('extern "C" {\n')
|
|
||||||
for obj in q:
|
for obj in q:
|
||||||
dst.write(obj.declare())
|
dst.write(obj.declare())
|
||||||
dst.write('\n')
|
dst.write('\n')
|
||||||
dst.write(obj.define(reg))
|
dst.write(obj.define(reg))
|
||||||
dst.write('\n')
|
dst.write('\n')
|
||||||
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:
|
with open(args.icd, 'w') as icd:
|
||||||
commands = [i for i in q if isinstance(i, command)]
|
commands = [i for i in q if isinstance(i, command)]
|
||||||
@ -798,7 +843,7 @@ if __name__ == '__main__':
|
|||||||
#define MAP_DEVICE_COMMANDS(FUNC) MAP0(FUNC,{",".join(i.name for i in device_commands)})
|
#define MAP_DEVICE_COMMANDS(FUNC) MAP0(FUNC,{",".join(i.name for i in device_commands)})
|
||||||
|
|
||||||
namespace cruft::vk::icd {{
|
namespace cruft::vk::icd {{
|
||||||
struct vendor;
|
class vendor;
|
||||||
|
|
||||||
struct func {{
|
struct func {{
|
||||||
void *handle;
|
void *handle;
|
||||||
@ -828,7 +873,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
with open(args.dispatch, 'w') as dispatch:
|
with open(args.dispatch, 'w') as dispatch:
|
||||||
dispatch.write("""
|
dispatch.write("""
|
||||||
#include "vk.hpp"
|
#include "../vk.hpp"
|
||||||
#include "vtable.hpp"
|
#include "vtable.hpp"
|
||||||
|
|
||||||
#include <cruft/util/debug.hpp>
|
#include <cruft/util/debug.hpp>
|
||||||
@ -840,20 +885,37 @@ if __name__ == '__main__':
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
for obj in commands:
|
for obj in commands:
|
||||||
if obj.is_instance(reg):
|
first_arg = reg.types[obj.params[0].type]
|
||||||
table = "i_table"
|
|
||||||
elif obj.is_device(reg):
|
if not isinstance(first_arg, handle):
|
||||||
table = "d_table"
|
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:
|
else:
|
||||||
raise Exception("unhandled command type")
|
raise Exception("Unknown param type")
|
||||||
|
|
||||||
|
|
||||||
dispatch.write(f"""
|
dispatch.write(f"""
|
||||||
extern "C" {obj.result} {rename(obj.name)} ({", ".join(p.param for p in obj.params)}) noexcept {{
|
extern "C" {obj.result} {rename(obj.name)} ({", ".join(p.param for p in obj.params)}) noexcept {{
|
||||||
auto const entry = reinterpret_cast<cruft::vk::icd::func const*> ({obj.params[0].name});
|
using first_arg_t = std::decay_t<decltype({obj.params[0].name})>;
|
||||||
auto const *table = reinterpret_cast<decltype({table})> (entry->table);
|
|
||||||
|
|
||||||
return (table->{obj.name})(
|
if constexpr (is_instance_v<first_arg_t>) {{
|
||||||
reinterpret_cast<decltype({obj.params[0].name})> (entry->handle),
|
auto const entry = reinterpret_cast<cruft::vk::icd::func const*> ({obj.params[0].name});
|
||||||
{", ".join(p.name for p in obj.params[1:])}
|
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