From b5e0d01ba2bc026cd58aa3c2ccedb7107c5cb46a Mon Sep 17 00:00:00 2001 From: Vivek Pandya Date: Tue, 25 Aug 2020 20:22:38 +0530 Subject: [PATCH] LibreSoc Vulkan Driver Initial Commit - This commit mostly includes copy & paste code from other vulkan driver. - Python scripts to generate extensions, entrypoints and icd. - Meson file updates. --- meson.build | 1 + meson_options.txt | 2 +- src/libre-soc/meson.build | 32 + src/libre-soc/vulkan/libresoc_device.c | 324 +++++++ .../vulkan/libresoc_entrypoints_gen.py | 798 ++++++++++++++++++ src/libre-soc/vulkan/libresoc_extensions.py | 137 +++ .../vulkan/libresoc_extensions_gen.py | 216 +++++ src/libre-soc/vulkan/libresoc_icd.py | 48 ++ src/libre-soc/vulkan/libresoc_pipeline.c | 85 ++ src/libre-soc/vulkan/libresoc_private.h | 175 ++++ src/libre-soc/vulkan/libresoc_util.c | 85 ++ src/libre-soc/vulkan/meson.build | 174 ++++ src/meson.build | 3 + 13 files changed, 2079 insertions(+), 1 deletion(-) create mode 100644 src/libre-soc/meson.build create mode 100644 src/libre-soc/vulkan/libresoc_device.c create mode 100644 src/libre-soc/vulkan/libresoc_entrypoints_gen.py create mode 100644 src/libre-soc/vulkan/libresoc_extensions.py create mode 100644 src/libre-soc/vulkan/libresoc_extensions_gen.py create mode 100644 src/libre-soc/vulkan/libresoc_icd.py create mode 100644 src/libre-soc/vulkan/libresoc_pipeline.c create mode 100644 src/libre-soc/vulkan/libresoc_private.h create mode 100644 src/libre-soc/vulkan/libresoc_util.c create mode 100644 src/libre-soc/vulkan/meson.build diff --git a/meson.build b/meson.build index fa178c435a9..9cbf6a7f7e7 100644 --- a/meson.build +++ b/meson.build @@ -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_libresoc_vk = _vulkan_drivers.contains('libre-soc') with_swrast_vk = _vulkan_drivers.contains('swrast') with_any_vk = _vulkan_drivers.length() != 0 diff --git a/meson_options.txt b/meson_options.txt index a0cf4abca92..0e0a5a785e0 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -166,7 +166,7 @@ option( '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( diff --git a/src/libre-soc/meson.build b/src/libre-soc/meson.build new file mode 100644 index 00000000000..7f7ce285a15 --- /dev/null +++ b/src/libre-soc/meson.build @@ -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 index 00000000000..089aa36cee0 --- /dev/null +++ b/src/libre-soc/vulkan/libresoc_device.c @@ -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 +#include +#include +#include +#include +#include + +#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 index 00000000000..d4ba55ccb5d --- /dev/null +++ b/src/libre-soc/vulkan/libresoc_entrypoints_gen.py @@ -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; +} + + +${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 index 00000000000..3d83d41ed4c --- /dev/null +++ b/src/libre-soc/vulkan/libresoc_extensions.py @@ -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', ), +] + +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 index 00000000000..1a25a7eea6d --- /dev/null +++ b/src/libre-soc/vulkan/libresoc_extensions_gen.py @@ -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 index 00000000000..dcc479e8656 --- /dev/null +++ b/src/libre-soc/vulkan/libresoc_icd.py @@ -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 index 00000000000..211c209afb5 --- /dev/null +++ b/src/libre-soc/vulkan/libresoc_pipeline.c @@ -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 index 00000000000..3b497a368bf --- /dev/null +++ b/src/libre-soc/vulkan/libresoc_private.h @@ -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 +#include +#include +#include + +//#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 index 00000000000..2d65b089be3 --- /dev/null +++ b/src/libre-soc/vulkan/libresoc_util.c @@ -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 +#include +#include +#include +#include +#include + +#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 index 00000000000..b6cfaa58b6d --- /dev/null +++ b/src/libre-soc/vulkan/meson.build @@ -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, +) diff --git a/src/meson.build b/src/meson.build index ed0a3091d6d..dfe41d08972 100644 --- a/src/meson.build +++ b/src/meson.build @@ -91,6 +91,9 @@ 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 -- 2.30.2