From: Alex Smith Date: Tue, 6 Jun 2017 11:31:05 +0000 (+0100) Subject: util/vulkan: Move Vulkan utilities to src/vulkan/util X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=621b3410f5f8;p=mesa.git util/vulkan: Move Vulkan utilities to src/vulkan/util We have Vulkan utilities in both src/util and src/vulkan/util. The latter seems a more appropriate place for Vulkan-specific things, so move them there. v2: Android build system changes (from Tapani Pälli) Signed-off-by: Alex Smith Reviewed-by: Emil Velikov Reviewed-by: Eric Engestrom Acked-by: Jason Ekstrand --- diff --git a/Android.common.mk b/Android.common.mk index 44ad97b6be2..6bd30816bc4 100644 --- a/Android.common.mk +++ b/Android.common.mk @@ -37,6 +37,7 @@ LOCAL_CFLAGS += \ -Wno-missing-field-initializers \ -Wno-initializer-overrides \ -Wno-mismatched-tags \ + -DVERSION=\"$(MESA_VERSION)\" \ -DPACKAGE_VERSION=\"$(MESA_VERSION)\" \ -DPACKAGE_BUGREPORT=\"https://bugs.freedesktop.org/enter_bug.cgi?product=Mesa\" diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c index 887916f558f..a812527ebe4 100644 --- a/src/amd/vulkan/radv_device.c +++ b/src/amd/vulkan/radv_device.c @@ -33,7 +33,7 @@ #include "radv_cs.h" #include "util/disk_cache.h" #include "util/strtod.h" -#include "util/vk_util.h" +#include "vk_util.h" #include #include #include diff --git a/src/amd/vulkan/radv_formats.c b/src/amd/vulkan/radv_formats.c index 6cff0a5384e..b13adb9abdc 100644 --- a/src/amd/vulkan/radv_formats.c +++ b/src/amd/vulkan/radv_formats.c @@ -28,7 +28,8 @@ #include "sid.h" #include "r600d_common.h" -#include "util/vk_util.h" +#include "vk_util.h" + #include "util/u_half.h" #include "util/format_srgb.h" #include "util/format_r11g11b10f.h" diff --git a/src/amd/vulkan/radv_private.h b/src/amd/vulkan/radv_private.h index ed80ba79e7f..a3920a72702 100644 --- a/src/amd/vulkan/radv_private.h +++ b/src/amd/vulkan/radv_private.h @@ -47,8 +47,8 @@ #include "compiler/shader_enums.h" #include "util/macros.h" #include "util/list.h" -#include "util/vk_alloc.h" #include "main/macros.h" +#include "vk_alloc.h" #include "radv_radeon_winsys.h" #include "ac_binary.h" diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index 51fe159aaf8..cdb04ca9628 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -26,7 +26,7 @@ #include "radv_private.h" #include "radv_meta.h" #include "wsi_common.h" -#include "util/vk_util.h" +#include "vk_util.h" static const struct wsi_callbacks wsi_cbs = { .get_phys_device_format_properties = radv_GetPhysicalDeviceFormatProperties, diff --git a/src/intel/Android.vulkan.mk b/src/intel/Android.vulkan.mk index 2ede3f75b32..e31c4391df0 100644 --- a/src/intel/Android.vulkan.mk +++ b/src/intel/Android.vulkan.mk @@ -31,6 +31,7 @@ VULKAN_COMMON_INCLUDES := \ $(MESA_TOP)/src/gallium/include \ $(MESA_TOP)/src/mesa \ $(MESA_TOP)/src/vulkan/wsi \ + $(MESA_TOP)/src/vulkan/util \ $(MESA_TOP)/src/intel \ $(MESA_TOP)/src/intel/vulkan diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index ab484ed0f9a..52e5d7b0252 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -35,7 +35,7 @@ #include "util/debug.h" #include "util/build_id.h" #include "util/mesa-sha1.h" -#include "util/vk_util.h" +#include "vk_util.h" #include "genxml/gen7_pack.h" diff --git a/src/intel/vulkan/anv_formats.c b/src/intel/vulkan/anv_formats.c index 25801e8b065..104d4f7a5fe 100644 --- a/src/intel/vulkan/anv_formats.c +++ b/src/intel/vulkan/anv_formats.c @@ -23,8 +23,7 @@ #include "anv_private.h" #include "vk_format_info.h" - -#include "util/vk_util.h" +#include "vk_util.h" /* * gcc-4 and earlier don't allow compound literals where a constant diff --git a/src/intel/vulkan/anv_pass.c b/src/intel/vulkan/anv_pass.c index 93f14830cc5..1b30c1409d9 100644 --- a/src/intel/vulkan/anv_pass.c +++ b/src/intel/vulkan/anv_pass.c @@ -23,7 +23,7 @@ #include "anv_private.h" -#include "util/vk_util.h" +#include "vk_util.h" static unsigned num_subpass_attachments(const VkSubpassDescription *desc) diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h index c261faa78b8..fe6ac3bc1bd 100644 --- a/src/intel/vulkan/anv_private.h +++ b/src/intel/vulkan/anv_private.h @@ -47,7 +47,7 @@ #include "util/macros.h" #include "util/list.h" #include "util/u_vector.h" -#include "util/vk_alloc.h" +#include "vk_alloc.h" /* Pre-declarations needed for WSI entrypoints */ struct wl_surface; diff --git a/src/intel/vulkan/anv_queue.c b/src/intel/vulkan/anv_queue.c index be7fd310081..fd4d36297f0 100644 --- a/src/intel/vulkan/anv_queue.c +++ b/src/intel/vulkan/anv_queue.c @@ -30,7 +30,7 @@ #include #include "anv_private.h" -#include "util/vk_util.h" +#include "vk_util.h" #include "genxml/gen7_pack.h" diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c index 7575f58ff24..9369f26a8fa 100644 --- a/src/intel/vulkan/anv_wsi.c +++ b/src/intel/vulkan/anv_wsi.c @@ -24,7 +24,7 @@ #include "anv_private.h" #include "wsi_common.h" #include "vk_format_info.h" -#include "util/vk_util.h" +#include "vk_util.h" #ifdef VK_USE_PLATFORM_WAYLAND_KHR static const struct wsi_callbacks wsi_cbs = { diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index 072d0d50325..59430a24eb9 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -26,7 +26,7 @@ #include "anv_private.h" #include "vk_format_info.h" -#include "util/vk_util.h" +#include "vk_util.h" #include "common/gen_l3_config.h" #include "genxml/gen_macros.h" diff --git a/src/util/Makefile.sources b/src/util/Makefile.sources index e9057343dc2..e9f820a3ee0 100644 --- a/src/util/Makefile.sources +++ b/src/util/Makefile.sources @@ -51,9 +51,7 @@ MESA_UTIL_FILES := \ u_string.h \ u_thread.h \ u_vector.c \ - u_vector.h \ - vk_alloc.h \ - vk_util.h + u_vector.h MESA_UTIL_GENERATED_FILES = \ format_srgb.c diff --git a/src/util/vk_alloc.h b/src/util/vk_alloc.h deleted file mode 100644 index 29150218269..00000000000 --- a/src/util/vk_alloc.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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. - */ -#ifndef VK_ALLOC_H -#define VK_ALLOC_H - -/* common allocation inlines for vulkan drivers */ - -#include -#include - -static inline void * -vk_alloc(const VkAllocationCallbacks *alloc, - size_t size, size_t align, - VkSystemAllocationScope scope) -{ - return alloc->pfnAllocation(alloc->pUserData, size, align, scope); -} - -static inline void * -vk_realloc(const VkAllocationCallbacks *alloc, - void *ptr, size_t size, size_t align, - VkSystemAllocationScope scope) -{ - return alloc->pfnReallocation(alloc->pUserData, ptr, size, align, scope); -} - -static inline void -vk_free(const VkAllocationCallbacks *alloc, void *data) -{ - if (data == NULL) - return; - - alloc->pfnFree(alloc->pUserData, data); -} - -static inline void * -vk_alloc2(const VkAllocationCallbacks *parent_alloc, - const VkAllocationCallbacks *alloc, - size_t size, size_t align, - VkSystemAllocationScope scope) -{ - if (alloc) - return vk_alloc(alloc, size, align, scope); - else - return vk_alloc(parent_alloc, size, align, scope); -} - -static inline void * -vk_zalloc2(const VkAllocationCallbacks *parent_alloc, - const VkAllocationCallbacks *alloc, - size_t size, size_t align, - VkSystemAllocationScope scope) -{ - void *mem = vk_alloc2(parent_alloc, alloc, size, align, scope); - if (mem == NULL) - return NULL; - - memset(mem, 0, size); - - return mem; -} - -static inline void -vk_free2(const VkAllocationCallbacks *parent_alloc, - const VkAllocationCallbacks *alloc, - void *data) -{ - if (alloc) - vk_free(alloc, data); - else - vk_free(parent_alloc, data); -} - -#endif diff --git a/src/util/vk_util.h b/src/util/vk_util.h deleted file mode 100644 index 5ff1f00195c..00000000000 --- a/src/util/vk_util.h +++ /dev/null @@ -1,200 +0,0 @@ -/* - * 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 (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 VK_UTIL_H -#define VK_UTIL_H - -/* common inlines and macros for vulkan drivers */ - -#include - -struct vk_struct_common { - VkStructureType sType; - struct vk_struct_common *pNext; -}; - -#define vk_foreach_struct(__iter, __start) \ - for (struct vk_struct_common *__iter = (struct vk_struct_common *)(__start); \ - __iter; __iter = __iter->pNext) - -#define vk_foreach_struct_const(__iter, __start) \ - for (const struct vk_struct_common *__iter = (const struct vk_struct_common *)(__start); \ - __iter; __iter = __iter->pNext) - -/** - * A wrapper for a Vulkan output array. A Vulkan output array is one that - * follows the convention of the parameters to - * vkGetPhysicalDeviceQueueFamilyProperties(). - * - * Example Usage: - * - * VkResult - * vkGetPhysicalDeviceQueueFamilyProperties( - * VkPhysicalDevice physicalDevice, - * uint32_t* pQueueFamilyPropertyCount, - * VkQueueFamilyProperties* pQueueFamilyProperties) - * { - * VK_OUTARRAY_MAKE(props, pQueueFamilyProperties, - * pQueueFamilyPropertyCount); - * - * vk_outarray_append(&props, p) { - * p->queueFlags = ...; - * p->queueCount = ...; - * } - * - * vk_outarray_append(&props, p) { - * p->queueFlags = ...; - * p->queueCount = ...; - * } - * - * return vk_outarray_status(&props); - * } - */ -struct __vk_outarray { - /** May be null. */ - void *data; - - /** - * Capacity, in number of elements. Capacity is unlimited (UINT32_MAX) if - * data is null. - */ - uint32_t cap; - - /** - * Count of elements successfully written to the array. Every write is - * considered successful if data is null. - */ - uint32_t *filled_len; - - /** - * Count of elements that would have been written to the array if its - * capacity were sufficient. Vulkan functions often return VK_INCOMPLETE - * when `*filled_len < wanted_len`. - */ - uint32_t wanted_len; -}; - -static inline void -__vk_outarray_init(struct __vk_outarray *a, - void *data, uint32_t *restrict len) -{ - a->data = data; - a->cap = *len; - a->filled_len = len; - *a->filled_len = 0; - a->wanted_len = 0; - - if (a->data == NULL) - a->cap = UINT32_MAX; -} - -static inline VkResult -__vk_outarray_status(const struct __vk_outarray *a) -{ - if (*a->filled_len < a->wanted_len) - return VK_INCOMPLETE; - else - return VK_SUCCESS; -} - -static inline void * -__vk_outarray_next(struct __vk_outarray *a, size_t elem_size) -{ - void *p = NULL; - - a->wanted_len += 1; - - if (*a->filled_len >= a->cap) - return NULL; - - if (a->data != NULL) - p = a->data + (*a->filled_len) * elem_size; - - *a->filled_len += 1; - - return p; -} - -#define vk_outarray(elem_t) \ - struct { \ - struct __vk_outarray base; \ - elem_t meta[]; \ - } - -#define vk_outarray_typeof_elem(a) __typeof__((a)->meta[0]) -#define vk_outarray_sizeof_elem(a) sizeof((a)->meta[0]) - -#define vk_outarray_init(a, data, len) \ - __vk_outarray_init(&(a)->base, (data), (len)) - -#define VK_OUTARRAY_MAKE(name, data, len) \ - vk_outarray(__typeof__((data)[0])) name; \ - vk_outarray_init(&name, (data), (len)) - -#define vk_outarray_status(a) \ - __vk_outarray_status(&(a)->base) - -#define vk_outarray_next(a) \ - ((vk_outarray_typeof_elem(a) *) \ - __vk_outarray_next(&(a)->base, vk_outarray_sizeof_elem(a))) - -/** - * Append to a Vulkan output array. - * - * This is a block-based macro. For example: - * - * vk_outarray_append(&a, elem) { - * elem->foo = ...; - * elem->bar = ...; - * } - * - * The array `a` has type `vk_outarray(elem_t) *`. It is usually declared with - * VK_OUTARRAY_MAKE(). The variable `elem` is block-scoped and has type - * `elem_t *`. - * - * The macro unconditionally increments the array's `wanted_len`. If the array - * is not full, then the macro also increment its `filled_len` and then - * executes the block. When the block is executed, `elem` is non-null and - * points to the newly appended element. - */ -#define vk_outarray_append(a, elem) \ - for (vk_outarray_typeof_elem(a) *elem = vk_outarray_next(a); \ - elem != NULL; elem = NULL) - -static inline void * -__vk_find_struct(void *start, VkStructureType sType) -{ - vk_foreach_struct(s, start) { - if (s->sType == sType) - return s; - } - - return NULL; -} - -#define vk_find_struct(__start, __sType) \ - __vk_find_struct((__start), VK_STRUCTURE_TYPE_##__sType) - -#define vk_find_struct_const(__start, __sType) \ - (const void *)__vk_find_struct((void *)(__start), VK_STRUCTURE_TYPE_##__sType) - -#endif /* VK_UTIL_H */ diff --git a/src/vulkan/Android.mk b/src/vulkan/Android.mk index 7653f34c68a..8eb42ece878 100644 --- a/src/vulkan/Android.mk +++ b/src/vulkan/Android.mk @@ -41,6 +41,8 @@ LOCAL_C_INCLUDES := \ LOCAL_GENERATED_SOURCES := $(addprefix $(intermediates)/, \ $(VULKAN_UTIL_GENERATED_FILES)) +LOCAL_SRC_FILES := $(VULKAN_UTIL_FILES)) + vulkan_api_xml = $(MESA_TOP)/src/vulkan/registry/vk.xml $(LOCAL_GENERATED_SOURCES): $(MESA_TOP)/src/vulkan/util/gen_enum_to_str.py $(vulkan_api_xml) diff --git a/src/vulkan/Makefile.am b/src/vulkan/Makefile.am index 71fb2d97bba..c897a07d6a8 100644 --- a/src/vulkan/Makefile.am +++ b/src/vulkan/Makefile.am @@ -11,6 +11,10 @@ PYTHON_GEN = $(AM_V_GEN)$(PYTHON2) $(PYTHON_FLAGS) EXTRA_DIST = \ util/gen_enum_to_str.py +VULKAN_UTIL_SOURCES = \ + $(VULKAN_UTIL_FILES) \ + $(VULKAN_UTIL_GENERATED_FILES) + BUILT_SOURCES = \ $(VULKAN_UTIL_GENERATED_FILES) @@ -18,12 +22,13 @@ util/vk_enum_to_str.c util/vk_enum_to_str.h: util/gen_enum_to_str.py $(vulkan_ap $(MKDIR_GEN) $(PYTHON_GEN) $(srcdir)/util/gen_enum_to_str.py --xml $(vulkan_api_xml) --outdir $(top_builddir)/src/vulkan/util -libvulkan_util_la_SOURCES = $(VULKAN_UTIL_GENERATED_FILES) +libvulkan_util_la_SOURCES = $(VULKAN_UTIL_SOURCES) AM_CPPFLAGS = \ $(DEFINES) \ -I$(top_srcdir)/include \ -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/vulkan/util \ -I$(top_srcdir)/src/gallium/auxiliary \ -I$(top_srcdir)/src/gallium/include diff --git a/src/vulkan/Makefile.sources b/src/vulkan/Makefile.sources index 63f4ac11620..9962c1b077d 100644 --- a/src/vulkan/Makefile.sources +++ b/src/vulkan/Makefile.sources @@ -15,6 +15,10 @@ VULKAN_WSI_X11_FILES := \ wsi/wsi_common_x11.c \ wsi/wsi_common_x11.h +VULKAN_UTIL_FILES := \ + util/vk_alloc.h \ + util/vk_util.h + VULKAN_UTIL_GENERATED_FILES := \ util/vk_enum_to_str.c \ util/vk_enum_to_str.h diff --git a/src/vulkan/util/vk_alloc.h b/src/vulkan/util/vk_alloc.h new file mode 100644 index 00000000000..29150218269 --- /dev/null +++ b/src/vulkan/util/vk_alloc.h @@ -0,0 +1,94 @@ +/* + * 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. + */ +#ifndef VK_ALLOC_H +#define VK_ALLOC_H + +/* common allocation inlines for vulkan drivers */ + +#include +#include + +static inline void * +vk_alloc(const VkAllocationCallbacks *alloc, + size_t size, size_t align, + VkSystemAllocationScope scope) +{ + return alloc->pfnAllocation(alloc->pUserData, size, align, scope); +} + +static inline void * +vk_realloc(const VkAllocationCallbacks *alloc, + void *ptr, size_t size, size_t align, + VkSystemAllocationScope scope) +{ + return alloc->pfnReallocation(alloc->pUserData, ptr, size, align, scope); +} + +static inline void +vk_free(const VkAllocationCallbacks *alloc, void *data) +{ + if (data == NULL) + return; + + alloc->pfnFree(alloc->pUserData, data); +} + +static inline void * +vk_alloc2(const VkAllocationCallbacks *parent_alloc, + const VkAllocationCallbacks *alloc, + size_t size, size_t align, + VkSystemAllocationScope scope) +{ + if (alloc) + return vk_alloc(alloc, size, align, scope); + else + return vk_alloc(parent_alloc, size, align, scope); +} + +static inline void * +vk_zalloc2(const VkAllocationCallbacks *parent_alloc, + const VkAllocationCallbacks *alloc, + size_t size, size_t align, + VkSystemAllocationScope scope) +{ + void *mem = vk_alloc2(parent_alloc, alloc, size, align, scope); + if (mem == NULL) + return NULL; + + memset(mem, 0, size); + + return mem; +} + +static inline void +vk_free2(const VkAllocationCallbacks *parent_alloc, + const VkAllocationCallbacks *alloc, + void *data) +{ + if (alloc) + vk_free(alloc, data); + else + vk_free(parent_alloc, data); +} + +#endif diff --git a/src/vulkan/util/vk_util.h b/src/vulkan/util/vk_util.h new file mode 100644 index 00000000000..5ff1f00195c --- /dev/null +++ b/src/vulkan/util/vk_util.h @@ -0,0 +1,200 @@ +/* + * 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 (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 VK_UTIL_H +#define VK_UTIL_H + +/* common inlines and macros for vulkan drivers */ + +#include + +struct vk_struct_common { + VkStructureType sType; + struct vk_struct_common *pNext; +}; + +#define vk_foreach_struct(__iter, __start) \ + for (struct vk_struct_common *__iter = (struct vk_struct_common *)(__start); \ + __iter; __iter = __iter->pNext) + +#define vk_foreach_struct_const(__iter, __start) \ + for (const struct vk_struct_common *__iter = (const struct vk_struct_common *)(__start); \ + __iter; __iter = __iter->pNext) + +/** + * A wrapper for a Vulkan output array. A Vulkan output array is one that + * follows the convention of the parameters to + * vkGetPhysicalDeviceQueueFamilyProperties(). + * + * Example Usage: + * + * VkResult + * vkGetPhysicalDeviceQueueFamilyProperties( + * VkPhysicalDevice physicalDevice, + * uint32_t* pQueueFamilyPropertyCount, + * VkQueueFamilyProperties* pQueueFamilyProperties) + * { + * VK_OUTARRAY_MAKE(props, pQueueFamilyProperties, + * pQueueFamilyPropertyCount); + * + * vk_outarray_append(&props, p) { + * p->queueFlags = ...; + * p->queueCount = ...; + * } + * + * vk_outarray_append(&props, p) { + * p->queueFlags = ...; + * p->queueCount = ...; + * } + * + * return vk_outarray_status(&props); + * } + */ +struct __vk_outarray { + /** May be null. */ + void *data; + + /** + * Capacity, in number of elements. Capacity is unlimited (UINT32_MAX) if + * data is null. + */ + uint32_t cap; + + /** + * Count of elements successfully written to the array. Every write is + * considered successful if data is null. + */ + uint32_t *filled_len; + + /** + * Count of elements that would have been written to the array if its + * capacity were sufficient. Vulkan functions often return VK_INCOMPLETE + * when `*filled_len < wanted_len`. + */ + uint32_t wanted_len; +}; + +static inline void +__vk_outarray_init(struct __vk_outarray *a, + void *data, uint32_t *restrict len) +{ + a->data = data; + a->cap = *len; + a->filled_len = len; + *a->filled_len = 0; + a->wanted_len = 0; + + if (a->data == NULL) + a->cap = UINT32_MAX; +} + +static inline VkResult +__vk_outarray_status(const struct __vk_outarray *a) +{ + if (*a->filled_len < a->wanted_len) + return VK_INCOMPLETE; + else + return VK_SUCCESS; +} + +static inline void * +__vk_outarray_next(struct __vk_outarray *a, size_t elem_size) +{ + void *p = NULL; + + a->wanted_len += 1; + + if (*a->filled_len >= a->cap) + return NULL; + + if (a->data != NULL) + p = a->data + (*a->filled_len) * elem_size; + + *a->filled_len += 1; + + return p; +} + +#define vk_outarray(elem_t) \ + struct { \ + struct __vk_outarray base; \ + elem_t meta[]; \ + } + +#define vk_outarray_typeof_elem(a) __typeof__((a)->meta[0]) +#define vk_outarray_sizeof_elem(a) sizeof((a)->meta[0]) + +#define vk_outarray_init(a, data, len) \ + __vk_outarray_init(&(a)->base, (data), (len)) + +#define VK_OUTARRAY_MAKE(name, data, len) \ + vk_outarray(__typeof__((data)[0])) name; \ + vk_outarray_init(&name, (data), (len)) + +#define vk_outarray_status(a) \ + __vk_outarray_status(&(a)->base) + +#define vk_outarray_next(a) \ + ((vk_outarray_typeof_elem(a) *) \ + __vk_outarray_next(&(a)->base, vk_outarray_sizeof_elem(a))) + +/** + * Append to a Vulkan output array. + * + * This is a block-based macro. For example: + * + * vk_outarray_append(&a, elem) { + * elem->foo = ...; + * elem->bar = ...; + * } + * + * The array `a` has type `vk_outarray(elem_t) *`. It is usually declared with + * VK_OUTARRAY_MAKE(). The variable `elem` is block-scoped and has type + * `elem_t *`. + * + * The macro unconditionally increments the array's `wanted_len`. If the array + * is not full, then the macro also increment its `filled_len` and then + * executes the block. When the block is executed, `elem` is non-null and + * points to the newly appended element. + */ +#define vk_outarray_append(a, elem) \ + for (vk_outarray_typeof_elem(a) *elem = vk_outarray_next(a); \ + elem != NULL; elem = NULL) + +static inline void * +__vk_find_struct(void *start, VkStructureType sType) +{ + vk_foreach_struct(s, start) { + if (s->sType == sType) + return s; + } + + return NULL; +} + +#define vk_find_struct(__start, __sType) \ + __vk_find_struct((__start), VK_STRUCTURE_TYPE_##__sType) + +#define vk_find_struct_const(__start, __sType) \ + (const void *)__vk_find_struct((void *)(__start), VK_STRUCTURE_TYPE_##__sType) + +#endif /* VK_UTIL_H */ diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 8aee9c73513..8166b7dd344 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -26,7 +26,7 @@ #include #include -#include "util/vk_alloc.h" +#include "vk_alloc.h" #include #include diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index 644ed62b414..dd283a12111 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -31,7 +31,7 @@ #include #include -#include "util/vk_util.h" +#include "vk_util.h" #include "wsi_common_wayland.h" #include "wayland-drm-client-protocol.h" diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 5be56f1232f..ecdaf914344 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -38,7 +38,7 @@ #include #include "util/hash_table.h" -#include "util/vk_util.h" +#include "vk_util.h" #include "wsi_common.h" #include "wsi_common_x11.h" #include "wsi_common_queue.h"