1COPYRIGHT = """\ 2/* 3 * Copyright (C) 2017 Intel Corporation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24""" 25 26import argparse 27import json 28from sys import stdout 29from mako.template import Template 30 31def collect_data(spirv, kind): 32 for x in spirv["operand_kinds"]: 33 if x["kind"] == kind: 34 operands = x 35 break 36 37 # There are some duplicate values in some of the tables (thanks guys!), so 38 # filter them out. 39 seen = set() 40 values = [] 41 for x in operands["enumerants"]: 42 if x["value"] not in seen: 43 seen.add(x["value"]) 44 values.append(x["enumerant"]) 45 46 return (kind, values, operands["category"]) 47 48def collect_opcodes(spirv): 49 seen = set() 50 values = [] 51 for x in spirv["instructions"]: 52 # Handle aliases by choosing the first one in the grammar. 53 # E.g. OpDecorateString and OpDecorateStringGOOGLE share same opcode. 54 if x["opcode"] in seen: 55 continue 56 opcode = x["opcode"] 57 name = x["opname"] 58 assert name.startswith("Op") 59 values.append(name[2:]) 60 seen.add(opcode) 61 62 return ("Op", values, None) 63 64def parse_args(): 65 p = argparse.ArgumentParser() 66 p.add_argument("json") 67 p.add_argument("out") 68 return p.parse_args() 69 70TEMPLATE = Template("""\ 71/* DO NOT EDIT - This file is generated automatically by spirv_info_c.py script */ 72 73""" + COPYRIGHT + """\ 74#include "spirv_info.h" 75% for kind,values,category in info: 76 77% if category == "BitEnum": 78const char * 79spirv_${kind.lower()}_to_string(Spv${kind}Mask v) 80{ 81 switch (v) { 82 % for name in values: 83 %if name != "None": 84 case Spv${kind}${name}Mask: return "Spv${kind}${name}"; 85 % else: 86 case Spv${kind}MaskNone: return "Spv${kind}${name}"; 87 % endif 88 % endfor 89 } 90 91 return "unknown"; 92} 93% else: 94const char * 95spirv_${kind.lower()}_to_string(Spv${kind} v) 96{ 97 switch (v) { 98 % for name in values: 99 case Spv${kind}${name}: return "Spv${kind}${name}"; 100 % endfor 101 case Spv${kind}Max: break; /* silence warnings about unhandled enums. */ 102 } 103 104 return "unknown"; 105} 106% endif 107% endfor 108""") 109 110if __name__ == "__main__": 111 pargs = parse_args() 112 113 spirv_info = json.JSONDecoder().decode(open(pargs.json, "r").read()) 114 115 info = [ 116 collect_data(spirv_info, "AddressingModel"), 117 collect_data(spirv_info, "BuiltIn"), 118 collect_data(spirv_info, "Capability"), 119 collect_data(spirv_info, "Decoration"), 120 collect_data(spirv_info, "Dim"), 121 collect_data(spirv_info, "ExecutionMode"), 122 collect_data(spirv_info, "ExecutionModel"), 123 collect_data(spirv_info, "ImageFormat"), 124 collect_data(spirv_info, "MemoryModel"), 125 collect_data(spirv_info, "StorageClass"), 126 collect_data(spirv_info, "ImageOperands"), 127 collect_data(spirv_info, "FPRoundingMode"), 128 collect_opcodes(spirv_info), 129 ] 130 131 with open(pargs.out, 'w') as f: 132 f.write(TEMPLATE.render(info=info)) 133