blob: c0fc4b1a1764b43204087f217cd89ea23a76a8c4 [file] [log] [blame]
#!/usr/bin/python
# Copyright 2019 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_mtl_internal_shaders.py:
# Code generation for Metal backend's default shaders.
# NOTE: don't run this script directly. Run scripts/run_code_generation.py.
import os
import sys
import json
from datetime import datetime
sys.path.append('../..')
import angle_format
import gen_angle_format_table
template_header_boilerplate = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name}
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
"""
def gen_shader_enums_code(angle_formats):
code = """// This file is similar to src/libANGLE/renderer/FormatID_autogen.h but is used by Metal default
// shaders instead of C++ code.
//
"""
code += "namespace rx\n"
code += "{\n"
code += "namespace mtl_shader\n"
code += "{\n"
code += "\n"
code += "namespace FormatID\n"
code += "{\n"
code += "enum\n"
code += "{\n"
code += gen_angle_format_table.gen_enum_string(angle_formats) + '\n'
code += "};\n\n"
code += "}\n"
code += "\n"
code += "}\n"
code += "}\n"
return code
def main():
angle_format_script_files = [
'../../angle_format_map.json', '../../angle_format.py', '../../gen_angle_format_table.py'
]
src_files = [
'blit.metal', 'clear.metal', 'gen_indices.metal', 'gen_mipmap.metal', 'copy_buffer.metal',
'visibility.metal'
]
# auto_script parameters.
if len(sys.argv) > 1:
inputs = angle_format_script_files + src_files + ['common.h', 'constants.h']
outputs = ['format_autogen.h', 'mtl_default_shaders_src_autogen.inc']
if sys.argv[1] == 'inputs':
print ','.join(inputs)
elif sys.argv[1] == 'outputs':
print ','.join(outputs)
else:
print('Invalid script parameters')
return 1
return 0
os.chdir(sys.path[0])
boilerplate_code = template_header_boilerplate.format(
script_name=sys.argv[0], copyright_year=datetime.today().year)
# -------- Generate shader constants -----------
angle_to_gl = angle_format.load_inverse_table('../../angle_format_map.json')
shader_formats_autogen = gen_shader_enums_code(angle_to_gl.keys())
shader_autogen_header = boilerplate_code + shader_formats_autogen
with open('format_autogen.h', 'wt') as out_file:
out_file.write(shader_autogen_header)
out_file.close()
# -------- Combine and create shader source string -----------
# Generate a combination source
os.system('mkdir -p temp && rm -f temp/master_source.metal && touch temp/master_source.metal')
for src_file in src_files:
os.system('echo "#include \\"../{0}\\"" >> temp/master_source.metal'.format(src_file))
# Use clang/gcc to preprocess the combination source. "@@" token is used to prevent clang from
# expanding the preprocessor directive
if os.system('which gcc') == 0:
print('combining source files using gcc -E')
os.system('gcc -xc++ -E temp/master_source.metal > temp/master_source.metal.pp')
else:
print('combining source files using clang -E')
os.system('clang -xc++ -E temp/master_source.metal > temp/master_source.metal.pp')
# Remove '@@' tokens
final_combined_src_string = ''
with open('temp/master_source.metal.pp', 'rt') as in_file:
final_combined_src_string = in_file.read().replace('@@', '')
in_file.close()
# Generate final file:
with open('mtl_default_shaders_src_autogen.inc', 'wt') as out_file:
out_file.write(boilerplate_code)
out_file.write('\n')
out_file.write('// C++ string version of combined Metal default shaders.\n\n')
out_file.write('\n\nstatic char gDefaultMetallibSrc[] = R"(\n')
out_file.write(final_combined_src_string)
out_file.write('\n')
out_file.write(')";\n')
out_file.close()
# Clean up
os.system('rm -rf temp')
if __name__ == '__main__':
sys.exit(main())