anv: pCreateInfo->pApplicationInfo parameter to vkCreateInstance may be NULL
[mesa.git] / src / vulkan / anv_entrypoints_gen.py
index 96c4884d158b966470fe9d4a51ce0912109b2296..1e4cfcb17555fa7d829d2de393ceac0a6bfc3873 100644 (file)
@@ -27,7 +27,7 @@ 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 \*PFN_vk([^(]*)\)(.*);')
+p = re.compile('typedef ([^ ]*) *\((?:VKAPI_PTR)? *\*PFN_vk([^(]*)\)(.*);')
 
 entrypoints = []
 
@@ -78,8 +78,27 @@ for line in fileinput.input():
 # 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 in entrypoints:
+        print "         %s (*%s)%s;" % (type, name, args)
+    print "      };\n"
+    print "   };\n"
+    print "};\n"
+
+    print "void anv_set_dispatch_devinfo(const struct brw_device_info *info);\n"
+
     for type, name, args, num, h in entrypoints:
         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 "%s anv_validate_%s%s;" % (type, name, args)
     exit()
 
@@ -115,8 +134,6 @@ print """/*
 struct anv_entrypoint {
    uint32_t name;
    uint32_t hash;
-   void *function;
-   void *validate;
 };
 
 /* We use a big string constant to avoid lots of reloctions from the entry
@@ -141,16 +158,21 @@ print """   ;
  */
 """
 
-for type, name, args, num, h in entrypoints:
-    print "%s anv_validate_%s%s __attribute__ ((weak));" % (type, name, args)
-
 # Now generate the table of all entry points and their validation functions
 
 print "\nstatic const struct anv_entrypoint entrypoints[] = {"
 for type, name, args, num, h in entrypoints:
-    print "   { %5d, 0x%08x, anv_%s, anv_validate_%s }," % (offsets[num], h, name, name)
+    print "   { %5d, 0x%08x }," % (offsets[num], h)
 print "};\n"
 
+for layer in [ "anv", "validate", "gen7", "gen75", "gen8", "gen9" ]:
+    for type, name, args, num, h in entrypoints:
+        print "%s %s_%s%s __attribute__ ((weak));" % (type, layer, name, args)
+    print "\nconst struct anv_dispatch_table %s_layer = {" % layer
+    for type, name, args, num, h in entrypoints:
+        print "   .%s = %s_%s," % (name, layer, name)
+    print "};\n"
+
 print """
 #ifdef DEBUG
 static bool enable_validate = true;
@@ -173,13 +195,46 @@ determine_validate(void)
       enable_validate = atoi(s);
 }
 
-static void * __attribute__ ((noinline))
-resolve_entrypoint(uint32_t index)
+static const struct brw_device_info *dispatch_devinfo;
+
+void
+anv_set_dispatch_devinfo(const struct brw_device_info *devinfo)
 {
-   if (enable_validate && entrypoints[index].validate)
-      return entrypoints[index].validate;
+   dispatch_devinfo = devinfo;
+}
 
-   return entrypoints[index].function;
+void * __attribute__ ((noinline))
+anv_resolve_entrypoint(uint32_t index)
+{
+   if (enable_validate && validate_layer.entrypoints[index])
+      return validate_layer.entrypoints[index];
+
+   if (dispatch_devinfo == NULL) {
+      assert(anv_layer.entrypoints[index]);
+      return anv_layer.entrypoints[index];
+   }
+
+   switch (dispatch_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 (dispatch_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");
+   }
 }
 """
 
@@ -188,7 +243,7 @@ resolve_entrypoint(uint32_t index)
 # lets the resolver look it up in the table.
 
 for type, name, args, num, h in entrypoints:
-    print "static void *resolve_%s(void) { return resolve_entrypoint(%d); }" % (name, num)
+    print "static void *resolve_%s(void) { return anv_resolve_entrypoint(%d); }" % (name, num)
     print "%s vk%s%s\n   __attribute__ ((ifunc (\"resolve_%s\"), visibility (\"default\")));\n" % (type, name, args, name)
 
 
@@ -264,6 +319,6 @@ anv_lookup_entrypoint(const char *name)
    if (strcmp(name, strings + e->name) != 0)
       return NULL;
 
-   return resolve_entrypoint(i);
+   return anv_resolve_entrypoint(i);
 }
 """ % (prime_factor, prime_step, hash_mask)