From c7fc310cd1f0fa0ce291521821fa0b7d8539bb87 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Thu, 12 Jan 2017 17:02:04 +0000 Subject: [PATCH] anv: generate entry points from vk.xml v2: rework entry point iteration (Jason) cleanup unused imports v3: don't drop header installation (Emil) Signed-off-by: Lionel Landwerlin Reviewed-by: Emil Velikov Reviewed-by: Jason Ekstrand --- src/intel/vulkan/Makefile.am | 10 +- src/intel/vulkan/anv_entrypoints_gen.py | 126 ++++++++++++------------ 2 files changed, 71 insertions(+), 65 deletions(-) diff --git a/src/intel/vulkan/Makefile.am b/src/intel/vulkan/Makefile.am index df7645fb130..fba3d663c7a 100644 --- a/src/intel/vulkan/Makefile.am +++ b/src/intel/vulkan/Makefile.am @@ -138,12 +138,14 @@ VULKAN_LIB_DEPS += \ nodist_EXTRA_libvulkan_intel_la_SOURCES = dummy.cpp libvulkan_intel_la_SOURCES = $(VULKAN_GEM_FILES) -anv_entrypoints.h : anv_entrypoints_gen.py $(vulkan_include_HEADERS) - $(AM_V_GEN) cat $(vulkan_include_HEADERS) |\ +vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml + +anv_entrypoints.h : anv_entrypoints_gen.py $(vulkan_api_xml) + $(AM_V_GEN) cat $(vulkan_api_xml) |\ $(PYTHON2) $(srcdir)/anv_entrypoints_gen.py header > $@ -anv_entrypoints.c : anv_entrypoints_gen.py $(vulkan_include_HEADERS) - $(AM_V_GEN) cat $(vulkan_include_HEADERS) |\ +anv_entrypoints.c : anv_entrypoints_gen.py $(vulkan_api_xml) + $(AM_V_GEN) cat $(vulkan_api_xml) |\ $(PYTHON2) $(srcdir)/anv_entrypoints_gen.py code > $@ BUILT_SOURCES = $(VULKAN_GENERATED_FILES) diff --git a/src/intel/vulkan/anv_entrypoints_gen.py b/src/intel/vulkan/anv_entrypoints_gen.py index 9d23dbb358b..0eb523d7ac9 100644 --- a/src/intel/vulkan/anv_entrypoints_gen.py +++ b/src/intel/vulkan/anv_entrypoints_gen.py @@ -22,14 +22,8 @@ # IN THE SOFTWARE. # -import fileinput, re, sys - -# Each function typedef in the vulkan.h header is all on one line and matches -# this regepx. We hope that won't change. - -p = re.compile('typedef ([^ ]*) *\((?:VKAPI_PTR)? *\*PFN_vk([^(]*)\)(.*);') - -entrypoints = [] +import sys +import xml.etree.ElementTree as ET # We generate a static hash table for entry point lookup # (vkGetProcAddress). We use a linear congruential generator for our hash @@ -51,29 +45,11 @@ def hash(name): return h -def get_platform_guard_macro(name): - if "Xlib" in name: - return "VK_USE_PLATFORM_XLIB_KHR" - elif "Xcb" in name: - return "VK_USE_PLATFORM_XCB_KHR" - elif "Wayland" in name: - return "VK_USE_PLATFORM_WAYLAND_KHR" - elif "Mir" in name: - return "VK_USE_PLATFORM_MIR_KHR" - elif "Android" in name: - return "VK_USE_PLATFORM_ANDROID_KHR" - elif "Win32" in name: - return "VK_USE_PLATFORM_WIN32_KHR" - else: - return None - -def print_guard_start(name): - guard = get_platform_guard_macro(name) +def print_guard_start(guard): if guard is not None: print "#ifdef {0}".format(guard) -def print_guard_end(name): - guard = get_platform_guard_macro(name) +def print_guard_end(guard): if guard is not None: print "#endif // {0}".format(guard) @@ -87,18 +63,47 @@ elif (sys.argv[1] == "code"): opt_code = True sys.argv.pop() -# Parse the entry points in the header - -i = 0 -for line in fileinput.input(): - m = p.match(line) - if (m): - if m.group(2) == 'VoidFunction': - continue - fullname = "vk" + m.group(2) - h = hash(fullname) - entrypoints.append((m.group(1), m.group(2), m.group(3), i, h)) - i = i + 1 +# Extract the entry points from the registry +def get_entrypoints(doc, entrypoints_to_defines): + entrypoints = [] + commands = doc.findall('./commands/command') + for i, command in enumerate(commands): + type = command.find('./proto/type').text + fullname = command.find('./proto/name').text + shortname = fullname[2:] + params = map(lambda p: "".join(p.itertext()), command.findall('./param')) + params = ', '.join(params) + if fullname in entrypoints_to_defines: + guard = entrypoints_to_defines[fullname] + else: + guard = None + entrypoints.append((type, shortname, params, i, hash(fullname), guard)) + return entrypoints + +# Maps entry points to extension defines +def get_entrypoints_defines(doc): + entrypoints_to_defines = {} + extensions = doc.findall('./extensions/extension') + for extension in extensions: + define = extension.get('protect') + entrypoints = extension.findall('./require/command') + for entrypoint in entrypoints: + fullname = entrypoint.get('name') + entrypoints_to_defines[fullname] = define + return entrypoints_to_defines + +doc = ET.parse(sys.stdin) +entrypoints = get_entrypoints(doc, get_entrypoints_defines(doc)) + +# Manually add CreateDmaBufImageINTEL for which we don't have an extension +# defined. +entrypoints.append(('VkResult', 'CreateDmaBufImageINTEL', + 'VkDevice device, ' + + 'const VkDmaBufImageCreateInfo* pCreateInfo, ' + + 'const VkAllocationCallbacks* pAllocator,' + + 'VkDeviceMemory* pMem,' + + 'VkImage* pImage', len(entrypoints), + hash('vkCreateDmaBufImageINTEL'), None)) # For outputting entrypoints.h we generate a anv_EntryPoint() prototype # per entry point. @@ -111,8 +116,7 @@ if opt_header: print " void *entrypoints[%d];" % len(entrypoints) print " struct {" - for type, name, args, num, h in entrypoints: - guard = get_platform_guard_macro(name) + for type, name, args, num, h, guard in entrypoints: if guard is not None: print "#ifdef {0}".format(guard) print " PFN_vk{0} {0};".format(name) @@ -127,14 +131,14 @@ if opt_header: print "void anv_set_dispatch_devinfo(const struct gen_device_info *info);\n" - for type, name, args, num, h in entrypoints: - print_guard_start(name) - print "%s anv_%s%s;" % (type, name, args) - print "%s gen7_%s%s;" % (type, name, args) - print "%s gen75_%s%s;" % (type, name, args) - print "%s gen8_%s%s;" % (type, name, args) - print "%s gen9_%s%s;" % (type, name, args) - print_guard_end(name) + for type, name, args, num, h, guard in entrypoints: + print_guard_start(guard) + print "%s anv_%s(%s);" % (type, name, args) + print "%s gen7_%s(%s);" % (type, name, args) + print "%s gen75_%s(%s);" % (type, name, args) + print "%s gen8_%s(%s);" % (type, name, args) + print "%s gen9_%s(%s);" % (type, name, args) + print_guard_end(guard) exit() @@ -180,7 +184,7 @@ static const char strings[] =""" offsets = [] i = 0; -for type, name, args, num, h in entrypoints: +for type, name, args, num, h, guard in entrypoints: print " \"vk%s\\0\"" % name offsets.append(i) i += 2 + len(name) + 1 @@ -189,7 +193,7 @@ print " ;" # Now generate the table of all entry points print "\nstatic const struct anv_entrypoint entrypoints[] = {" -for type, name, args, num, h in entrypoints: +for type, name, args, num, h, guard in entrypoints: print " { %5d, 0x%08x }," % (offsets[num], h) print "};\n" @@ -202,15 +206,15 @@ print """ """ for layer in [ "anv", "gen7", "gen75", "gen8", "gen9" ]: - for type, name, args, num, h in entrypoints: - print_guard_start(name) - print "%s %s_%s%s __attribute__ ((weak));" % (type, layer, name, args) - print_guard_end(name) + for type, name, args, num, h, guard in entrypoints: + print_guard_start(guard) + print "%s %s_%s(%s) __attribute__ ((weak));" % (type, layer, name, args) + print_guard_end(guard) print "\nconst struct anv_dispatch_table %s_layer = {" % layer - for type, name, args, num, h in entrypoints: - print_guard_start(name) + for type, name, args, num, h, guard in entrypoints: + print_guard_start(guard) print " .%s = %s_%s," % (name, layer, name) - print_guard_end(name) + print_guard_end(guard) print "};\n" print """ @@ -251,7 +255,7 @@ anv_resolve_entrypoint(const struct gen_device_info *devinfo, uint32_t index) map = [none for f in xrange(hash_size)] collisions = [0 for f in xrange(10)] -for type, name, args, num, h in entrypoints: +for type, name, args, num, h, guard in entrypoints: level = 0 while map[h & hash_mask] != none: h = h + prime_step @@ -286,7 +290,7 @@ for i in xrange(0, hash_size, 8): print "0x%04x," % (map[j] & 0xffff), print -print "};" +print "};" # Finally we generate the hash table lookup function. The hash function and # linear probing algorithm matches the hash table generated above. -- 2.30.2