spec: add initial vtable stubs

This commit is contained in:
Danny Robson 2018-09-08 12:32:20 +10:00
parent 11c142f849
commit 26c9c3f70d
2 changed files with 76 additions and 20 deletions

View File

@ -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

View File

@ -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)});
}}
""")