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>
This commit is contained in:
Chia-I Wu 2020-06-03 13:18:30 -07:00 committed by Marge Bot
parent dab339b07e
commit b0736f49d3
12 changed files with 790 additions and 2 deletions

View File

@ -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

View File

@ -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(

View File

@ -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

View File

@ -19,3 +19,7 @@
# SOFTWARE.
inc_virtio = include_directories('.')
if with_virtio_vk
subdir('vulkan')
endif

View File

@ -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

View File

@ -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,
)

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 */