• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/python
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
14from datetime import date
15
16sys.path.append('../..')
17import angle_format
18
19template = """// GENERATED FILE - DO NOT EDIT.
20// Generated by gen_load_functions_table.py using data from load_functions_data.json
21//
22// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
23// Use of this source code is governed by a BSD-style license that can be
24// found in the LICENSE file.
25//
26// load_functions_table:
27//   Contains the GetLoadFunctionsMap for texture_format_util.h
28//
29
30#include "libANGLE/renderer/load_functions_table.h"
31
32#include "image_util/copyimage.h"
33#include "image_util/generatemip.h"
34#include "image_util/loadimage.h"
35
36using namespace rx;
37
38namespace angle
39{{
40
41namespace
42{{
43
44// ES3 image loading functions vary based on:
45//    - the GL internal format (supplied to glTex*Image*D)
46//    - the GL data type given (supplied to glTex*Image*D)
47//    - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D
48//    device's capabilities)
49// This map type determines which loading function to use, based on these three parameters.
50// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec.
51void UnimplementedLoadFunction(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(size_t width,
65                             size_t height,
66                             size_t depth,
67                             const uint8_t *input,
68                             size_t inputRowPitch,
69                             size_t inputDepthPitch,
70                             uint8_t *output,
71                             size_t outputRowPitch,
72                             size_t outputDepthPitch)
73{{
74    UNREACHABLE();
75}}
76
77{load_functions_data}}}  // namespace
78
79LoadFunctionMap GetLoadFunctionsMap(GLenum {internal_format}, FormatID {angle_format})
80{{
81    // clang-format off
82    switch ({internal_format})
83    {{
84{switch_data}
85        default:
86            break;
87    }}
88    // clang-format on
89    ASSERT(internalFormat == GL_NONE || angleFormat == angle::FormatID::NONE);
90    static LoadFunctionMap emptyLoadFunctionsMap;
91    return emptyLoadFunctionsMap;
92
93}}  // GetLoadFunctionsMap
94
95}}  // namespace angle
96"""
97
98internal_format_param = 'internalFormat'
99angle_format_param = 'angleFormat'
100angle_format_unknown = 'NONE'
101
102
103def load_functions_name(internal_format, angle_format):
104    return internal_format[3:] + "_to_" + angle_format
105
106
107def unknown_func_name(internal_format):
108    return load_functions_name(internal_format, "default")
109
110
111def get_load_func(func_name, type_functions):
112    snippet = "LoadImageFunctionInfo " + func_name + "(GLenum type)\n"
113    snippet += "{\n"
114    snippet += "    switch (type)\n"
115    snippet += "    {\n"
116    for gl_type, load_function in sorted(type_functions.iteritems()):
117        snippet += "        case " + gl_type + ":\n"
118        requiresConversion = str('LoadToNative<' not in load_function).lower()
119        snippet += "            return LoadImageFunctionInfo(" + load_function + ", " + requiresConversion + ");\n"
120    snippet += "        default:\n"
121    snippet += "            UNREACHABLE();\n"
122    snippet += "            return LoadImageFunctionInfo(UnreachableLoadFunction, true);\n"
123    snippet += "    }\n"
124    snippet += "}\n"
125    snippet += "\n"
126
127    return snippet
128
129
130def get_unknown_load_func(angle_to_type_map, internal_format):
131    assert angle_format_unknown in angle_to_type_map
132    return get_load_func(
133        unknown_func_name(internal_format), angle_to_type_map[angle_format_unknown])
134
135
136def parse_json(json_data):
137    table_data = ''
138    load_functions_data = ''
139    for internal_format, angle_to_type_map in sorted(json_data.iteritems()):
140
141        s = '        '
142
143        table_data += s + 'case ' + internal_format + ':\n'
144
145        do_switch = len(
146            angle_to_type_map) > 1 or angle_to_type_map.keys()[0] != angle_format_unknown
147
148        if do_switch:
149            table_data += s + '{\n'
150            s += '    '
151            table_data += s + 'switch (' + angle_format_param + ')\n'
152            table_data += s + '{\n'
153            s += '    '
154
155        for angle_format, type_functions in sorted(angle_to_type_map.iteritems()):
156
157            if angle_format == angle_format_unknown:
158                continue
159
160            func_name = load_functions_name(internal_format, angle_format)
161
162            # Main case statements
163            table_data += s + 'case FormatID::' + angle_format + ':\n'
164            table_data += s + '    return ' + func_name + ';\n'
165
166            if angle_format_unknown in angle_to_type_map:
167                for gl_type, load_function in angle_to_type_map[angle_format_unknown].iteritems():
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        copyright_year=date.today().year)
222
223    with open('load_functions_table_autogen.cpp', 'wt') as out_file:
224        out_file.write(output)
225        out_file.close()
226    return 0
227
228
229if __name__ == '__main__':
230    sys.exit(main())
231