1#!/usr/bin/env python3 2 3import argparse 4import filecmp 5import os 6import struct 7import subprocess 8import tempfile 9import sys 10 11p = argparse.ArgumentParser(usage="%(prog)s SOURCE [-- [EXTRA_FLAGS ...]]") 12p.add_argument('SOURCE', 13 help='SPIR-V assembly source filename') 14p.add_argument('EXTRA_FLAGS', 15 help='extra flags passed to spirv-as, e.g. --target-env spv1.0', 16 nargs=argparse.REMAINDER) 17args = p.parse_args() 18source = args.SOURCE 19 20fd, generated = tempfile.mkstemp(prefix="spirv-to-c-array.", suffix=".spv") 21os.close(fd) 22 23assembler_cmd = ['spirv-as'] + args.EXTRA_FLAGS 24 25ret = subprocess.run(assembler_cmd + ['-o', generated, source]) 26 27if ret.returncode != 0: 28 print(f'Failed to assemble {source}, see error above.') 29 sys.exit(1) 30 31if os.path.getsize(generated) == 0: 32 print(f'Failed to assemble {source}. Output {generated} is empty.') 33 sys.exit(1) 34 35if (os.path.getsize(generated) % 4) != 0: 36 print(f'Failed to assemble {source}. Output {generated} size is not multiple of 4 bytes.') 37 sys.exit(1) 38 39ret = subprocess.run(['spirv-dis', '--raw-id', generated], capture_output=True) 40if ret.returncode != 0: 41 print(ret.stderr.decode('ascii')) 42 print(f'Something is wrong: assembled binary {generated} ') 43 print('failed to disassemble for checking.') 44 sys.exit(1) 45 46disassembled_source = ret.stdout 47 48generated_check = os.path.splitext(generated)[0] + '.check.spv' 49 50ret = subprocess.run(assembler_cmd + ['-o', generated_check], 51 input=disassembled_source, capture_output=True) 52if ret.returncode != 0: 53 print(ret.stderr.decode('ascii')) 54 print(f'Something is wrong: assembled binary {generated} ') 55 print('failed to reassemble for checking.') 56 sys.exit(1) 57 58if not filecmp.cmp(generated, generated_check, shallow=False): 59 print('Something is wrong: assembled binary generated ') 60 print('does not match after round trip of using disassembler ') 61 print('and assembler again. See files:') 62 print() 63 print(f' {generated}') 64 print(f' {generated_check}') 65 print() 66 print(f'Extra arguments for spirv-as {" ".join(args.EXTRA_FLAGS)}') 67 sys.exit(1) 68 69with open(source, 'r') as f: 70 source_lines = f.readlines() 71 72words = [] 73with open(generated, 'rb') as f: 74 while True: 75 w = f.read(4) 76 if not w: 77 break 78 v = struct.unpack('<I', w)[0] 79 words.append(f'{v:#010x}') 80 81os.remove(generated_check) 82os.remove(generated) 83 84print(" /*") 85 86if args.EXTRA_FLAGS: 87 print(f' ; Extra arguments for spirv-as {" ".join(args.EXTRA_FLAGS)}') 88 print() 89 90for line in source_lines: 91 print(f' {line}', end='') 92 93print(' */') 94print(' static const uint32_t words[] = {') 95 96while words: 97 line, words = words[:6], words[6:] 98 line = ', '.join(line) 99 print(f' {line},') 100 101print(' };') 102