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