summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2020-06-03 13:18:30 -0700
committerMarge Bot <eric+marge@anholt.net>2021-04-08 17:15:37 +0000
commitb0736f49d31b2b347ed42fadd45b627b9e0a5a48 (patch)
treeb65c16d309d6065ac20deb5b23322b53326fa457
parentdab339b07e44636a2879d8e99a97f96df7a4a3ac (diff)
venus: add driver skeleton
It only has enough stubs to be loadable by the loader. Signed-off-by: Chia-I Wu <olvaffe@gmail.com> Reviewed-by: Ryan Neph <ryanneph@google.com> Reviewed-by: Gert Wollny <gert.wollny@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5800>
-rw-r--r--meson.build1
-rw-r--r--meson_options.txt2
-rw-r--r--src/meson.build2
-rw-r--r--src/virtio/meson.build4
-rw-r--r--src/virtio/vulkan/.clang-format37
-rw-r--r--src/virtio/vulkan/meson.build62
-rw-r--r--src/virtio/vulkan/vn_common.c103
-rw-r--r--src/virtio/vulkan/vn_common.h217
-rw-r--r--src/virtio/vulkan/vn_device.c225
-rw-r--r--src/virtio/vulkan/vn_device.h59
-rw-r--r--src/virtio/vulkan/vn_icd.c49
-rw-r--r--src/virtio/vulkan/vn_icd.h31
12 files changed, 790 insertions, 2 deletions
diff --git a/meson.build b/meson.build
index 9520da6252b..5b2e706e70e 100644
--- a/meson.build
+++ b/meson.build
@@ -273,6 +273,7 @@ with_intel_vk = _vulkan_drivers.contains('intel')
with_amd_vk = _vulkan_drivers.contains('amd')
with_freedreno_vk = _vulkan_drivers.contains('freedreno')
with_swrast_vk = _vulkan_drivers.contains('swrast')
+with_virtio_vk = _vulkan_drivers.contains('virtio-experimental')
with_freedreno_kgsl = get_option('freedreno-kgsl')
with_broadcom_vk = _vulkan_drivers.contains('broadcom')
with_any_vk = _vulkan_drivers.length() != 0
diff --git a/meson_options.txt b/meson_options.txt
index a3967c50d59..a7030aba31e 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -178,7 +178,7 @@ option(
'vulkan-drivers',
type : 'array',
value : ['auto'],
- choices : ['auto', 'amd', 'broadcom', 'freedreno', 'intel', 'swrast'],
+ choices : ['auto', 'amd', 'broadcom', 'freedreno', 'intel', 'swrast', 'virtio-experimental'],
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/meson.build b/src/meson.build
index 84a990358a3..0c60f9bc463 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -86,7 +86,7 @@ endif
if with_gallium_panfrost or with_gallium_lima
subdir('panfrost')
endif
-if with_gallium_virgl
+if with_gallium_virgl or with_virtio_vk
subdir('virtio')
endif
if with_any_intel
diff --git a/src/virtio/meson.build b/src/virtio/meson.build
index 1bd14feba91..cf84c8311a6 100644
--- a/src/virtio/meson.build
+++ b/src/virtio/meson.build
@@ -19,3 +19,7 @@
# SOFTWARE.
inc_virtio = include_directories('.')
+
+if with_virtio_vk
+ subdir('vulkan')
+endif
diff --git a/src/virtio/vulkan/.clang-format b/src/virtio/vulkan/.clang-format
new file mode 100644
index 00000000000..ecf6925ba98
--- /dev/null
+++ b/src/virtio/vulkan/.clang-format
@@ -0,0 +1,37 @@
+BasedOnStyle: LLVM
+AlwaysBreakAfterReturnType: TopLevel
+BinPackParameters: false
+BraceWrapping:
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: true
+ AfterStruct: false
+ BeforeElse: false
+ SplitEmptyFunction: true
+BreakBeforeBraces: Custom
+ColumnLimit: 78
+ContinuationIndentWidth: 3
+Cpp11BracedListStyle: false
+ForEachMacros:
+ - list_for_each_entry
+ - list_for_each_entry_safe
+ - vk_outarray_append
+ - vk_foreach_struct
+ - vk_foreach_struct_const
+IncludeBlocks: Regroup
+IncludeCategories:
+ - Regex: '^"vn_common.h"$'
+ Priority: 0
+ - Regex: '^"vn_'
+ Priority: 3
+ - Regex: '^"(venus-protocol/|virtio-gpu/|vtest/)'
+ Priority: 2
+ - Regex: '^"(c11/|util/|drm-uapi/|vk_|wsi_|git_)'
+ Priority: 2
+ - Regex: '.*'
+ Priority: 1
+IndentWidth: 3
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyExcessCharacter: 100
+SpaceAfterCStyleCast: false
+SpaceBeforeCpp11BracedList: false
diff --git a/src/virtio/vulkan/meson.build b/src/virtio/vulkan/meson.build
new file mode 100644
index 00000000000..4b66a2d7bc7
--- /dev/null
+++ b/src/virtio/vulkan/meson.build
@@ -0,0 +1,62 @@
+# Copyright 2019 Google LLC
+# SPDX-License-Identifier: MIT
+#
+# based in part on anv and radv which are:
+# Copyright © 2017 Intel Corporation
+
+vn_entrypoints = custom_target(
+ 'vn_entrypoints',
+ input : [vk_entrypoints_gen, vk_api_xml],
+ output : ['vn_entrypoints.h', 'vn_entrypoints.c'],
+ command : [
+ prog_python, '@INPUT0@', '--xml', '@INPUT1@', '--proto', '--weak',
+ '--out-h', '@OUTPUT0@', '--out-c', '@OUTPUT1@', '--prefix', 'vn',
+ ],
+)
+
+virtio_icd = custom_target(
+ 'virtio_icd',
+ input : [vk_icd_gen, vk_api_xml],
+ output : 'virtio_icd.@0@.json'.format(host_machine.cpu()),
+ command : [
+ prog_python, '@INPUT0@',
+ '--api-version', '1.2', '--xml', '@INPUT1@',
+ '--lib-path', join_paths(get_option('prefix'), get_option('libdir'),
+ 'libvulkan_virtio.so'),
+ '--out', '@OUTPUT@',
+ ],
+ build_by_default : true,
+ install_dir : with_vulkan_icd_dir,
+ install : true,
+)
+
+libvn_files = files(
+ 'vn_common.c',
+ 'vn_device.c',
+ 'vn_icd.c',
+)
+
+vn_deps = [
+ dep_thread,
+ idep_mesautil,
+ idep_vulkan_util,
+ idep_xmlconfig,
+]
+
+vn_flags = [
+ no_override_init_args,
+]
+
+libvulkan_virtio = shared_library(
+ 'vulkan_virtio',
+ [libvn_files, vn_entrypoints, sha1_h],
+ include_directories : [
+ inc_include, inc_src, inc_vulkan_wsi, inc_virtio,
+ ],
+ link_with : [libvulkan_wsi],
+ dependencies : [vn_deps],
+ c_args : [vn_flags],
+ link_args : [ld_args_bsymbolic, ld_args_gc_sections],
+ gnu_symbol_visibility : 'hidden',
+ install : true,
+)
diff --git a/src/virtio/vulkan/vn_common.c b/src/virtio/vulkan/vn_common.c
new file mode 100644
index 00000000000..e167d85cb7c
--- /dev/null
+++ b/src/virtio/vulkan/vn_common.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2019 Google LLC
+ * SPDX-License-Identifier: MIT
+ *
+ * based in part on anv and radv which are:
+ * Copyright © 2015 Intel Corporation
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ */
+
+#include "vn_common.h"
+
+#include <stdarg.h>
+
+#include "util/debug.h"
+#include "util/log.h"
+#include "vk_enum_to_str.h"
+
+#if __STDC_VERSION__ >= 201112L
+#define VN_MAX_ALIGN _Alignof(max_align_t)
+#else
+#define VN_MAX_ALIGN VN_DEFAULT_ALIGN
+#endif
+
+static const struct debug_control vn_debug_options[] = {
+ { "init", VN_DEBUG_INIT },
+ { "result", VN_DEBUG_RESULT },
+ { NULL, 0 },
+};
+
+uint64_t vn_debug;
+
+static void
+vn_debug_init_once(void)
+{
+ vn_debug = parse_debug_string(getenv("VN_DEBUG"), vn_debug_options);
+}
+
+void
+vn_debug_init(void)
+{
+ static once_flag once = ONCE_FLAG_INIT;
+ call_once(&once, vn_debug_init_once);
+}
+
+void
+vn_log(struct vn_instance *instance, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ mesa_log_v(MESA_LOG_DEBUG, "MESA-VIRTIO", format, ap);
+ va_end(ap);
+
+ /* instance may be NULL or partially initialized */
+}
+
+VkResult
+vn_log_result(struct vn_instance *instance,
+ VkResult result,
+ const char *where)
+{
+ vn_log(instance, "%s: %s", where, vk_Result_to_str(result));
+ return result;
+}
+
+static void *
+vn_default_alloc(void *pUserData,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope allocationScope)
+{
+ assert(VN_MAX_ALIGN % alignment == 0);
+ return malloc(size);
+}
+
+static void *
+vn_default_realloc(void *pUserData,
+ void *pOriginal,
+ size_t size,
+ size_t alignment,
+ VkSystemAllocationScope allocationScope)
+{
+ assert(VN_MAX_ALIGN % alignment == 0);
+ return realloc(pOriginal, size);
+}
+
+static void
+vn_default_free(void *pUserData, void *pMemory)
+{
+ free(pMemory);
+}
+
+const VkAllocationCallbacks *
+vn_default_allocator(void)
+{
+ static const VkAllocationCallbacks allocator = {
+ .pfnAllocation = vn_default_alloc,
+ .pfnReallocation = vn_default_realloc,
+ .pfnFree = vn_default_free,
+ };
+ return &allocator;
+}
diff --git a/src/virtio/vulkan/vn_common.h b/src/virtio/vulkan/vn_common.h
new file mode 100644
index 00000000000..df226173413
--- /dev/null
+++ b/src/virtio/vulkan/vn_common.h
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2019 Google LLC
+ * SPDX-License-Identifier: MIT
+ *
+ * based in part on anv and radv which are:
+ * Copyright © 2015 Intel Corporation
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ */
+
+#ifndef VN_COMMON_H
+#define VN_COMMON_H
+
+#include <assert.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdatomic.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vulkan/vulkan.h>
+
+#include "c11/threads.h"
+#include "util/bitscan.h"
+#include "util/list.h"
+#include "util/macros.h"
+#include "util/os_time.h"
+#include "util/u_math.h"
+#include "util/xmlconfig.h"
+#include "vk_alloc.h"
+#include "vk_debug_report.h"
+#include "vk_device.h"
+#include "vk_instance.h"
+#include "vk_object.h"
+#include "vk_physical_device.h"
+#include "vk_util.h"
+
+#include "vn_entrypoints.h"
+
+#define VN_DEFAULT_ALIGN 8
+
+#define VN_DEBUG(category) unlikely(vn_debug &VN_DEBUG_##category)
+
+#define vn_error(instance, error) \
+ (VN_DEBUG(RESULT) ? vn_log_result((instance), (error), __func__) : (error))
+#define vn_result(instance, result) \
+ ((result) >= VK_SUCCESS ? (result) : vn_error((instance), (result)))
+
+struct vn_instance;
+struct vn_physical_device;
+struct vn_device;
+struct vn_queue;
+struct vn_command_buffer;
+
+enum vn_debug {
+ VN_DEBUG_INIT = 1ull << 0,
+ VN_DEBUG_RESULT = 1ull << 1,
+};
+
+typedef uint64_t vn_object_id;
+
+/* base class of vn_instance */
+struct vn_instance_base {
+ struct vk_instance base;
+ vn_object_id id;
+};
+
+/* base class of vn_physical_device */
+struct vn_physical_device_base {
+ struct vk_physical_device base;
+ vn_object_id id;
+};
+
+/* base class of vn_device */
+struct vn_device_base {
+ struct vk_device base;
+ vn_object_id id;
+};
+
+/* base class of other driver objects */
+struct vn_object_base {
+ struct vk_object_base base;
+ vn_object_id id;
+};
+
+extern uint64_t vn_debug;
+
+void
+vn_debug_init(void);
+
+void
+vn_log(struct vn_instance *instance, const char *format, ...)
+ PRINTFLIKE(2, 3);
+
+VkResult
+vn_log_result(struct vn_instance *instance,
+ VkResult result,
+ const char *where);
+
+const VkAllocationCallbacks *
+vn_default_allocator(void);
+
+static_assert(sizeof(vn_object_id) >= sizeof(uintptr_t), "");
+
+static inline VkResult
+vn_instance_base_init(
+ struct vn_instance_base *instance,
+ const struct vk_instance_extension_table *supported_extensions,
+ const struct vk_instance_dispatch_table *dispatch_table,
+ const VkInstanceCreateInfo *info,
+ const VkAllocationCallbacks *alloc)
+{
+ VkResult result = vk_instance_init(&instance->base, supported_extensions,
+ dispatch_table, info, alloc);
+ instance->id = (uintptr_t)instance;
+ return result;
+}
+
+static inline void
+vn_instance_base_fini(struct vn_instance_base *instance)
+{
+ vk_instance_finish(&instance->base);
+}
+
+static inline VkResult
+vn_physical_device_base_init(
+ struct vn_physical_device_base *physical_dev,
+ struct vn_instance_base *instance,
+ const struct vk_device_extension_table *supported_extensions,
+ const struct vk_physical_device_dispatch_table *dispatch_table)
+{
+ VkResult result =
+ vk_physical_device_init(&physical_dev->base, &instance->base,
+ supported_extensions, dispatch_table);
+ physical_dev->id = (uintptr_t)physical_dev;
+ return result;
+}
+
+static inline void
+vn_physical_device_base_fini(struct vn_physical_device_base *physical_dev)
+{
+ vk_physical_device_finish(&physical_dev->base);
+}
+
+static inline VkResult
+vn_device_base_init(struct vn_device_base *dev,
+ struct vn_physical_device_base *physical_dev,
+ const struct vk_device_dispatch_table *dispatch_table,
+ const VkDeviceCreateInfo *info,
+ const VkAllocationCallbacks *alloc)
+{
+ VkResult result = vk_device_init(&dev->base, &physical_dev->base,
+ dispatch_table, info, alloc);
+ dev->id = (uintptr_t)dev;
+ return result;
+}
+
+static inline void
+vn_device_base_fini(struct vn_device_base *dev)
+{
+ vk_device_finish(&dev->base);
+}
+
+static inline void
+vn_object_base_init(struct vn_object_base *obj,
+ VkObjectType type,
+ struct vn_device_base *dev)
+{
+ vk_object_base_init(&dev->base, &obj->base, type);
+ obj->id = (uintptr_t)obj;
+}
+
+static inline void
+vn_object_base_fini(struct vn_object_base *obj)
+{
+ vk_object_base_finish(&obj->base);
+}
+
+static inline void
+vn_object_set_id(void *obj, vn_object_id id, VkObjectType type)
+{
+ assert(((const struct vk_object_base *)obj)->type == type);
+ switch (type) {
+ case VK_OBJECT_TYPE_INSTANCE:
+ ((struct vn_instance_base *)obj)->id = id;
+ break;
+ case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
+ ((struct vn_physical_device_base *)obj)->id = id;
+ break;
+ case VK_OBJECT_TYPE_DEVICE:
+ ((struct vn_device_base *)obj)->id = id;
+ break;
+ default:
+ ((struct vn_object_base *)obj)->id = id;
+ break;
+ }
+}
+
+static inline vn_object_id
+vn_object_get_id(const void *obj, VkObjectType type)
+{
+ assert(((const struct vk_object_base *)obj)->type == type);
+ switch (type) {
+ case VK_OBJECT_TYPE_INSTANCE:
+ return ((struct vn_instance_base *)obj)->id;
+ case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
+ return ((struct vn_physical_device_base *)obj)->id;
+ case VK_OBJECT_TYPE_DEVICE:
+ return ((struct vn_device_base *)obj)->id;
+ default:
+ return ((struct vn_object_base *)obj)->id;
+ }
+}
+
+#endif /* VN_COMMON_H */
diff --git a/src/virtio/vulkan/vn_device.c b/src/virtio/vulkan/vn_device.c
new file mode 100644
index 00000000000..3a655f5d1ed
--- /dev/null
+++ b/src/virtio/vulkan/vn_device.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2019 Google LLC
+ * SPDX-License-Identifier: MIT
+ *
+ * based in part on anv and radv which are:
+ * Copyright © 2015 Intel Corporation
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ */
+
+#include "vn_device.h"
+
+#include "vn_icd.h"
+
+/*
+ * Instance extensions add instance-level or physical-device-level
+ * functionalities. It seems renderer support is either unnecessary or
+ * optional. We should be able to advertise them or lie about them locally.
+ */
+static const struct vk_instance_extension_table
+ vn_instance_supported_extensions;
+
+/* instance commands */
+
+VkResult
+vn_EnumerateInstanceVersion(uint32_t *pApiVersion)
+{
+ *pApiVersion = VK_HEADER_VERSION_COMPLETE;
+ return VK_SUCCESS;
+}
+
+VkResult
+vn_EnumerateInstanceExtensionProperties(const char *pLayerName,
+ uint32_t *pPropertyCount,
+ VkExtensionProperties *pProperties)
+{
+ if (pLayerName)
+ return vn_error(NULL, VK_ERROR_LAYER_NOT_PRESENT);
+
+ return vk_enumerate_instance_extension_properties(
+ &vn_instance_supported_extensions, pPropertyCount, pProperties);
+}
+
+VkResult
+vn_EnumerateInstanceLayerProperties(uint32_t *pPropertyCount,
+ VkLayerProperties *pProperties)
+{
+ *pPropertyCount = 0;
+ return VK_SUCCESS;
+}
+
+VkResult
+vn_CreateInstance(const VkInstanceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkInstance *pInstance)
+{
+ const VkAllocationCallbacks *alloc =
+ pAllocator ? pAllocator : vn_default_allocator();
+ struct vn_instance *instance;
+ VkResult result;
+
+ vn_debug_init();
+
+ instance = vk_zalloc(alloc, sizeof(*instance), VN_DEFAULT_ALIGN,
+ VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
+ if (!instance)
+ return vn_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
+
+ struct vk_instance_dispatch_table dispatch_table;
+ vk_instance_dispatch_table_from_entrypoints(
+ &dispatch_table, &vn_instance_entrypoints, true);
+ result = vn_instance_base_init(&instance->base,
+ &vn_instance_supported_extensions,
+ &dispatch_table, pCreateInfo, alloc);
+ if (result != VK_SUCCESS) {
+ vk_free(alloc, instance);
+ return vn_error(NULL, result);
+ }
+
+ if (!vn_icd_supports_api_version(
+ instance->base.base.app_info.api_version)) {
+ result = VK_ERROR_INCOMPATIBLE_DRIVER;
+ goto fail;
+ }
+
+ if (pCreateInfo->enabledLayerCount) {
+ result = VK_ERROR_LAYER_NOT_PRESENT;
+ goto fail;
+ }
+
+ if (pCreateInfo->enabledExtensionCount) {
+ result = VK_ERROR_EXTENSION_NOT_PRESENT;
+ goto fail;
+ }
+
+ *pInstance = vn_instance_to_handle(instance);
+ return VK_SUCCESS;
+
+fail:
+ vn_instance_base_fini(&instance->base);
+ vk_free(alloc, instance);
+
+ return vn_error(NULL, result);
+}
+
+void
+vn_DestroyInstance(VkInstance _instance,
+ const VkAllocationCallbacks *pAllocator)
+{
+ struct vn_instance *instance = vn_instance_from_handle(_instance);
+ const VkAllocationCallbacks *alloc =
+ pAllocator ? pAllocator : &instance->base.base.alloc;
+
+ if (!instance)
+ return;
+
+ vn_instance_base_fini(&instance->base);
+ vk_free(alloc, instance);
+}
+
+PFN_vkVoidFunction
+vn_GetInstanceProcAddr(VkInstance _instance, const char *pName)
+{
+ struct vn_instance *instance = vn_instance_from_handle(_instance);
+ return vk_instance_get_proc_addr(&instance->base.base,
+ &vn_instance_entrypoints, pName);
+}
+
+/* physical device commands */
+
+VkResult
+vn_EnumeratePhysicalDevices(VkInstance _instance,
+ uint32_t *pPhysicalDeviceCount,
+ VkPhysicalDevice *pPhysicalDevices)
+{
+ struct vn_instance *instance = vn_instance_from_handle(_instance);
+
+ return vn_error(instance, VK_ERROR_INCOMPATIBLE_DRIVER);
+}
+
+void
+vn_GetPhysicalDeviceFeatures(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceFeatures *pFeatures)
+{
+}
+
+void
+vn_GetPhysicalDeviceProperties(VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceProperties *pProperties)
+{
+}
+
+void
+vn_GetPhysicalDeviceQueueFamilyProperties(
+ VkPhysicalDevice physicalDevice,
+ uint32_t *pQueueFamilyPropertyCount,
+ VkQueueFamilyProperties *pQueueFamilyProperties)
+{
+}
+
+void
+vn_GetPhysicalDeviceMemoryProperties(
+ VkPhysicalDevice physicalDevice,
+ VkPhysicalDeviceMemoryProperties *pMemoryProperties)
+{
+}
+
+void
+vn_GetPhysicalDeviceFormatProperties(VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkFormatProperties *pFormatProperties)
+{
+}
+
+VkResult
+vn_GetPhysicalDeviceImageFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ VkImageTiling tiling,
+ VkImageUsageFlags usage,
+ VkImageCreateFlags flags,
+ VkImageFormatProperties *pImageFormatProperties)
+{
+ return vn_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
+}
+
+void
+vn_GetPhysicalDeviceSparseImageFormatProperties(
+ VkPhysicalDevice physicalDevice,
+ VkFormat format,
+ VkImageType type,
+ uint32_t samples,
+ VkImageUsageFlags usage,
+ VkImageTiling tiling,
+ uint32_t *pPropertyCount,
+ VkSparseImageFormatProperties *pProperties)
+{
+}
+
+/* device commands */
+
+VkResult
+vn_EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,
+ const char *pLayerName,
+ uint32_t *pPropertyCount,
+ VkExtensionProperties *pProperties)
+{
+ return vn_error(NULL, VK_ERROR_OUT_OF_HOST_MEMORY);
+}
+
+VkResult
+vn_CreateDevice(VkPhysicalDevice physicalDevice,
+ const VkDeviceCreateInfo *pCreateInfo,
+ const VkAllocationCallbacks *pAllocator,
+ VkDevice *pDevice)
+{
+ return vn_error(NULL, VK_ERROR_INCOMPATIBLE_DRIVER);
+}
+
+PFN_vkVoidFunction
+vn_GetDeviceProcAddr(VkDevice device, const char *pName)
+{
+ return NULL;
+}
diff --git a/src/virtio/vulkan/vn_device.h b/src/virtio/vulkan/vn_device.h
new file mode 100644
index 00000000000..ce5b7e3cb94
--- /dev/null
+++ b/src/virtio/vulkan/vn_device.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 Google LLC
+ * SPDX-License-Identifier: MIT
+ *
+ * based in part on anv and radv which are:
+ * Copyright © 2015 Intel Corporation
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ */
+
+#ifndef VN_DEVICE_H
+#define VN_DEVICE_H
+
+#include "vn_common.h"
+
+struct vn_instance {
+ struct vn_instance_base base;
+};
+VK_DEFINE_HANDLE_CASTS(vn_instance,
+ base.base.base,
+ VkInstance,
+ VK_OBJECT_TYPE_INSTANCE)
+
+struct vn_physical_device {
+ struct vn_physical_device_base base;
+
+ struct vn_instance *instance;
+};
+VK_DEFINE_HANDLE_CASTS(vn_physical_device,
+ base.base.base,
+ VkPhysicalDevice,
+ VK_OBJECT_TYPE_PHYSICAL_DEVICE)
+
+struct vn_device {
+ struct vn_device_base base;
+};
+VK_DEFINE_HANDLE_CASTS(vn_device,
+ base.base.base,
+ VkDevice,
+ VK_OBJECT_TYPE_DEVICE)
+
+struct vn_queue {
+ struct vn_object_base base;
+
+ struct vn_device *device;
+};
+VK_DEFINE_HANDLE_CASTS(vn_queue, base.base, VkQueue, VK_OBJECT_TYPE_QUEUE)
+
+struct vn_command_buffer {
+ struct vn_object_base base;
+
+ struct vn_device *device;
+};
+VK_DEFINE_HANDLE_CASTS(vn_command_buffer,
+ base.base,
+ VkCommandBuffer,
+ VK_OBJECT_TYPE_COMMAND_BUFFER)
+
+#endif /* VN_DEVICE_H */
diff --git a/src/virtio/vulkan/vn_icd.c b/src/virtio/vulkan/vn_icd.c
new file mode 100644
index 00000000000..2cbc1337e23
--- /dev/null
+++ b/src/virtio/vulkan/vn_icd.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019 Google LLC
+ * SPDX-License-Identifier: MIT
+ *
+ * based in part on anv and radv which are:
+ * Copyright © 2015 Intel Corporation
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ */
+
+#include "vn_icd.h"
+
+#include "vn_device.h"
+
+/* we support all versions from version 1 up to version 5 */
+static uint32_t vn_icd_version = 5;
+
+VkResult
+vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion)
+{
+ vn_debug_init();
+
+ vn_icd_version = MIN2(vn_icd_version, *pSupportedVersion);
+ if (VN_DEBUG(INIT))
+ vn_log(NULL, "using ICD interface version %d", vn_icd_version);
+
+ *pSupportedVersion = vn_icd_version;
+ return VK_SUCCESS;
+}
+
+PFN_vkVoidFunction
+vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName)
+{
+ return vn_GetInstanceProcAddr(instance, pName);
+}
+
+PFN_vkVoidFunction
+vk_icdGetPhysicalDeviceProcAddr(VkInstance _instance, const char *pName)
+{
+ struct vn_instance *instance = vn_instance_from_handle(_instance);
+ return vk_instance_get_physical_device_proc_addr(&instance->base.base,
+ pName);
+}
+
+bool
+vn_icd_supports_api_version(uint32_t api_version)
+{
+ return vn_icd_version >= 5 || api_version < VK_API_VERSION_1_1;
+}
diff --git a/src/virtio/vulkan/vn_icd.h b/src/virtio/vulkan/vn_icd.h
new file mode 100644
index 00000000000..62880b63ed4
--- /dev/null
+++ b/src/virtio/vulkan/vn_icd.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2019 Google LLC
+ * SPDX-License-Identifier: MIT
+ *
+ * based in part on anv and radv which are:
+ * Copyright © 2015 Intel Corporation
+ * Copyright © 2016 Red Hat.
+ * Copyright © 2016 Bas Nieuwenhuizen
+ */
+
+#ifndef VN_ICD_H
+#define VN_ICD_H
+
+#include "vn_common.h"
+
+PUBLIC
+VKAPI_ATTR VkResult VKAPI_CALL
+vk_icdNegotiateLoaderICDInterfaceVersion(uint32_t *pSupportedVersion);
+
+PUBLIC
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName);
+
+PUBLIC
+VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
+vk_icdGetPhysicalDeviceProcAddr(VkInstance instance, const char *pName);
+
+bool
+vn_icd_supports_api_version(uint32_t api_version);
+
+#endif /* VN_ICD_H */