1#!/usr/bin/python3 2 3import argparse 4import pathlib 5import os 6import subprocess 7from datetime import datetime 8import sys 9 10BYTES_PER_UINT32 = 4 11 12UINT32_PER_LINE = 8 13 14def main(): 15 parser = argparse.ArgumentParser( 16 description='Compile glsl source to spv bytes and generate a C file that export the spv bytes as an array.') 17 parser.add_argument('source_file', type=pathlib.Path) 18 parser.add_argument('target_file', type=str) 19 parser.add_argument('export_symbol', type=str) 20 args = parser.parse_args() 21 vulkan_sdk_path = os.getenv('VULKAN_SDK') 22 if vulkan_sdk_path == None: 23 print("Environment variable VULKAN_SDK not set. Please install the LunarG Vulkan SDK and set VULKAN_SDK accordingly") 24 return 25 vulkan_sdk_path = pathlib.Path(vulkan_sdk_path) 26 glslc_path = vulkan_sdk_path / 'bin' / 'glslc' 27 if os.name == 'nt': 28 glslc_path = glslc_path.with_suffix('.exe') 29 if not glslc_path.exists(): 30 print("Can't find " + str(glslc_path)) 31 return 32 if not args.source_file.exists(): 33 print("Can't find source file: " + str(args.source_file)) 34 return 35 36 spv_bytes = None 37 with subprocess.Popen([str(glslc_path), str(args.source_file), '-o', '-'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc: 38 if proc.wait() != 0: 39 print(proc.stderr.read().decode('utf-8')) 40 spv_bytes = proc.stdout.read() 41 spv_bytes = [int.from_bytes(spv_bytes[i:i + BYTES_PER_UINT32], byteorder="little") 42 for i in range(0, len(spv_bytes), BYTES_PER_UINT32)] 43 spv_bytes_chunks = [spv_bytes[i:i + UINT32_PER_LINE] 44 for i in range(0, len(spv_bytes), UINT32_PER_LINE)] 45 spv_bytes_in_vector = ',\n'.join([', '.join( 46 [f'{spv_byte:#010x}' for spv_byte in spv_bytes_chunk]) for spv_bytes_chunk in spv_bytes_chunks]) 47 spv_bytes_in_vector = f'const std::vector<uint32_t> {args.export_symbol} = ' + \ 48 '{\n' + spv_bytes_in_vector + '\n};' 49 50 source_file_lines = None 51 with open(args.source_file, mode='r') as source_file: 52 source_file_lines = source_file.readlines() 53 54 with open(args.target_file, mode='wt') as target_file: 55 header = f"""// Copyright (C) {datetime.today().year} The Android Open Source Project 56// Copyright (C) {datetime.today().year} Google Inc. 57// 58// Licensed under the Apache License, Version 2.0 (the "License"); 59// you may not use this file except in compliance with the License. 60// You may obtain a copy of the License at 61// 62// http://www.apache.org/licenses/LICENSE-2.0 63// 64// Unless required by applicable law or agreed to in writing, software 65// distributed under the License is distributed on an "AS IS" BASIS, 66// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 67// See the License for the specific language governing permissions and 68// limitations under the License. 69 70// Please do not modify directly. 71 72// Autogenerated module {args.target_file} generated by: 73// {"python3 " + " ".join(sys.argv)} 74 75#include <stdint.h> 76#include <vector> 77 78// From {args.source_file}: 79 80""" 81 target_file.write(header) 82 83 for source_file_line in source_file_lines: 84 target_file.write("// " + source_file_line) 85 86 target_file.write("\n\n") 87 88 target_file.write(spv_bytes_in_vector) 89 90 91if __name__ == '__main__': 92 main() 93