diff options
author | Jonathan Gray <jsg@cvs.openbsd.org> | 2021-07-22 10:50:50 +0000 |
---|---|---|
committer | Jonathan Gray <jsg@cvs.openbsd.org> | 2021-07-22 10:50:50 +0000 |
commit | 9130ec005fbc78a62420643414d8354d0929ca50 (patch) | |
tree | 6762777acdd2d4eee17ef87290e80dc7afe2b73d /lib/mesa/src/vulkan/util | |
parent | ca11beabae33eb59fb981b8adf50b1d47a2a98f0 (diff) |
Merge Mesa 21.1.5
Diffstat (limited to 'lib/mesa/src/vulkan/util')
-rw-r--r-- | lib/mesa/src/vulkan/util/gen_enum_to_str.py | 118 | ||||
-rw-r--r-- | lib/mesa/src/vulkan/util/vk_alloc.h | 116 | ||||
-rw-r--r-- | lib/mesa/src/vulkan/util/vk_util.h | 43 |
3 files changed, 171 insertions, 106 deletions
diff --git a/lib/mesa/src/vulkan/util/gen_enum_to_str.py b/lib/mesa/src/vulkan/util/gen_enum_to_str.py index 035aa02a1..bfcc466be 100644 --- a/lib/mesa/src/vulkan/util/gen_enum_to_str.py +++ b/lib/mesa/src/vulkan/util/gen_enum_to_str.py @@ -25,7 +25,7 @@ from __future__ import print_function import argparse import os import textwrap -import xml.etree.cElementTree as et +import xml.etree.ElementTree as et from mako.template import Template @@ -60,6 +60,7 @@ C_TEMPLATE = Template(textwrap.dedent(u"""\ #include <string.h> #include <vulkan/vulkan.h> #include <vulkan/vk_android_native_buffer.h> + #include <vulkan/vk_layer.h> #include "util/macros.h" #include "vk_enum_to_str.h" @@ -71,16 +72,14 @@ C_TEMPLATE = Template(textwrap.dedent(u"""\ const char * vk_${enum.name[2:]}_to_str(${enum.name} input) { - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wswitch" switch(input) { - % for v in sorted(enum.values.keys()): - case ${v}: - return "${enum.values[v]}"; - % endfor + % for v in sorted(enum.values.keys()): + case ${v}: + return "${enum.values[v]}"; + % endfor + default: + unreachable("Undefined enum value."); } - #pragma GCC diagnostic pop - unreachable("Undefined enum value."); } % if enum.guard: @@ -90,9 +89,7 @@ C_TEMPLATE = Template(textwrap.dedent(u"""\ size_t vk_structure_type_size(const struct VkBaseInStructure *item) { - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wswitch" - switch(item->sType) { + switch((int)item->sType) { % for struct in structs: % if struct.extension is not None and struct.extension.define is not None: #ifdef ${struct.extension.define} @@ -102,47 +99,11 @@ C_TEMPLATE = Template(textwrap.dedent(u"""\ case ${struct.stype}: return sizeof(${struct.name}); % endif %endfor + case VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO: return sizeof(VkLayerInstanceCreateInfo); + case VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO: return sizeof(VkLayerDeviceCreateInfo); + default: + unreachable("Undefined struct type."); } - #pragma GCC diagnostic pop - unreachable("Undefined struct type."); - } - - void vk_load_instance_commands(VkInstance instance, - PFN_vkGetInstanceProcAddr gpa, - struct vk_instance_dispatch_table *table) - { - memset(table, 0, sizeof(*table)); - table->GetInstanceProcAddr = gpa; - % for cmd in commands: - % if not cmd.device_entrypoint and cmd.name != 'vkGetInstanceProcAddr': - % if cmd.extension is not None and cmd.extension.define is not None: - #ifdef ${cmd.extension.define} - table->${cmd.name[2:]} = (PFN_${cmd.name}) gpa(instance, "${cmd.name}"); - #endif - % else: - table->${cmd.name[2:]} = (PFN_${cmd.name}) gpa(instance, "${cmd.name}"); - % endif - % endif - %endfor - } - - void vk_load_device_commands(VkDevice device, - PFN_vkGetDeviceProcAddr gpa, - struct vk_device_dispatch_table *table) - { - memset(table, 0, sizeof(*table)); - table->GetDeviceProcAddr = gpa; - % for cmd in commands: - % if cmd.device_entrypoint and cmd.name != 'vkGetDeviceProcAddr': - % if cmd.extension is not None and cmd.extension.define is not None: - #ifdef ${cmd.extension.define} - table->${cmd.name[2:]} = (PFN_${cmd.name}) gpa(device, "${cmd.name}"); - #endif - % else: - table->${cmd.name[2:]} = (PFN_${cmd.name}) gpa(device, "${cmd.name}"); - % endif - % endif - %endfor } """), output_encoding='utf-8') @@ -180,39 +141,6 @@ H_TEMPLATE = Template(textwrap.dedent(u"""\ size_t vk_structure_type_size(const struct VkBaseInStructure *item); - struct vk_instance_dispatch_table { - PFN_vkGetInstanceProcAddr GetInstanceProcAddr; - % for cmd in commands: - % if not cmd.device_entrypoint and cmd.name != 'vkGetInstanceProcAddr': - % if cmd.extension is not None and cmd.extension.define is not None: - #ifdef ${cmd.extension.define} - PFN_${cmd.name} ${cmd.name[2:]}; - #endif - % else: - PFN_${cmd.name} ${cmd.name[2:]}; - % endif - % endif - %endfor - }; - - struct vk_device_dispatch_table { - PFN_vkGetDeviceProcAddr GetDeviceProcAddr; - % for cmd in commands: - % if cmd.device_entrypoint and cmd.name != 'vkGetDeviceProcAddr': - % if cmd.extension is not None and cmd.extension.define is not None: - #ifdef ${cmd.extension.define} - PFN_${cmd.name} ${cmd.name[2:]}; - #endif - % else: - PFN_${cmd.name} ${cmd.name[2:]}; - % endif - % endif - %endfor - }; - - void vk_load_instance_commands(VkInstance instance, PFN_vkGetInstanceProcAddr gpa, struct vk_instance_dispatch_table *table); - void vk_load_device_commands(VkDevice device, PFN_vkGetDeviceProcAddr gpa, struct vk_device_dispatch_table *table); - #ifdef __cplusplus } /* extern "C" */ #endif @@ -340,7 +268,7 @@ def struct_get_stype(xml_node): return None -def parse_xml(cmd_factory, enum_factory, ext_factory, struct_factory, filename): +def parse_xml(enum_factory, ext_factory, struct_factory, filename): """Parse the XML file. Accumulate results into the factories. This parser is a memory efficient iterative XML parser that returns a list @@ -359,14 +287,6 @@ def parse_xml(cmd_factory, enum_factory, ext_factory, struct_factory, filename): if enum is not None: enum.add_value_from_xml(value) - for command in xml.findall('./commands/command'): - name = command.find('./proto/name') - first_arg = command.find('./param/type') - # Some commands are alias KHR -> nonKHR, ignore those - if name is not None: - cmd_factory(name.text, - device_entrypoint=(first_arg.text in ('VkDevice', 'VkCommandBuffer', 'VkQueue'))) - for struct_type in xml.findall('./types/type[@category="struct"]'): name = struct_type.attrib['name'] stype = struct_get_stype(struct_type) @@ -402,11 +322,6 @@ def parse_xml(cmd_factory, enum_factory, ext_factory, struct_factory, filename): if enum is not None: enum.set_guard(define) - for t in ext_elem.findall('./require/command'): - command = cmd_factory.get(t.attrib['name']) - if command is not None: - command.extension = extension - def main(): parser = argparse.ArgumentParser() @@ -420,13 +335,11 @@ def main(): args = parser.parse_args() - command_factory = NamedFactory(VkCommand) enum_factory = NamedFactory(VkEnum) ext_factory = NamedFactory(VkExtension) struct_factory = NamedFactory(VkChainStruct) for filename in args.xml_files: - parse_xml(command_factory, enum_factory, ext_factory, struct_factory, filename) - commands = sorted(command_factory.registry.values(), key=lambda e: e.name) + parse_xml(enum_factory, ext_factory, struct_factory, filename) enums = sorted(enum_factory.registry.values(), key=lambda e: e.name) extensions = sorted(ext_factory.registry.values(), key=lambda e: e.name) structs = sorted(struct_factory.registry.values(), key=lambda e: e.name) @@ -436,7 +349,6 @@ def main(): with open(file_, 'wb') as f: f.write(template.render( file=os.path.basename(__file__), - commands=commands, enums=enums, extensions=extensions, structs=structs, diff --git a/lib/mesa/src/vulkan/util/vk_alloc.h b/lib/mesa/src/vulkan/util/vk_alloc.h index 2e807a96d..e9842efa9 100644 --- a/lib/mesa/src/vulkan/util/vk_alloc.h +++ b/lib/mesa/src/vulkan/util/vk_alloc.h @@ -28,6 +28,9 @@ #include <string.h> #include <vulkan/vulkan.h> +#include "util/u_math.h" +#include "util/macros.h" + static inline void * vk_alloc(const VkAllocationCallbacks *alloc, size_t size, size_t align, @@ -122,4 +125,117 @@ vk_free2(const VkAllocationCallbacks *parent_alloc, vk_free(parent_alloc, data); } +/* A multi-pointer allocator + * + * When copying data structures from the user (such as a render pass), it's + * common to need to allocate data for a bunch of different things. Instead + * of doing several allocations and having to handle all of the error checking + * that entails, it can be easier to do a single allocation. This struct + * helps facilitate that. The intended usage looks like this: + * + * VK_MULTIALLOC(ma) + * vk_multialloc_add(&ma, &main_ptr, 1); + * vk_multialloc_add(&ma, &substruct1, substruct1Count); + * vk_multialloc_add(&ma, &substruct2, substruct2Count); + * + * if (!vk_multialloc_alloc(&ma, pAllocator, VK_ALLOCATION_SCOPE_FOO)) + * return vk_error(VK_ERROR_OUT_OF_HOST_MEORY); + */ +struct vk_multialloc { + size_t size; + size_t align; + + uint32_t ptr_count; + void **ptrs[8]; +}; + +#define VK_MULTIALLOC_INIT \ + ((struct vk_multialloc) { 0, }) + +#define VK_MULTIALLOC(_name) \ + struct vk_multialloc _name = VK_MULTIALLOC_INIT + +static ALWAYS_INLINE void +vk_multialloc_add_size_align(struct vk_multialloc *ma, + void **ptr, size_t size, size_t align) +{ + assert(util_is_power_of_two_nonzero(align)); + if (size == 0) { + *ptr = NULL; + return; + } + + size_t offset = ALIGN_POT(ma->size, align); + ma->size = offset + size; + ma->align = MAX2(ma->align, align); + + /* Store the offset in the pointer. */ + *ptr = (void *)(uintptr_t)offset; + + assert(ma->ptr_count < ARRAY_SIZE(ma->ptrs)); + ma->ptrs[ma->ptr_count++] = ptr; +} + +#define vk_multialloc_add_size(_ma, _ptr, _type, _size) \ + do { \ + _type **_tmp = (_ptr); \ + (void)_tmp; \ + vk_multialloc_add_size_align((_ma), (void **)(_ptr), \ + (_size), alignof(_type)); \ + } while(0) + +#define vk_multialloc_add(_ma, _ptr, _type, _count) \ + vk_multialloc_add_size(_ma, _ptr, _type, (_count) * sizeof(**(_ptr))); + +#define VK_MULTIALLOC_DECL_SIZE(_ma, _type, _name, _size) \ + _type *_name; \ + vk_multialloc_add_size(_ma, &_name, _type, _size); + +#define VK_MULTIALLOC_DECL(_ma, _type, _name, _count) \ + VK_MULTIALLOC_DECL_SIZE(_ma, _type, _name, (_count) * sizeof(_type)); + +static ALWAYS_INLINE void * +vk_multialloc_alloc(struct vk_multialloc *ma, + const VkAllocationCallbacks *alloc, + VkSystemAllocationScope scope) +{ + char *ptr = vk_alloc(alloc, ma->size, ma->align, scope); + if (!ptr) + return NULL; + + /* Fill out each of the pointers with their final value. + * + * for (uint32_t i = 0; i < ma->ptr_count; i++) + * *ma->ptrs[i] = ptr + (uintptr_t)*ma->ptrs[i]; + * + * Unfortunately, even though ma->ptr_count is basically guaranteed to be a + * constant, GCC is incapable of figuring this out and unrolling the loop + * so we have to give it a little help. + */ + STATIC_ASSERT(ARRAY_SIZE(ma->ptrs) == 8); +#define _VK_MULTIALLOC_UPDATE_POINTER(_i) \ + if ((_i) < ma->ptr_count) \ + *ma->ptrs[_i] = ptr + (uintptr_t)*ma->ptrs[_i] + _VK_MULTIALLOC_UPDATE_POINTER(0); + _VK_MULTIALLOC_UPDATE_POINTER(1); + _VK_MULTIALLOC_UPDATE_POINTER(2); + _VK_MULTIALLOC_UPDATE_POINTER(3); + _VK_MULTIALLOC_UPDATE_POINTER(4); + _VK_MULTIALLOC_UPDATE_POINTER(5); + _VK_MULTIALLOC_UPDATE_POINTER(6); + _VK_MULTIALLOC_UPDATE_POINTER(7); +#undef _VK_MULTIALLOC_UPDATE_POINTER + + return ptr; +} + +static ALWAYS_INLINE void * +vk_multialloc_alloc2(struct vk_multialloc *ma, + const VkAllocationCallbacks *parent_alloc, + const VkAllocationCallbacks *alloc, + VkSystemAllocationScope scope) +{ + return vk_multialloc_alloc(ma, alloc ? alloc : parent_alloc, scope); +} + #endif diff --git a/lib/mesa/src/vulkan/util/vk_util.h b/lib/mesa/src/vulkan/util/vk_util.h index 8ae384b9f..946d92231 100644 --- a/lib/mesa/src/vulkan/util/vk_util.h +++ b/lib/mesa/src/vulkan/util/vk_util.h @@ -23,6 +23,11 @@ #ifndef VK_UTIL_H #define VK_UTIL_H +#include "util/bitscan.h" +#include "util/macros.h" +#include "compiler/shader_enums.h" +#include <string.h> + #ifdef __cplusplus extern "C" { #endif @@ -146,14 +151,18 @@ __vk_outarray_next(struct __vk_outarray *a, size_t elem_size) __vk_outarray_init(&(a)->base, (data), (len)) #define VK_OUTARRAY_MAKE(name, data, len) \ - vk_outarray(__typeof__((data)[0])) name; \ + VK_OUTARRAY_MAKE_TYPED(__typeof__((data)[0]), name, data, len) +#define VK_OUTARRAY_MAKE_TYPED(type, name, data, len) \ + vk_outarray(type) 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_typed(vk_outarray_typeof_elem(a), a) +#define vk_outarray_next_typed(type, a) \ + ((type *) \ __vk_outarray_next(&(a)->base, vk_outarray_sizeof_elem(a))) /** @@ -176,7 +185,9 @@ __vk_outarray_next(struct __vk_outarray *a, size_t elem_size) * points to the newly appended element. */ #define vk_outarray_append(a, elem) \ - for (vk_outarray_typeof_elem(a) *elem = vk_outarray_next(a); \ + vk_outarray_append_typed(vk_outarray_typeof_elem(a), a, elem) +#define vk_outarray_append_typed(type, a, elem) \ + for (type *elem = vk_outarray_next_typed(type, a); \ elem != NULL; elem = NULL) static inline void * @@ -212,12 +223,38 @@ uint32_t vk_get_driver_version(void); uint32_t vk_get_version_override(void); +struct vk_pipeline_cache_header { + uint32_t header_size; + uint32_t header_version; + uint32_t vendor_id; + uint32_t device_id; + uint8_t uuid[VK_UUID_SIZE]; +}; + #define VK_EXT_OFFSET (1000000000UL) #define VK_ENUM_EXTENSION(__enum) \ ((__enum) >= VK_EXT_OFFSET ? ((((__enum) - VK_EXT_OFFSET) / 1000UL) + 1) : 0) #define VK_ENUM_OFFSET(__enum) \ ((__enum) >= VK_EXT_OFFSET ? ((__enum) % 1000) : (__enum)) +#define typed_memcpy(dest, src, count) do { \ + STATIC_ASSERT(sizeof(*(src)) == sizeof(*(dest))); \ + memcpy((dest), (src), (count) * sizeof(*(src))); \ +} while (0) + +static inline gl_shader_stage +vk_to_mesa_shader_stage(VkShaderStageFlagBits vk_stage) +{ + assert(util_bitcount((uint32_t) vk_stage) == 1); + return (gl_shader_stage) (ffs((uint32_t) vk_stage) - 1); +} + +static inline VkShaderStageFlagBits +mesa_to_vk_shader_stage(gl_shader_stage mesa_stage) +{ + return (VkShaderStageFlagBits) (1 << ((uint32_t) mesa_stage)); +} + #ifdef __cplusplus } #endif |