#!/usr/bin/python3 -i
#
# Copyright (c) 2015-2021 The Khronos Group Inc.
# Copyright (c) 2015-2021 Valve Corporation
# Copyright (c) 2015-2021 LunarG, Inc.
# Copyright (c) 2015-2021 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author: John Zulauf <jzulauf@lunarg.com>
# Author: Jeremy Gebben <jeremyg@lunarg.com>
import os
import json
import re

# Script operation controls
debug_json_parse = False
debug_table_parse = False
debug_in_bit_order = False
debug_top_level = False
debug_queue_caps = False
debug_stage_order_parse = False
debug_bubble_insert = False
experimental_ordering = False

# Some DRY constants
host_stage = 'VK_PIPELINE_STAGE_2_HOST_BIT_KHR'
top_stage ='VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR'
bot_stage ='VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR'

def ParseAccessMasks(valid_usage_path, all_stages):
    vu_json_filename = os.path.join(valid_usage_path + os.sep, 'validusage.json')
    access_stage_table = {}
    if os.path.isfile(vu_json_filename):
        json_file = open(vu_json_filename, 'r', encoding='utf-8')
        vuid_dict = json.load(json_file)
        json_file.close()
    if len(vuid_dict) == 0:
        print('Error: Could not find, or error loading %s/validusage.json\n', vu_json_filename)
        sys.exit(1)
    # every synchronization2 access mask bit has a VUID enumerating all pipeline stages it is compatible with. It looks like this:
    # {
    #   "vuid": "VUID-VkMemoryBarrier2KHR-srcAccessMask-03900",
    #   "text": " If pname:srcAccessMask includes <code>access_mask</code>,
    #             pname:srcStageMask <strong class=\"purple\">must</strong> include <code>stage_1</code>,
    #             <code>stage_2</code>, <code>VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR</code>,
    #             or <code>VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR</code>"
    # },
    vuid_prefix = 'VUID-VkMemoryBarrier2KHR-srcAccessMask'
    text_prefix = ' If pname:srcAccessMask includes '
    # remove catch-all pipeline stages that we don't need in our tables.
    strip_stages = [
        'VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR',
        'VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR',
        'VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR',
        # expands to INDEX_INPUT and VERTEX_ATTRIBUTE_INPUT, which are included explicitly in the VUIDs
        'VK_PIPELINE_STAGE_2_VERTEX_INPUT_BIT_KHR',
        # temporarily disable VK_HUAWEI_invocation_mask pending more detail in the sync chapter
        'VK_PIPELINE_STAGE_2_INVOCATION_MASK_BIT_HUAWEI',
    ]
    expand_stages = {
        # these have the same value
        'VK_PIPELINE_STAGE_2_SHADING_RATE_IMAGE_BIT_NV': ['VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR'],
        # some VUIDs include the text "or one of the etext:VK_PIPELINE_STAGE_*_SHADER_BIT stages"
        'VK_PIPELINE_STAGE_*_SHADER_BIT': [stage for stage in all_stages if '_SHADER_BIT' in stage]
    }
    expand_access_bits = {
        'VK_ACCESS_2_SHADING_RATE_IMAGE_READ_BIT_NV': ['VK_ACCESS_2_FRAGMENT_SHADING_RATE_ATTACHMENT_READ_BIT_KHR'],
        'VK_ACCESS_2_SHADER_WRITE_BIT_KHR': ['VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT_KHR'],
        'VK_ACCESS_2_SHADER_READ_BIT_KHR': ['VK_ACCESS_2_UNIFORM_READ_BIT_KHR', 'VK_ACCESS_2_SHADER_SAMPLED_READ_BIT_KHR',
                                            'VK_ACCESS_2_SHADER_STORAGE_READ_BIT_KHR'],
    }
    for extension_combo, vuid_list in vuid_dict['validation']['VkMemoryBarrier2KHR'].items():
        for vuid in vuid_list:
            if debug_json_parse:
                print('extension_combo: ', extension_combo)
            if 'VK_KHR_synchronization2' not in extension_combo:
                continue
            # skip ray-query off VUIDs so we get the maximum set of pipeline stages allowed.
            if '!(VK_KHR_ray_query)' in extension_combo:
                continue
            if vuid['vuid'].startswith(vuid_prefix) and vuid['text'].startswith(text_prefix):
                matches = re.findall('<code>(.*?)</code>', vuid['text'], re.DOTALL)
                access_bits = expand_access_bits.get(matches[0], [matches[0]])
                stages = []
                for m in matches[1:]:
                    if m not in strip_stages:
                        stages += expand_stages.get(m, [m])
                for bit in access_bits:
                    if debug_json_parse:
                        print('access_mask: ', bit, ' stages: ', stages)
                    access_stage_table[bit] = stages
    return access_stage_table

# use simplest filtering to assure completest list
def ParseQueueCaps(table_text):
    preproc = ''
    access_stage_table = {}
    skip = False
    outside_table = True
    for line in table_text.split('\n'):
        if not line.strip():
            continue
        elif outside_table:
            if line.startswith('|===='):
                outside_table = False
            continue
        elif line.startswith('ifndef'):
            # Negative preproc filter
            preproc = line
            skip = True # for now just ignore subset filtering
        elif line.startswith('ifdef'):
            # Positive preproc filter
            preproc = line
            skip = False # No support for nested directives...
        elif line.startswith('endif'):
            # Positive preproc filter
            skip = False
        elif (line.startswith('|ename:') or line.startswith('        ')) and not skip:
            if debug_table_parse:
                print('// line {}'.format(line))
            cols = line.split('|')
            if debug_table_parse:
                print('len(cols)', len(cols), cols)
            if len(cols) == 3:
                stage_column = cols[2]
                access_enum = cols[1].split(':')[1].strip()
                access_stage_table[access_enum]=[]
            else:
                stage_column = cols[0].strip()
            if debug_table_parse:
                print('stage_column:', stage_column)
            if stage_column.startswith(' Any'):
                continue
            if stage_column.startswith(' None required'):
                continue
            stage_column = stage_column.replace(', or ',', ') # Oxford comma
            stage_column = stage_column.replace(' or ',', ') # !Oxford comma
            stage_column = stage_column.replace(', ',',')
            stage_column = stage_column.rstrip(',')
            stages = stage_column.split(',')
            if debug_table_parse:
                print('stages', len(stages), stages)
            if len(stages) < 1:
                continue
            elif not stages[0]:
                continue
            stages_lens = [len(s.split(':')) for s in stages]
            stage_enums = [ s.split(':')[1].strip('or ') for s in stages]

            access_stage_table[access_enum] += stage_enums
            if(debug_table_parse):
                print('// access_stage_table[{}]: {}'.format(access_enum, '|'.join(access_stage_table[access_enum])))

    return access_stage_table

def CreateStageAccessTable(stage_order, access_stage_table):
    stage_access_table = { stage: list() for stage in stage_order}
    for access, stages in access_stage_table.items():
        for stage in stages:
            stage_access_table[stage].append(access)

    return stage_access_table

# Snipped from chapters/synchronization.txt -- tag v1.2.185
# manual fixups:
# - add back TOP_OF_PIPE and BOTTOM_OF_PIPE stages to everything
# - sync2-ify stage names
# - remove ifndef::VK_KHR_synchronization2[] content
# - remove ifdefs
# - make sure each pipeline section starts with "For"
# - move single stage 'pipeline' descriptions out of the snippet
#   and into a python list.
snippet_pipeline_stages_order = '''
[[synchronization-pipeline-stages-types]][[synchronization-pipeline-graphics]]
<<pipelines-graphics, Graphics pipelines>> are executable on queues
supporting ename:VK_QUEUE_GRAPHICS_BIT.
Stages executed by graphics pipelines can: only be specified in commands
recorded for queues supporting ename:VK_QUEUE_GRAPHICS_BIT.

For the graphics primitive pipeline executes the following stages, with the logical ordering of the
stages matching the order specified here:

  * ename:VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT
  * ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR

For the graphics mesh pipeline executes the following stages, with the logical
ordering of the stages matching the order specified here:

  * ename:VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV
  * ename:VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV
  * ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR

For the compute pipeline, the following stages occur in this order:

  * ename:VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR

For graphics pipeline commands executing in a render pass with a fragment
density map attachment, the following pipeline stage where the fragment
density map read happens has no particular order relative to the other
stages, except that it is logically earlier than
ename:VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR:

  * ename:VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT
  * ename:VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR

For the ray tracing pipeline, the following stages occur in this order:

  * ename:VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR
  * ename:VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR

'''

#For the X pipeline, only one pipeline stage occurs, so no order is guaranteed:
unordered_stages =  [
  'VK_PIPELINE_STAGE_2_COPY_BIT_KHR',
  'VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR',
  'VK_PIPELINE_STAGE_2_BLIT_BIT_KHR',
  'VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR',
  'VK_PIPELINE_STAGE_2_HOST_BIT_KHR',
  'VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV',
  'VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR',
  'VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT',
  'VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR',
  'VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR',
  'VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI',
]

pipeline_name_labels = {
    'GRAPHICS': 'For the graphics primitive pipeline',
    'MESH': 'For the graphics mesh pipeline',
    'COMPUTE': 'For the compute pipeline',
    'RAY_TRACING_SHADE': 'For the ray tracing pipeline',
}

def StageOrderListFromSet(stage_order, stage_set):
    return [ stage for stage in stage_order if stage in stage_set]

def BubbleInsertStages(stage_order, prior, subseq):
    # Get a fixed list for the order in which we'll add... this is a 'seed' order and will guarantee repeatilbity as it fixes the
    # order items not sorted relative to each other.  Any seed would do, even alphabetical
    stage_set = set(prior.keys()).union(set(subseq.keys()))

    #stage_set_ordered = StageOrderListFromSet(stage_order, stage_set)
    # Come up with a consistent stage order seed that will leave stage types (extension, core, vendor) grouped
    # Reverse the strings -- a spoonerism of the whole stage string, to put the type first
    #     spoonerism -- https://en.wikipedia.org/wiki/Spoonerism
    stage_spooner = list()
    acme = '_AAAAAA'
    stage_spooner = sorted([ stage.replace('_BIT', acme)[::-1] for stage in stage_set if stage != host_stage])
    print('ZZZ BUBBLE spooner\n', '\n '.join(stage_spooner))

    # De-spoonerize
    stage_set_ordered = [ stage[::-1].replace(acme, '_BIT') for stage in stage_spooner]
    print('ZZZ BUBBLE de-spooner\n', '\n '.join(stage_set_ordered))

    stage_set_ordered.append(host_stage)
    stages = [ stage_set_ordered.pop(0) ]

    for stage in stage_set_ordered:
        if debug_bubble_insert: print('BUBBLE adding stage:', stage)
        inserted = False;
        for i in range(len(stages)):
            if stages[i] in subseq[stage]:
                stages.insert(i, stage)
                inserted = True
                break
        if not inserted:
            stages.append(stage)
        if debug_bubble_insert: print('BUBBLE result:', stages)

    print('BUBBLE\n', '\n '.join(stages))
    return stages

def ParsePipelineStageOrder(stage_order, stage_order_snippet, config) :
    pipeline_name = ''
    stage_lists = {}
    touchup = set()
    stage_entry_prefix = '* ename:'
    all_stages = set()
    list_started = False
    # Parse the snippet
    for line in stage_order_snippet.split('\n'):
        line = line.strip()
        if debug_stage_order_parse: print ('STAGE_ORDER', line)
        if not line:
            if debug_stage_order_parse: print ('STAGE_ORDER', 'skip empty')
            if list_started:
                if debug_stage_order_parse: print ('STAGE_ORDER', 'EOL')
                pipeline_name = ''
            continue
        if line.startswith('For') :
            for name, label in pipeline_name_labels.items():
                if line.startswith(label):
                    pipeline_name = name
                    stage_lists[name] = list()
                    list_started = False
                    break
            if debug_stage_order_parse: print ('STAGE_ORDER', 'new pipeline', pipeline_name)
            continue
        if line.startswith(stage_entry_prefix):
            if debug_stage_order_parse: print ('STAGE_ORDER', 'new entry')
            list_started = True
            stage = line.lstrip(stage_entry_prefix)
            all_stages.add(stage)
            if pipeline_name:
                if debug_stage_order_parse: print ('STAGE_ORDER', 'normal entry')
                stage_lists[pipeline_name].append(stage)
            else:
                # See if we've seen this before.  Touchups must be novel
                novel_stage = all([not stage in stage_list for stage_list in stage_lists.values()])
                if (novel_stage):
                    if debug_stage_order_parse: print ('STAGE_ORDER', 'touchup entry')
                    touchup.add(stage)
                else:
                    if debug_stage_order_parse: print ('STAGE_ORDER', 'context entry')

    if debug_stage_order_parse:
        print('STAGE_ORDER', 'PARSED PIPELINES')
        for pipeline_name, stage_list in stage_lists.items():
            print(pipeline_name,'|'.join(stage_list))

        print('STAGE_ORDER', 'PARSED all_stages')
        print('all_stages','|'.join(all_stages))


    # Create earlier/later maps
    prior = { stage:set() for stage in all_stages }
    subseq = { stage:set() for stage in all_stages }

    for pipeline_name, stage_list in stage_lists.items():
        for i in range(len(stage_list)):
            prior[stage_list[i]].update(stage_list[:i])
            subseq[stage_list[i]].update(stage_list[i+1:])

    # Touch up the stages that don't quite parse right
    touchups_done = set()

    # FDP Stage is only constrained to be before VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR
    fdp_stage = 'VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT'
    fdp_before = 'VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR'
    prior[fdp_stage] = set()
    subseq[fdp_stage] = set([fdp_before])
    subseq[fdp_stage].update(subseq[fdp_before])
    for stage in subseq[fdp_stage]:
        prior[stage].add(fdp_stage)

    touchups_done.add(fdp_stage)


    # Handle all stages that don't enforce an order
    for stage in unordered_stages:
        prior[stage] = set()
        subseq[stage] = set()

    # Make sure top and bottom got added to every prior and subseq (respectively) except for HOST
    # and the every stage is prior and susequent to bottom and top (respectively) also except for HOST
    for stage, prior_stages in prior.items():
        if stage == host_stage: continue
        prior_stages.add(top_stage)
        subseq[top_stage].add(stage)
    for stage, subseq_stages in subseq.items():
        if stage == host_stage: continue
        subseq_stages.add(bot_stage)
        prior[bot_stage].add(stage)

    if experimental_ordering:
        stage_order = BubbleInsertStages(stage_order, prior, subseq)

    # Convert sets to ordered vectors
    prior_sets = prior
    prior = { key:StageOrderListFromSet(stage_order, value) for key, value in prior_sets.items() }
    subseq_sets = subseq
    subseq = { key:StageOrderListFromSet(stage_order, value) for key, value in subseq_sets.items() }

    if debug_stage_order_parse:
        print('STAGE_ORDER PRIOR STAGES')
        for stage, stage_set in prior.items():
            print(stage,'|'.join(stage_set))

        print('STAGE_ORDER SUBSEQUENT STAGES')
        for stage, stage_set in subseq.items():
            print(stage,'|'.join(stage_set))

    if touchups_done != touchup:
        print('STAGE_ORDER Stage order touchups failed')
        print('STAGE_ORDER touchups_done', touchups_done)
        print('STAGE_ORDER touchups found', touchup)
        exit(-1)

    return { 'stages': all_stages, 'stage_lists':stage_lists, 'prior': prior, 'subseq':subseq, 'touchups':touchup }

# Note: there should be a machine readable merged order, but there isn't... so we'll need some built-in consistency checks
# Pipeline stages in rough order, merge sorted.  When
# Legal stages are masked in, remaining stages are ordered
pipeline_order = '''
VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR
VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR
VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR
VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR
VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR
VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR
VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR
VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR
VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT
VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT
VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV
VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV
VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR
VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR
VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR
VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR
VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR
VK_PIPELINE_STAGE_2_COPY_BIT_KHR
VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR
VK_PIPELINE_STAGE_2_BLIT_BIT_KHR
VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR
VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV
VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT
VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR
VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR
VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR
VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR
VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI
VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR
VK_PIPELINE_STAGE_2_HOST_BIT_KHR
'''

sync_enum_types = ('VkPipelineStageFlagBits2KHR', 'VkAccessFlagBits2KHR' )

def InBitOrder(tag, enum_elem):
    # The input may be unordered or sparse w.r.t. the mask field, sort and gap fill
    found = []
    for elem in enum_elem:
        bitpos = elem.get('bitpos')
        name = elem.get('name')
        if not bitpos:
            continue

        if name.endswith('NONE_KHR'):
            break

        found.append({'name': name, 'bitpos': int(bitpos)})

    in_bit_order = []
    for entry in sorted(found, key=lambda record: record['bitpos']):
        if debug_in_bit_order:
            print ('adding ', {'name': entry['name'], 'mask': (1 << entry['bitpos'])})
        bitpos = entry['bitpos']
        in_bit_order.append({'name': entry['name'], 'mask': (1 << bitpos), 'bitpos': bitpos})

    return in_bit_order


# Snipped from chapters/synchronization.txt -- tag v1.2.185
# manual fixups:
# - sync2-ify stage names
# - remove ifdefs
# - expand VERTEX_INPUT and TRANSFER stages
# - manually add VIDEO_DECODE and VIDEO_ENCODE stages TODO: get them added to the spec
snippet_pipeline_stages_supported = '''
[[synchronization-pipeline-stages-supported]]
.Supported pipeline stage flags
[cols="60%,40%",options="header"]
|====
|Pipeline stage flag                                          | Required queue capability flag
|ename:VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR                      | None required
|ename:VK_PIPELINE_STAGE_2_DRAW_INDIRECT_BIT_KHR                    | ename:VK_QUEUE_GRAPHICS_BIT or ename:VK_QUEUE_COMPUTE_BIT
|ename:VK_PIPELINE_STAGE_2_VERTEX_ATTRIBUTE_INPUT_BIT_KHR     | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_INDEX_INPUT_BIT_KHR                | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_VERTEX_SHADER_BIT_KHR                    | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_TESSELLATION_CONTROL_SHADER_BIT_KHR      | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_TESSELLATION_EVALUATION_SHADER_BIT_KHR   | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_GEOMETRY_SHADER_BIT_KHR                  | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT_KHR                  | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_EARLY_FRAGMENT_TESTS_BIT_KHR             | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_LATE_FRAGMENT_TESTS_BIT_KHR              | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT_KHR          | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT_KHR                   | ename:VK_QUEUE_COMPUTE_BIT
|ename:VK_PIPELINE_STAGE_2_COPY_BIT_KHR                       | ename:VK_QUEUE_GRAPHICS_BIT, ename:VK_QUEUE_COMPUTE_BIT or ename:VK_QUEUE_TRANSFER_BIT
|ename:VK_PIPELINE_STAGE_2_CLEAR_BIT_KHR                      | ename:VK_QUEUE_GRAPHICS_BIT, ename:VK_QUEUE_COMPUTE_BIT or ename:VK_QUEUE_TRANSFER_BIT
|ename:VK_PIPELINE_STAGE_2_RESOLVE_BIT_KHR                    | ename:VK_QUEUE_GRAPHICS_BIT, ename:VK_QUEUE_COMPUTE_BIT or ename:VK_QUEUE_TRANSFER_BIT
|ename:VK_PIPELINE_STAGE_2_BLIT_BIT_KHR                       | ename:VK_QUEUE_GRAPHICS_BIT, ename:VK_QUEUE_COMPUTE_BIT or ename:VK_QUEUE_TRANSFER_BIT
|ename:VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT_KHR                   | None required
|ename:VK_PIPELINE_STAGE_2_HOST_BIT_KHR                             | None required
|ename:VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR                     | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR                     | None required
|ename:VK_PIPELINE_STAGE_2_CONDITIONAL_RENDERING_BIT_EXT        | ename:VK_QUEUE_GRAPHICS_BIT or ename:VK_QUEUE_COMPUTE_BIT
|ename:VK_PIPELINE_STAGE_2_TRANSFORM_FEEDBACK_BIT_EXT           | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_COMMAND_PREPROCESS_BIT_NV            | ename:VK_QUEUE_GRAPHICS_BIT or ename:VK_QUEUE_COMPUTE_BIT
|ename:VK_PIPELINE_STAGE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR            | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_TASK_SHADER_BIT_NV                   | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_MESH_SHADER_BIT_NV                   | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_ACCELERATION_STRUCTURE_BUILD_BIT_KHR | ename:VK_QUEUE_COMPUTE_BIT
|ename:VK_PIPELINE_STAGE_2_RAY_TRACING_SHADER_BIT_KHR           | ename:VK_QUEUE_COMPUTE_BIT
|ename:VK_PIPELINE_STAGE_2_FRAGMENT_DENSITY_PROCESS_BIT_EXT     | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_SUBPASS_SHADING_BIT_HUAWEI         | ename:VK_QUEUE_GRAPHICS_BIT
|ename:VK_PIPELINE_STAGE_2_VIDEO_DECODE_BIT_KHR                 | ename:VK_QUEUE_VIDEO_DECODE_BIT_KHR
|ename:VK_PIPELINE_STAGE_2_VIDEO_ENCODE_BIT_KHR                 | ename:VK_QUEUE_VIDEO_ENCODE_BIT_KHR
|====
'''

def BitSuffixed(name):
    alt_bit = ('_ANDROID', '_EXT', '_IMG', '_KHR', '_NV', '_NVX')
    bit_suf = name + '_BIT'
    # Since almost every bit ends with _KHR, just ignore it.
    # Otherwise some generated names end up with every other word being KHR.
    if name.endswith('_KHR') :
            bit_suf = name.replace('_KHR', '_BIT')
    else:
        for alt in alt_bit:
            if name.endswith(alt) :
                bit_suf = name.replace(alt, '_BIT' + alt)
                break
    return bit_suf;

 # Create the stage/access combination from the legal uses of access with stages
def CreateStageAccessCombinations(config, stage_order, stage_access_types):
    index = 1;
    enum_prefix = config['enum_prefix']
    stage_accesses = []
    none_stage_access = enum_prefix + 'ACCESS_INDEX_NONE'
    stage_accesses.append({
                    'stage_access': none_stage_access,
                    'stage_access_string' : '"' + none_stage_access + '"',
                    'stage_access_bit': None,
                    'index': 0,
                    'stage': 'VK_PIPELINE_STAGE_2_NONE_KHR',
                    'access': 'VK_ACCESS_2_NONE_KHR',
                    'is_read': None}) #tri-state logic hack...
    for stage in stage_order:
        mini_stage = stage.lstrip()
        if mini_stage.startswith(enum_prefix):
            mini_stage = mini_stage.replace(enum_prefix,'')
        else:
            mini_stage = mini_stage.replace('VK_PIPELINE_STAGE_2_', '')
        mini_stage = mini_stage.replace('_BIT_KHR', '')
        mini_stage = mini_stage.replace('_BIT', '')

        # Because access_stage_table's elements order might be different sometimes.
        # It causes the generator creates different code. It needs to be sorted.
        stage_access_types[stage].sort();
        for access in stage_access_types[stage]:
            mini_access = access.replace('VK_ACCESS_2_', '').replace('_BIT_KHR', '')
            mini_access = mini_access.replace('_BIT', '')
            stage_access = '_'.join((mini_stage,mini_access))
            stage_access = enum_prefix + stage_access
            stage_access_bit = BitSuffixed(stage_access)
            is_read = stage_access.endswith('_READ') or ( '_READ_' in stage_access)
            stage_accesses.append({
                    'stage_access': stage_access,
                    'stage_access_string' : '"' + stage_access + '"',
                    'stage_access_bit': stage_access_bit,
                    'index': index,
                    'stage': stage,
                    'access': access,
                    'is_read': 'true' if is_read else 'false' })
            index += 1

    # Add synthetic stage/access
    synth_stage_access = [ 'IMAGE_LAYOUT_TRANSITION', 'QUEUE_FAMILY_OWNERSHIP_TRANSFER']
    stage = 'VK_PIPELINE_STAGE_2_NONE_KHR'
    access = 'VK_ACCESS_2_NONE_KHR'

    for synth in synth_stage_access :
        stage_access = enum_prefix + synth
        stage_access_bit = BitSuffixed(stage_access)
        is_read = False # both ILT and QFO are R/W operations
        stage_accesses.append({
                    'stage_access': stage_access,
                    'stage_access_string' : '"' + stage_access + '"',
                    'stage_access_bit': stage_access_bit,
                    'index': index,
                    'stage': stage,
                    'access': access,
                    'is_read': 'true' if is_read else 'false' })
        index += 1

    return stage_accesses

def StageAccessEnums(stage_accesses, config):
    type_prefix = config['type_prefix']
    var_prefix = config['var_prefix']
    sync_mask_name = config['sync_mask_name']
    indent = config['indent']
    # The stage/access combinations in ordinal order
    output = []
    ordinal_name = config['ordinal_name']
    if not config['is_source']:
        output.append('// Unique number for each  stage/access combination')
        output.append('enum {} {{'.format(ordinal_name))
        output.extend([ '{}{} = {},'.format(indent, e['stage_access'], e['index'])  for e in stage_accesses])
        output.append('};')
        output.append('')

    # The stage/access combinations as bit mask
    output.append('// Unique bit for each  stage/access combination')
    if not config['is_source']:
        output.extend([ '{}static const {} {} = ({}(1) << {});'.format('', sync_mask_name, e['stage_access_bit'], sync_mask_name, e['stage_access'])  for e in stage_accesses if e['stage_access_bit'] is not None])
    output.append('')

    map_name = var_prefix + 'StageAccessIndexByStageAccessBit'
    output.append('// Map of the StageAccessIndices from the StageAccess Bit')
    if config['is_source']:
        output.append('const layer_data::unordered_map<{}, {}> {}  = {{'.format(sync_mask_name, ordinal_name, map_name))
        output.extend([ '{}{{ {}, {} }},'.format(indent, e['stage_access_bit'], e['stage_access'])  for e in stage_accesses if e['stage_access_bit'] is not None])
        output.append('};')
    else:
        output.append('extern const layer_data::unordered_map<{}, {}> {};'.format(sync_mask_name, ordinal_name, map_name))
    output.append('')

    # stage/access debug information based on ordinal enum
    sa_info_type = '{}StageAccessInfoType'.format(type_prefix)
    if not config['is_source']:
        output.append('struct {} {{'.format(sa_info_type))
        output.append('{}const char *name;'.format(indent))
        output.append('{}VkPipelineStageFlags2KHR stage_mask;'.format(indent))
        output.append('{}VkAccessFlags2KHR access_mask;'.format(indent))
        output.append('{}{} stage_access_index;'.format(indent, ordinal_name))
        output.append('{}{} stage_access_bit;'.format(indent, sync_mask_name))
        output.append('};\n')

    sa_info_var = '{}StageAccessInfoByStageAccessIndex'.format(config['var_prefix'])
    output.append('// Array of text names and component masks for each stage/access index')
    if config['is_source']:
        output.append('const std::array<{}, {}> {} {{ {{'.format(sa_info_type, len(stage_accesses), sa_info_var))
        fields_format ='{tab}{tab}{}'
        fields = ['stage_access_string', 'stage', 'access', 'stage_access']
        for entry in stage_accesses:
            output.append(indent+'{')
            for field in fields:
                output.append(fields_format.format(entry[field], tab=indent) + ',')
            bit = entry['stage_access_bit']
            output.append(fields_format.format(bit if bit is not None else 'SyncStageAccessFlags(0)', tab=indent))
            output.append(indent +'},')
        output.append('} };')
    else:
        output.append('extern const std::array<{}, {}> {};'.format(sa_info_type, len(stage_accesses), sa_info_var))
    output.append('')

    return output

def UnpackField(map, field='name'):
    return [ e[field] for e in map ]

def CrossReferenceTable(table_name, table_desc, key_type, mapped_type, key_vec, mask_map, config):
    indent = config['indent']

    table = ['// ' + table_desc]
    if config['is_source']:
        table.append('const std::map<{}, {}> {} {{'.format(key_type, mapped_type, config['var_prefix'] + table_name))

        for mask_key in key_vec:
            mask_vec = mask_map[mask_key]
            if len(mask_vec) == 0:
                continue

            if len(mask_vec) > 1:
                sep = ' |\n' + indent * 2
                table.append( '{tab}{{ {}, (\n{tab}{tab}{}\n{tab})}},'.format(mask_key, sep.join(mask_vec), tab=indent))
            else:
                table.append( '{}{{ {}, {}}},'.format(indent, mask_key, mask_vec[0]))
        if(table_name == 'StageAccessMaskByAccessBit'):
            table.append( '{}{{ {}, {}}},'.format(indent, 'VK_ACCESS_2_MEMORY_READ_BIT_KHR', 'syncStageAccessReadMask'))
            table.append( '{}{{ {}, {}}},'.format(indent, 'VK_ACCESS_2_MEMORY_WRITE_BIT_KHR', 'syncStageAccessWriteMask'))
        table.append('};')
    else:
        table.append('extern const std::map<{}, {}> {};'.format(key_type, mapped_type, config['var_prefix'] + table_name))
    table.append('')

    return table

def DoubleCrossReferenceTable(table_name, table_desc, stage_keys, access_keys, stage_access_stage_access_map, config):
    indent = config['indent']
    ordinal_name = config['ordinal_name']

    table = ['// ' + table_desc]
    if config['is_source']:
        table.append('const std::map<{vk_stage_flags}, std::map<{vk_access_flags}, {ordinal_name}>> {var_prefix}{} {{'.format(table_name, **config))
        sep = ' },\n' + indent * 2 + '{ '

        # Because stage_access_stage_access_map's elements order might be different sometimes.
        # It causes the generator creates different code. It needs to be sorted.
        for i in sorted(stage_access_stage_access_map):
            if len(stage_access_stage_access_map[i].keys()) == 0: continue
            accesses = [ '{}, {}'.format(access, index) for access, index in sorted(stage_access_stage_access_map[i].items()) ]
            entry_format = '{tab}{{ {key}, {{\n{tab}{tab}{{ {val} }}\n{tab}}} }},'
            table.append( entry_format.format(key=i, val=sep.join(accesses), tab=indent))
        table.append('};')
    else:
        table.append('extern const std::map<{vk_stage_flags}, std::map<{vk_access_flags}, {ordinal_name}>> {var_prefix}{};'.format(table_name, **config))
    table.append('')

    return table

def StageAccessCrossReference(sync_enum, stage_access_combinations, config):
    output = []
    # Setup the cross reference tables
    enum_in_bit_order = dict()
    for enum_type in sync_enum_types:
        enum_in_bit_order[enum_type] = InBitOrder(enum_type, sync_enum[enum_type])

    stages_in_bit_order =  enum_in_bit_order['VkPipelineStageFlagBits2KHR']
    access_in_bit_order =  enum_in_bit_order['VkAccessFlagBits2KHR']
    stage_access_mask_stage_map = { e['name']: [] for e in stages_in_bit_order }
    #stage_access_mask_stage_map[none_stage] = [] # Support for N/A
    stage_access_mask_access_map = { e['name']: [] for e in access_in_bit_order }
    stage_access_stage_access_map = {  e['name']: dict() for e in stages_in_bit_order }
    direct_stage_to_access_map = {  e['name']: [] for e in stages_in_bit_order }

    for stage_access_combo in stage_access_combinations:
        combo_bit = stage_access_combo['stage_access_bit']
        stage = stage_access_combo['stage']
        if stage == 'VK_PIPELINE_STAGE_2_NONE_KHR': continue
        access = stage_access_combo['access']
        if access == 'VK_ACCESS_2_FLAG_NONE_KHR' : continue
        stage_access_mask_stage_map[stage].append(combo_bit)
        stage_access_mask_access_map[access].append(combo_bit)
        stage_access_stage_access_map[stage][access] = stage_access_combo['stage_access']
        direct_stage_to_access_map[stage].append(stage_access_combo['access'])

    # sas: stage_access masks by stage used to build up SyncMaskTypes from VkPipelineStageFlagBits
    sas_desc = 'Bit order mask of stage_access bit for each stage'
    sas_name = 'StageAccessMaskByStageBit'
    output.extend(CrossReferenceTable(sas_name, sas_desc, 'VkPipelineStageFlags2KHR', config['sync_mask_name'],
                                      UnpackField(stages_in_bit_order), stage_access_mask_stage_map, config))

    # saa -- stage_access by access used to build up SyncMaskTypes from VkAccessFlagBits
    saa_name = 'StageAccessMaskByAccessBit'
    saa_desc = 'Bit order mask of stage_access bit for each access'
    output.extend(CrossReferenceTable(saa_name, saa_desc, 'VkAccessFlags2KHR',  config['sync_mask_name'],
                                      UnpackField(access_in_bit_order), stage_access_mask_access_map, config))

    #sasa -- stage access index by stage by access
    sasa_name = 'StageAccessIndexByStageAndAccess'
    sasa_desc = 'stage_access index for each stage and access'
    output.extend(DoubleCrossReferenceTable(sasa_name, sasa_desc,stages_in_bit_order, access_in_bit_order, stage_access_stage_access_map, config))


    # direct VkPipelineStageFlags to valid VkAccessFlags lookup table
    direct_name = 'DirectStageToAccessMask'
    direct_desc = 'Direct VkPipelineStageFlags to valid VkAccessFlags lookup table'
    output.extend(CrossReferenceTable(direct_name, direct_desc, 'VkPipelineStageFlags2KHR', 'VkAccessFlags2KHR',
                                      UnpackField(stages_in_bit_order), direct_stage_to_access_map, config))

    return output

def GenerateStaticMask(name, desc, bits, config):
    sep = ' |\n' + config['indent']
    if not config['is_source']:
        variable_format = 'static const {sync_mask_name} {var_prefix}StageAccess{}Mask = ( //  {}'
        output = [variable_format.format(name, desc, **config)]
        output.append(config['indent'] + sep.join([b for b in bits if b is not None]))
        output.extend([');', ''])
        return output
    return []

def ReadWriteMasks(stage_access_combinations, config):
    # tri-state logic hack to keep the NONE stage access index out of these masks.
    read_list = [ e['stage_access_bit'] for e in stage_access_combinations if e['is_read']  == 'true' and e['is_read'] is not None]
    write_list = [ e['stage_access_bit'] for e in stage_access_combinations if e['is_read'] != 'true' and e['is_read'] is not None]
    output = ['// Constants defining the mask of all read and write stage_access states']
    output.extend(GenerateStaticMask('Read',  'Mask of all read StageAccess bits', read_list, config))
    output.extend(GenerateStaticMask('Write',  'Mask of all write StageAccess bits', write_list, config))

    return output

def AllCommandsByQueueCapability(stage_order, stage_queue_table, config):
    queue_cap_set = set()
    for stage, queue_flag_list in stage_queue_table.items():
        for queue_flag in queue_flag_list:
            queue_cap_set.add(queue_flag)

    queue_caps = sorted(queue_cap_set)
    queue_flag_map = { queue_flag:list() for queue_flag in queue_caps }

    # bits that expand out to several different stages
    expanded = ('VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR', 'VK_PIPELINE_STAGE_2_ALL_GRAPHICS_BIT_KHR',
                'VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT_KHR', 'VK_PIPELINE_STAGE_2_PRE_RASTERIZATION_SHADERS_BIT_KHR')
    for stage in stage_order:
        if stage in expanded:
            continue

        queue_flag_list = stage_queue_table[stage]

        if len(queue_flag_list) == 0:
            queue_flag_list = queue_caps

        if debug_queue_caps: print(stage, queue_flag_list)
        for queue_flag in queue_flag_list:
             queue_flag_map[queue_flag].append(stage)

    name = 'AllCommandStagesByQueueFlags'
    desc = 'Pipeline stages corresponding to VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR for each VkQueueFlagBits'
    return CrossReferenceTable(name, desc, 'VkQueueFlagBits', 'VkPipelineStageFlags2KHR', queue_caps, queue_flag_map, config)

def PipelineOrderMaskMap(stage_order, stage_order_map, config):
    output = list()
    prior_name = 'LogicallyEarlierStages'
    prior_desc = 'Masks of logically earlier stage flags for a given stage flag'
    output.extend(CrossReferenceTable(prior_name, prior_desc, config['vk_stage_bits'], config['vk_stage_flags'], stage_order,
                                     stage_order_map['prior'], config))

    subseq_name = 'LogicallyLaterStages'
    subseq_desc = 'Masks of logically later stage flags for a given stage flag'
    output.extend(CrossReferenceTable(subseq_name, subseq_desc, config['vk_stage_bits'], config['vk_stage_flags'], stage_order,
                                     stage_order_map['subseq'], config))

    order_name = 'StageOrder'
    order_desc = 'Lookup table of stage orderings'
    order_nums = {stage_order[i] : [i] for i in range(len(stage_order)) }

    output.extend(CrossReferenceTable(order_name, order_desc, config['vk_stage_bits'], 'int', stage_order,
                                      order_nums, config))
    return output

def ShaderStageToSyncStageAccess( shader_stage_key, sync_stage_key ):
    return '    {{VK_SHADER_STAGE_{}, {{\n        SYNC_{}_SHADER_SAMPLED_READ, SYNC_{}_SHADER_STORAGE_READ, SYNC_{}_SHADER_STORAGE_WRITE, SYNC_{}_UNIFORM_READ}}}},'.format(shader_stage_key, sync_stage_key, sync_stage_key, sync_stage_key, sync_stage_key)

def ShaderStageAndSyncStageAccessMap(config):
    output = []
    if not config['is_source']:
        output.append('struct SyncShaderStageAccess {')
        output.append('    SyncStageAccessIndex sampled_read;')
        output.append('    SyncStageAccessIndex storage_read;')
        output.append('    SyncStageAccessIndex storage_write;')
        output.append('    SyncStageAccessIndex uniform_read;')
        output.append('};\n')
        output.append('extern const std::map<VkShaderStageFlagBits, SyncShaderStageAccess> syncStageAccessMaskByShaderStage;')
    else:
        output.append('const std::map<VkShaderStageFlagBits, SyncShaderStageAccess> syncStageAccessMaskByShaderStage {')
        output.append(ShaderStageToSyncStageAccess('VERTEX_BIT', 'VERTEX_SHADER'))
        output.append(ShaderStageToSyncStageAccess('TESSELLATION_CONTROL_BIT', 'TESSELLATION_CONTROL_SHADER'))
        output.append(ShaderStageToSyncStageAccess('TESSELLATION_EVALUATION_BIT', 'TESSELLATION_EVALUATION_SHADER'))
        output.append(ShaderStageToSyncStageAccess('GEOMETRY_BIT', 'GEOMETRY_SHADER'))
        output.append(ShaderStageToSyncStageAccess('FRAGMENT_BIT', 'FRAGMENT_SHADER'))
        output.append(ShaderStageToSyncStageAccess('COMPUTE_BIT', 'COMPUTE_SHADER'))
        output.append(ShaderStageToSyncStageAccess('RAYGEN_BIT_KHR', 'RAY_TRACING_SHADER'))
        output.append(ShaderStageToSyncStageAccess('ANY_HIT_BIT_KHR', 'RAY_TRACING_SHADER'))
        output.append(ShaderStageToSyncStageAccess('CLOSEST_HIT_BIT_KHR', 'RAY_TRACING_SHADER'))
        output.append(ShaderStageToSyncStageAccess('MISS_BIT_KHR', 'RAY_TRACING_SHADER'))
        output.append(ShaderStageToSyncStageAccess('INTERSECTION_BIT_KHR', 'RAY_TRACING_SHADER'))
        output.append(ShaderStageToSyncStageAccess('CALLABLE_BIT_KHR', 'RAY_TRACING_SHADER'))
        output.append(ShaderStageToSyncStageAccess('TASK_BIT_NV', 'TASK_SHADER_NV'))
        output.append(ShaderStageToSyncStageAccess('MESH_BIT_NV', 'MESH_SHADER_NV'))
        output.append('};\n')
    return output

def GenSyncTypeHelper(gen, is_source) :
    config = {
        'var_prefix': 'sync',
        'type_prefix': 'Sync',
        'enum_prefix': 'SYNC_',
        'indent': '    ',
        'sync_mask_base_type': 'std::bitset<128>',
        'vk_stage_flags': 'VkPipelineStageFlags2KHR',
        'vk_stage_bits': 'VkPipelineStageFlags2KHR',
        'vk_access_flags': 'VkAccessFlags2KHR',
        'vk_access_bits': 'VkAccessFlags2KHR',
        'is_source': is_source}
    config['sync_mask_name'] = '{}StageAccessFlags'.format(config['type_prefix'])
    config['ordinal_name'] = '{}StageAccessIndex'.format(config['type_prefix'])
    config['bits_name'] = '{}StageAccessFlags'.format(config['type_prefix'])

    if config['is_source']:
        lines = ['#include "synchronization_validation_types.h"', '']
    else:
        lines = ['#pragma once', '', '#include <array>', '#include <bitset>', '#include <map>', '#include <stdint.h>', '#include <vulkan/vulkan.h>',
                 '#include "vk_layer_data.h"']
        lines.extend(('using {} = {};'.format(config['sync_mask_name'], config['sync_mask_base_type']), ''))
    lines.extend(['// clang-format off', ''])

    stage_order = pipeline_order.split()
    access_types = {stage:list() for stage in stage_order}
    if debug_top_level:
        lines.append('// Access types \n//    ' + '\n//    '.join(access_types) +  '\n' * 2)

    stage_order_map = ParsePipelineStageOrder(stage_order, snippet_pipeline_stages_order, config)
    access_stage_table = ParseAccessMasks(gen.genOpts.valid_usage_path, stage_order)
    stage_queue_cap_table = ParseQueueCaps(snippet_pipeline_stages_supported)
    stage_access_table = CreateStageAccessTable(stage_order, access_stage_table)
    stage_access_combinations = CreateStageAccessCombinations(config, stage_order, stage_access_table)
    lines.extend(StageAccessEnums(stage_access_combinations, config))

    lines.extend(ReadWriteMasks(stage_access_combinations, config))

    lines.extend(StageAccessCrossReference(gen.sync_enum, stage_access_combinations, config))
    lines.extend(AllCommandsByQueueCapability(stage_order, stage_queue_cap_table, config))
    lines.extend(PipelineOrderMaskMap(stage_order, stage_order_map, config))
    lines.extend(ShaderStageAndSyncStageAccessMap(config))
    return  '\n'.join(lines)
