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