vk: Implement multi-gen dispatch mechanism
authorKristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
Thu, 30 Jul 2015 21:44:01 +0000 (14:44 -0700)
committerKristian Høgsberg Kristensen <kristian.h.kristensen@intel.com>
Mon, 24 Aug 2015 20:45:39 +0000 (13:45 -0700)
src/vulkan/anv_device.c
src/vulkan/anv_entrypoints_gen.py

index eaeae3b0a4ffe2021ebbfe7a42976c5397895a98..4db344bf08c95778110974983466d7ede4ae8003 100644 (file)
@@ -532,6 +532,15 @@ VkResult anv_CreateDevice(
 
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
 
+   switch (physical_device->info->gen) {
+   case 7:
+      driver_layer = &gen7_layer;
+      break;
+   case 8:
+      driver_layer = &gen8_layer;
+      break;
+   }
+
    device = anv_instance_alloc(instance, sizeof(*device), 8,
                                VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
    if (!device)
index 96c4884d158b966470fe9d4a51ce0912109b2296..21f87f181e9a7aaf489699538b44543c7f5fbedb 100644 (file)
@@ -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_layer {"
+    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 "extern const struct anv_layer gen7_layer;\n"
+    print "extern const struct anv_layer gen8_layer;\n"
+    print "extern const struct anv_layer *driver_layer;\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 gen8_%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", "gen8" ]:
+    for type, name, args, num, h in entrypoints:
+        print "%s %s_%s%s __attribute__ ((weak));" % (type, layer, name, args)
+    print "\nconst struct anv_layer %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,18 @@ determine_validate(void)
       enable_validate = atoi(s);
 }
 
+const struct anv_layer *driver_layer = &anv_layer;
+
 static void * __attribute__ ((noinline))
 resolve_entrypoint(uint32_t index)
 {
-   if (enable_validate && entrypoints[index].validate)
-      return entrypoints[index].validate;
+   if (enable_validate && validate_layer.entrypoints[index])
+      return validate_layer.entrypoints[index];
+
+   if (driver_layer && driver_layer->entrypoints[index])
+      return driver_layer->entrypoints[index];
 
-   return entrypoints[index].function;
+   return anv_layer.entrypoints[index];
 }
 """