xref: /aosp_15_r20/external/angle/scripts/gen_interpreter_utils.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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