Edit

IABSD.fr/xenocara/lib/mesa/src/gfxstream/codegen/scripts/genvk.py

Branch :

  • Show log

    Commit

  • Author : jsg
    Date : 2025-06-05 11:23:11
    Hash : 67d6f117
    Message : Import Mesa 25.0.7

  • lib/mesa/src/gfxstream/codegen/scripts/genvk.py
  • #!/usr/bin/python3
    #
    # Copyright 2013-2023 The Khronos Group Inc.
    # Copyright 2023-2024 Google Inc.
    #
    # SPDX-License-Identifier: Apache-2.0
    
    import argparse
    import os
    import re
    import sys
    import xml.etree.ElementTree as etree
    
    sys.path.append(os.path.abspath(os.path.dirname(__file__)))
    
    from cgenerator import CGeneratorOptions, COutputGenerator
    
    from generator import write
    from reg import Registry
    
    # gfxstream + cereal modules
    from cerealgenerator import CerealGenerator
    
    from typing import Optional
    
    def makeREstring(strings, default=None, strings_are_regex=False):
        """Turn a list of strings into a regexp string matching exactly those strings."""
        if strings or default is None:
            if not strings_are_regex:
                strings = (re.escape(s) for s in strings)
            return '^(' + '|'.join(strings) + ')$'
        return default
    
    
    def makeGenOpts(args):
        """Returns a directory of [ generator function, generator options ] indexed
        by specified short names. The generator options incorporate the following
        parameters:
    
        args is an parsed argument object; see below for the fields that are used."""
        global genOpts
        genOpts = {}
    
        # Output target directory
        directory = args.directory
    
        # Descriptive names for various regexp patterns used to select
        # versions and extensions
        allFormats = allFeatures = allExtensions = r'.*'
    
        # Turn lists of names/patterns into matching regular expressions
        emitExtensionsPat    = makeREstring([], allExtensions)
        emitFormatsPat       = makeREstring([], allFormats)
        featuresPat          = makeREstring([], allFeatures)
    
        # Copyright text prefixing all headers (list of strings).
        # The SPDX formatting below works around constraints of the 'reuse' tool
        prefixStrings = [
            '/*',
            '** Copyright 2015-2023 The Khronos Group Inc.',
            '**',
            '** SPDX-License-Identifier' + ': Apache-2.0',
            '*/',
            ''
        ]
    
        # Text specific to Vulkan headers
        vkPrefixStrings = [
            '/*',
            '** This header is generated from the Khronos Vulkan XML API Registry.',
            '**',
            '*/',
            ''
        ]
    
        genOpts['cereal'] = [
                CerealGenerator,
                CGeneratorOptions(
                    directory         = directory,
                    versions          = featuresPat,
                    emitversions      = featuresPat,
                    addExtensions     = None,
                    emitExtensions    = emitExtensionsPat,
                    prefixText        = prefixStrings + vkPrefixStrings,
                    apientry          = 'VKAPI_CALL ',
                    apientryp         = 'VKAPI_PTR *',
                    alignFuncParam    = 48)
            ]
    
        gfxstreamPrefixStrings = [
            '#pragma once',
            '#ifdef VK_GFXSTREAM_STRUCTURE_TYPE_EXT',
            '#include "vulkan_gfxstream_structure_type.h"',
            '#endif',
        ]
    
        # gfxstream specific header
        genOpts['vulkan_gfxstream.h'] = [
              COutputGenerator,
              CGeneratorOptions(
                filename          = 'vulkan_gfxstream.h',
                directory         = directory,
                versions          = featuresPat,
                emitversions      = None,
                addExtensions     = makeREstring(['VK_GOOGLE_gfxstream'], None),
                emitExtensions    = makeREstring(['VK_GOOGLE_gfxstream'], None),
                prefixText        = prefixStrings + vkPrefixStrings + gfxstreamPrefixStrings,
                # Use #pragma once in the prefixText instead, so that we can put the copyright comments
                # at the beginning of the file.
                apientry          = 'VKAPI_CALL ',
                apientryp         = 'VKAPI_PTR *',
                alignFuncParam    = 48)
            ]
    
    def genTarget(args):
        """Create an API generator and corresponding generator options based on
        the requested target and command line options.
    
        This is encapsulated in a function so it can be profiled and/or timed.
        The args parameter is an parsed argument object containing the following
        fields that are used:
    
        - target - target to generate
        - directory - directory to generate it in
        - extensions - list of additional extensions to include in generated interfaces"""
    
        # Create generator options with parameters specified on command line
        makeGenOpts(args)
    
        # Select a generator matching the requested target
        if args.target in genOpts:
            createGenerator = genOpts[args.target][0]
            options = genOpts[args.target][1]
    
            gen = createGenerator(errFile=errWarn,
                                  warnFile=errWarn,
                                  diagFile=diag)
            return (gen, options)
        else:
            return None
    
    
    # -feature name
    # -extension name
    # For both, "name" may be a single name, or a space-separated list
    # of names, or a regular expression.
    if __name__ == '__main__':
        parser = argparse.ArgumentParser()
        parser.add_argument('-registry', action='store',
                            default='vk.xml',
                            help='Use specified registry file instead of vk.xml')
        parser.add_argument('-registryGfxstream', action='store',
                            default=None,
                            help='Use specified gfxstream registry file')
        parser.add_argument('-o', action='store', dest='directory',
                            default='.',
                            help='Create target and related files in specified directory')
        parser.add_argument('target', metavar='target', nargs='?',
                            help='Specify target')
    
        args = parser.parse_args()
    
        errWarn = sys.stderr
        diag = None
    
        # Create the API generator & generator options
        (gen, options) = genTarget(args)
    
        # Create the registry object with the specified generator and generator
        # options. The options are set before XML loading as they may affect it.
        reg = Registry(gen, options)
    
        # Parse the specified registry XML into an ElementTree object
        tree = etree.parse(args.registry)
    
        # Merge the gfxstream registry with the official Vulkan registry if the
        # target is the cereal generator
        if args.registryGfxstream is not None and args.target == 'cereal':
            treeGfxstream = etree.parse(args.registryGfxstream)
            treeRoot = tree.getroot()
            treeGfxstreamRoot = treeGfxstream.getroot()
    
            def getEntryName(entry) -> Optional[str]:
                name = entry.get("name")
                if name is not None:
                    return name
                try:
                    return entry.find("proto").find("name").text
                except AttributeError:
                    return None
    
            for entriesName in ['types', 'commands', 'extensions']:
                treeEntries = treeRoot.find(entriesName)
    
                originalEntryDict = {}
                for entry in treeEntries:
                    name = getEntryName(entry)
                    if name is not None:
                        originalEntryDict[name] = entry
    
                for entry in treeGfxstreamRoot.find(entriesName):
                    name = getEntryName(entry)
                    # New entry, just append to entry list
                    if name not in originalEntryDict.keys():
                        treeEntries.append(entry)
                        continue
    
                    originalEntry = originalEntryDict[name]
    
                    # Extending an existing entry. This happens for MVK.
                    if entriesName == "extensions":
                        for key, value in entry.attrib.items():
                            originalEntry.set(key, value)
                        require = entry.find("require")
                        if require is not None:
                            for child in require:
                                originalEntry.find("require").append(child)
                        continue
    
                    # Overwriting an existing entry. This happen for
                    # VkNativeBufferANDROID
                    if entriesName == "types" or entriesName == "commands":
                        originalEntry.clear()
                        originalEntry.attrib = entry.attrib
                        for child in entry:
                            originalEntry.append(child)
    
        # Load the XML tree into the registry object
        reg.loadElementTree(tree)
        reg.apiGen()