From abd72f2e3568c5fca3abdc4f6caca7ceee745afb Mon Sep 17 00:00:00 2001 From: Dylan Baker Date: Fri, 17 Feb 2017 11:00:03 -0800 Subject: [PATCH] anv: anv_entrypoints_gen.py: use a main function This is just good practice. Signed-off-by: Dylan Baker --- src/intel/vulkan/anv_entrypoints_gen.py | 458 ++++++++++++------------ 1 file changed, 233 insertions(+), 225 deletions(-) diff --git a/src/intel/vulkan/anv_entrypoints_gen.py b/src/intel/vulkan/anv_entrypoints_gen.py index 4e5d2ee6c54..9db86f89f19 100644 --- a/src/intel/vulkan/anv_entrypoints_gen.py +++ b/src/intel/vulkan/anv_entrypoints_gen.py @@ -1,6 +1,6 @@ # coding=utf-8 # -# Copyright © 2015 Intel Corporation +# Copyright © 2015, 2017 Intel Corporation # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ # import sys +import textwrap import xml.etree.ElementTree as ET max_api_version = 1.0 @@ -132,235 +133,242 @@ def get_entrypoints_defines(doc): 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. - -if opt_header: - print "/* This file generated from vk_gen.py, don't edit directly. */\n" - - print "struct anv_dispatch_table {" - print " union {" - print " void *entrypoints[%d];" % len(entrypoints) - print " struct {" +def main(): + 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. + + if opt_header: + print "/* This file generated from vk_gen.py, don't edit directly. */\n" + + print "struct anv_dispatch_table {" + print " union {" + print " void *entrypoints[%d];" % len(entrypoints) + print " struct {" + + 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) + print "#else" + print " void *{0};".format(name) + print "#endif" + else: + print " PFN_vk{0} {0};".format(name) + print " };\n" + print " };\n" + print "};\n" + + print "void anv_set_dispatch_devinfo(const struct gen_device_info *info);\n" + + 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() + + + + print textwrap.dedent("""\ + /* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + + /* DO NOT EDIT! This is a generated file. */ + + #include "anv_private.h" + + struct anv_entrypoint { + uint32_t name; + uint32_t hash; + }; + + /* We use a big string constant to avoid lots of reloctions from the entry + * point table to lots of little strings. The entries in the entry point table + * store the index into this big string. + */ + + static const char strings[] =""") + + offsets = [] + i = 0; 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) - print "#else" - print " void *{0};".format(name) - print "#endif" - else: - print " PFN_vk{0} {0};".format(name) - print " };\n" - print " };\n" - print "};\n" + print " \"vk%s\\0\"" % name + offsets.append(i) + i += 2 + len(name) + 1 + print " ;" - print "void anv_set_dispatch_devinfo(const struct gen_device_info *info);\n" + # Now generate the table of all entry points + print "\nstatic const struct anv_entrypoint entrypoints[] = {" 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() - - - -print """/* - * Copyright © 2015 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* DO NOT EDIT! This is a generated file. */ - -#include "anv_private.h" - -struct anv_entrypoint { - uint32_t name; - uint32_t hash; -}; - -/* We use a big string constant to avoid lots of reloctions from the entry - * point table to lots of little strings. The entries in the entry point table - * store the index into this big string. - */ - -static const char strings[] =""" - -offsets = [] -i = 0; -for type, name, args, num, h, guard in entrypoints: - print " \"vk%s\\0\"" % name - offsets.append(i) - i += 2 + len(name) + 1 -print " ;" - -# Now generate the table of all entry points - -print "\nstatic const struct anv_entrypoint entrypoints[] = {" -for type, name, args, num, h, guard in entrypoints: - print " { %5d, 0x%08x }," % (offsets[num], h) -print "};\n" - -print """ - -/* Weak aliases for all potential implementations. These will resolve to - * NULL if they're not defined, which lets the resolve_entrypoint() function - * either pick the correct entry point. - */ -""" - -for layer in [ "anv", "gen7", "gen75", "gen8", "gen9" ]: - 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, guard in entrypoints: - print_guard_start(guard) - print " .%s = %s_%s," % (name, layer, name) - print_guard_end(guard) + print " { %5d, 0x%08x }," % (offsets[num], h) print "};\n" -print """ -static void * __attribute__ ((noinline)) -anv_resolve_entrypoint(const struct gen_device_info *devinfo, uint32_t index) -{ - if (devinfo == NULL) { - return anv_layer.entrypoints[index]; - } - - switch (devinfo->gen) { - case 9: - if (gen9_layer.entrypoints[index]) - return gen9_layer.entrypoints[index]; - /* fall through */ - case 8: - if (gen8_layer.entrypoints[index]) - return gen8_layer.entrypoints[index]; - /* fall through */ - case 7: - if (devinfo->is_haswell && gen75_layer.entrypoints[index]) - return gen75_layer.entrypoints[index]; - - if (gen7_layer.entrypoints[index]) - return gen7_layer.entrypoints[index]; - /* fall through */ - case 0: - return anv_layer.entrypoints[index]; - default: - unreachable("unsupported gen\\n"); - } -} -""" - -# Now generate the hash table used for entry point look up. This is a -# uint16_t table of entry point indices. We use 0xffff to indicate an entry -# in the hash table is empty. - -map = [none for f in xrange(hash_size)] -collisions = [0 for f in xrange(10)] -for type, name, args, num, h, guard in entrypoints: - level = 0 - while map[h & hash_mask] != none: - h = h + prime_step - level = level + 1 - if level > 9: - collisions[9] += 1 - else: - collisions[level] += 1 - map[h & hash_mask] = num - -print "/* Hash table stats:" -print " * size %d entries" % hash_size -print " * collisions entries" -for i in xrange(10): - if (i == 9): - plus = "+" - else: - plus = " " - - print " * %2d%s %4d" % (i, plus, collisions[i]) -print " */\n" - -print "#define none 0x%04x\n" % none - -print "static const uint16_t map[] = {" -for i in xrange(0, hash_size, 8): - print " ", - for j in xrange(i, i + 8): - if map[j] & 0xffff == 0xffff: - print " none,", + print textwrap.dedent(""" + + /* Weak aliases for all potential implementations. These will resolve to + * NULL if they're not defined, which lets the resolve_entrypoint() function + * either pick the correct entry point. + */ + """) + + for layer in [ "anv", "gen7", "gen75", "gen8", "gen9" ]: + 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, guard in entrypoints: + print_guard_start(guard) + print " .%s = %s_%s," % (name, layer, name) + print_guard_end(guard) + print "};\n" + + print textwrap.dedent(""" + static void * __attribute__ ((noinline)) + anv_resolve_entrypoint(const struct gen_device_info *devinfo, uint32_t index) + { + if (devinfo == NULL) { + return anv_layer.entrypoints[index]; + } + + switch (devinfo->gen) { + case 9: + if (gen9_layer.entrypoints[index]) + return gen9_layer.entrypoints[index]; + /* fall through */ + case 8: + if (gen8_layer.entrypoints[index]) + return gen8_layer.entrypoints[index]; + /* fall through */ + case 7: + if (devinfo->is_haswell && gen75_layer.entrypoints[index]) + return gen75_layer.entrypoints[index]; + + if (gen7_layer.entrypoints[index]) + return gen7_layer.entrypoints[index]; + /* fall through */ + case 0: + return anv_layer.entrypoints[index]; + default: + unreachable("unsupported gen\\n"); + } + } + """) + + # Now generate the hash table used for entry point look up. This is a + # uint16_t table of entry point indices. We use 0xffff to indicate an entry + # in the hash table is empty. + + map = [none for f in xrange(hash_size)] + collisions = [0 for f in xrange(10)] + for type, name, args, num, h, guard in entrypoints: + level = 0 + while map[h & hash_mask] != none: + h = h + prime_step + level = level + 1 + if level > 9: + collisions[9] += 1 + else: + collisions[level] += 1 + map[h & hash_mask] = num + + print "/* Hash table stats:" + print " * size %d entries" % hash_size + print " * collisions entries" + for i in xrange(10): + if (i == 9): + plus = "+" else: - print "0x%04x," % (map[j] & 0xffff), - print - -print "};" - -# Finally we generate the hash table lookup function. The hash function and -# linear probing algorithm matches the hash table generated above. - -print """ -void * -anv_lookup_entrypoint(const struct gen_device_info *devinfo, const char *name) -{ - static const uint32_t prime_factor = %d; - static const uint32_t prime_step = %d; - const struct anv_entrypoint *e; - uint32_t hash, h, i; - const char *p; - - hash = 0; - for (p = name; *p; p++) - hash = hash * prime_factor + *p; - - h = hash; - do { - i = map[h & %d]; - if (i == none) - return NULL; - e = &entrypoints[i]; - h += prime_step; - } while (e->hash != hash); - - if (strcmp(name, strings + e->name) != 0) - return NULL; - - return anv_resolve_entrypoint(devinfo, i); -} -""" % (prime_factor, prime_step, hash_mask) + plus = " " + + print " * %2d%s %4d" % (i, plus, collisions[i]) + print " */\n" + + print "#define none 0x%04x\n" % none + + print "static const uint16_t map[] = {" + for i in xrange(0, hash_size, 8): + print " ", + for j in xrange(i, i + 8): + if map[j] & 0xffff == 0xffff: + print " none,", + else: + print "0x%04x," % (map[j] & 0xffff), + print + + print "};" + + # Finally we generate the hash table lookup function. The hash function and + # linear probing algorithm matches the hash table generated above. + + print textwrap.dedent(""" + void * + anv_lookup_entrypoint(const struct gen_device_info *devinfo, const char *name) + { + static const uint32_t prime_factor = %d; + static const uint32_t prime_step = %d; + const struct anv_entrypoint *e; + uint32_t hash, h, i; + const char *p; + + hash = 0; + for (p = name; *p; p++) + hash = hash * prime_factor + *p; + + h = hash; + do { + i = map[h & %d]; + if (i == none) + return NULL; + e = &entrypoints[i]; + h += prime_step; + } while (e->hash != hash); + + if (strcmp(name, strings + e->name) != 0) + return NULL; + + return anv_resolve_entrypoint(devinfo, i); + } + """) % (prime_factor, prime_step, hash_mask) + + +if __name__ == '__main__': + main() -- 2.30.2