1#!/usr/bin/python3 2# Copyright 2017 The ANGLE Project Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5# 6# gen_emulated_builtin_function_tables.py: 7# Generator for the builtin function maps. 8# NOTE: don't run this script directly. Run scripts/run_code_generation.py. 9 10import json 11import os, sys 12 13template_emulated_builtin_functions_hlsl = """// GENERATED FILE - DO NOT EDIT. 14// Generated by {script_name} using data from {data_source_name}. 15// 16// Copyright 2017 The ANGLE Project Authors. All rights reserved. 17// Use of this source code is governed by a BSD-style license that can be 18// found in the LICENSE file. 19// 20// emulated_builtin_functions_hlsl: 21// HLSL code for emulating GLSL builtin functions not present in HLSL. 22 23#include "compiler/translator/BuiltInFunctionEmulator.h" 24#include "compiler/translator/tree_util/BuiltIn.h" 25 26namespace sh 27{{ 28 29namespace 30{{ 31 32struct FunctionPair 33{{ 34 constexpr FunctionPair(const TSymbolUniqueId &idIn, const char *bodyIn) : id(idIn.get()), body(bodyIn) 35 {{ 36 }} 37 38 int id; 39 const char *body; 40}}; 41 42constexpr FunctionPair g_hlslFunctions[] = {{ 43{emulated_functions}}}; 44}} // anonymous namespace 45 46const char *FindHLSLFunction(int uniqueId) 47{{ 48 for (size_t index = 0; index < ArraySize(g_hlslFunctions); ++index) 49 {{ 50 const auto &function = g_hlslFunctions[index]; 51 if (function.id == uniqueId) 52 {{ 53 return function.body; 54 }} 55 }} 56 57 return nullptr; 58}} 59}} // namespace sh 60""" 61 62 63def reject_duplicate_keys(pairs): 64 found_keys = {} 65 for key, value in pairs: 66 if key in found_keys: 67 raise ValueError("duplicate key: %r" % (key,)) 68 else: 69 found_keys[key] = value 70 return found_keys 71 72 73def load_json(path): 74 with open(path) as map_file: 75 file_data = map_file.read() 76 map_file.close() 77 return json.loads(file_data, object_pairs_hook=reject_duplicate_keys) 78 79 80def enum_type(arg): 81 # handle 'argtype argname' and 'out argtype argname' 82 chunks = arg.split(' ') 83 arg_type = chunks[0] 84 if len(chunks) == 3: 85 arg_type = chunks[1] 86 87 suffix = "" 88 if not arg_type[-1].isdigit(): 89 suffix = '1' 90 if arg_type[0:4] == 'uint': 91 return 'UI' + arg_type[2:] + suffix 92 return arg_type.capitalize() + suffix 93 94 95def gen_emulated_function(data): 96 97 func = "" 98 if 'comment' in data: 99 func += "".join(["// " + line + "\n" for line in data['comment']]) 100 101 sig = data['return_type'] + ' ' + data['op'] + '_emu(' + ', '.join(data['args']) + ')' 102 body = [sig, '{'] + [' ' + line for line in data['body']] + ['}'] 103 104 func += "{\n" 105 func += "BuiltInId::" + data['op'] + "_" + "_".join([enum_type(arg) for arg in data['args'] 106 ]) + ",\n" 107 if 'helper' in data: 108 func += '"' + '\\n"\n"'.join(data['helper']) + '\\n"\n' 109 func += '"' + '\\n"\n"'.join(body) + '\\n"\n' 110 func += "},\n" 111 return [func] 112 113 114def main(): 115 116 input_script = "emulated_builtin_function_data_hlsl.json" 117 hlsl_fname = "emulated_builtin_functions_hlsl_autogen.cpp" 118 119 # auto_script parameters. 120 if len(sys.argv) > 1: 121 inputs = [input_script] 122 outputs = [hlsl_fname] 123 124 if sys.argv[1] == 'inputs': 125 print(','.join(inputs)) 126 elif sys.argv[1] == 'outputs': 127 print(','.join(outputs)) 128 else: 129 print('Invalid script parameters') 130 return 1 131 return 0 132 133 hlsl_json = load_json(input_script) 134 emulated_functions = [] 135 136 for item in hlsl_json: 137 emulated_functions += gen_emulated_function(item) 138 139 hlsl_gen = template_emulated_builtin_functions_hlsl.format( 140 script_name=sys.argv[0], 141 data_source_name=input_script, 142 emulated_functions="".join(emulated_functions)) 143 144 with open(hlsl_fname, 'wt') as f: 145 f.write(hlsl_gen) 146 f.close() 147 148 return 0 149 150 151if __name__ == '__main__': 152 sys.exit(main()) 153