spec: add initial vtable stubs
This commit is contained in:
parent
11c142f849
commit
26c9c3f70d
@ -32,6 +32,7 @@ add_custom_command (
|
||||
OUTPUT
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/vk.hpp"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/icd/dispatch.cpp"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/icd/vtable.hpp"
|
||||
COMMENT
|
||||
"[spec.py] vk.hpp"
|
||||
COMMAND
|
||||
@ -39,6 +40,7 @@ COMMAND
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/tools/spec.py"
|
||||
"--src" "${CMAKE_CURRENT_SOURCE_DIR}/specs/xml/vk.xml"
|
||||
"--dst" "${CMAKE_CURRENT_BINARY_DIR}/vk.hpp"
|
||||
"--icd" "${CMAKE_CURRENT_BINARY_DIR}/icd/vtable.hpp"
|
||||
"--dispatch" "${CMAKE_CURRENT_BINARY_DIR}/icd/dispatch.cpp"
|
||||
"--platform" "${VK_PLATFORM}"
|
||||
DEPENDS
|
||||
@ -61,6 +63,7 @@ endif()
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
add_library (cruft-vk-icd STATIC
|
||||
${CMAKE_CURRENT_BINARY_DIR}/icd/vtable.hpp
|
||||
${CMAKE_CURRENT_BINARY_DIR}/icd/dispatch.cpp
|
||||
icd/vendor.hpp
|
||||
icd/vendor.cpp
|
||||
|
@ -69,9 +69,15 @@ class type(object):
|
||||
This includes (but is not limited to) types, like structures; and values,
|
||||
like constants.
|
||||
"""
|
||||
def __init__(self, name:str, depends:List[str] = []):
|
||||
def __init__(self, name:str, depends:List[str] = None):
|
||||
assert name
|
||||
|
||||
self.name = name
|
||||
self.depends = [] + depends
|
||||
self.depends = depends or []
|
||||
|
||||
assert isinstance(self.depends, list)
|
||||
for i in self.depends:
|
||||
assert isinstance(i, str)
|
||||
|
||||
def depends(self):
|
||||
return self.depends
|
||||
@ -85,18 +91,28 @@ class type(object):
|
||||
|
||||
###############################################################################
|
||||
class aliastype(type):
|
||||
def __init__(self, name:str, target:str):
|
||||
super().__init__(name, depends=[target])
|
||||
"""
|
||||
A type that is an alias for another type.
|
||||
|
||||
May be serialised using an appropriate host language facility
|
||||
(eg, a typedef)
|
||||
"""
|
||||
def __init__(self, name:str, target:str, depends:List[str]=None):
|
||||
depends = depends or []
|
||||
super().__init__(name, depends=depends+[target])
|
||||
self.target = target
|
||||
|
||||
def declare(self):
|
||||
return "using %(name)s = %(target)s;" % {
|
||||
"name": self.name,
|
||||
"target": self.target
|
||||
}
|
||||
return f"using {rename(self.name)} = {rename(self.target)};"
|
||||
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
class aliasvalue(type):
|
||||
"""
|
||||
A value that is an alias for another value.
|
||||
|
||||
May be serialised using an appropriate host language facility.
|
||||
"""
|
||||
def __init__(self, name:str, target:str):
|
||||
super().__init__(name, depends=[target])
|
||||
self.target = target
|
||||
@ -104,8 +120,8 @@ class aliasvalue(type):
|
||||
|
||||
def declare(self):
|
||||
return "constexpr auto %(name)s = %(target)s;" % {
|
||||
"name": self.name,
|
||||
"target": self.target
|
||||
"name": rename(self.name),
|
||||
"target": rename(self.target),
|
||||
}
|
||||
|
||||
|
||||
@ -369,6 +385,21 @@ class constant(type):
|
||||
|
||||
|
||||
class command(type):
|
||||
class param(type):
|
||||
def __init__(self, node, **kwargs):
|
||||
assert node.tag == 'param'
|
||||
|
||||
super().__init__(
|
||||
name = node.find('name').text,
|
||||
depends=[node.find('type').text],
|
||||
**kwargs
|
||||
)
|
||||
|
||||
self.type = ""
|
||||
for i in node.iter():
|
||||
self.type += i.text or ""
|
||||
self.type += i.tail or ""
|
||||
|
||||
def __init__(self, node):
|
||||
assert node.tag == "command"
|
||||
proto = node.find('proto')
|
||||
@ -376,20 +407,16 @@ class command(type):
|
||||
super().__init__(name)
|
||||
|
||||
self.result = proto.find('type').text
|
||||
self.params = [self.param(p) for p in node.findall('./param')]
|
||||
self.depends += [self.result]
|
||||
|
||||
self.params = []
|
||||
for p in node.findall('./param'):
|
||||
self.depends.append(p.find('type').text)
|
||||
self.params.append("".join(p.itertext()))
|
||||
|
||||
pass
|
||||
for p in self.params:
|
||||
self.depends += p.depends
|
||||
|
||||
def declare(self):
|
||||
return "%(result)s %(name)s (%(params)s) noexcept;" % {
|
||||
'name': rename(self.name),
|
||||
'result': self.result,
|
||||
'params': ", ".join(self.params)
|
||||
'params': ", ".join(p.type for p in self.params)
|
||||
}
|
||||
|
||||
|
||||
@ -652,6 +679,7 @@ if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(description='Transform XML API specification into C++ headers')
|
||||
parser.add_argument('--src', type=str, help='the path to the XML file to transform')
|
||||
parser.add_argument('--dst', type=str, help='the output path for the result')
|
||||
parser.add_argument('--icd', type=str, help='the output path for the icd loading routines')
|
||||
parser.add_argument('--dispatch', type=str, help="the output path for function dispatch")
|
||||
parser.add_argument(
|
||||
'--platform',
|
||||
@ -700,19 +728,44 @@ if __name__ == '__main__':
|
||||
dst.write('\n')
|
||||
dst.write('}\n')
|
||||
|
||||
with open(args.icd, 'w') as icd:
|
||||
icd.write("""
|
||||
#include "vk.hpp"
|
||||
|
||||
namespace cruft::vk::icd {
|
||||
struct vtable {
|
||||
""")
|
||||
|
||||
for obj in q:
|
||||
if not isinstance(obj, command):
|
||||
continue
|
||||
icd.write(f"{obj.result} (*{obj.name}) ({','.join(p.type for p in obj.params)});\n")
|
||||
|
||||
icd.write("""
|
||||
};
|
||||
}
|
||||
""")
|
||||
|
||||
|
||||
with open(args.dispatch, 'w') as dispatch:
|
||||
dispatch.write("""
|
||||
#include "vk.hpp"
|
||||
#include "vtable.hpp"
|
||||
|
||||
#include <cruft/util/debug.hpp>
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
static cruft::vk::icd::vtable *s_vtable = nullptr;
|
||||
""")
|
||||
|
||||
|
||||
for obj in q:
|
||||
if not isinstance(obj, command):
|
||||
continue
|
||||
|
||||
dispatch.write(f"""
|
||||
extern "C" {obj.result} {rename(obj.name)} ({", ".join(obj.params)}) noexcept {{
|
||||
unimplemented ();
|
||||
extern "C" {obj.result} {rename(obj.name)} ({", ".join(p.type for p in obj.params)}) noexcept {{
|
||||
return (*s_vtable->{obj.name})({", ".join(p.name for p in obj.params)});
|
||||
}}
|
||||
""")
|
||||
|
Loading…
Reference in New Issue
Block a user