1*8975f5c5SAndroid Build Coastguard Worker#!/usr/bin/python3 2*8975f5c5SAndroid Build Coastguard Worker# 3*8975f5c5SAndroid Build Coastguard Worker# Copyright 2022 The ANGLE Project Authors. All rights reserved. 4*8975f5c5SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 5*8975f5c5SAndroid Build Coastguard Worker# found in the LICENSE file. 6*8975f5c5SAndroid Build Coastguard Worker# 7*8975f5c5SAndroid Build Coastguard Worker# gen_interpreter_utils.py: 8*8975f5c5SAndroid Build Coastguard Worker# Code generator for the GLC interpreter. 9*8975f5c5SAndroid Build Coastguard Worker# NOTE: don't run this script directly. Run scripts/run_code_generation.py. 10*8975f5c5SAndroid Build Coastguard Worker 11*8975f5c5SAndroid Build Coastguard Workerimport os 12*8975f5c5SAndroid Build Coastguard Workerimport re 13*8975f5c5SAndroid Build Coastguard Workerimport sys 14*8975f5c5SAndroid Build Coastguard Worker 15*8975f5c5SAndroid Build Coastguard Workerimport registry_xml 16*8975f5c5SAndroid Build Coastguard Worker 17*8975f5c5SAndroid Build Coastguard WorkerEXIT_SUCCESS = 0 18*8975f5c5SAndroid Build Coastguard WorkerEXIT_FAILURE = 1 19*8975f5c5SAndroid Build Coastguard Worker 20*8975f5c5SAndroid Build Coastguard WorkerBASE_PATH = '../util/capture/trace_interpreter_autogen' 21*8975f5c5SAndroid Build Coastguard Worker 22*8975f5c5SAndroid Build Coastguard WorkerCPP_TEMPLATE = """\ 23*8975f5c5SAndroid Build Coastguard Worker// GENERATED FILE - DO NOT EDIT. 24*8975f5c5SAndroid Build Coastguard Worker// Generated by {script_name} using data from {data_source_name}. 25*8975f5c5SAndroid Build Coastguard Worker// 26*8975f5c5SAndroid Build Coastguard Worker// Copyright 2022 The ANGLE Project Authors. All rights reserved. 27*8975f5c5SAndroid Build Coastguard Worker// Use of this source code is governed by a BSD-style license that can be 28*8975f5c5SAndroid Build Coastguard Worker// found in the LICENSE file. 29*8975f5c5SAndroid Build Coastguard Worker// 30*8975f5c5SAndroid Build Coastguard Worker// {file_name}.cpp: 31*8975f5c5SAndroid Build Coastguard Worker// Helper code for trace interpreter. 32*8975f5c5SAndroid Build Coastguard Worker 33*8975f5c5SAndroid Build Coastguard Worker#include "angle_trace_gl.h" 34*8975f5c5SAndroid Build Coastguard Worker#include "trace_fixture.h" 35*8975f5c5SAndroid Build Coastguard Worker#include "trace_interpreter.h" 36*8975f5c5SAndroid Build Coastguard Worker 37*8975f5c5SAndroid Build Coastguard Workernamespace angle 38*8975f5c5SAndroid Build Coastguard Worker{{ 39*8975f5c5SAndroid Build Coastguard WorkerCallCapture ParseCallCapture(const Token &nameToken, size_t numParamTokens, const Token *paramTokens, const TraceStringMap &strings) 40*8975f5c5SAndroid Build Coastguard Worker{{ 41*8975f5c5SAndroid Build Coastguard Worker{parse_cases} 42*8975f5c5SAndroid Build Coastguard Worker if (numParamTokens > 0) 43*8975f5c5SAndroid Build Coastguard Worker {{ 44*8975f5c5SAndroid Build Coastguard Worker printf("Expected zero parameter tokens for %s\\n", nameToken); 45*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE(); 46*8975f5c5SAndroid Build Coastguard Worker }} 47*8975f5c5SAndroid Build Coastguard Worker return CallCapture(nameToken, ParamBuffer()); 48*8975f5c5SAndroid Build Coastguard Worker}} 49*8975f5c5SAndroid Build Coastguard Worker 50*8975f5c5SAndroid Build Coastguard Worker{dispatch_cases} 51*8975f5c5SAndroid Build Coastguard Worker 52*8975f5c5SAndroid Build Coastguard Workervoid ReplayCustomFunctionCall(const CallCapture &call, const TraceFunctionMap &customFunctions) 53*8975f5c5SAndroid Build Coastguard Worker{{ 54*8975f5c5SAndroid Build Coastguard Worker ASSERT(call.entryPoint == EntryPoint::Invalid); 55*8975f5c5SAndroid Build Coastguard Worker const Captures &captures = call.params.getParamCaptures(); 56*8975f5c5SAndroid Build Coastguard Worker 57*8975f5c5SAndroid Build Coastguard Worker{custom_dispatch_cases} 58*8975f5c5SAndroid Build Coastguard Worker 59*8975f5c5SAndroid Build Coastguard Worker auto iter = customFunctions.find(call.customFunctionName); 60*8975f5c5SAndroid Build Coastguard Worker if (iter == customFunctions.end()) 61*8975f5c5SAndroid Build Coastguard Worker {{ 62*8975f5c5SAndroid Build Coastguard Worker printf("Unknown custom function: %s\\n", call.customFunctionName.c_str()); 63*8975f5c5SAndroid Build Coastguard Worker UNREACHABLE(); 64*8975f5c5SAndroid Build Coastguard Worker }} 65*8975f5c5SAndroid Build Coastguard Worker else 66*8975f5c5SAndroid Build Coastguard Worker {{ 67*8975f5c5SAndroid Build Coastguard Worker ASSERT(call.params.empty()); 68*8975f5c5SAndroid Build Coastguard Worker const TraceFunction &customFunc = iter->second; 69*8975f5c5SAndroid Build Coastguard Worker for (const CallCapture &customCall : customFunc) 70*8975f5c5SAndroid Build Coastguard Worker {{ 71*8975f5c5SAndroid Build Coastguard Worker ReplayTraceFunctionCall(customCall, customFunctions); 72*8975f5c5SAndroid Build Coastguard Worker }} 73*8975f5c5SAndroid Build Coastguard Worker }} 74*8975f5c5SAndroid Build Coastguard Worker}} 75*8975f5c5SAndroid Build Coastguard Worker}} // namespace angle 76*8975f5c5SAndroid Build Coastguard Worker""" 77*8975f5c5SAndroid Build Coastguard Worker 78*8975f5c5SAndroid Build Coastguard WorkerPARSE_CASE = """\ 79*8975f5c5SAndroid Build Coastguard Worker if (strcmp(nameToken, "{ep}") == 0) 80*8975f5c5SAndroid Build Coastguard Worker {{ 81*8975f5c5SAndroid Build Coastguard Worker ParamBuffer params = ParseParameters<{pfn}>(paramTokens, strings); 82*8975f5c5SAndroid Build Coastguard Worker return CallCapture({call}, std::move(params)); 83*8975f5c5SAndroid Build Coastguard Worker }} 84*8975f5c5SAndroid Build Coastguard Worker""" 85*8975f5c5SAndroid Build Coastguard Worker 86*8975f5c5SAndroid Build Coastguard WorkerCUSTOM_DISPATCH_CASE = """\ 87*8975f5c5SAndroid Build Coastguard Worker if (call.customFunctionName == "{fn}") 88*8975f5c5SAndroid Build Coastguard Worker {{ 89*8975f5c5SAndroid Build Coastguard Worker DispatchCallCapture({fn}, captures); 90*8975f5c5SAndroid Build Coastguard Worker return; 91*8975f5c5SAndroid Build Coastguard Worker }} 92*8975f5c5SAndroid Build Coastguard Worker""" 93*8975f5c5SAndroid Build Coastguard Worker 94*8975f5c5SAndroid Build Coastguard WorkerDISPATCH_CASE = """\ 95*8975f5c5SAndroid Build Coastguard Workertemplate <typename Fn, EnableIfNArgs<Fn, {nargs}> = 0> 96*8975f5c5SAndroid Build Coastguard Workervoid DispatchCallCapture(Fn *fn, const Captures &cap) 97*8975f5c5SAndroid Build Coastguard Worker{{ 98*8975f5c5SAndroid Build Coastguard Worker (*fn)({args}); 99*8975f5c5SAndroid Build Coastguard Worker}} 100*8975f5c5SAndroid Build Coastguard Worker""" 101*8975f5c5SAndroid Build Coastguard Worker 102*8975f5c5SAndroid Build Coastguard WorkerFIXTURE_H = '../util/capture/trace_fixture.h' 103*8975f5c5SAndroid Build Coastguard Worker 104*8975f5c5SAndroid Build Coastguard Worker 105*8975f5c5SAndroid Build Coastguard Workerdef GetFunctionsFromFixture(): 106*8975f5c5SAndroid Build Coastguard Worker funcs = [] 107*8975f5c5SAndroid Build Coastguard Worker arg_counts = set() 108*8975f5c5SAndroid Build Coastguard Worker pattern = 'void ' 109*8975f5c5SAndroid Build Coastguard Worker with open(FIXTURE_H) as f: 110*8975f5c5SAndroid Build Coastguard Worker lines = f.read().split(';') 111*8975f5c5SAndroid Build Coastguard Worker for line in lines: 112*8975f5c5SAndroid Build Coastguard Worker line = re.sub('// .*\n', '', line.strip()) 113*8975f5c5SAndroid Build Coastguard Worker if line.startswith(pattern): 114*8975f5c5SAndroid Build Coastguard Worker func_name = line[len(pattern):line.find('(')] 115*8975f5c5SAndroid Build Coastguard Worker func_args = line.count(',') + 1 116*8975f5c5SAndroid Build Coastguard Worker funcs.append(func_name) 117*8975f5c5SAndroid Build Coastguard Worker arg_counts.add(func_args) 118*8975f5c5SAndroid Build Coastguard Worker f.close() 119*8975f5c5SAndroid Build Coastguard Worker return sorted(funcs), arg_counts 120*8975f5c5SAndroid Build Coastguard Worker 121*8975f5c5SAndroid Build Coastguard Worker 122*8975f5c5SAndroid Build Coastguard Workerdef get_dispatch(n): 123*8975f5c5SAndroid Build Coastguard Worker return ', '.join(['Arg<Fn, %d>(cap)' % i for i in range(n)]) 124*8975f5c5SAndroid Build Coastguard Worker 125*8975f5c5SAndroid Build Coastguard Worker 126*8975f5c5SAndroid Build Coastguard Workerdef main(cpp_output_path): 127*8975f5c5SAndroid Build Coastguard Worker gles = registry_xml.GetGLES() 128*8975f5c5SAndroid Build Coastguard Worker egl = registry_xml.GetEGL() 129*8975f5c5SAndroid Build Coastguard Worker 130*8975f5c5SAndroid Build Coastguard Worker def fn(ep): 131*8975f5c5SAndroid Build Coastguard Worker return 'std::remove_pointer<PFN%sPROC>::type' % ep.upper() 132*8975f5c5SAndroid Build Coastguard Worker 133*8975f5c5SAndroid Build Coastguard Worker fixture_functions, arg_counts = GetFunctionsFromFixture() 134*8975f5c5SAndroid Build Coastguard Worker 135*8975f5c5SAndroid Build Coastguard Worker eps_and_enums = sorted(list(set(gles.GetEnums() + egl.GetEnums()))) 136*8975f5c5SAndroid Build Coastguard Worker parse_cases = [ 137*8975f5c5SAndroid Build Coastguard Worker PARSE_CASE.format(ep=ep, pfn=fn(ep), call='EntryPoint::%s' % enum) 138*8975f5c5SAndroid Build Coastguard Worker for (enum, ep) in eps_and_enums 139*8975f5c5SAndroid Build Coastguard Worker ] 140*8975f5c5SAndroid Build Coastguard Worker parse_cases += [ 141*8975f5c5SAndroid Build Coastguard Worker PARSE_CASE.format(ep=fn, pfn='decltype(%s)' % fn, call='"%s"' % fn) 142*8975f5c5SAndroid Build Coastguard Worker for fn in fixture_functions 143*8975f5c5SAndroid Build Coastguard Worker ] 144*8975f5c5SAndroid Build Coastguard Worker 145*8975f5c5SAndroid Build Coastguard Worker dispatch_cases = [DISPATCH_CASE.format(nargs=n, args=get_dispatch(n)) for n in arg_counts] 146*8975f5c5SAndroid Build Coastguard Worker 147*8975f5c5SAndroid Build Coastguard Worker custom_dispatch_cases = [CUSTOM_DISPATCH_CASE.format(fn=fn) for fn in fixture_functions] 148*8975f5c5SAndroid Build Coastguard Worker 149*8975f5c5SAndroid Build Coastguard Worker format_args = { 150*8975f5c5SAndroid Build Coastguard Worker 'script_name': os.path.basename(sys.argv[0]), 151*8975f5c5SAndroid Build Coastguard Worker 'data_source_name': 'gl.xml and gl_angle_ext.xml', 152*8975f5c5SAndroid Build Coastguard Worker 'file_name': os.path.basename(BASE_PATH), 153*8975f5c5SAndroid Build Coastguard Worker 'parse_cases': ''.join(parse_cases), 154*8975f5c5SAndroid Build Coastguard Worker 'dispatch_cases': '\n'.join(dispatch_cases), 155*8975f5c5SAndroid Build Coastguard Worker 'custom_dispatch_cases': ''.join(custom_dispatch_cases), 156*8975f5c5SAndroid Build Coastguard Worker } 157*8975f5c5SAndroid Build Coastguard Worker 158*8975f5c5SAndroid Build Coastguard Worker cpp_content = CPP_TEMPLATE.format(**format_args) 159*8975f5c5SAndroid Build Coastguard Worker cpp_output_path = registry_xml.script_relative(cpp_output_path) 160*8975f5c5SAndroid Build Coastguard Worker with open(cpp_output_path, 'w') as f: 161*8975f5c5SAndroid Build Coastguard Worker f.write(cpp_content) 162*8975f5c5SAndroid Build Coastguard Worker 163*8975f5c5SAndroid Build Coastguard Worker return EXIT_SUCCESS 164*8975f5c5SAndroid Build Coastguard Worker 165*8975f5c5SAndroid Build Coastguard Worker 166*8975f5c5SAndroid Build Coastguard Workerif __name__ == '__main__': 167*8975f5c5SAndroid Build Coastguard Worker inputs = registry_xml.xml_inputs + [FIXTURE_H] 168*8975f5c5SAndroid Build Coastguard Worker outputs = [ 169*8975f5c5SAndroid Build Coastguard Worker '%s.cpp' % BASE_PATH, 170*8975f5c5SAndroid Build Coastguard Worker ] 171*8975f5c5SAndroid Build Coastguard Worker 172*8975f5c5SAndroid Build Coastguard Worker if len(sys.argv) > 1: 173*8975f5c5SAndroid Build Coastguard Worker if sys.argv[1] == 'inputs': 174*8975f5c5SAndroid Build Coastguard Worker print(','.join(inputs)) 175*8975f5c5SAndroid Build Coastguard Worker elif sys.argv[1] == 'outputs': 176*8975f5c5SAndroid Build Coastguard Worker print(','.join(outputs)) 177*8975f5c5SAndroid Build Coastguard Worker else: 178*8975f5c5SAndroid Build Coastguard Worker sys.exit(main(registry_xml.script_relative(outputs[0]))) 179