xref: /aosp_15_r20/external/mesa3d/src/compiler/spirv/tests/spirv-to-c-array.py (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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