summaryrefslogtreecommitdiff
path: root/lib/mesa/src/vulkan/util
diff options
context:
space:
mode:
authorJonathan Gray <jsg@cvs.openbsd.org>2021-07-22 10:50:50 +0000
committerJonathan Gray <jsg@cvs.openbsd.org>2021-07-22 10:50:50 +0000
commit9130ec005fbc78a62420643414d8354d0929ca50 (patch)
tree6762777acdd2d4eee17ef87290e80dc7afe2b73d /lib/mesa/src/vulkan/util
parentca11beabae33eb59fb981b8adf50b1d47a2a98f0 (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.py118
-rw-r--r--lib/mesa/src/vulkan/util/vk_alloc.h116
-rw-r--r--lib/mesa/src/vulkan/util/vk_util.h43
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