~mmach/netext73/webkit2gtk

« back to all changes in this revision

Viewing changes to Source/ThirdParty/ANGLE/src/libANGLE/renderer/metal/gen_mtl_format_table.py

  • Committer: mmach
  • Date: 2023-06-16 17:21:37 UTC
  • Revision ID: netbit73@gmail.com-20230616172137-2rqx6yr96ga9g3kp
1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
# Copyright 2019 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_mtl_format_table.py:
 
7
#  Code generation for Metal format map.
 
8
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.
 
9
#
 
10
 
 
11
from datetime import date
 
12
import json
 
13
import math
 
14
import pprint
 
15
import re
 
16
import sys
 
17
 
 
18
sys.path.append('..')
 
19
import angle_format
 
20
 
 
21
template_autogen_inl = """// GENERATED FILE - DO NOT EDIT.
 
22
// Generated by {script_name} using data from {data_source_name}
 
23
//
 
24
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
 
25
// Use of this source code is governed by a BSD-style license that can be
 
26
// found in the LICENSE file.
 
27
//
 
28
// Metal Format table:
 
29
//   Conversion from ANGLE format to Metal format.
 
30
 
 
31
#import <Metal/Metal.h>
 
32
#include <TargetConditionals.h>
 
33
 
 
34
#include "libANGLE/renderer/Format.h"
 
35
#include "libANGLE/renderer/metal/DisplayMtl.h"
 
36
#include "libANGLE/renderer/metal/mtl_format_utils.h"
 
37
 
 
38
namespace rx
 
39
{{
 
40
namespace mtl
 
41
{{
 
42
 
 
43
void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
 
44
{{
 
45
    this->intendedFormatId = intendedFormatId_;
 
46
 
 
47
    id<MTLDevice> metalDevice = display->getMetalDevice();
 
48
 
 
49
    // Actual conversion
 
50
    switch (this->intendedFormatId)
 
51
    {{
 
52
{angle_image_format_switch}
 
53
    }}
 
54
}}
 
55
 
 
56
void VertexFormat::init(angle::FormatID angleFormatId, bool tightlyPacked)
 
57
{{
 
58
    this->intendedFormatId = angleFormatId;
 
59
 
 
60
    // Actual conversion
 
61
    switch (this->intendedFormatId)
 
62
    {{
 
63
{angle_vertex_format_switch}
 
64
    }}
 
65
}}
 
66
 
 
67
}}  // namespace mtl
 
68
}}  // namespace rx
 
69
"""
 
70
 
 
71
case_image_format_template1 = """        case angle::FormatID::{angle_format}:
 
72
            this->metalFormat = {mtl_format};
 
73
            this->actualFormatId = angle::FormatID::{actual_angle_format};
 
74
            break;
 
75
 
 
76
"""
 
77
 
 
78
case_image_format_template2 = """        case angle::FormatID::{angle_format}:
 
79
            if (metalDevice.depth24Stencil8PixelFormatSupported)
 
80
            {{
 
81
                this->metalFormat = {mtl_format};
 
82
                this->actualFormatId = angle::FormatID::{actual_angle_format};
 
83
            }}
 
84
            else
 
85
            {{
 
86
                this->metalFormat = {mtl_format_fallback};
 
87
                this->actualFormatId = angle::FormatID::{actual_angle_format_fallback};
 
88
            }}
 
89
            break;
 
90
 
 
91
"""
 
92
 
 
93
case_vertex_format_template1 = """        case angle::FormatID::{angle_format}:
 
94
            this->metalFormat = {mtl_format};
 
95
            this->actualFormatId = angle::FormatID::{actual_angle_format};
 
96
            this->vertexLoadFunction = {vertex_copy_function};
 
97
            break;
 
98
 
 
99
"""
 
100
 
 
101
case_vertex_format_template2 = """        case angle::FormatID::{angle_format}:
 
102
            if (tightlyPacked)
 
103
            {{
 
104
                this->metalFormat = {mtl_format_packed};
 
105
                this->actualFormatId = angle::FormatID::{actual_angle_format_packed};
 
106
                this->vertexLoadFunction = {vertex_copy_function_packed};
 
107
            }}
 
108
            else
 
109
            {{
 
110
                this->metalFormat = {mtl_format};
 
111
                this->actualFormatId = angle::FormatID::{actual_angle_format};
 
112
                this->vertexLoadFunction = {vertex_copy_function};
 
113
            }}
 
114
            break;
 
115
 
 
116
"""
 
117
 
 
118
 
 
119
def gen_image_map_switch_simple_case(angle_format, actual_angle_format, angle_to_mtl_map):
 
120
    mtl_format = angle_to_mtl_map[actual_angle_format]
 
121
    return case_image_format_template1.format(
 
122
        angle_format=angle_format, actual_angle_format=actual_angle_format, mtl_format=mtl_format)
 
123
 
 
124
 
 
125
def gen_image_map_switch_mac_case(angle_format, actual_angle_format, angle_to_mtl_map,
 
126
                                  mac_specific_map, mac_fallbacks):
 
127
    if actual_angle_format in mac_specific_map:
 
128
        # look for the metal format in mac specific table
 
129
        mtl_format = mac_specific_map[actual_angle_format]
 
130
    else:
 
131
        # look for the metal format in common table
 
132
        mtl_format = angle_to_mtl_map[actual_angle_format]
 
133
 
 
134
    if actual_angle_format in mac_fallbacks:
 
135
        # This format requires fallback when depth24Stencil8PixelFormatSupported flag is false.
 
136
        # Fallback format:
 
137
        actual_angle_format_fallback = mac_fallbacks[actual_angle_format]
 
138
        if actual_angle_format_fallback in mac_specific_map:
 
139
            # look for the metal format in mac specific table
 
140
            mtl_format_fallback = mac_specific_map[actual_angle_format_fallback]
 
141
        else:
 
142
            # look for the metal format in common table
 
143
            mtl_format_fallback = angle_to_mtl_map[actual_angle_format_fallback]
 
144
        # return if else block:
 
145
        return case_image_format_template2.format(
 
146
            angle_format=angle_format,
 
147
            actual_angle_format=actual_angle_format,
 
148
            mtl_format=mtl_format,
 
149
            actual_angle_format_fallback=actual_angle_format_fallback,
 
150
            mtl_format_fallback=mtl_format_fallback)
 
151
    else:
 
152
        # return ordinary block:
 
153
        return case_image_format_template1.format(
 
154
            angle_format=angle_format,
 
155
            actual_angle_format=actual_angle_format,
 
156
            mtl_format=mtl_format)
 
157
 
 
158
 
 
159
def gen_image_map_switch_string(image_table):
 
160
    angle_override = image_table["override"]
 
161
    mac_override = image_table["override_mac"]
 
162
    ios_override = image_table["override_ios"]
 
163
    mac_fallbacks = image_table["fallbacks_mac"]
 
164
    angle_to_mtl = image_table["map"]
 
165
    mac_specific_map = image_table["map_mac"]
 
166
    ios_specific_map = image_table["map_ios"]
 
167
 
 
168
    switch_data = ''
 
169
 
 
170
    def gen_image_map_switch_common_case(angle_format, actual_angle_format):
 
171
        mac_case = gen_image_map_switch_mac_case(angle_format, actual_angle_format, angle_to_mtl,
 
172
                                                 mac_specific_map, mac_fallbacks)
 
173
        non_mac_case = gen_image_map_switch_simple_case(angle_format, actual_angle_format,
 
174
                                                        angle_to_mtl)
 
175
        if mac_case == non_mac_case:
 
176
            return mac_case
 
177
 
 
178
        re = ''
 
179
        re += "#if TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
 
180
        re += mac_case
 
181
        re += "#else  // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
 
182
        re += non_mac_case
 
183
        re += "#endif  // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
 
184
        return re
 
185
 
 
186
    # Common case
 
187
    for angle_format in sorted(angle_to_mtl.keys()):
 
188
        switch_data += gen_image_map_switch_common_case(angle_format, angle_format)
 
189
    for angle_format in sorted(angle_override.keys()):
 
190
        switch_data += gen_image_map_switch_common_case(angle_format, angle_override[angle_format])
 
191
 
 
192
    # Mac specific
 
193
    switch_data += "#if TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
 
194
    for angle_format in sorted(mac_specific_map.keys()):
 
195
        switch_data += gen_image_map_switch_mac_case(angle_format, angle_format, angle_to_mtl,
 
196
                                                     mac_specific_map, mac_fallbacks)
 
197
    for angle_format in sorted(mac_override.keys()):
 
198
        # overide case will always map to a format in common table, i.e. angle_to_mtl
 
199
        switch_data += gen_image_map_switch_mac_case(angle_format, mac_override[angle_format],
 
200
                                                     angle_to_mtl, mac_specific_map, mac_fallbacks)
 
201
 
 
202
    # iOS specific
 
203
    switch_data += "#elif TARGET_OS_IOS  // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
 
204
    for angle_format in sorted(ios_specific_map.keys()):
 
205
        switch_data += gen_image_map_switch_simple_case(angle_format, angle_format,
 
206
                                                        ios_specific_map)
 
207
    for angle_format in sorted(ios_override.keys()):
 
208
        # overide case will always map to a format in common table, i.e. angle_to_mtl
 
209
        switch_data += gen_image_map_switch_simple_case(angle_format, ios_override[angle_format],
 
210
                                                        angle_to_mtl)
 
211
    switch_data += "#endif  // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
 
212
    switch_data += "        default:\n"
 
213
    switch_data += "            this->metalFormat = MTLPixelFormatInvalid;\n"
 
214
    switch_data += "            this->actualFormatId = angle::FormatID::NONE;"
 
215
    return switch_data
 
216
 
 
217
 
 
218
def gen_vertex_map_switch_case(angle_fmt, actual_angle_fmt, angle_to_mtl_map, override_packed_map):
 
219
    mtl_format = angle_to_mtl_map[actual_angle_fmt]
 
220
    copy_function = angle_format.get_vertex_copy_function(angle_fmt, actual_angle_fmt)
 
221
    if actual_angle_fmt in override_packed_map:
 
222
        # This format has an override when used in tightly packed buffer,
 
223
        # Return if else block
 
224
        angle_fmt_packed = override_packed_map[actual_angle_fmt]
 
225
        mtl_format_packed = angle_to_mtl_map[angle_fmt_packed]
 
226
        copy_function_packed = angle_format.get_vertex_copy_function(angle_fmt, angle_fmt_packed)
 
227
        return case_vertex_format_template2.format(
 
228
            angle_format=angle_fmt,
 
229
            mtl_format_packed=mtl_format_packed,
 
230
            actual_angle_format_packed=angle_fmt_packed,
 
231
            vertex_copy_function_packed=copy_function_packed,
 
232
            mtl_format=mtl_format,
 
233
            actual_angle_format=actual_angle_fmt,
 
234
            vertex_copy_function=copy_function)
 
235
    else:
 
236
        # This format has no packed buffer's override, return ordinary block.
 
237
        return case_vertex_format_template1.format(
 
238
            angle_format=angle_fmt,
 
239
            mtl_format=mtl_format,
 
240
            actual_angle_format=actual_angle_fmt,
 
241
            vertex_copy_function=copy_function)
 
242
 
 
243
 
 
244
def gen_vertex_map_switch_string(vertex_table):
 
245
    angle_to_mtl = vertex_table["map"]
 
246
    angle_override = vertex_table["override"]
 
247
    override_packed = vertex_table["override_tightly_packed"]
 
248
 
 
249
    switch_data = ''
 
250
    for angle_fmt in sorted(angle_to_mtl.keys()):
 
251
        switch_data += gen_vertex_map_switch_case(angle_fmt, angle_fmt, angle_to_mtl,
 
252
                                                  override_packed)
 
253
 
 
254
    for angle_fmt in sorted(angle_override.keys()):
 
255
        switch_data += gen_vertex_map_switch_case(angle_fmt, angle_override[angle_fmt],
 
256
                                                  angle_to_mtl, override_packed)
 
257
 
 
258
    switch_data += "        default:\n"
 
259
    switch_data += "            this->metalFormat = MTLVertexFormatInvalid;\n"
 
260
    switch_data += "            this->actualFormatId = angle::FormatID::NONE;\n"
 
261
    switch_data += "            this->vertexLoadFunction = nullptr;"
 
262
    return switch_data
 
263
 
 
264
 
 
265
def main():
 
266
    # auto_script parameters.
 
267
    if len(sys.argv) > 1:
 
268
        inputs = ['../angle_format.py', 'mtl_format_map.json']
 
269
        outputs = ['mtl_format_table_autogen.mm']
 
270
 
 
271
        if sys.argv[1] == 'inputs':
 
272
            print ','.join(inputs)
 
273
        elif sys.argv[1] == 'outputs':
 
274
            print ','.join(outputs)
 
275
        else:
 
276
            print('Invalid script parameters')
 
277
            return 1
 
278
        return 0
 
279
 
 
280
    data_source_name = 'mtl_format_map.json'
 
281
    map_json = angle_format.load_json(data_source_name)
 
282
    map_image = map_json["image"]
 
283
    map_vertex = map_json["vertex"]
 
284
 
 
285
    image_switch_data = gen_image_map_switch_string(map_image)
 
286
 
 
287
    vertex_switch_data = gen_vertex_map_switch_string(map_vertex)
 
288
 
 
289
    output_cpp = template_autogen_inl.format(
 
290
        script_name=sys.argv[0],
 
291
        copyright_year=date.today().year,
 
292
        data_source_name=data_source_name,
 
293
        angle_image_format_switch=image_switch_data,
 
294
        angle_vertex_format_switch=vertex_switch_data)
 
295
    with open('mtl_format_table_autogen.mm', 'wt') as out_file:
 
296
        out_file.write(output_cpp)
 
297
        out_file.close()
 
298
 
 
299
 
 
300
if __name__ == '__main__':
 
301
    sys.exit(main())