Skip to content

Commit a1b1c99

Browse files
authored
Add vkrun, use it in worker_vk (#91)
* Add vkrun, use it in worker_vk * Force-stop the app whenever something goes wrong
1 parent f645af1 commit a1b1c99

File tree

2 files changed

+249
-166
lines changed

2 files changed

+249
-166
lines changed
+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
#!/usr/bin/env python3
2+
3+
# Copyright 2018 The GraphicsFuzz Project Authors
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
import argparse
18+
import os
19+
import subprocess
20+
import time
21+
22+
################################################################################
23+
# Constants
24+
25+
LOGFILE = 'vklog.txt'
26+
TIMEOUT_RUN = 30
27+
28+
################################################################################
29+
# Common
30+
31+
# prepare_shader translates a shader to binary spir-v
32+
# shader.frag -> shader.frag.spv
33+
# shader.vert -> shader.vert.spv
34+
# shader.frag.asm -> shader.frag.spv
35+
# shader.vert.asm -> shader.vert.spv
36+
def prepare_shader(shader):
37+
assert(os.path.exists(shader))
38+
39+
# Translate shader to spv
40+
output = ''
41+
if shader[-5:] == '.frag' or shader[-5:] == '.vert':
42+
output = shader + '.spv'
43+
cmd = 'glslangValidator -V ' + shader + ' -o ' + output
44+
subprocess.check_call(cmd, shell=True, timeout=TIMEOUT_RUN)
45+
elif shader[-9:] == '.frag.asm' or shader[-9:] == '.vert.asm':
46+
output = shader.replace('.asm', '.spv')
47+
cmd = 'spirv-as ' + shader + ' -o ' + output
48+
subprocess.check_call(cmd, shell=True, timeout=TIMEOUT_RUN)
49+
else:
50+
assert(shader[-4:] == '.spv')
51+
output = shader
52+
53+
return output
54+
55+
################################################################################
56+
# Linux
57+
58+
def run_linux(vert, frag, json):
59+
assert(os.path.exists(vert))
60+
assert(os.path.exists(frag))
61+
assert(os.path.exists(json))
62+
cmd = 'vkworker ' + vert + ' ' + frag + ' ' + json + ' > ' + LOGFILE
63+
subprocess.run(cmd, shell=True, timeout=TIMEOUT_RUN)
64+
65+
################################################################################
66+
# Android
67+
68+
ANDROID_SDCARD = '/sdcard/graphicsfuzz'
69+
ANDROID_APP = 'com.graphicsfuzz.vkworker'
70+
TIMEOUT_APP = 30
71+
72+
def adb(adbargs):
73+
74+
adbcmd = 'adb ' + adbargs
75+
76+
try:
77+
p = subprocess.run(adbcmd, shell=True, timeout=TIMEOUT_RUN, stdout=subprocess.PIPE, universal_newlines=True)
78+
except subprocess.TimeoutExpired as err:
79+
print('ERROR: adb command timed out: ' + err.cmd)
80+
return err
81+
else:
82+
return p
83+
84+
def run_android(vert, frag, json):
85+
assert(os.path.exists(vert))
86+
assert(os.path.exists(frag))
87+
assert(os.path.exists(json))
88+
89+
adb('shell rm -rf ' + ANDROID_SDCARD)
90+
adb('shell mkdir -p ' + ANDROID_SDCARD)
91+
adb('push ' + vert + ' ' + ANDROID_SDCARD + '/test.vert.spv')
92+
adb('push ' + frag + ' ' + ANDROID_SDCARD + '/test.frag.spv')
93+
adb('push ' + json + ' ' + ANDROID_SDCARD + '/test.json')
94+
adb('logcat -c')
95+
adb('shell am start ' + ANDROID_APP + '/android.app.NativeActivity')
96+
97+
# Busy wait
98+
deadline = time.time() + TIMEOUT_APP
99+
crash = False
100+
done = False
101+
102+
while time.time() < deadline:
103+
104+
# Begin the busy-wait loop by sleeping to let the app start
105+
# properly. The 'adb shell am start' may return before the app is
106+
# actually started (this is all asynchronous), in which case we may not
107+
# be able to detect the app pid.
108+
time.sleep(0.1)
109+
110+
retcode = adb('shell test -f /sdcard/graphicsfuzz/DONE').returncode
111+
if retcode == 0:
112+
done = True
113+
break
114+
115+
retcode = adb('shell pidof ' + ANDROID_APP + ' > /dev/null').returncode
116+
if retcode == 1:
117+
118+
# double check that no DONE file is present
119+
retcode = adb('shell test -f /sdcard/graphicsfuzz/DONE').returncode
120+
if retcode == 0:
121+
done = True
122+
break
123+
124+
# No pid, and no DONE file, this looks like a crash indeed.
125+
crash = True
126+
break
127+
128+
# Grab log
129+
adb('logcat -d > ' + LOGFILE)
130+
131+
with open(LOGFILE, 'a') as f:
132+
if done:
133+
f.write('\nGFZVK DONE\n')
134+
else:
135+
# Something went wrong, make sure to stop the app in any case
136+
adb('shell am force-stop ' + ANDROID_APP)
137+
if crash:
138+
f.write('\nGFZVK CRASH\n')
139+
else:
140+
f.write('\nGFZVK TIMEOUT\n')
141+
142+
# Grab image if present
143+
imagepath = ANDROID_SDCARD + '/image.png'
144+
retcode = adb('shell test -f ' + imagepath).returncode
145+
if retcode == 0:
146+
adb('pull ' + imagepath)
147+
148+
################################################################################
149+
# Main
150+
151+
if __name__ == '__main__':
152+
153+
desc='Run shaders on vulkan worker. Output: ' + LOGFILE + ', image.png'
154+
155+
parser = argparse.ArgumentParser(description=desc)
156+
157+
group = parser.add_mutually_exclusive_group()
158+
group.add_argument('-a', '--android', action='store_true', help='Render on Android')
159+
group.add_argument('-s', '--serial', help='Android device serial ID. Implies --android')
160+
group.add_argument('-l', '--linux', action='store_true', help='Render on Linux')
161+
162+
parser.add_argument('vert', help='Vertex shader: shader.vert[.asm|.spv]')
163+
parser.add_argument('frag', help='Fragment shader: shader.frag[.asm|.spv]')
164+
parser.add_argument('json', help='Uniforms values')
165+
166+
args = parser.parse_args()
167+
168+
vert = prepare_shader(args.vert)
169+
frag = prepare_shader(args.frag)
170+
171+
if args.serial:
172+
os.environ['ANDROID_SERIAL'] = args.serial
173+
run_android(vert, frag, args.json)
174+
175+
if args.android:
176+
run_android(vert, frag, args.json)
177+
178+
if args.linux:
179+
run_linux(vert, frag, args.json)

0 commit comments

Comments
 (0)