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.
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.
11
from datetime import date
21
template_autogen_inl = """// GENERATED FILE - DO NOT EDIT.
22
// Generated by {script_name} using data from {data_source_name}
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.
28
// Metal Format table:
29
// Conversion from ANGLE format to Metal format.
31
#import <Metal/Metal.h>
32
#include <TargetConditionals.h>
34
#include "libANGLE/renderer/Format.h"
35
#include "libANGLE/renderer/metal/DisplayMtl.h"
36
#include "libANGLE/renderer/metal/mtl_format_utils.h"
43
void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
45
this->intendedFormatId = intendedFormatId_;
47
id<MTLDevice> metalDevice = display->getMetalDevice();
50
switch (this->intendedFormatId)
52
{angle_image_format_switch}
56
void VertexFormat::init(angle::FormatID angleFormatId, bool tightlyPacked)
58
this->intendedFormatId = angleFormatId;
61
switch (this->intendedFormatId)
63
{angle_vertex_format_switch}
71
case_image_format_template1 = """ case angle::FormatID::{angle_format}:
72
this->metalFormat = {mtl_format};
73
this->actualFormatId = angle::FormatID::{actual_angle_format};
78
case_image_format_template2 = """ case angle::FormatID::{angle_format}:
79
if (metalDevice.depth24Stencil8PixelFormatSupported)
81
this->metalFormat = {mtl_format};
82
this->actualFormatId = angle::FormatID::{actual_angle_format};
86
this->metalFormat = {mtl_format_fallback};
87
this->actualFormatId = angle::FormatID::{actual_angle_format_fallback};
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};
101
case_vertex_format_template2 = """ case angle::FormatID::{angle_format}:
104
this->metalFormat = {mtl_format_packed};
105
this->actualFormatId = angle::FormatID::{actual_angle_format_packed};
106
this->vertexLoadFunction = {vertex_copy_function_packed};
110
this->metalFormat = {mtl_format};
111
this->actualFormatId = angle::FormatID::{actual_angle_format};
112
this->vertexLoadFunction = {vertex_copy_function};
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)
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]
131
# look for the metal format in common table
132
mtl_format = angle_to_mtl_map[actual_angle_format]
134
if actual_angle_format in mac_fallbacks:
135
# This format requires fallback when depth24Stencil8PixelFormatSupported flag is false.
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]
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)
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)
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"]
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,
175
if mac_case == non_mac_case:
179
re += "#if TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
181
re += "#else // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
183
re += "#endif // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
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])
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)
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,
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],
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;"
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)
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)
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"]
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,
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)
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;"
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']
271
if sys.argv[1] == 'inputs':
272
print ','.join(inputs)
273
elif sys.argv[1] == 'outputs':
274
print ','.join(outputs)
276
print('Invalid script parameters')
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"]
285
image_switch_data = gen_image_map_switch_string(map_image)
287
vertex_switch_data = gen_vertex_map_switch_string(map_vertex)
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)
300
if __name__ == '__main__':