xref: /aosp_15_r20/external/angle/src/libANGLE/gen_format_map.py (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1#!/usr/bin/python3
2# Copyright 2016 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_format_map.py:
7#  Code generation for GL format map. The format map matches between
8#  {format,type} and internal format.
9#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.
10
11import sys
12import os
13
14sys.path.append('renderer')
15import angle_format
16
17template_cpp = """// GENERATED FILE - DO NOT EDIT.
18// Generated by {script_name} using data from {data_source_name}.
19// ES3 format info from {es3_data_source_name}.
20//
21// Copyright 2016 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// format_map:
26//   Determining the sized internal format from a (format,type) pair.
27//   Also check es3 format combinations for validity.
28
29#include "angle_gl.h"
30#include "common/debug.h"
31
32namespace gl
33{{
34
35GLenum GetSizedFormatInternal(GLenum format, GLenum type)
36{{
37    switch (format)
38    {{
39{format_cases}        case GL_NONE:
40            return GL_NONE;
41
42        default:
43            break;
44    }}
45
46    return GL_NONE;
47}}
48
49bool ValidES3Format(GLenum format)
50{{
51    switch (format)
52    {{
53{es3_format_cases}            return true;
54
55        default:
56            return false;
57    }}
58}}
59
60bool ValidES3Type(GLenum type)
61{{
62    switch (type)
63    {{
64{es3_type_cases}            return true;
65
66        default:
67            return false;
68    }}
69}}
70
71bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat)
72{{
73    ASSERT(ValidES3Format(format) && ValidES3Type(type));
74
75    switch (format)
76    {{
77{es3_combo_cases}        default:
78            UNREACHABLE();
79            break;
80    }}
81
82    return false;
83}}
84
85}}  // namespace gl
86"""
87
88template_format_case = """        case {format}:
89            switch (type)
90            {{
91{type_cases}                default:
92                    break;
93            }}
94            break;
95
96"""
97
98template_simple_case = """                case {key}:
99                    return {result};
100"""
101
102template_es3_combo_type_case = """                case {type}:
103                {{
104                    switch (internalFormat)
105                    {{
106{internal_format_cases}                            return true;
107                        default:
108                            break;
109                    }}
110                    break;
111                }}
112"""
113
114
115def parse_type_case(type, result):
116    return template_simple_case.format(key=type, result=result)
117
118
119def parse_format_case(format, type_map):
120    type_cases = ""
121    for type, internal_format in sorted(type_map.items()):
122        type_cases += parse_type_case(type, internal_format)
123    return template_format_case.format(format=format, type_cases=type_cases)
124
125
126def main():
127
128    # auto_script parameters.
129    if len(sys.argv) > 1:
130        inputs = [
131            'renderer/angle_format.py', 'es3_format_type_combinations.json', 'format_map_data.json'
132        ]
133        outputs = ['format_map_autogen.cpp']
134
135        if sys.argv[1] == 'inputs':
136            print(','.join(inputs))
137        elif sys.argv[1] == 'outputs':
138            print(','.join(outputs))
139        else:
140            print('Invalid script parameters')
141            return 1
142        return 0
143
144    input_script = 'format_map_data.json'
145
146    format_map = angle_format.load_json(input_script)
147
148    format_cases = ""
149
150    for format, type_map in sorted(format_map.items()):
151        format_cases += parse_format_case(format, type_map)
152
153    combo_data_file = 'es3_format_type_combinations.json'
154    es3_combo_data = angle_format.load_json(combo_data_file)
155    combo_data = [combo for sublist in es3_combo_data.values() for combo in sublist]
156
157    types = set()
158    formats = set()
159    combos = {}
160
161    for internal_format, format, type in combo_data:
162        types.update([type])
163        formats.update([format])
164        if format not in combos:
165            combos[format] = {}
166        if type not in combos[format]:
167            combos[format][type] = [internal_format]
168        else:
169            combos[format][type] += [internal_format]
170
171    es3_format_cases = ""
172
173    for format in sorted(formats):
174        es3_format_cases += "        case " + format + ":\n"
175
176    es3_type_cases = ""
177
178    for type in sorted(types):
179        es3_type_cases += "        case " + type + ":\n"
180
181    es3_combo_cases = ""
182
183    for format, type_combos in sorted(combos.items()):
184        this_type_cases = ""
185        for type, combos in sorted(type_combos.items()):
186            internal_format_cases = ""
187            for internal_format in combos:
188                internal_format_cases += "                        case " + internal_format + ":\n"
189
190            this_type_cases += template_es3_combo_type_case.format(
191                type=type, internal_format_cases=internal_format_cases)
192
193        es3_combo_cases += template_format_case.format(format=format, type_cases=this_type_cases)
194
195    with open('format_map_autogen.cpp', 'wt') as out_file:
196        output_cpp = template_cpp.format(
197            script_name=os.path.basename(sys.argv[0]),
198            data_source_name=input_script,
199            es3_data_source_name=combo_data_file,
200            format_cases=format_cases,
201            es3_format_cases=es3_format_cases,
202            es3_type_cases=es3_type_cases,
203            es3_combo_cases=es3_combo_cases)
204        out_file.write(output_cpp)
205    return 0
206
207
208if __name__ == '__main__':
209    sys.exit(main())
210