xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/gen_load_functions_table.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1#!/usr/bin/python3
2# Copyright 2015 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_load_functions_table.py:
7#  Code generation for the load function tables used for texture formats. These mappings are
8#  not renderer specific. The mappings are done from the GL internal format, to the ANGLE
9#  format ID, and then for the specific data type.
10#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.
11#
12
13import json, sys
14
15sys.path.append('../..')
16import angle_format
17
18template = """// GENERATED FILE - DO NOT EDIT.
19// Generated by gen_load_functions_table.py using data from load_functions_data.json
20//
21// Copyright 2020 The ANGLE Project Authors. All rights reserved.
22// Use of this source code is governed by a BSD-style license that can be
23// found in the LICENSE file.
24//
25// load_functions_table:
26//   Contains the GetLoadFunctionsMap for texture_format_util.h
27//
28
29#include "libANGLE/renderer/load_functions_table.h"
30
31#include "image_util/copyimage.h"
32#include "image_util/generatemip.h"
33#include "image_util/loadimage.h"
34
35using namespace rx;
36
37namespace angle
38{{
39
40namespace
41{{
42
43// ES3 image loading functions vary based on:
44//    - the GL internal format (supplied to glTex*Image*D)
45//    - the GL data type given (supplied to glTex*Image*D)
46//    - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D
47//    device's capabilities)
48// This map type determines which loading function to use, based on these three parameters.
49// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec.
50void UnimplementedLoadFunction(const ImageLoadContext &context,
51                               size_t width,
52                               size_t height,
53                               size_t depth,
54                               const uint8_t *input,
55                               size_t inputRowPitch,
56                               size_t inputDepthPitch,
57                               uint8_t *output,
58                               size_t outputRowPitch,
59                               size_t outputDepthPitch)
60{{
61    UNIMPLEMENTED();
62}}
63
64void UnreachableLoadFunction(const ImageLoadContext &context,
65                             size_t width,
66                             size_t height,
67                             size_t depth,
68                             const uint8_t *input,
69                             size_t inputRowPitch,
70                             size_t inputDepthPitch,
71                             uint8_t *output,
72                             size_t outputRowPitch,
73                             size_t outputDepthPitch)
74{{
75    UNREACHABLE();
76}}
77
78{load_functions_data}}}  // namespace
79
80LoadFunctionMap GetLoadFunctionsMap(GLenum {internal_format}, FormatID {angle_format})
81{{
82    // clang-format off
83    switch ({internal_format})
84    {{
85{switch_data}
86        default:
87            break;
88    }}
89    // clang-format on
90    ASSERT(internalFormat == GL_NONE || angleFormat == angle::FormatID::NONE);
91    static LoadFunctionMap emptyLoadFunctionsMap;
92    return emptyLoadFunctionsMap;
93
94}}  // GetLoadFunctionsMap
95
96}}  // namespace angle
97"""
98
99internal_format_param = 'internalFormat'
100angle_format_param = 'angleFormat'
101angle_format_unknown = 'NONE'
102
103
104def load_functions_name(internal_format, angle_format):
105    return internal_format[3:] + "_to_" + angle_format
106
107
108def unknown_func_name(internal_format):
109    return load_functions_name(internal_format, "default")
110
111
112def get_load_func(func_name, type_functions):
113    snippet = "LoadImageFunctionInfo " + func_name + "(GLenum type)\n"
114    snippet += "{\n"
115    snippet += "    switch (type)\n"
116    snippet += "    {\n"
117    for gl_type, load_function in sorted(type_functions.items()):
118        snippet += "        case " + gl_type + ":\n"
119        requiresConversion = str('LoadToNative<' not in load_function and
120                                 'LoadCompressedToNative<' not in load_function).lower()
121        snippet += "            return LoadImageFunctionInfo(" + load_function + ", " + requiresConversion + ");\n"
122    snippet += "        default:\n"
123    snippet += "            UNREACHABLE();\n"
124    snippet += "            return LoadImageFunctionInfo(UnreachableLoadFunction, true);\n"
125    snippet += "    }\n"
126    snippet += "}\n"
127    snippet += "\n"
128
129    return snippet
130
131
132def get_unknown_load_func(angle_to_type_map, internal_format):
133    assert angle_format_unknown in angle_to_type_map
134    return get_load_func(
135        unknown_func_name(internal_format), angle_to_type_map[angle_format_unknown])
136
137
138def parse_json(json_data):
139    table_data = ''
140    load_functions_data = ''
141    for internal_format, angle_to_type_map in sorted(json_data.items()):
142
143        s = '        '
144
145        table_data += s + 'case ' + internal_format + ':\n'
146
147        do_switch = len(angle_to_type_map) > 1 or list(
148            angle_to_type_map)[0] != angle_format_unknown
149
150        if do_switch:
151            table_data += s + '{\n'
152            s += '    '
153            table_data += s + 'switch (' + angle_format_param + ')\n'
154            table_data += s + '{\n'
155            s += '    '
156
157        for angle_format, type_functions in sorted(angle_to_type_map.items()):
158
159            if angle_format == angle_format_unknown:
160                continue
161
162            func_name = load_functions_name(internal_format, angle_format)
163
164            # Main case statements
165            table_data += s + 'case FormatID::' + angle_format + ':\n'
166            table_data += s + '    return ' + func_name + ';\n'
167
168            if angle_format_unknown in angle_to_type_map:
169                for gl_type, load_function in sorted(
170                        angle_to_type_map[angle_format_unknown].items()):
171                    if gl_type not in type_functions:
172                        type_functions[gl_type] = load_function
173
174            load_functions_data += get_load_func(func_name, type_functions)
175
176        if do_switch:
177            table_data += s + 'default:\n'
178
179        has_break_in_switch = False
180        if angle_format_unknown in angle_to_type_map:
181            table_data += s + '    return ' + unknown_func_name(internal_format) + ';\n'
182            load_functions_data += get_unknown_load_func(angle_to_type_map, internal_format)
183        else:
184            has_break_in_switch = True
185            table_data += s + '    break;\n'
186
187        if do_switch:
188            s = s[4:]
189            table_data += s + '}\n'
190            if has_break_in_switch:
191                # If the inner switch contains a break statement, add a break
192                # statement after the switch as well.
193                table_data += s + 'break;\n'
194            s = s[4:]
195            table_data += s + '}\n'
196
197    return table_data, load_functions_data
198
199
200def main():
201
202    # auto_script parameters.
203    if len(sys.argv) > 1:
204        inputs = ['angle_format.py', 'load_functions_data.json']
205        outputs = ['load_functions_table_autogen.cpp']
206
207        if sys.argv[1] == 'inputs':
208            print(','.join(inputs))
209        elif sys.argv[1] == 'outputs':
210            print(','.join(outputs))
211        else:
212            print('Invalid script parameters')
213            return 1
214        return 0
215
216    json_data = angle_format.load_json('load_functions_data.json')
217
218    switch_data, load_functions_data = parse_json(json_data)
219    output = template.format(
220        internal_format=internal_format_param,
221        angle_format=angle_format_param,
222        switch_data=switch_data,
223        load_functions_data=load_functions_data)
224
225    with open('load_functions_table_autogen.cpp', 'wt') as out_file:
226        out_file.write(output)
227        out_file.close()
228    return 0
229
230
231if __name__ == '__main__':
232    sys.exit(main())
233