• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(size_t width,
51                               size_t height,
52                               size_t depth,
53                               const uint8_t *input,
54                               size_t inputRowPitch,
55                               size_t inputDepthPitch,
56                               uint8_t *output,
57                               size_t outputRowPitch,
58                               size_t outputDepthPitch)
59{{
60    UNIMPLEMENTED();
61}}
62
63void UnreachableLoadFunction(size_t width,
64                             size_t height,
65                             size_t depth,
66                             const uint8_t *input,
67                             size_t inputRowPitch,
68                             size_t inputDepthPitch,
69                             uint8_t *output,
70                             size_t outputRowPitch,
71                             size_t outputDepthPitch)
72{{
73    UNREACHABLE();
74}}
75
76{load_functions_data}}}  // namespace
77
78LoadFunctionMap GetLoadFunctionsMap(GLenum {internal_format}, FormatID {angle_format})
79{{
80    // clang-format off
81    switch ({internal_format})
82    {{
83{switch_data}
84        default:
85            break;
86    }}
87    // clang-format on
88    ASSERT(internalFormat == GL_NONE || angleFormat == angle::FormatID::NONE);
89    static LoadFunctionMap emptyLoadFunctionsMap;
90    return emptyLoadFunctionsMap;
91
92}}  // GetLoadFunctionsMap
93
94}}  // namespace angle
95"""
96
97internal_format_param = 'internalFormat'
98angle_format_param = 'angleFormat'
99angle_format_unknown = 'NONE'
100
101
102def load_functions_name(internal_format, angle_format):
103    return internal_format[3:] + "_to_" + angle_format
104
105
106def unknown_func_name(internal_format):
107    return load_functions_name(internal_format, "default")
108
109
110def get_load_func(func_name, type_functions):
111    snippet = "LoadImageFunctionInfo " + func_name + "(GLenum type)\n"
112    snippet += "{\n"
113    snippet += "    switch (type)\n"
114    snippet += "    {\n"
115    for gl_type, load_function in sorted(type_functions.items()):
116        snippet += "        case " + gl_type + ":\n"
117        requiresConversion = str('LoadToNative<' not in load_function).lower()
118        snippet += "            return LoadImageFunctionInfo(" + load_function + ", " + requiresConversion + ");\n"
119    snippet += "        default:\n"
120    snippet += "            UNREACHABLE();\n"
121    snippet += "            return LoadImageFunctionInfo(UnreachableLoadFunction, true);\n"
122    snippet += "    }\n"
123    snippet += "}\n"
124    snippet += "\n"
125
126    return snippet
127
128
129def get_unknown_load_func(angle_to_type_map, internal_format):
130    assert angle_format_unknown in angle_to_type_map
131    return get_load_func(
132        unknown_func_name(internal_format), angle_to_type_map[angle_format_unknown])
133
134
135def parse_json(json_data):
136    table_data = ''
137    load_functions_data = ''
138    for internal_format, angle_to_type_map in sorted(json_data.items()):
139
140        s = '        '
141
142        table_data += s + 'case ' + internal_format + ':\n'
143
144        do_switch = len(angle_to_type_map) > 1 or list(
145            angle_to_type_map)[0] != angle_format_unknown
146
147        if do_switch:
148            table_data += s + '{\n'
149            s += '    '
150            table_data += s + 'switch (' + angle_format_param + ')\n'
151            table_data += s + '{\n'
152            s += '    '
153
154        for angle_format, type_functions in sorted(angle_to_type_map.items()):
155
156            if angle_format == angle_format_unknown:
157                continue
158
159            func_name = load_functions_name(internal_format, angle_format)
160
161            # Main case statements
162            table_data += s + 'case FormatID::' + angle_format + ':\n'
163            table_data += s + '    return ' + func_name + ';\n'
164
165            if angle_format_unknown in angle_to_type_map:
166                for gl_type, load_function in sorted(
167                        angle_to_type_map[angle_format_unknown].items()):
168                    if gl_type not in type_functions:
169                        type_functions[gl_type] = load_function
170
171            load_functions_data += get_load_func(func_name, type_functions)
172
173        if do_switch:
174            table_data += s + 'default:\n'
175
176        has_break_in_switch = False
177        if angle_format_unknown in angle_to_type_map:
178            table_data += s + '    return ' + unknown_func_name(internal_format) + ';\n'
179            load_functions_data += get_unknown_load_func(angle_to_type_map, internal_format)
180        else:
181            has_break_in_switch = True
182            table_data += s + '    break;\n'
183
184        if do_switch:
185            s = s[4:]
186            table_data += s + '}\n'
187            if has_break_in_switch:
188                # If the inner switch contains a break statement, add a break
189                # statement after the switch as well.
190                table_data += s + 'break;\n'
191            s = s[4:]
192            table_data += s + '}\n'
193
194    return table_data, load_functions_data
195
196
197def main():
198
199    # auto_script parameters.
200    if len(sys.argv) > 1:
201        inputs = ['angle_format.py', 'load_functions_data.json']
202        outputs = ['load_functions_table_autogen.cpp']
203
204        if sys.argv[1] == 'inputs':
205            print(','.join(inputs))
206        elif sys.argv[1] == 'outputs':
207            print(','.join(outputs))
208        else:
209            print('Invalid script parameters')
210            return 1
211        return 0
212
213    json_data = angle_format.load_json('load_functions_data.json')
214
215    switch_data, load_functions_data = parse_json(json_data)
216    output = template.format(
217        internal_format=internal_format_param,
218        angle_format=angle_format_param,
219        switch_data=switch_data,
220        load_functions_data=load_functions_data)
221
222    with open('load_functions_table_autogen.cpp', 'wt') as out_file:
223        out_file.write(output)
224        out_file.close()
225    return 0
226
227
228if __name__ == '__main__':
229    sys.exit(main())
230