[Mesa-dev] [PATCH 3/4] anv: Use central api generation scripts.
Bas Nieuwenhuizen
bas at basnieuwenhuizen.nl
Tue Aug 7 23:14:33 UTC 2018
This became kind of messy as python imports cannot really look up
parent/sibling directories. I saw some scripts use sys.path but
that became even more messy due to import locations.
I also move the selections of the dispatch table out of the
generation script because it is not easily shared, and generating
it did not really win anything anyway.
---
src/intel/Android.vulkan.mk | 9 +
src/intel/Makefile.vulkan.am | 25 +-
src/intel/vulkan/anv_device.c | 46 ++
src/intel/vulkan/anv_entrypoints_gen.py | 537 +-----------------------
src/intel/vulkan/anv_extensions.py | 68 +--
src/intel/vulkan/anv_extensions_gen.py | 177 +-------
src/intel/vulkan/meson.build | 15 +-
src/vulkan/util/vk_extensions.py | 5 +-
8 files changed, 98 insertions(+), 784 deletions(-)
diff --git a/src/intel/Android.vulkan.mk b/src/intel/Android.vulkan.mk
index 09dc22875a1..af59963c66d 100644
--- a/src/intel/Android.vulkan.mk
+++ b/src/intel/Android.vulkan.mk
@@ -27,6 +27,11 @@ VK_ENTRYPOINTS_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/vulkan/anv_entrypoints_ge
VK_EXTENSIONS_SCRIPT := $(MESA_PYTHON2) $(LOCAL_PATH)/vulkan/anv_extensions_gen.py
+vulkan_api_generators_py := \
+ $(MESA_TOP)/src/vulkan/util/vk_entrypoints_gen.py \
+ $(MESA_TOP)/src/vulkan/util/vk_extensions_gen.py \
+ $(MESA_TOP)/src/vulkan/util/vk_extensions.py
+
VULKAN_COMMON_INCLUDES := \
$(MESA_TOP)/include \
$(MESA_TOP)/src/mapi \
@@ -65,6 +70,7 @@ $(intermediates)/vulkan/dummy.c:
$(hide) touch $@
$(intermediates)/vulkan/anv_entrypoints.h: $(intermediates)/vulkan/dummy.c
+ PYTHONPATH=$(MESA_TOP)/src/vulkan/util \
$(VK_ENTRYPOINTS_SCRIPT) \
--outdir $(dir $@) \
--xml $(MESA_TOP)/src/vulkan/registry/vk.xml
@@ -242,18 +248,21 @@ LOCAL_GENERATED_SOURCES += $(intermediates)/vulkan/anv_extensions.h
$(intermediates)/vulkan/anv_entrypoints.c:
@mkdir -p $(dir $@)
+ PYTHONPATH=$(MESA_TOP)/src/vulkan/util \
$(VK_ENTRYPOINTS_SCRIPT) \
--xml $(MESA_TOP)/src/vulkan/registry/vk.xml \
--outdir $(dir $@)
$(intermediates)/vulkan/anv_extensions.c:
@mkdir -p $(dir $@)
+ PYTHONPATH=$(MESA_TOP)/src/vulkan/util \
$(VK_EXTENSIONS_SCRIPT) \
--xml $(MESA_TOP)/src/vulkan/registry/vk.xml \
--out-c $@
$(intermediates)/vulkan/anv_extensions.h:
@mkdir -p $(dir $@)
+ PYTHONPATH=$(MESA_TOP)/src/vulkan/util \
$(VK_EXTENSIONS_SCRIPT) \
--xml $(MESA_TOP)/src/vulkan/registry/vk.xml \
--out-h $@
diff --git a/src/intel/Makefile.vulkan.am b/src/intel/Makefile.vulkan.am
index 9555d98095b..91577bc9026 100644
--- a/src/intel/Makefile.vulkan.am
+++ b/src/intel/Makefile.vulkan.am
@@ -24,10 +24,17 @@
# out and we'll fail at `make dist'
vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml
+vulkan_api_generators_py = \
+ $(top_srcdir)/src/vulkan/util/vk_entrypoints_gen.py \
+ $(top_srcdir)/src/vulkan/util/vk_extensions_gen.py \
+ $(top_srcdir)/src/vulkan/util/vk_extensions.py
+
vulkan/anv_entrypoints.c: vulkan/anv_entrypoints_gen.py \
vulkan/anv_extensions.py \
- $(vulkan_api_xml)
+ $(vulkan_api_xml) \
+ $(vulkan_api_generators_py)
$(MKDIR_GEN)
+ PYTHONPATH=$(top_srcdir)/src/vulkan/util \
$(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_entrypoints_gen.py \
--xml $(vulkan_api_xml) \
--outdir $(builddir)/vulkan
@@ -35,16 +42,20 @@ vulkan/anv_entrypoints.h: vulkan/anv_entrypoints.c
vulkan/anv_extensions.c: vulkan/anv_extensions_gen.py \
vulkan/anv_extensions.py \
- $(vulkan_api_xml)
+ $(vulkan_api_xml) \
+ $(vulkan_api_generators_py)
$(MKDIR_GEN)
+ PYTHONPATH=$(top_srcdir)/src/vulkan/util \
$(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_extensions_gen.py \
--xml $(vulkan_api_xml) \
--out-c $@
vulkan/anv_extensions.h: vulkan/anv_extensions_gen.py \
vulkan/anv_extensions.py \
- $(vulkan_api_xml)
+ $(vulkan_api_xml) \
+ $(vulkan_api_generators_py)
$(MKDIR_GEN)
+ PYTHONPATH=$(top_srcdir)/src/vulkan/util \
$(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_extensions_gen.py \
--xml $(vulkan_api_xml) \
--out-h $@
@@ -63,13 +74,17 @@ EXTRA_DIST += \
vulkan/anv_icd.py \
vulkan/TODO
-vulkan/dev_icd.json : vulkan/anv_extensions.py vulkan/anv_icd.py
+vulkan/dev_icd.json : vulkan/anv_extensions.py vulkan/anv_icd.py \
+ $(vulkan_api_generators_py)
$(MKDIR_GEN)
+ PYTHONPATH=$(top_srcdir)/src/vulkan/util \
$(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_icd.py \
--lib-path="${abs_top_builddir}/${LIB_DIR}" --out $@
-vulkan/intel_icd. at host_cpu@.json : vulkan/anv_extensions.py vulkan/anv_icd.py
+vulkan/intel_icd. at host_cpu@.json : vulkan/anv_extensions.py vulkan/anv_icd.py \
+ $(vulkan_api_generators_py)
$(MKDIR_GEN)
+ PYTHONPATH=$(top_srcdir)/src/vulkan/util \
$(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_icd.py \
--lib-path="${libdir}" --out $@
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index c40b94d69f3..9f1dc930c34 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -1251,6 +1251,52 @@ anv_GetDeviceGroupPeerMemoryFeatures(
VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
}
+static void * __attribute__ ((noinline))
+anv_resolve_entrypoint(const struct gen_device_info *devinfo, uint32_t index)
+{
+ if (devinfo == NULL) {
+ return anv_dispatch_table.entrypoints[index];
+ }
+
+ const struct anv_dispatch_table *genX_table;
+ switch (devinfo->gen) {
+ case 11:
+ genX_table = &gen11_dispatch_table;
+ break;
+ case 10:
+ genX_table = &gen10_dispatch_table;
+ break;
+ case 9:
+ genX_table = &gen9_dispatch_table;
+ break;
+ case 8:
+ genX_table = &gen8_dispatch_table;
+ break;
+ case 7:
+ if (devinfo->is_haswell)
+ genX_table = &gen75_dispatch_table;
+ else
+ genX_table = &gen7_dispatch_table;
+ break;
+ default:
+ unreachable("unsupported gen\\n");
+ }
+
+ if (genX_table->entrypoints[index])
+ return genX_table->entrypoints[index];
+ else
+ return anv_dispatch_table.entrypoints[index];
+}
+
+void *
+anv_lookup_entrypoint(const struct gen_device_info *devinfo, const char *name)
+{
+ int idx = anv_get_entrypoint_index(name);
+ if (idx < 0)
+ return NULL;
+ return anv_resolve_entrypoint(devinfo, idx);
+}
+
PFN_vkVoidFunction anv_GetInstanceProcAddr(
VkInstance _instance,
const char* pName)
diff --git a/src/intel/vulkan/anv_entrypoints_gen.py b/src/intel/vulkan/anv_entrypoints_gen.py
index e6cd9bbf0a9..219369ecc67 100644
--- a/src/intel/vulkan/anv_entrypoints_gen.py
+++ b/src/intel/vulkan/anv_entrypoints_gen.py
@@ -23,14 +23,10 @@
#
import argparse
-import math
import os
-import xml.etree.cElementTree as et
-from collections import OrderedDict, namedtuple
-from mako.template import Template
-
-from anv_extensions import VkVersion, MAX_API_VERSION, EXTENSIONS
+from anv_extensions import MAX_API_VERSION, EXTENSIONS
+import vk_entrypoints_gen
# We generate a static hash table for entry point lookup
# (vkGetProcAddress). We use a linear congruential generator for our hash
@@ -47,483 +43,6 @@ LAYERS = [
'gen11',
]
-TEMPLATE_H = Template("""\
-/* This file generated from ${filename}, don't edit directly. */
-
-struct anv_dispatch_table {
- union {
- void *entrypoints[${len(entrypoints)}];
- struct {
- % for e in 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
- };
- };
-};
-
-%for layer in LAYERS:
-extern const struct anv_dispatch_table ${layer}_dispatch_table;
-%endfor
-extern const struct anv_dispatch_table anv_tramp_dispatch_table;
-
-% for e in 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 "anv_private.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.
- */
-
-static const char strings[] =
-% for s in strmap.sorted_strings:
- "${s.string}\\0"
-% endfor
-;
-
-static const struct string_map_entry 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 string_map[${strmap.hash_size}] = {
-% for e in strmap.mapping:
- ${ '{:0=#6x}'.format(e) if e >= 0 else 'none' },
-% endfor
-};
-
-static int
-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 = string_map[h & ${strmap.hash_mask}];
- if (i == none)
- return -1;
- e = &string_map_entries[i];
- if (e->hash == hash && strcmp(str, strings + e->name) == 0)
- return e->num;
- h += prime_step;
- }
-
- return -1;
-}
-
-/* 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 layer in LAYERS:
- % for e in entrypoints:
- % if e.alias:
- <% continue %>
- % endif
- % if e.guard is not None:
-#ifdef ${e.guard}
- % endif
- ${e.return_type} ${e.prefixed_name(layer)}(${e.decl_params()}) __attribute__ ((weak));
- % if e.guard is not None:
-#endif // ${e.guard}
- % endif
- % endfor
-
- const struct anv_dispatch_table ${layer}_dispatch_table = {
- % for e in 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
-
-
-/** Trampoline entrypoints for all device functions */
-
-% for e in entrypoints:
- % if e.alias or not e.is_device_entrypoint():
- <% continue %>
- % endif
- % if e.guard is not None:
-#ifdef ${e.guard}
- % endif
- static ${e.return_type}
- ${e.prefixed_name('anv_tramp')}(${e.decl_params()})
- {
- % if e.params[0].type == 'VkDevice':
- ANV_FROM_HANDLE(anv_device, anv_device, ${e.params[0].name});
- return anv_device->dispatch.${e.name}(${e.call_params()});
- % elif e.params[0].type == 'VkCommandBuffer':
- ANV_FROM_HANDLE(anv_cmd_buffer, anv_cmd_buffer, ${e.params[0].name});
- return anv_cmd_buffer->device->dispatch.${e.name}(${e.call_params()});
- % elif e.params[0].type == 'VkQueue':
- ANV_FROM_HANDLE(anv_queue, anv_queue, ${e.params[0].name});
- return anv_queue->device->dispatch.${e.name}(${e.call_params()});
- % else:
- assert(!"Unhandled device child trampoline case: ${e.params[0].type}");
- % endif
- }
- % if e.guard is not None:
-#endif // ${e.guard}
- % endif
-% endfor
-
-const struct anv_dispatch_table anv_tramp_dispatch_table = {
-% for e in entrypoints:
- % if not e.is_device_entrypoint():
- <% continue %>
- % endif
- % if e.guard is not None:
-#ifdef ${e.guard}
- % endif
- .${e.name} = ${e.prefixed_name('anv_tramp')},
- % if e.guard is not None:
-#endif // ${e.guard}
- % endif
-% 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
-anv_entrypoint_is_enabled(int index, uint32_t core_version,
- const struct anv_instance_extension_table *instance,
- const struct anv_device_extension_table *device)
-{
- switch (index) {
-% for e in entrypoints:
- case ${e.num}:
- /* ${e.name} */
- % if e.core_version:
- % if e.is_device_entrypoint():
- return ${e.core_version.c_vk_version()} <= core_version;
- % else:
- return !device && ${e.core_version.c_vk_version()} <= core_version;
- % endif
- % elif e.extensions:
- % for ext in e.extensions:
- % if ext.type == 'instance':
- if (!device && instance->${ext.name[3:]}) return true;
- % else:
- if (!device || device->${ext.name[3:]}) return true;
- % endif
- % endfor
- return false;
- % else:
- return true;
- % endif
-% endfor
- default:
- return false;
- }
-}
-
-static void * __attribute__ ((noinline))
-anv_resolve_entrypoint(const struct gen_device_info *devinfo, uint32_t index)
-{
- if (devinfo == NULL) {
- return anv_dispatch_table.entrypoints[index];
- }
-
- const struct anv_dispatch_table *genX_table;
- switch (devinfo->gen) {
- case 11:
- genX_table = &gen11_dispatch_table;
- break;
- case 10:
- genX_table = &gen10_dispatch_table;
- break;
- case 9:
- genX_table = &gen9_dispatch_table;
- break;
- case 8:
- genX_table = &gen8_dispatch_table;
- break;
- case 7:
- if (devinfo->is_haswell)
- genX_table = &gen75_dispatch_table;
- else
- genX_table = &gen7_dispatch_table;
- break;
- default:
- unreachable("unsupported gen\\n");
- }
-
- if (genX_table->entrypoints[index])
- return genX_table->entrypoints[index];
- else
- return anv_dispatch_table.entrypoints[index];
-}
-
-int
-anv_get_entrypoint_index(const char *name)
-{
- return string_map_lookup(name);
-}
-
-void *
-anv_lookup_entrypoint(const struct gen_device_info *devinfo, const char *name)
-{
- int idx = anv_get_entrypoint_index(name);
- if (idx < 0)
- return NULL;
- return anv_resolve_entrypoint(devinfo, idx);
-}""", 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 num >= 0 and 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_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_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, start_index):
- """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 = {}
-
- for extension in doc.findall('./extensions/extension[@platform]'):
- platform = extension.attrib['platform']
- ext = '_KHR'
- if platform.upper() == 'XLIB_XRANDR':
- ext = '_EXT'
- define = 'VK_USE_PLATFORM_' + platform.upper() + ext
-
- 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.',
@@ -535,54 +54,10 @@ def main():
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),
- start_index=len(entrypoints))
-
- # Manually add CreateDmaBufImageINTEL for which we don't have an extension
- # defined.
- entrypoints.append(Entrypoint('vkCreateDmaBufImageINTEL', 'VkResult', [
- EntrypointParam('VkDevice', 'device', 'VkDevice device'),
- EntrypointParam('VkDmaBufImageCreateInfo', 'pCreateInfo',
- 'const VkDmaBufImageCreateInfo* pCreateInfo'),
- EntrypointParam('VkAllocationCallbacks', 'pAllocator',
- 'const VkAllocationCallbacks* pAllocator'),
- EntrypointParam('VkDeviceMemory', 'pMem', 'VkDeviceMemory* pMem'),
- EntrypointParam('VkImage', 'pImage', 'VkImage* pImage')
- ]))
-
- strmap = StringIntMap()
- for num, e in enumerate(entrypoints):
- strmap.add_string(e.name, num)
- e.num = num
- strmap.bake()
-
- # For outputting entrypoints.h we generate a anv_EntryPoint() prototype
- # per entry point.
- try:
- with open(os.path.join(args.outdir, 'anv_entrypoints.h'), 'wb') as f:
- f.write(TEMPLATE_H.render(entrypoints=entrypoints,
- LAYERS=LAYERS,
- filename=os.path.basename(__file__)))
- with open(os.path.join(args.outdir, 'anv_entrypoints.c'), 'wb') as f:
- f.write(TEMPLATE_C.render(entrypoints=entrypoints,
- LAYERS=LAYERS,
- strmap=strmap,
- filename=os.path.basename(__file__)))
- except Exception:
- # In the even 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
+ vk_entrypoints_gen.generate_entrypoints(MAX_API_VERSION, EXTENSIONS, LAYERS, 'anv', args.xml_files,
+ os.path.join(args.outdir, 'anv_entrypoints.c'),
+ os.path.join(args.outdir, 'anv_entrypoints.h'),
+ has_intel_entrypoints=True)
if __name__ == '__main__':
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
index 9a65aed1c46..eab48a42a64 100644
--- a/src/intel/vulkan/anv_extensions.py
+++ b/src/intel/vulkan/anv_extensions.py
@@ -24,29 +24,7 @@ COPYRIGHT = """\
*/
"""
-import argparse
-import copy
-import re
-import xml.etree.cElementTree as et
-
-def _bool_to_c_expr(b):
- if b is True:
- return 'true'
- elif b is False:
- return 'false'
- else:
- 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)
+from vk_extensions import ApiVersion, Extension, VkVersion
API_PATCH_VERSION = 80
@@ -127,50 +105,6 @@ EXTENSIONS = [
Extension('VK_EXT_post_depth_coverage', 1, 'device->info.gen >= 9'),
]
-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)
diff --git a/src/intel/vulkan/anv_extensions_gen.py b/src/intel/vulkan/anv_extensions_gen.py
index a140c267452..6e8361c7227 100644
--- a/src/intel/vulkan/anv_extensions_gen.py
+++ b/src/intel/vulkan/anv_extensions_gen.py
@@ -25,162 +25,9 @@ COPYRIGHT = """\
"""
import argparse
-import xml.etree.cElementTree as et
-
-from mako.template import Template
from anv_extensions import *
-
-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
-
- 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 ANV_EXTENSIONS_H
-#define ANV_EXTENSIONS_H
-
-#include "stdbool.h"
-
-#define ANV_INSTANCE_EXTENSION_COUNT ${len(instance_extensions)}
-
-extern const VkExtensionProperties anv_instance_extensions[];
-
-struct anv_instance_extension_table {
- union {
- bool extensions[ANV_INSTANCE_EXTENSION_COUNT];
- struct {
-%for ext in instance_extensions:
- bool ${ext.name[3:]};
-%endfor
- };
- };
-};
-
-extern const struct anv_instance_extension_table anv_instance_extensions_supported;
-
-
-#define ANV_DEVICE_EXTENSION_COUNT ${len(device_extensions)}
-
-extern const VkExtensionProperties anv_device_extensions[];
-
-struct anv_device_extension_table {
- union {
- bool extensions[ANV_DEVICE_EXTENSION_COUNT];
- struct {
-%for ext in device_extensions:
- bool ${ext.name[3:]};
-%endfor
- };
- };
-};
-
-struct anv_physical_device;
-
-void
-anv_physical_device_get_supported_extensions(const struct anv_physical_device *device,
- struct anv_device_extension_table *extensions);
-
-#endif /* ANV_EXTENSIONS_H */
-""")
-
-_TEMPLATE_C = Template(COPYRIGHT + """
-#include "anv_private.h"
-
-#include "vk_util.h"
-
-/* Convert the VK_USE_PLATFORM_* defines to booleans */
-%for platform in ['ANDROID_KHR', 'WAYLAND_KHR', 'XCB_KHR', 'XLIB_KHR', 'DISPLAY_KHR', 'XLIB_XRANDR_EXT']:
-#ifdef VK_USE_PLATFORM_${platform}
-# undef VK_USE_PLATFORM_${platform}
-# define VK_USE_PLATFORM_${platform} true
-#else
-# define VK_USE_PLATFORM_${platform} false
-#endif
-%endfor
-
-/* And ANDROID too */
-#ifdef ANDROID
-# undef ANDROID
-# define ANDROID true
-#else
-# define ANDROID false
-#endif
-
-#define ANV_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()};
-
-VkResult anv_EnumerateInstanceVersion(
- uint32_t* pApiVersion)
-{
- *pApiVersion = MAX_API_VERSION;
- return VK_SUCCESS;
-}
-
-const VkExtensionProperties anv_instance_extensions[ANV_INSTANCE_EXTENSION_COUNT] = {
-%for ext in instance_extensions:
- {"${ext.name}", ${ext.ext_version}},
-%endfor
-};
-
-const struct anv_instance_extension_table anv_instance_extensions_supported = {
-%for ext in instance_extensions:
- .${ext.name[3:]} = ${ext.enable},
-%endfor
-};
-
-uint32_t
-anv_physical_device_api_version(struct anv_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 anv_device_extensions[ANV_DEVICE_EXTENSION_COUNT] = {
-%for ext in device_extensions:
- {"${ext.name}", ${ext.ext_version}},
-%endfor
-};
-
-void
-anv_physical_device_get_supported_extensions(const struct anv_physical_device *device,
- struct anv_device_extension_table *extensions)
-{
- *extensions = (struct anv_device_extension_table) {
-%for ext in device_extensions:
- .${ext.name[3:]} = ${ext.enable},
-%endfor
- };
-}
-""")
+import vk_extensions_gen
if __name__ == '__main__':
parser = argparse.ArgumentParser()
@@ -193,23 +40,5 @@ if __name__ == '__main__':
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'],
- }
-
- 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))
+ vk_extensions_gen.generate_extensions(MAX_API_VERSION, API_VERSIONS, EXTENSIONS, 'anv',
+ args.xml_files, args.out_c, args.out_h)
diff --git a/src/intel/vulkan/meson.build b/src/intel/vulkan/meson.build
index e427c7471f4..41f94398679 100644
--- a/src/intel/vulkan/meson.build
+++ b/src/intel/vulkan/meson.build
@@ -25,10 +25,11 @@ anv_entrypoints = custom_target(
input : ['anv_entrypoints_gen.py', vk_api_xml],
output : ['anv_entrypoints.h', 'anv_entrypoints.c'],
command : [
+ 'env', 'PYTHONPATH=@0@'.format(join_paths(meson.source_root(), 'src/vulkan/util/')),
prog_python2, '@INPUT0@', '--xml', '@INPUT1@',
'--outdir', meson.current_build_dir(),
],
- depend_files : anv_extensions_py,
+ depend_files : [anv_extensions_py, vk_api_generators_py],
)
anv_extensions_c = custom_target(
@@ -36,10 +37,11 @@ anv_extensions_c = custom_target(
input : ['anv_extensions_gen.py', vk_api_xml],
output : 'anv_extensions.c',
command : [
+ 'env', 'PYTHONPATH=@0@'.format(join_paths(meson.source_root(), 'src/vulkan/util/')),
prog_python2, '@INPUT0@', '--xml', '@INPUT1@',
'--out-c', '@OUTPUT@',
],
- depend_files : anv_extensions_py,
+ depend_files : [anv_extensions_py, vk_api_generators_py],
)
anv_extensions_h = custom_target(
@@ -47,10 +49,11 @@ anv_extensions_h = custom_target(
input : ['anv_extensions_gen.py', vk_api_xml],
output : 'anv_extensions.h',
command : [
+ 'env', 'PYTHONPATH=@0@'.format(join_paths(meson.source_root(), 'src/vulkan/util/')),
prog_python2, '@INPUT0@', '--xml', '@INPUT1@',
'--out-h', '@OUTPUT@',
],
- depend_files : anv_extensions_py,
+ depend_files : [anv_extensions_py, vk_api_generators_py],
)
intel_icd = custom_target(
@@ -58,11 +61,12 @@ intel_icd = custom_target(
input : 'anv_icd.py',
output : 'intel_icd. at 0@.json'.format(host_machine.cpu()),
command : [
+ 'env', 'PYTHONPATH=@0@'.format(join_paths(meson.source_root(), 'src/vulkan/util/')),
prog_python2, '@INPUT@',
'--lib-path', join_paths(get_option('prefix'), get_option('libdir')),
'--out', '@OUTPUT@',
],
- depend_files : anv_extensions_py,
+ depend_files : [anv_extensions_py, vk_api_generators_py],
build_by_default : true,
install_dir : with_vulkan_icd_dir,
install : true,
@@ -73,10 +77,11 @@ dev_icd = custom_target(
input : 'anv_icd.py',
output : 'dev_icd. at 0@.json'.format(host_machine.cpu()),
command : [
+ 'env', 'PYTHONPATH=@0@'.format(join_paths(meson.source_root(), 'src/vulkan/util/')),
prog_python2, '@INPUT@', '--lib-path', meson.current_build_dir(),
'--out', '@OUTPUT@'
],
- depend_files : files('anv_extensions.py'),
+ depend_files : [anv_extensions_py, vk_api_generators_py],
build_by_default : true,
install : false,
)
diff --git a/src/vulkan/util/vk_extensions.py b/src/vulkan/util/vk_extensions.py
index 4f6667fe86c..79ae3af02ea 100644
--- a/src/vulkan/util/vk_extensions.py
+++ b/src/vulkan/util/vk_extensions.py
@@ -82,11 +82,12 @@ class VkVersion:
patch = self.patch if self.patch is not None else 0
return (self.major << 22) | (self.minor << 12) | patch
- def __cmp__(self, other):
+ 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().__cmp__(other.__int_ver())
+ return self.__int_ver() > other.__int_ver()
+
--
2.18.0
More information about the mesa-dev
mailing list