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