LibreSoc Vulkan Driver Initial Commit
authorVivek Pandya <vivekvpandya@gmail.com>
Tue, 25 Aug 2020 14:52:38 +0000 (20:22 +0530)
committerVivek Pandya <vivekvpandya@gmail.com>
Sat, 5 Sep 2020 11:50:32 +0000 (17:20 +0530)
  - This commit mostly includes copy & paste code from other vulkan driver.
  - Python scripts to generate extensions, entrypoints and icd.
  - Meson file updates.

13 files changed:
meson.build
meson_options.txt
src/libre-soc/meson.build [new file with mode: 0644]
src/libre-soc/vulkan/libresoc_device.c [new file with mode: 0644]
src/libre-soc/vulkan/libresoc_entrypoints_gen.py [new file with mode: 0644]
src/libre-soc/vulkan/libresoc_extensions.py [new file with mode: 0644]
src/libre-soc/vulkan/libresoc_extensions_gen.py [new file with mode: 0644]
src/libre-soc/vulkan/libresoc_icd.py [new file with mode: 0644]
src/libre-soc/vulkan/libresoc_pipeline.c [new file with mode: 0644]
src/libre-soc/vulkan/libresoc_private.h [new file with mode: 0644]
src/libre-soc/vulkan/libresoc_util.c [new file with mode: 0644]
src/libre-soc/vulkan/meson.build [new file with mode: 0644]
src/meson.build

index fa178c435a9fa690c0b3d437b73f41098eb47bdc..9cbf6a7f7e772adb876053746bd71ab5fd89d2a2 100644 (file)
@@ -262,6 +262,7 @@ endif
 with_intel_vk = _vulkan_drivers.contains('intel')
 with_amd_vk = _vulkan_drivers.contains('amd')
 with_freedreno_vk = _vulkan_drivers.contains('freedreno')
 with_intel_vk = _vulkan_drivers.contains('intel')
 with_amd_vk = _vulkan_drivers.contains('amd')
 with_freedreno_vk = _vulkan_drivers.contains('freedreno')
+with_libresoc_vk = _vulkan_drivers.contains('libre-soc')
 with_swrast_vk = _vulkan_drivers.contains('swrast')
 with_any_vk = _vulkan_drivers.length() != 0
 
 with_swrast_vk = _vulkan_drivers.contains('swrast')
 with_any_vk = _vulkan_drivers.length() != 0
 
index a0cf4abca9282cb34823b701711faa5c7c190e37..0e0a5a785e0cbcc042a571ae2dcfa9a0af96f754 100644 (file)
@@ -166,7 +166,7 @@ option(
   'vulkan-drivers',
   type : 'array',
   value : ['auto'],
   'vulkan-drivers',
   type : 'array',
   value : ['auto'],
-  choices : ['auto', 'amd', 'freedreno', 'intel', 'swrast'],
+  choices : ['auto', 'amd', 'freedreno', 'intel', 'libre-soc', 'swrast'],
   description : 'List of vulkan drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built'
 )
 option(
   description : 'List of vulkan drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built'
 )
 option(
diff --git a/src/libre-soc/meson.build b/src/libre-soc/meson.build
new file mode 100644 (file)
index 0000000..7f7ce28
--- /dev/null
@@ -0,0 +1,32 @@
+# Copyright © 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"), 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 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.
+
+inc_libresoc = include_directories('.')
+
+#subdir('addrlib')
+#subdir('common')
+#subdir('llvm')
+if with_libresoc_vk
+  #  subdir('compiler')
+  subdir('vulkan')
+  #if with_aco_tests
+  #  subdir('compiler/tests')
+  #endif
+endif
diff --git a/src/libre-soc/vulkan/libresoc_device.c b/src/libre-soc/vulkan/libresoc_device.c
new file mode 100644 (file)
index 0000000..089aa36
--- /dev/null
@@ -0,0 +1,324 @@
+/*
+ * Copyright © 2019 Raspberry Pi
+ *
+ * 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.
+ */
+
+#include <assert.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/sysinfo.h>
+#include <unistd.h>
+
+#include "libresoc_private.h"
+#include "vk_util.h"
+
+VkResult
+libresoc_EnumerateInstanceExtensionProperties(const char *pLayerName,
+                                          uint32_t *pPropertyCount,
+                                          VkExtensionProperties *pProperties)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "EnumerateInstanceExtensionProperties called for: %s \n", pLayerName);
+       }
+   VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);
+
+   for (int i = 0; i < LIBRESOC_INSTANCE_EXTENSION_COUNT; i++) {
+      if (libresoc_instance_extensions_supported.extensions[i]) {
+         vk_outarray_append(&out, prop) {
+            *prop = libresoc_instance_extensions[i];
+         }
+      }
+   }
+
+   return vk_outarray_status(&out);
+}
+
+VkResult
+libresoc_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
+                    const VkAllocationCallbacks *pAllocator,
+                    VkInstance *pInstance)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "CreateInstance called. \n");
+       }
+   /* FIXME: stub */
+   return VK_SUCCESS;
+}
+
+void
+libresoc_DestroyInstance(VkInstance _instance,
+                     const VkAllocationCallbacks *pAllocator)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "DestroyInstance called. \n");
+       }
+   /* FIXME: stub */
+}
+
+VkResult
+libresoc_EnumeratePhysicalDevices(VkInstance _instance,
+                              uint32_t *pPhysicalDeviceCount,
+                              VkPhysicalDevice *pPhysicalDevices)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "EnumeratePhysicalDevices called\n");
+       }
+   /* FIXME: stub */
+   return VK_SUCCESS;
+}
+
+void
+libresoc_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
+                               VkPhysicalDeviceFeatures *pFeatures)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "GetPhysicalDeviceFeatures called. \n");
+       }
+   /* FIXME: stub */
+}
+
+void
+libresoc_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
+                                 VkPhysicalDeviceProperties *pProperties)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "GetPhysicalDeviceProperties called. \n");
+       }
+   /* FIXME: stub */
+}
+
+void
+libresoc_GetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
+                                            uint32_t *pCount,
+                                            VkQueueFamilyProperties *pQueueFamilyProperties)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "GetPhysicalDeviceQueueFamilyProperites called. \n");
+       }
+   /* FIXME: stub */
+}
+
+void
+libresoc_GetPhysicalDeviceMemoryProperties(VkPhysicalDevice physicalDevice,
+                                       VkPhysicalDeviceMemoryProperties *pMemoryProperties)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "GetPhysicalDEviceMemoryProperties called. \n");
+       }
+   /* FIXME: stub */
+}
+
+void
+libresoc_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkFormatProperties *pFormatProperties) {
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "GetPhysicalDeviceFormatProperties called. \n");
+       }
+   /* FIXME: stub */
+}
+
+VkResult
+      libresoc_GetPhysicalDeviceImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags, VkImageFormatProperties* pImageFormatProperties)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "GetPhysicalDEviceImageFormatProperties called. \n");
+       }
+      
+   /* FIXME: stub */
+   return VK_SUCCESS;
+}
+      void 
+      libresoc_GetPhysicalDeviceSparseImageFormatProperties(VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling, uint32_t* pPropertyCount, VkSparseImageFormatProperties* pProperties)
+      {
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "GetPhysicalDeviceSparseImageFormatProperties called. \n");
+       }
+   /* FIXME: stub */
+      }
+PFN_vkVoidFunction
+libresoc_GetInstanceProcAddr(VkInstance _instance,
+                         const char *pName)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "GetInstanceProcAddr called for: %s \n", pName);
+       }
+   LIBRESOC_FROM_HANDLE(libresoc_instance, instance, _instance);
+
+   /* The Vulkan 1.0 spec for vkGetInstanceProcAddr has a table of exactly
+    * when we have to return valid function pointers, NULL, or it's left
+    * undefined.  See the table for exact details.
+    */
+   if (pName == NULL)
+      return NULL;
+
+#define LOOKUP_LIBRESOC_ENTRYPOINT(entrypoint)              \
+   if (strcmp(pName, "vk" #entrypoint) == 0)            \
+      return (PFN_vkVoidFunction)libresoc_##entrypoint
+
+   LOOKUP_LIBRESOC_ENTRYPOINT(EnumerateInstanceExtensionProperties);
+   LOOKUP_LIBRESOC_ENTRYPOINT(CreateInstance);
+   LOOKUP_LIBRESOC_ENTRYPOINT(DestroyInstance);
+   LOOKUP_LIBRESOC_ENTRYPOINT(EnumeratePhysicalDevices);
+   LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceFeatures);
+   LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceFormatProperties);
+   LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceImageFormatProperties);
+   LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceProperties);
+   LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceQueueFamilyProperties);
+   LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceMemoryProperties);
+   LOOKUP_LIBRESOC_ENTRYPOINT(GetDeviceProcAddr);
+   LOOKUP_LIBRESOC_ENTRYPOINT(CreateDevice);
+   LOOKUP_LIBRESOC_ENTRYPOINT(EnumerateDeviceExtensionProperties);
+   LOOKUP_LIBRESOC_ENTRYPOINT(GetPhysicalDeviceSparseImageFormatProperties);
+
+
+#undef LOOKUP_LIBRESOC_ENTRYPOINT
+
+   if (instance == NULL)
+      return NULL;
+
+   int idx = libresoc_get_instance_entrypoint_index(pName);
+   if (idx >= 0)
+      return instance->dispatch.entrypoints[idx];
+
+   idx = libresoc_get_physical_device_entrypoint_index(pName);
+   if (idx >= 0)
+      return instance->physicalDevice.dispatch.entrypoints[idx];
+
+   idx = libresoc_get_device_entrypoint_index(pName);
+   if (idx >= 0)
+      return instance->device_dispatch.entrypoints[idx];
+
+   return NULL;
+}
+
+/* With version 1+ of the loader interface the ICD should expose
+ * vk_icdGetInstanceProcAddr to work around certain LD_PRELOAD issues seen in apps.
+ */
+PUBLIC
+VKAPI_ATTR PFN_vkVoidFunction
+VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance,
+                                     const char *pName);
+
+PUBLIC
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+vk_icdGetInstanceProcAddr(VkInstance instance,
+                          const char*                                 pName)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "vk_icdGetInstanceProcAddr called for: %s \n", pName);
+       }
+   return libresoc_GetInstanceProcAddr(instance, pName);
+}
+
+PFN_vkVoidFunction
+libresoc_GetDeviceProcAddr(VkDevice _device,
+                       const char *pName)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "GetDeviceProcAddr called for: %s \n", pName);
+       }
+   LIBRESOC_FROM_HANDLE(libresoc_device, device, _device);
+
+   if (!device || !pName)
+      return NULL;
+
+   int idx = libresoc_get_device_entrypoint_index(pName);
+   if (idx < 0)
+      return NULL;
+
+   return device->dispatch.entrypoints[idx];
+}
+
+/* With version 4+ of the loader interface the ICD should expose
+ * vk_icdGetPhysicalDeviceProcAddr()
+ */
+PUBLIC
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+vk_icdGetPhysicalDeviceProcAddr(VkInstance  _instance,
+                                const char* pName);
+
+PFN_vkVoidFunction
+vk_icdGetPhysicalDeviceProcAddr(VkInstance  _instance,
+                                const char* pName)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "vk_icdGetPhysicalDeviceProcAddr called for: %s \n", pName);
+       }
+   LIBRESOC_FROM_HANDLE(libresoc_instance, instance, _instance);
+
+   if (!pName || !instance)
+      return NULL;
+
+   int idx = libresoc_get_physical_device_entrypoint_index(pName);
+   if (idx < 0)
+      return NULL;
+
+   return instance->physicalDevice.dispatch.entrypoints[idx];
+}
+
+VkResult
+libresoc_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
+                                        const char *pLayerName,
+                                        uint32_t *pPropertyCount,
+                                        VkExtensionProperties *pProperties)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "EnumerateDeviceExtensionProperties called for layer: %s \n", pLayerName);
+       }
+   /* FIXME: stub */
+   return VK_SUCCESS;
+}
+
+VkResult
+libresoc_CreateDevice(VkPhysicalDevice physicalDevice,
+                  const VkDeviceCreateInfo *pCreateInfo,
+                  const VkAllocationCallbacks *pAllocator,
+                  VkDevice *pDevice)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "CreateDevice called \n");
+       }
+   /* FIXME: stub */
+   return VK_SUCCESS;
+}
+
+void
+libresoc_DestroyDevice(VkDevice _device,
+                   const VkAllocationCallbacks *pAllocator)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "DestroyDevice called. \n");
+       }
+   /* FIXME: stub */
+}
+
+void
+libresoc_GetDeviceQueue(VkDevice _device,
+                    uint32_t queueNodeIndex,
+                    uint32_t queueIndex,
+                    VkQueue *pQueue)
+{
+       if (getenv("LIBRESOC_TRACE")) {
+               fprintf(stderr, "GetDeviceQueue called. \n");
+       }
+   /* FIXME: stub */
+}
diff --git a/src/libre-soc/vulkan/libresoc_entrypoints_gen.py b/src/libre-soc/vulkan/libresoc_entrypoints_gen.py
new file mode 100644 (file)
index 0000000..d4ba55c
--- /dev/null
@@ -0,0 +1,798 @@
+# coding=utf-8
+#
+# 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"),
+# 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.
+#
+
+import argparse
+import math
+import os
+import xml.etree.cElementTree as et
+
+from collections import OrderedDict, namedtuple
+from mako.template import Template
+
+from libresoc_extensions import VkVersion, MAX_API_VERSION, EXTENSIONS
+
+# We currently don't use layers in libresoc, but keeping the ability for anv
+# anyways, so we can use it for device groups.
+
+LAYERS = [
+    'libresoc'
+]
+
+TEMPLATE_H = Template("""\
+/* This file generated from ${filename}, don't edit directly. */
+
+struct libresoc_instance_dispatch_table {
+   union {
+      void *entrypoints[${len(instance_entrypoints)}];
+      struct {
+      % for e in instance_entrypoints:
+        % if e.guard is not None:
+#ifdef ${e.guard}
+          PFN_${e.name} ${e.name};
+#else
+          void *${e.name};
+# endif
+        % else:
+          PFN_${e.name} ${e.name};
+        % endif
+      % endfor
+      };
+   };
+};
+
+struct libresoc_physical_device_dispatch_table {
+   union {
+      void *entrypoints[${len(physical_device_entrypoints)}];
+      struct {
+      % for e in physical_device_entrypoints:
+        % if e.guard is not None:
+#ifdef ${e.guard}
+          PFN_${e.name} ${e.name};
+#else
+          void *${e.name};
+# endif
+        % else:
+          PFN_${e.name} ${e.name};
+        % endif
+      % endfor
+      };
+   };
+};
+
+struct libresoc_device_dispatch_table {
+   union {
+      void *entrypoints[${len(device_entrypoints)}];
+      struct {
+      % for e in device_entrypoints:
+        % if e.guard is not None:
+#ifdef ${e.guard}
+          PFN_${e.name} ${e.name};
+#else
+          void *${e.name};
+# endif
+        % else:
+          PFN_${e.name} ${e.name};
+        % endif
+      % endfor
+      };
+   };
+};
+
+extern const struct libresoc_instance_dispatch_table libresoc_instance_dispatch_table;
+%for layer in LAYERS:
+extern const struct libresoc_physical_device_dispatch_table ${layer}_physical_device_dispatch_table;
+%endfor
+%for layer in LAYERS:
+extern const struct libresoc_device_dispatch_table ${layer}_device_dispatch_table;
+%endfor
+
+% for e in instance_entrypoints:
+  % if e.alias:
+    <% continue %>
+  % endif
+  % if e.guard is not None:
+#ifdef ${e.guard}
+  % endif
+  ${e.return_type} ${e.prefixed_name('libresoc')}(${e.decl_params()});
+  % if e.guard is not None:
+#endif // ${e.guard}
+  % endif
+% endfor
+
+% for e in physical_device_entrypoints:
+  % if e.alias:
+    <% continue %>
+  % endif
+  % if e.guard is not None:
+#ifdef ${e.guard}
+  % endif
+  % for layer in LAYERS:
+  ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()});
+  % endfor
+  % if e.guard is not None:
+#endif // ${e.guard}
+  % endif
+% endfor
+
+% for e in device_entrypoints:
+  % if e.alias:
+    <% continue %>
+  % endif
+  % if e.guard is not None:
+#ifdef ${e.guard}
+  % endif
+  % for layer in LAYERS:
+  ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()});
+  % endfor
+  % if e.guard is not None:
+#endif // ${e.guard}
+  % endif
+% endfor
+""", output_encoding='utf-8')
+
+TEMPLATE_C = Template(u"""\
+/*
+ * 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.
+ */
+
+/* This file generated from ${filename}, don't edit directly. */
+
+#include "libresoc_private.h"
+
+#include "util/macros.h"
+
+struct string_map_entry {
+   uint32_t name;
+   uint32_t hash;
+   uint32_t num;
+};
+
+/* 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.
+ */
+
+<%def name="strmap(strmap, prefix)">
+static const char ${prefix}_strings[] =
+% for s in strmap.sorted_strings:
+    "${s.string}\\0"
+% endfor
+;
+
+static const struct string_map_entry ${prefix}_string_map_entries[] = {
+% for s in strmap.sorted_strings:
+    { ${s.offset}, ${'{:0=#8x}'.format(s.hash)}, ${s.num} }, /* ${s.string} */
+% endfor
+};
+
+/* Hash table stats:
+ * size ${len(strmap.sorted_strings)} entries
+ * collisions entries:
+% for i in range(10):
+ *     ${i}${'+' if i == 9 else ' '}     ${strmap.collisions[i]}
+% endfor
+ */
+
+#define none 0xffff
+static const uint16_t ${prefix}_string_map[${strmap.hash_size}] = {
+% for e in strmap.mapping:
+    ${ '{:0=#6x}'.format(e) if e >= 0 else 'none' },
+% endfor
+};
+
+static int
+${prefix}_string_map_lookup(const char *str)
+{
+    static const uint32_t prime_factor = ${strmap.prime_factor};
+    static const uint32_t prime_step = ${strmap.prime_step};
+    const struct string_map_entry *e;
+    uint32_t hash, h;
+    uint16_t i;
+    const char *p;
+
+    hash = 0;
+    for (p = str; *p; p++)
+        hash = hash * prime_factor + *p;
+
+    h = hash;
+    while (1) {
+        i = ${prefix}_string_map[h & ${strmap.hash_mask}];
+        if (i == none)
+           return -1;
+        e = &${prefix}_string_map_entries[i];
+        if (e->hash == hash && strcmp(str, ${prefix}_strings + e->name) == 0)
+            return e->num;
+        h += prime_step;
+    }
+
+    return -1;
+}
+
+static const char *
+${prefix}_entry_name(int num)
+{
+   for (int i = 0; i < ARRAY_SIZE(${prefix}_string_map_entries); i++) {
+      if (${prefix}_string_map_entries[i].num == num)
+         return &${prefix}_strings[${prefix}_string_map_entries[i].name];
+   }
+   return NULL;
+}
+</%def>
+
+${strmap(instance_strmap, 'instance')}
+${strmap(physical_device_strmap, 'physical_device')}
+${strmap(device_strmap, 'device')}
+
+/* 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 e in instance_entrypoints:
+  % if e.alias:
+    <% continue %>
+  % endif
+  % if e.guard is not None:
+#ifdef ${e.guard}
+  % endif
+  ${e.return_type} ${e.prefixed_name('libresoc')}(${e.decl_params()}) __attribute__ ((weak));
+  % if e.guard is not None:
+#endif // ${e.guard}
+  % endif
+% endfor
+
+const struct libresoc_instance_dispatch_table libresoc_instance_dispatch_table = {
+% for e in instance_entrypoints:
+  % if e.guard is not None:
+#ifdef ${e.guard}
+  % endif
+  .${e.name} = ${e.prefixed_name('libresoc')},
+  % if e.guard is not None:
+#endif // ${e.guard}
+  % endif
+% endfor
+};
+
+% for layer in LAYERS:
+  % for e in physical_device_entrypoints:
+    % if e.alias:
+      <% continue %>
+    % endif
+    % if e.guard is not None:
+#ifdef ${e.guard}
+    % endif
+    % if layer == 'libresoc':
+      ${e.return_type} __attribute__ ((weak))
+      ${e.prefixed_name('libresoc')}(${e.decl_params()})
+      {
+        % if e.params[0].type == 'VkPhysicalDevice':
+          LIBRESOC_FROM_HANDLE(libresoc_physical_device, libresoc_physical_device, ${e.params[0].name});
+          return libresoc_physical_device->dispatch.${e.name}(${e.call_params()});
+        % else:
+          assert(!"Unhandled device child trampoline case: ${e.params[0].type}");
+        % endif
+      }
+    % else:
+      ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()}) __attribute__ ((weak));
+    % endif
+    % if e.guard is not None:
+#endif // ${e.guard}
+    % endif
+  % endfor
+
+  const struct libresoc_physical_device_dispatch_table ${layer}_physical_device_dispatch_table = {
+  % for e in physical_device_entrypoints:
+    % if e.guard is not None:
+#ifdef ${e.guard}
+    % endif
+    .${e.name} = ${e.prefixed_name(layer)},
+    % if e.guard is not None:
+#endif // ${e.guard}
+    % endif
+  % endfor
+  };
+% endfor
+
+
+% for layer in LAYERS:
+  % for e in device_entrypoints:
+    % if e.alias:
+      <% continue %>
+    % endif
+    % if e.guard is not None:
+#ifdef ${e.guard}
+    % endif
+    % if layer == 'libresoc':
+      ${e.return_type} __attribute__ ((weak))
+      ${e.prefixed_name('libresoc')}(${e.decl_params()})
+      {
+        % if e.params[0].type == 'VkDevice':
+          LIBRESOC_FROM_HANDLE(libresoc_device, libresoc_device, ${e.params[0].name});
+          return libresoc_device->dispatch.${e.name}(${e.call_params()});
+        % elif e.params[0].type == 'VkCommandBuffer':
+          LIBRESOC_FROM_HANDLE(libresoc_cmd_buffer, libresoc_cmd_buffer, ${e.params[0].name});
+          return libresoc_cmd_buffer->device->dispatch.${e.name}(${e.call_params()});
+        % elif e.params[0].type == 'VkQueue':
+          LIBRESOC_FROM_HANDLE(libresoc_queue, libresoc_queue, ${e.params[0].name});
+          return libresoc_queue->device->dispatch.${e.name}(${e.call_params()});
+        % else:
+          assert(!"Unhandled device child trampoline case: ${e.params[0].type}");
+        % endif
+      }
+    % else:
+      ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()}) __attribute__ ((weak));
+    % endif
+    % if e.guard is not None:
+#endif // ${e.guard}
+    % endif
+  % endfor
+
+  const struct libresoc_device_dispatch_table ${layer}_device_dispatch_table = {
+  % for e in device_entrypoints:
+    % if e.guard is not None:
+#ifdef ${e.guard}
+    % endif
+    .${e.name} = ${e.prefixed_name(layer)},
+    % if e.guard is not None:
+#endif // ${e.guard}
+    % endif
+  % endfor
+  };
+% endfor
+
+
+/** Return true if the core version or extension in which the given entrypoint
+ * is defined is enabled.
+ *
+ * If device is NULL, all device extensions are considered enabled.
+ */
+bool
+libresoc_instance_entrypoint_is_enabled(int index, uint32_t core_version,
+                                   const struct libresoc_instance_extension_table *instance)
+{
+   switch (index) {
+% for e in instance_entrypoints:
+   case ${e.num}:
+      /* ${e.name} */
+   % if e.core_version:
+      return ${e.core_version.c_vk_version()} <= core_version;
+   % elif e.extensions:
+     % for ext in e.extensions:
+        % if ext.type == 'instance':
+      if (instance->${ext.name[3:]}) return true;
+        % else:
+      /* All device extensions are considered enabled at the instance level */
+      return true;
+        % endif
+     % endfor
+      return false;
+   % else:
+      return true;
+   % endif
+% endfor
+   default:
+      return false;
+   }
+}
+
+/** Return true if the core version or extension in which the given entrypoint
+ * is defined is enabled.
+ *
+ * If device is NULL, all device extensions are considered enabled.
+ */
+bool
+libresoc_physical_device_entrypoint_is_enabled(int index, uint32_t core_version,
+                                          const struct libresoc_instance_extension_table *instance)
+{
+   switch (index) {
+% for e in physical_device_entrypoints:
+   case ${e.num}:
+      /* ${e.name} */
+   % if e.core_version:
+      return ${e.core_version.c_vk_version()} <= core_version;
+   % elif e.extensions:
+     % for ext in e.extensions:
+        % if ext.type == 'instance':
+      if (instance->${ext.name[3:]}) return true;
+        % else:
+      /* All device extensions are considered enabled at the instance level */
+      return true;
+        % endif
+     % endfor
+      return false;
+   % else:
+      return true;
+   % endif
+% endfor
+   default:
+      return false;
+   }
+}
+
+/** Return true if the core version or extension in which the given entrypoint
+ * is defined is enabled.
+ *
+ * If device is NULL, all device extensions are considered enabled.
+ */
+bool
+libresoc_device_entrypoint_is_enabled(int index, uint32_t core_version,
+                                 const struct libresoc_instance_extension_table *instance,
+                                 const struct libresoc_device_extension_table *device)
+{
+   switch (index) {
+% for e in device_entrypoints:
+   case ${e.num}:
+      /* ${e.name} */
+   % if e.core_version:
+      return ${e.core_version.c_vk_version()} <= core_version;
+   % elif e.extensions:
+     % for ext in e.extensions:
+        % if ext.type == 'instance':
+           <% assert False %>
+        % else:
+      if (!device || device->${ext.name[3:]}) return true;
+        % endif
+     % endfor
+      return false;
+   % else:
+      return true;
+   % endif
+% endfor
+   default:
+      return false;
+   }
+}
+
+int
+libresoc_get_instance_entrypoint_index(const char *name)
+{
+   return instance_string_map_lookup(name);
+}
+
+int
+libresoc_get_physical_device_entrypoint_index(const char *name)
+{
+   return physical_device_string_map_lookup(name);
+}
+
+int
+libresoc_get_device_entrypoint_index(const char *name)
+{
+   return device_string_map_lookup(name);
+}
+
+const char *
+libresoc_get_instance_entry_name(int index)
+{
+   return instance_entry_name(index);
+}
+
+const char *
+libresoc_get_physical_device_entry_name(int index)
+{
+   return physical_device_entry_name(index);
+}
+
+const char *
+libresoc_get_device_entry_name(int index)
+{
+   return device_entry_name(index);
+}
+
+void *
+libresoc_lookup_entrypoint(const char *name)
+{
+   int idx = libresoc_get_instance_entrypoint_index(name);
+   if (idx >= 0)
+      return libresoc_instance_dispatch_table.entrypoints[idx];
+
+   idx = libresoc_get_physical_device_entrypoint_index(name);
+   if (idx >= 0)
+      return libresoc_physical_device_dispatch_table.entrypoints[idx];
+
+   idx = libresoc_get_device_entrypoint_index(name);
+   if (idx >= 0)
+      return libresoc_device_dispatch_table.entrypoints[idx];
+
+   return NULL;
+}""", output_encoding='utf-8')
+
+U32_MASK = 2**32 - 1
+
+PRIME_FACTOR = 5024183
+PRIME_STEP = 19
+
+class StringIntMapEntry(object):
+    def __init__(self, string, num):
+        self.string = string
+        self.num = num
+
+        # Calculate the same hash value that we will calculate in C.
+        h = 0
+        for c in string:
+            h = ((h * PRIME_FACTOR) + ord(c)) & U32_MASK
+        self.hash = h
+
+        self.offset = None
+
+def round_to_pow2(x):
+    return 2**int(math.ceil(math.log(x, 2)))
+
+class StringIntMap(object):
+    def __init__(self):
+        self.baked = False
+        self.strings = dict()
+
+    def add_string(self, string, num):
+        assert not self.baked
+        assert string not in self.strings
+        assert 0 <= num < 2**31
+        self.strings[string] = StringIntMapEntry(string, num)
+
+    def bake(self):
+        self.sorted_strings = \
+            sorted(self.strings.values(), key=lambda x: x.string)
+        offset = 0
+        for entry in self.sorted_strings:
+            entry.offset = offset
+            offset += len(entry.string) + 1
+
+        # Save off some values that we'll need in C
+        self.hash_size = round_to_pow2(len(self.strings) * 1.25)
+        self.hash_mask = self.hash_size - 1
+        self.prime_factor = PRIME_FACTOR
+        self.prime_step = PRIME_STEP
+
+        self.mapping = [-1] * self.hash_size
+        self.collisions = [0] * 10
+        for idx, s in enumerate(self.sorted_strings):
+            level = 0
+            h = s.hash
+            while self.mapping[h & self.hash_mask] >= 0:
+                h = h + PRIME_STEP
+                level = level + 1
+            self.collisions[min(level, 9)] += 1
+            self.mapping[h & self.hash_mask] = idx
+
+EntrypointParam = namedtuple('EntrypointParam', 'type name decl')
+
+class EntrypointBase(object):
+    def __init__(self, name):
+        self.name = name
+        self.alias = None
+        self.guard = None
+        self.enabled = False
+        self.num = None
+        # Extensions which require this entrypoint
+        self.core_version = None
+        self.extensions = []
+
+class Entrypoint(EntrypointBase):
+    def __init__(self, name, return_type, params, guard=None):
+        super(Entrypoint, self).__init__(name)
+        self.return_type = return_type
+        self.params = params
+        self.guard = guard
+
+    def is_physical_device_entrypoint(self):
+        return self.params[0].type in ('VkPhysicalDevice', )
+
+    def is_device_entrypoint(self):
+        return self.params[0].type in ('VkDevice', 'VkCommandBuffer', 'VkQueue')
+
+    def prefixed_name(self, prefix):
+        assert self.name.startswith('vk')
+        return prefix + '_' + self.name[2:]
+
+    def decl_params(self):
+        return ', '.join(p.decl for p in self.params)
+
+    def call_params(self):
+        return ', '.join(p.name for p in self.params)
+
+class EntrypointAlias(EntrypointBase):
+    def __init__(self, name, entrypoint):
+        super(EntrypointAlias, self).__init__(name)
+        self.alias = entrypoint
+
+    def is_physical_device_entrypoint(self):
+        return self.alias.is_physical_device_entrypoint()
+
+    def is_device_entrypoint(self):
+        return self.alias.is_device_entrypoint()
+
+    def prefixed_name(self, prefix):
+        return self.alias.prefixed_name(prefix)
+
+def get_entrypoints(doc, entrypoints_to_defines):
+    """Extract the entry points from the registry."""
+    entrypoints = OrderedDict()
+
+    for command in doc.findall('./commands/command'):
+        if 'alias' in command.attrib:
+            alias = command.attrib['name']
+            target = command.attrib['alias']
+            entrypoints[alias] = EntrypointAlias(alias, entrypoints[target])
+        else:
+            name = command.find('./proto/name').text
+            ret_type = command.find('./proto/type').text
+            params = [EntrypointParam(
+                type=p.find('./type').text,
+                name=p.find('./name').text,
+                decl=''.join(p.itertext())
+            ) for p in command.findall('./param')]
+            guard = entrypoints_to_defines.get(name)
+            # They really need to be unique
+            assert name not in entrypoints
+            entrypoints[name] = Entrypoint(name, ret_type, params, guard)
+
+    for feature in doc.findall('./feature'):
+        assert feature.attrib['api'] == 'vulkan'
+        version = VkVersion(feature.attrib['number'])
+        if version > MAX_API_VERSION:
+            continue
+
+        for command in feature.findall('./require/command'):
+            e = entrypoints[command.attrib['name']]
+            e.enabled = True
+            assert e.core_version is None
+            e.core_version = version
+
+    supported_exts = dict((ext.name, ext) for ext in EXTENSIONS)
+    for extension in doc.findall('.extensions/extension'):
+        ext_name = extension.attrib['name']
+        if ext_name not in supported_exts:
+            continue
+
+        ext = supported_exts[ext_name]
+        ext.type = extension.attrib['type']
+
+        for command in extension.findall('./require/command'):
+            e = entrypoints[command.attrib['name']]
+            e.enabled = True
+            assert e.core_version is None
+            e.extensions.append(ext)
+
+    return [e for e in entrypoints.values() if e.enabled]
+
+
+def get_entrypoints_defines(doc):
+    """Maps entry points to extension defines."""
+    entrypoints_to_defines = {}
+
+    platform_define = {}
+    for platform in doc.findall('./platforms/platform'):
+        name = platform.attrib['name']
+        define = platform.attrib['protect']
+        platform_define[name] = define
+
+    for extension in doc.findall('./extensions/extension[@platform]'):
+        platform = extension.attrib['platform']
+        define = platform_define[platform]
+
+        for entrypoint in extension.findall('./require/command'):
+            fullname = entrypoint.attrib['name']
+            entrypoints_to_defines[fullname] = define
+
+    return entrypoints_to_defines
+
+
+def main():
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--outdir', help='Where to write the files.',
+                        required=True)
+    parser.add_argument('--xml',
+                        help='Vulkan API XML file.',
+                        required=True,
+                        action='append',
+                        dest='xml_files')
+    args = parser.parse_args()
+
+    entrypoints = []
+
+    for filename in args.xml_files:
+        doc = et.parse(filename)
+        entrypoints += get_entrypoints(doc, get_entrypoints_defines(doc))
+
+    device_entrypoints = []
+    physical_device_entrypoints = []
+    instance_entrypoints = []
+    for e in entrypoints:
+        if e.is_device_entrypoint():
+            device_entrypoints.append(e)
+        elif e.is_physical_device_entrypoint():
+            physical_device_entrypoints.append(e)
+        else:
+            instance_entrypoints.append(e)
+
+    device_strmap = StringIntMap()
+    for num, e in enumerate(device_entrypoints):
+        device_strmap.add_string(e.name, num)
+        e.num = num
+    device_strmap.bake()
+
+    physical_device_strmap = StringIntMap()
+    for num, e in enumerate(physical_device_entrypoints):
+        physical_device_strmap.add_string(e.name, num)
+        e.num = num
+    physical_device_strmap.bake()
+
+    instance_strmap = StringIntMap()
+    for num, e in enumerate(instance_entrypoints):
+        instance_strmap.add_string(e.name, num)
+        e.num = num
+    instance_strmap.bake()
+
+    # For outputting entrypoints.h we generate a libresoc_EntryPoint() prototype
+    # per entry point.
+    try:
+        with open(os.path.join(args.outdir, 'libresoc_entrypoints.h'), 'wb') as f:
+            f.write(TEMPLATE_H.render(instance_entrypoints=instance_entrypoints,
+                                      physical_device_entrypoints=physical_device_entrypoints,
+                                      device_entrypoints=device_entrypoints,
+                                      LAYERS=LAYERS,
+                                      filename=os.path.basename(__file__)))
+        with open(os.path.join(args.outdir, 'libresoc_entrypoints.c'), 'wb') as f:
+            f.write(TEMPLATE_C.render(instance_entrypoints=instance_entrypoints,
+                                      physical_device_entrypoints=physical_device_entrypoints,
+                                      device_entrypoints=device_entrypoints,
+                                      LAYERS=LAYERS,
+                                      instance_strmap=instance_strmap,
+                                      physical_device_strmap=physical_device_strmap,
+                                      device_strmap=device_strmap,
+                                      filename=os.path.basename(__file__)))
+    except Exception:
+        # In the event there's an error, this imports some helpers from mako
+        # to print a useful stack trace and prints it, then exits with
+        # status 1, if python is run with debug; otherwise it just raises
+        # the exception
+        if __debug__:
+            import sys
+            from mako import exceptions
+            sys.stderr.write(exceptions.text_error_template().render() + '\n')
+            sys.exit(1)
+        raise
+
+
+if __name__ == '__main__':
+    main()
diff --git a/src/libre-soc/vulkan/libresoc_extensions.py b/src/libre-soc/vulkan/libresoc_extensions.py
new file mode 100644 (file)
index 0000000..3d83d41
--- /dev/null
@@ -0,0 +1,137 @@
+COPYRIGHT = """\
+/*
+ * Copyright 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"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
+ */
+"""
+
+import copy
+import re
+
+def _bool_to_c_expr(b):
+    if b is True:
+        return 'true'
+    if b is False:
+        return 'false'
+    return b
+
+class Extension:
+    def __init__(self, name, ext_version, enable):
+        self.name = name
+        self.ext_version = int(ext_version)
+        self.enable = _bool_to_c_expr(enable)
+
+class ApiVersion:
+    def __init__(self, version, enable):
+        self.version = version
+        self.enable = _bool_to_c_expr(enable)
+
+API_PATCH_VERSION = 102
+
+# Supported API versions.  Each one is the maximum patch version for the given
+# version.  Version come in increasing order and each version is available if
+# it's provided "enable" condition is true and all previous versions are
+# available.
+API_VERSIONS = [
+    ApiVersion('1.0',   True),
+
+    # FIXME: for now we only support 1.0. We maintain this support from anv just in case in
+    # the future we support more that one version supported.
+    # ApiVersion('1.1',   <condition> ),
+]
+
+MAX_API_VERSION = None # Computed later
+
+EXTENSIONS = [
+    #FIXME: for now we don't support additional extensions beyond 1.0. Revisit later
+]
+
+# Sort the extension list the way we expect: KHR, then EXT, then vendors
+# alphabetically. For digits, read them as a whole number sort that.
+# eg.: VK_KHR_8bit_storage < VK_KHR_16bit_storage < VK_EXT_acquire_xlib_display
+def extension_order(ext):
+    order = []
+    for substring in re.split('(KHR|EXT|[0-9]+)', ext.name):
+        if substring == 'KHR':
+            order.append(1)
+        if substring == 'EXT':
+            order.append(2)
+        elif substring.isdigit():
+            order.append(int(substring))
+        else:
+            order.append(substring)
+    return order
+for i in range(len(EXTENSIONS) - 1):
+    if extension_order(EXTENSIONS[i + 1]) < extension_order(EXTENSIONS[i]):
+        print(EXTENSIONS[i + 1].name + ' should come before ' + EXTENSIONS[i].name)
+        exit(1)
+
+class VkVersion:
+    def __init__(self, string):
+        split = string.split('.')
+        self.major = int(split[0])
+        self.minor = int(split[1])
+        if len(split) > 2:
+            assert len(split) == 3
+            self.patch = int(split[2])
+        else:
+            self.patch = None
+
+        # Sanity check.  The range bits are required by the definition of the
+        # VK_MAKE_VERSION macro
+        assert self.major < 1024 and self.minor < 1024
+        assert self.patch is None or self.patch < 4096
+        assert str(self) == string
+
+    def __str__(self):
+        ver_list = [str(self.major), str(self.minor)]
+        if self.patch is not None:
+            ver_list.append(str(self.patch))
+        return '.'.join(ver_list)
+
+    def c_vk_version(self):
+        patch = self.patch if self.patch is not None else 0
+        ver_list = [str(self.major), str(self.minor), str(patch)]
+        return 'VK_MAKE_VERSION(' + ', '.join(ver_list) + ')'
+
+    def __int_ver(self):
+        # This is just an expansion of VK_VERSION
+        patch = self.patch if self.patch is not None else 0
+        return (self.major << 22) | (self.minor << 12) | patch
+
+    def __gt__(self, other):
+        # If only one of them has a patch version, "ignore" it by making
+        # other's patch version match self.
+        if (self.patch is None) != (other.patch is None):
+            other = copy.copy(other)
+            other.patch = self.patch
+
+        return self.__int_ver() > other.__int_ver()
+
+
+
+MAX_API_VERSION = VkVersion('0.0.0')
+for version in API_VERSIONS:
+    version.version = VkVersion(version.version)
+    version.version.patch = API_PATCH_VERSION
+    assert version.version > MAX_API_VERSION
+    MAX_API_VERSION = version.version
diff --git a/src/libre-soc/vulkan/libresoc_extensions_gen.py b/src/libre-soc/vulkan/libresoc_extensions_gen.py
new file mode 100644 (file)
index 0000000..1a25a7e
--- /dev/null
@@ -0,0 +1,216 @@
+COPYRIGHT = """\
+/*
+ * Copyright 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"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
+ */
+"""
+
+import argparse
+import xml.etree.cElementTree as et
+
+from mako.template import Template
+
+from libresoc_extensions import *
+
+platform_defines = []
+
+def _init_exts_from_xml(xml):
+    """ Walk the Vulkan XML and fill out extra extension information. """
+
+    xml = et.parse(xml)
+
+    ext_name_map = {}
+    for ext in EXTENSIONS:
+        ext_name_map[ext.name] = ext
+
+    # KHR_display is missing from the list.
+    platform_defines.append('VK_USE_PLATFORM_DISPLAY_KHR')
+    for platform in xml.findall('./platforms/platform'):
+        platform_defines.append(platform.attrib['protect'])
+
+    for ext_elem in xml.findall('.extensions/extension'):
+        ext_name = ext_elem.attrib['name']
+        if ext_name not in ext_name_map:
+            continue
+
+        ext = ext_name_map[ext_name]
+        ext.type = ext_elem.attrib['type']
+
+_TEMPLATE_H = Template(COPYRIGHT + """
+
+#ifndef LIBRESOC_EXTENSIONS_H
+#define LIBRESOC_EXTENSIONS_H
+
+#include "stdbool.h"
+
+#define LIBRESOC_INSTANCE_EXTENSION_COUNT ${len(instance_extensions)}
+
+extern const VkExtensionProperties libresoc_instance_extensions[];
+
+struct libresoc_instance_extension_table {
+   union {
+      bool extensions[LIBRESOC_INSTANCE_EXTENSION_COUNT];
+      struct {
+%for ext in instance_extensions:
+         bool ${ext.name[3:]};
+%endfor
+      };
+   };
+};
+
+extern const struct libresoc_instance_extension_table libresoc_instance_extensions_supported;
+
+
+#define LIBRESOC_DEVICE_EXTENSION_COUNT ${len(device_extensions)}
+
+extern const VkExtensionProperties libresoc_device_extensions[];
+
+struct libresoc_device_extension_table {
+   union {
+      bool extensions[LIBRESOC_DEVICE_EXTENSION_COUNT];
+      struct {
+%for ext in device_extensions:
+        bool ${ext.name[3:]};
+%endfor
+      };
+   };
+};
+
+struct libresoc_physical_device;
+
+void
+libresoc_physical_device_get_supported_extensions(const struct libresoc_physical_device *device,
+                                             struct libresoc_device_extension_table *extensions);
+
+#endif /* LIBRESOC_EXTENSIONS_H */
+""")
+
+_TEMPLATE_C = Template(COPYRIGHT + """
+#include "libresoc_private.h"
+
+#include "vk_util.h"
+
+/* Convert the VK_USE_PLATFORM_* defines to booleans */
+%for platform_define in platform_defines:
+#ifdef ${platform_define}
+#   undef ${platform_define}
+#   define ${platform_define} true
+#else
+#   define ${platform_define} false
+#endif
+%endfor
+
+/* And ANDROID too */
+#ifdef ANDROID
+#   undef ANDROID
+#   define ANDROID true
+#else
+#   define ANDROID false
+#endif
+
+#define LIBRESOC_HAS_SURFACE (VK_USE_PLATFORM_WAYLAND_KHR || \\
+                         VK_USE_PLATFORM_XCB_KHR || \\
+                         VK_USE_PLATFORM_XLIB_KHR || \\
+                         VK_USE_PLATFORM_DISPLAY_KHR)
+
+static const uint32_t MAX_API_VERSION = ${MAX_API_VERSION.c_vk_version()};
+
+const VkExtensionProperties libresoc_instance_extensions[LIBRESOC_INSTANCE_EXTENSION_COUNT] = {
+%for ext in instance_extensions:
+   {"${ext.name}", ${ext.ext_version}},
+%endfor
+};
+
+const struct libresoc_instance_extension_table libresoc_instance_extensions_supported = {
+%for ext in instance_extensions:
+   .${ext.name[3:]} = ${ext.enable},
+%endfor
+};
+
+uint32_t
+libresoc_physical_device_api_version(struct libresoc_physical_device *device)
+{
+    uint32_t version = 0;
+
+    uint32_t override = vk_get_version_override();
+    if (override)
+        return MIN2(override, MAX_API_VERSION);
+
+%for version in API_VERSIONS:
+    if (!(${version.enable}))
+        return version;
+    version = ${version.version.c_vk_version()};
+
+%endfor
+    return version;
+}
+
+const VkExtensionProperties libresoc_device_extensions[LIBRESOC_DEVICE_EXTENSION_COUNT] = {
+%for ext in device_extensions:
+   {"${ext.name}", ${ext.ext_version}},
+%endfor
+};
+
+void
+libresoc_physical_device_get_supported_extensions(const struct libresoc_physical_device *device,
+                                             struct libresoc_device_extension_table *extensions)
+{
+   *extensions = (struct libresoc_device_extension_table) {
+%for ext in device_extensions:
+      .${ext.name[3:]} = ${ext.enable},
+%endfor
+   };
+}
+""")
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--out-c', help='Output C file.')
+    parser.add_argument('--out-h', help='Output H file.')
+    parser.add_argument('--xml',
+                        help='Vulkan API XML file.',
+                        required=True,
+                        action='append',
+                        dest='xml_files')
+    args = parser.parse_args()
+
+    for filename in args.xml_files:
+        _init_exts_from_xml(filename)
+
+    for ext in EXTENSIONS:
+        assert ext.type == 'instance' or ext.type == 'device'
+
+    template_env = {
+        'API_VERSIONS': API_VERSIONS,
+        'MAX_API_VERSION': MAX_API_VERSION,
+        'instance_extensions': [e for e in EXTENSIONS if e.type == 'instance'],
+        'device_extensions': [e for e in EXTENSIONS if e.type == 'device'],
+        'platform_defines': platform_defines,
+    }
+
+    if args.out_h:
+        with open(args.out_h, 'w') as f:
+            f.write(_TEMPLATE_H.render(**template_env))
+
+    if args.out_c:
+        with open(args.out_c, 'w') as f:
+            f.write(_TEMPLATE_C.render(**template_env))
diff --git a/src/libre-soc/vulkan/libresoc_icd.py b/src/libre-soc/vulkan/libresoc_icd.py
new file mode 100644 (file)
index 0000000..dcc479e
--- /dev/null
@@ -0,0 +1,48 @@
+# Copyright 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"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sub license, 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 NON-INFRINGEMENT.
+# IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS 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.
+
+import json
+import os.path
+import argparse
+
+from libresoc_extensions import *
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--out', help='Output json file.', required=True)
+    parser.add_argument('--lib-path', help='Path to libvulkan_libresoc.so')
+    args = parser.parse_args()
+
+    path = 'libvulkan_libresoc.so'
+    if args.lib_path:
+        path = os.path.join(args.lib_path, path)
+
+    json_data = {
+        'file_format_version': '1.0.0',
+        'ICD': {
+            'library_path': path,
+            'api_version': str(MAX_API_VERSION),
+        },
+    }
+
+    with open(args.out, 'w') as f:
+        json.dump(json_data, f, indent = 4, sort_keys=True, separators=(',', ': '))
diff --git a/src/libre-soc/vulkan/libresoc_pipeline.c b/src/libre-soc/vulkan/libresoc_pipeline.c
new file mode 100644 (file)
index 0000000..211c209
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ *
+ * based in part on anv driver which is:
+ * 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.
+ */
+
+#include "libresoc_private.h"
+#include "vk_util.h"
+
+#include "vk_format.h"
+#include "util/debug.h"
+
+VkResult
+libresoc_CreateShaderModule(VkDevice _device,
+               const VkShaderModuleCreateInfo *pCreateInfo,
+               const VkAllocationCallbacks *pAllocator,
+               VkShaderModule *pShaderModule)
+{
+       /* FIXME: stub */
+
+       return VK_SUCCESS;
+}
+
+void
+libresoc_DestroyShaderModule(VkDevice _device,
+               VkShaderModule _module,
+               const VkAllocationCallbacks *pAllocator)
+{
+       /* FIXME: stub */
+}
+
+VkResult libresoc_CreateGraphicsPipelines(
+       VkDevice                                    _device,
+       VkPipelineCache                             pipelineCache,
+       uint32_t                                    count,
+       const VkGraphicsPipelineCreateInfo*         pCreateInfos,
+       const VkAllocationCallbacks*                pAllocator,
+       VkPipeline*                                 pPipelines)
+{
+       return VK_ERROR_UNKNOWN;
+       //FIXME: stub
+}
+
+VkResult libresoc_CreateComputePipelines(
+       VkDevice                                    _device,
+       VkPipelineCache                             pipelineCache,
+       uint32_t                                    count,
+       const VkComputePipelineCreateInfo*          pCreateInfos,
+       const VkAllocationCallbacks*                pAllocator,
+       VkPipeline*                                 pPipelines)
+{
+       VkResult result = VK_SUCCESS;
+        //FIXME: stub
+
+       return result;
+}
+
+void libresoc_DestroyPipeline(
+       VkDevice                                    _device,
+       VkPipeline                                  _pipeline,
+       const VkAllocationCallbacks*                pAllocator)
+{
+        //FIXME: stub
+}
diff --git a/src/libre-soc/vulkan/libresoc_private.h b/src/libre-soc/vulkan/libresoc_private.h
new file mode 100644 (file)
index 0000000..3b497a3
--- /dev/null
@@ -0,0 +1,175 @@
+/*
+ * Copyright © 2019 Raspberry Pi
+ *
+ * based in part on anv driver which is:
+ * Copyright © 2015 Intel Corporation
+ *
+ * based in part on radv driver which is:
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ *
+ * 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.
+ */
+#ifndef LIBRESOC_PRIVATE_H
+#define LIBRESOC_PRIVATE_H
+
+#include <stdio.h>
+#include <string.h>
+#include <vulkan/vulkan.h>
+#include <vulkan/vk_icd.h>
+
+//#include "common/libresoc_device_info.h"
+
+#include "vk_debug_report.h"
+#include "util/xmlconfig.h"
+
+#include "libresoc_entrypoints.h"
+#include "libresoc_extensions.h"
+
+struct libresoc_instance;
+
+struct libresoc_device {
+   VK_LOADER_DATA _loader_data;
+
+   VkAllocationCallbacks alloc;
+
+   struct libresoc_instance *instance;
+
+   struct libresoc_device_extension_table enabled_extensions;
+   struct libresoc_device_dispatch_table dispatch;
+
+   /* FIXME: stub */
+};
+
+
+struct libresoc_physical_device {
+   VK_LOADER_DATA _loader_data;
+
+   struct libresoc_instance *instance;
+
+   struct libresoc_device_extension_table supported_extensions;
+   struct libresoc_physical_device_dispatch_table dispatch;
+
+   /* FIXME: stub */
+};
+
+struct libresoc_app_info {
+   const char *app_name;
+   uint32_t app_version;
+   const char *engine_name;
+   uint32_t engine_version;
+   uint32_t api_version;
+};
+
+struct libresoc_instance {
+   VK_LOADER_DATA _loader_data;
+
+   VkAllocationCallbacks alloc;
+
+   struct libresoc_app_info app_info;
+
+   struct libresoc_instance_extension_table enabled_extensions;
+   struct libresoc_instance_dispatch_table dispatch;
+   struct libresoc_device_dispatch_table device_dispatch;
+
+   int physicalDeviceCount;
+   struct libresoc_physical_device physicalDevice;
+
+   struct vk_debug_report_instance debug_report_callbacks;
+};
+
+struct libresoc_queue {
+   VK_LOADER_DATA _loader_data;
+
+   struct libresoc_device *device;
+
+   VkDeviceQueueCreateFlags flags;
+
+   /* FIXME: stub */
+};
+
+struct libresoc_cmd_buffer {
+   VK_LOADER_DATA _loader_data;
+
+   struct libresoc_device *device;
+
+   /* FIXME: stub */
+};
+
+uint32_t libresoc_physical_device_api_version(struct libresoc_physical_device *dev);
+
+int libresoc_get_instance_entrypoint_index(const char *name);
+int libresoc_get_device_entrypoint_index(const char *name);
+int libresoc_get_physical_device_entrypoint_index(const char *name);
+
+const char *libresoc_get_instance_entry_name(int index);
+const char *libresoc_get_physical_device_entry_name(int index);
+const char *libresoc_get_device_entry_name(int index);
+
+bool
+libresoc_instance_entrypoint_is_enabled(int index, uint32_t core_version,
+                                    const struct libresoc_instance_extension_table *instance);
+bool
+libresoc_physical_device_entrypoint_is_enabled(int index, uint32_t core_version,
+                                           const struct libresoc_instance_extension_table *instance);
+bool
+libresoc_device_entrypoint_is_enabled(int index, uint32_t core_version,
+                                  const struct libresoc_instance_extension_table *instance,
+                                  const struct libresoc_device_extension_table *device);
+
+void *libresoc_lookup_entrypoint(const char *name);
+
+#define libresoc_printflike(a, b) __attribute__((__format__(__printf__, a, b)))
+
+VkResult __vk_errorf(struct libresoc_instance *instance, VkResult error,
+                     const char *file, int line,
+                     const char *format, ...);
+
+#define vk_error(instance, error) __vk_errorf(instance, error, __FILE__, __LINE__, NULL);
+#define vk_errorf(instance, error, format, ...) __vk_errorf(instance, error, __FILE__, __LINE__, format, ## __VA_ARGS__);
+
+void libresoc_loge(const char *format, ...) libresoc_printflike(1, 2);
+void libresoc_loge_v(const char *format, va_list va);
+
+#define LIBRESOC_DEFINE_HANDLE_CASTS(__libresoc_type, __VkType)   \
+                                                        \
+   static inline struct __libresoc_type *                    \
+   __libresoc_type ## _from_handle(__VkType _handle)         \
+   {                                                    \
+      return (struct __libresoc_type *) _handle;             \
+   }                                                    \
+                                                        \
+   static inline __VkType                               \
+   __libresoc_type ## _to_handle(struct __libresoc_type *_obj)    \
+   {                                                    \
+      return (__VkType) _obj;                           \
+   }
+
+#define LIBRESOC_FROM_HANDLE(__libresoc_type, __name, __handle)                        \
+   struct __libresoc_type *__name = __libresoc_type ## _from_handle(__handle)
+
+LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_cmd_buffer, VkCommandBuffer)
+LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_device, VkDevice)
+LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_instance, VkInstance)
+LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_physical_device, VkPhysicalDevice)
+LIBRESOC_DEFINE_HANDLE_CASTS(libresoc_queue, VkQueue)
+
+
+#endif /* LIBRESOC_PRIVATE_H */
diff --git a/src/libre-soc/vulkan/libresoc_util.c b/src/libre-soc/vulkan/libresoc_util.c
new file mode 100644 (file)
index 0000000..2d65b08
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2019 Raspberry Pi
+ *
+ * based in part on anv driver which is:
+ * Copyright © 2015 Intel Corporation
+ *
+ * based in part on radv driver which is:
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ *
+ * 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.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "vk_enum_to_str.h"
+#include "libresoc_private.h"
+
+/** Log an error message.  */
+void libresoc_printflike(1, 2)
+   libresoc_loge(const char *format, ...)
+{
+   va_list va;
+
+   va_start(va, format);
+   libresoc_loge_v(format, va);
+   va_end(va);
+}
+
+/** \see libresoc_loge() */
+void
+libresoc_loge_v(const char *format, va_list va)
+{
+   fprintf(stderr, "vk: error: ");
+   vfprintf(stderr, format, va);
+   fprintf(stderr, "\n");
+}
+
+VkResult
+__vk_errorf(struct libresoc_instance *instance, VkResult error, const char *file,
+            int line, const char *format, ...)
+{
+   va_list ap;
+   char buffer[256];
+
+   const char *error_str = vk_Result_to_str(error);
+
+#ifndef DEBUG
+      return error;
+#endif
+
+   if (format) {
+      va_start(ap, format);
+      vsnprintf(buffer, sizeof(buffer), format, ap);
+      va_end(ap);
+
+      fprintf(stderr, "%s:%d: %s (%s)\n", file, line, buffer, error_str);
+   } else {
+      fprintf(stderr, "%s:%d: %s\n", file, line, error_str);
+   }
+
+   return error;
+}
diff --git a/src/libre-soc/vulkan/meson.build b/src/libre-soc/vulkan/meson.build
new file mode 100644 (file)
index 0000000..b6cfaa5
--- /dev/null
@@ -0,0 +1,174 @@
+# Copyright © 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"), 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 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.
+
+libresoc_extensions_h = custom_target(
+  'libresoc_extensions.h',
+  input : ['libresoc_extensions_gen.py', vk_api_xml],
+  output : 'libresoc_extensions.h',
+  command : [
+    prog_python, '@INPUT0@', '--xml', '@INPUT1@',
+    '--out-h', '@OUTPUT@',
+    ],
+  depend_files : files('libresoc_extensions.py'),
+  )
+
+libresoc_extensions_c = custom_target(
+  'libresoc_extensions.c',
+  input : ['libresoc_extensions_gen.py', vk_api_xml],
+  output : 'libresoc_extensions.c',
+  command : [
+    prog_python, '@INPUT0@', '--xml', '@INPUT1@',
+    '--out-c', '@OUTPUT@',
+    ],
+  depend_files : files('libresoc_extensions.py'),
+  )
+
+
+libresoc_entrypoints = custom_target(
+  'libresoc_entrypoints.[ch]',
+  input : ['libresoc_entrypoints_gen.py', vk_api_xml],
+  output : ['libresoc_entrypoints.h', 'libresoc_entrypoints.c'],
+  command : [
+    prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--outdir',
+    meson.current_build_dir()
+    ],
+  depend_files : files('libresoc_extensions.py'),
+  )
+#libresoc_entrypoints = custom_target(
+#  'libresoc_entrypoints.[ch]',
+#  input : ['libresoc_entrypoints_gen.py', vk_api_xml],
+#  output : ['libresoc_entrypoints.h', 'libresoc_entrypoints.c'],
+#  command : [
+#    prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--outdir',
+#    meson.current_build_dir()
+#  ],
+#  depend_files : files('libresoc_extensions.py'),
+#)
+#
+#libresoc_extensions_c = custom_target(
+#  'libresoc_extensions.c',
+#  input : ['libresoc_extensions.py', vk_api_xml],
+#  output : ['libresoc_extensions.c', 'libresoc_extensions.h'],
+#  command : [
+#    prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--out-c', '@OUTPUT0@',
+#    '--out-h', '@OUTPUT1@'
+#  ],
+#)
+
+libresoc_vk_format_table_c = custom_target(
+  'libresoc_vk_format_table.c',
+  input : ['vk_format_table.py', 'vk_format_layout.csv'],
+  output : 'vk_format_table.c',
+  command : [prog_python, '@INPUT@'],
+  depend_files : files('vk_format_parse.py'),
+  capture : true,
+)
+
+liblibresoc_files = files(
+  'libresoc_device.c',
+  'libresoc_pipeline.c',
+  'libresoc_util.c',
+)
+
+libresoc_deps = []
+libresoc_flags = []
+
+libresoc_flags += '-DVK_USE_PLATFORM_DISPLAY_KHR'
+if with_platform_x11
+  #libresoc_deps += dep_xcb_dri3
+  #libresoc_flags += [
+  #  '-DVK_USE_PLATFORM_XCB_KHR',
+  #  '-DVK_USE_PLATFORM_XLIB_KHR',
+  #]
+  #liblibresoc_files += files('libresoc_wsi_x11.c')
+endif
+
+if with_platform_wayland
+  #libresoc_deps += dep_wayland_client
+  #libresoc_flags += '-DVK_USE_PLATFORM_WAYLAND_KHR'
+  #liblibresoc_files += files('libresoc_wsi_wayland.c')
+endif
+
+if system_has_kms_drm and not with_platform_android
+  #libresoc_flags += '-DVK_USE_PLATFORM_DISPLAY_KHR'
+  #liblibresoc_files += files('libresoc_wsi_display.c')
+endif
+
+if with_xlib_lease
+  #libresoc_deps += [dep_xcb_xrandr, dep_xlib_xrandr]
+  #libresoc_flags += '-DVK_USE_PLATFORM_XLIB_XRANDR_EXT'
+endif
+
+if with_platform_android
+  #libresoc_deps += dep_android
+  #libresoc_flags += [
+  #  '-DVK_USE_PLATFORM_ANDROID_KHR'
+  #]
+endif
+
+libvulkan_libresoc = shared_library(
+  'vulkan_libresoc',
+  [liblibresoc_files, libresoc_entrypoints, libresoc_extensions_c, libresoc_extensions_h, libresoc_vk_format_table_c, sha1_h],
+  include_directories : [
+    inc_include, inc_src, inc_mapi, inc_mesa,  inc_compiler, inc_util, inc_vulkan_wsi, #inc_gallium, inc_gallium_aux, inc_amd, inc_amd_common, inc_amd_common_llvm,
+  ],
+  link_with : [
+    libvulkan_wsi, #libamd_common, libamd_common_llvm, libamdgpu_addrlib, 
+  ],
+  dependencies : [idep_vulkan_util, libresoc_deps,idep_xmlconfig, dep_libdrm,
+        dep_llvm, dep_thread, dep_elf, dep_dl, dep_m,dep_valgrind, idep_mesautil, idep_nir,
+    # libresoc_deps, idep_aco, dep_libdrm_amdgpu,
+    #  idep_amdgfxregs_h, 
+  ],
+  c_args : [no_override_init_args, libresoc_flags],
+  cpp_args : [libresoc_flags],
+  link_args : [ld_args_build_id, ld_args_bsymbolic, ld_args_gc_sections],
+  gnu_symbol_visibility : 'hidden',
+  install : true,
+)
+
+if with_symbols_check
+  test(
+    'libresoc symbols check',
+    symbols_check,
+    args : [
+      '--lib', libvulkan_libresoc,
+      '--symbols-file', vulkan_icd_symbols,
+      '--ignore-symbol', 'ac_init_llvm_once',
+      symbols_check_args,
+    ],
+    suite : ['libresoc'],
+  )
+endif
+
+libresoc_icd = custom_target(
+  'libresoc_icd',
+  input : 'libresoc_icd.py',
+  output : 'libresoc_icd.@0@.json'.format(host_machine.cpu()),
+  command : [
+    prog_python, '@INPUT@',
+    '--lib-path', join_paths(get_option('prefix'), get_option('libdir')),
+    '--out', '@OUTPUT@',
+  ],
+  depend_files : files('libresoc_extensions.py'),
+  build_by_default : true,
+  install_dir : with_vulkan_icd_dir,
+  install : true,
+)
index ed0a3091d6dfd4f3ed662c9ca654175491717019..dfe41d08972ec6e35120aa54c4fcae10b3942c3a 100644 (file)
@@ -91,6 +91,9 @@ endif
 if with_dri_i965 or with_intel_vk or with_gallium_iris
   subdir('intel')
 endif
 if with_dri_i965 or with_intel_vk or with_gallium_iris
   subdir('intel')
 endif
+if with_libresoc_vk
+  subdir('libre-soc')
+endif
 subdir('mesa')
 subdir('loader')
 if with_platform_haiku
 subdir('mesa')
 subdir('loader')
 if with_platform_haiku