Add --opt option to test_shaders.py.
Allows us to create a reference suite of optimized SPIR-V.
This commit is contained in:
parent
e5b11599b8
commit
230a0120d4
@ -72,8 +72,8 @@ def print_msl_compiler_version():
|
|||||||
if (e.errno != os.errno.ENOENT): # Ignore xcrun not found error
|
if (e.errno != os.errno.ENOENT): # Ignore xcrun not found error
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def validate_shader_msl(shader):
|
def validate_shader_msl(shader, opt):
|
||||||
msl_path = reference_path(shader[0], shader[1])
|
msl_path = reference_path(shader[0], shader[1], opt)
|
||||||
try:
|
try:
|
||||||
msl_os = 'macosx'
|
msl_os = 'macosx'
|
||||||
# msl_os = 'iphoneos'
|
# msl_os = 'iphoneos'
|
||||||
@ -86,7 +86,7 @@ def validate_shader_msl(shader):
|
|||||||
print('Error compiling Metal shader: ' + msl_path)
|
print('Error compiling Metal shader: ' + msl_path)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def cross_compile_msl(shader, spirv):
|
def cross_compile_msl(shader, spirv, opt):
|
||||||
spirv_f, spirv_path = tempfile.mkstemp()
|
spirv_f, spirv_path = tempfile.mkstemp()
|
||||||
msl_f, msl_path = tempfile.mkstemp(suffix = os.path.basename(shader))
|
msl_f, msl_path = tempfile.mkstemp(suffix = os.path.basename(shader))
|
||||||
os.close(spirv_f)
|
os.close(spirv_f)
|
||||||
@ -97,6 +97,9 @@ def cross_compile_msl(shader, spirv):
|
|||||||
else:
|
else:
|
||||||
subprocess.check_call(['glslangValidator', '-V', '-o', spirv_path, shader])
|
subprocess.check_call(['glslangValidator', '-V', '-o', spirv_path, shader])
|
||||||
|
|
||||||
|
if opt:
|
||||||
|
subprocess.check_call(['spirv-opt', '-O', '-o', spirv_path, spirv_path])
|
||||||
|
|
||||||
spirv_cross_path = './spirv-cross'
|
spirv_cross_path = './spirv-cross'
|
||||||
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', msl_path, spirv_path, '--msl'])
|
subprocess.check_call([spirv_cross_path, '--entry', 'main', '--output', msl_path, spirv_path, '--msl'])
|
||||||
subprocess.check_call(['spirv-val', spirv_path])
|
subprocess.check_call(['spirv-val', spirv_path])
|
||||||
@ -115,7 +118,7 @@ def shader_to_sm(shader):
|
|||||||
else:
|
else:
|
||||||
return '50'
|
return '50'
|
||||||
|
|
||||||
def cross_compile_hlsl(shader, spirv):
|
def cross_compile_hlsl(shader, spirv, opt):
|
||||||
spirv_f, spirv_path = tempfile.mkstemp()
|
spirv_f, spirv_path = tempfile.mkstemp()
|
||||||
hlsl_f, hlsl_path = tempfile.mkstemp(suffix = os.path.basename(shader))
|
hlsl_f, hlsl_path = tempfile.mkstemp(suffix = os.path.basename(shader))
|
||||||
os.close(spirv_f)
|
os.close(spirv_f)
|
||||||
@ -126,6 +129,9 @@ def cross_compile_hlsl(shader, spirv):
|
|||||||
else:
|
else:
|
||||||
subprocess.check_call(['glslangValidator', '-V', '-o', spirv_path, shader])
|
subprocess.check_call(['glslangValidator', '-V', '-o', spirv_path, shader])
|
||||||
|
|
||||||
|
if opt:
|
||||||
|
subprocess.check_call(['spirv-opt', '-O', '-o', spirv_path, spirv_path])
|
||||||
|
|
||||||
spirv_cross_path = './spirv-cross'
|
spirv_cross_path = './spirv-cross'
|
||||||
|
|
||||||
sm = shader_to_sm(shader)
|
sm = shader_to_sm(shader)
|
||||||
@ -142,7 +148,7 @@ def validate_shader(shader, vulkan):
|
|||||||
else:
|
else:
|
||||||
subprocess.check_call(['glslangValidator', shader])
|
subprocess.check_call(['glslangValidator', shader])
|
||||||
|
|
||||||
def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim):
|
def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt):
|
||||||
spirv_f, spirv_path = tempfile.mkstemp()
|
spirv_f, spirv_path = tempfile.mkstemp()
|
||||||
glsl_f, glsl_path = tempfile.mkstemp(suffix = os.path.basename(shader))
|
glsl_f, glsl_path = tempfile.mkstemp(suffix = os.path.basename(shader))
|
||||||
os.close(spirv_f)
|
os.close(spirv_f)
|
||||||
@ -157,6 +163,9 @@ def cross_compile(shader, vulkan, spirv, invalid_spirv, eliminate, is_legacy, fl
|
|||||||
else:
|
else:
|
||||||
subprocess.check_call(['glslangValidator', '-V', '-o', spirv_path, shader])
|
subprocess.check_call(['glslangValidator', '-V', '-o', spirv_path, shader])
|
||||||
|
|
||||||
|
if opt:
|
||||||
|
subprocess.check_call(['spirv-opt', '-O', '-o', spirv_path, spirv_path])
|
||||||
|
|
||||||
if not invalid_spirv:
|
if not invalid_spirv:
|
||||||
subprocess.check_call(['spirv-val', spirv_path])
|
subprocess.check_call(['spirv-val', spirv_path])
|
||||||
|
|
||||||
@ -202,14 +211,14 @@ def make_reference_dir(path):
|
|||||||
if not os.path.exists(base):
|
if not os.path.exists(base):
|
||||||
os.makedirs(base)
|
os.makedirs(base)
|
||||||
|
|
||||||
def reference_path(directory, relpath):
|
def reference_path(directory, relpath, opt):
|
||||||
split_paths = os.path.split(directory)
|
split_paths = os.path.split(directory)
|
||||||
reference_dir = os.path.join(split_paths[0], 'reference/')
|
reference_dir = os.path.join(split_paths[0], 'reference/' + ('opt/' if opt else ''))
|
||||||
reference_dir = os.path.join(reference_dir, split_paths[1])
|
reference_dir = os.path.join(reference_dir, split_paths[1])
|
||||||
return os.path.join(reference_dir, relpath)
|
return os.path.join(reference_dir, relpath)
|
||||||
|
|
||||||
def regression_check(shader, glsl, update, keep):
|
def regression_check(shader, glsl, update, keep, opt):
|
||||||
reference = reference_path(shader[0], shader[1])
|
reference = reference_path(shader[0], shader[1], opt)
|
||||||
joined_path = os.path.join(shader[0], shader[1])
|
joined_path = os.path.join(shader[0], shader[1])
|
||||||
print('Reference shader path:', reference)
|
print('Reference shader path:', reference)
|
||||||
|
|
||||||
@ -270,7 +279,7 @@ def shader_is_sso(shader):
|
|||||||
def shader_is_flatten_dimensions(shader):
|
def shader_is_flatten_dimensions(shader):
|
||||||
return '.flatten_dim.' in shader
|
return '.flatten_dim.' in shader
|
||||||
|
|
||||||
def test_shader(stats, shader, update, keep):
|
def test_shader(stats, shader, update, keep, opt):
|
||||||
joined_path = os.path.join(shader[0], shader[1])
|
joined_path = os.path.join(shader[0], shader[1])
|
||||||
vulkan = shader_is_vulkan(shader[1])
|
vulkan = shader_is_vulkan(shader[1])
|
||||||
desktop = shader_is_desktop(shader[1])
|
desktop = shader_is_desktop(shader[1])
|
||||||
@ -283,15 +292,15 @@ def test_shader(stats, shader, update, keep):
|
|||||||
flatten_dim = shader_is_flatten_dimensions(shader[1])
|
flatten_dim = shader_is_flatten_dimensions(shader[1])
|
||||||
|
|
||||||
print('Testing shader:', joined_path)
|
print('Testing shader:', joined_path)
|
||||||
spirv, glsl, vulkan_glsl = cross_compile(joined_path, vulkan, is_spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim)
|
spirv, glsl, vulkan_glsl = cross_compile(joined_path, vulkan, is_spirv, invalid_spirv, eliminate, is_legacy, flatten_ubo, sso, flatten_dim, opt)
|
||||||
|
|
||||||
# Only test GLSL stats if we have a shader following GL semantics.
|
# Only test GLSL stats if we have a shader following GL semantics.
|
||||||
if stats and (not vulkan) and (not is_spirv) and (not desktop):
|
if stats and (not vulkan) and (not is_spirv) and (not desktop):
|
||||||
cross_stats = get_shader_stats(glsl)
|
cross_stats = get_shader_stats(glsl)
|
||||||
|
|
||||||
regression_check(shader, glsl, update, keep)
|
regression_check(shader, glsl, update, keep, opt)
|
||||||
if vulkan_glsl:
|
if vulkan_glsl:
|
||||||
regression_check((shader[0], shader[1] + '.vk'), vulkan_glsl, update, keep)
|
regression_check((shader[0], shader[1] + '.vk'), vulkan_glsl, update, keep, opt)
|
||||||
os.remove(spirv)
|
os.remove(spirv)
|
||||||
|
|
||||||
if stats and (not vulkan) and (not is_spirv) and (not desktop):
|
if stats and (not vulkan) and (not is_spirv) and (not desktop):
|
||||||
@ -305,45 +314,45 @@ def test_shader(stats, shader, update, keep):
|
|||||||
a.append(str(i))
|
a.append(str(i))
|
||||||
print(','.join(a), file = stats)
|
print(','.join(a), file = stats)
|
||||||
|
|
||||||
def test_shader_msl(stats, shader, update, keep):
|
def test_shader_msl(stats, shader, update, keep, opt):
|
||||||
joined_path = os.path.join(shader[0], shader[1])
|
joined_path = os.path.join(shader[0], shader[1])
|
||||||
print('\nTesting MSL shader:', joined_path)
|
print('\nTesting MSL shader:', joined_path)
|
||||||
is_spirv = shader_is_spirv(shader[1])
|
is_spirv = shader_is_spirv(shader[1])
|
||||||
spirv, msl = cross_compile_msl(joined_path, is_spirv)
|
spirv, msl = cross_compile_msl(joined_path, is_spirv, opt)
|
||||||
regression_check(shader, msl, update, keep)
|
regression_check(shader, msl, update, keep, opt)
|
||||||
os.remove(spirv)
|
os.remove(spirv)
|
||||||
|
|
||||||
if not force_no_external_validation:
|
if not force_no_external_validation:
|
||||||
validate_shader_msl(shader)
|
validate_shader_msl(shader, opt)
|
||||||
|
|
||||||
def test_shader_hlsl(stats, shader, update, keep):
|
def test_shader_hlsl(stats, shader, update, keep, opt):
|
||||||
joined_path = os.path.join(shader[0], shader[1])
|
joined_path = os.path.join(shader[0], shader[1])
|
||||||
print('Testing HLSL shader:', joined_path)
|
print('Testing HLSL shader:', joined_path)
|
||||||
is_spirv = shader_is_spirv(shader[1])
|
is_spirv = shader_is_spirv(shader[1])
|
||||||
spirv, msl = cross_compile_hlsl(joined_path, is_spirv)
|
spirv, msl = cross_compile_hlsl(joined_path, is_spirv, opt)
|
||||||
regression_check(shader, msl, update, keep)
|
regression_check(shader, msl, update, keep, opt)
|
||||||
os.remove(spirv)
|
os.remove(spirv)
|
||||||
|
|
||||||
def test_shaders_helper(stats, shader_dir, update, malisc, keep, backend):
|
def test_shaders_helper(stats, shader_dir, update, malisc, keep, opt, backend):
|
||||||
for root, dirs, files in os.walk(os.path.join(shader_dir)):
|
for root, dirs, files in os.walk(os.path.join(shader_dir)):
|
||||||
files = [ f for f in files if not f.startswith(".") ] #ignore system files (esp OSX)
|
files = [ f for f in files if not f.startswith(".") ] #ignore system files (esp OSX)
|
||||||
for i in files:
|
for i in files:
|
||||||
path = os.path.join(root, i)
|
path = os.path.join(root, i)
|
||||||
relpath = os.path.relpath(path, shader_dir)
|
relpath = os.path.relpath(path, shader_dir)
|
||||||
if backend == 'msl':
|
if backend == 'msl':
|
||||||
test_shader_msl(stats, (shader_dir, relpath), update, keep)
|
test_shader_msl(stats, (shader_dir, relpath), update, keep, opt)
|
||||||
elif backend == 'hlsl':
|
elif backend == 'hlsl':
|
||||||
test_shader_hlsl(stats, (shader_dir, relpath), update, keep)
|
test_shader_hlsl(stats, (shader_dir, relpath), update, keep, opt)
|
||||||
else:
|
else:
|
||||||
test_shader(stats, (shader_dir, relpath), update, keep)
|
test_shader(stats, (shader_dir, relpath), update, keep, opt)
|
||||||
|
|
||||||
def test_shaders(shader_dir, update, malisc, keep, backend):
|
def test_shaders(shader_dir, update, malisc, keep, opt, backend):
|
||||||
if malisc:
|
if malisc:
|
||||||
with open('stats.csv', 'w') as stats:
|
with open('stats.csv', 'w') as stats:
|
||||||
print('Shader,OrigRegs,OrigUniRegs,OrigALUShort,OrigLSShort,OrigTEXShort,OrigALULong,OrigLSLong,OrigTEXLong,CrossRegs,CrossUniRegs,CrossALUShort,CrossLSShort,CrossTEXShort,CrossALULong,CrossLSLong,CrossTEXLong', file = stats)
|
print('Shader,OrigRegs,OrigUniRegs,OrigALUShort,OrigLSShort,OrigTEXShort,OrigALULong,OrigLSLong,OrigTEXLong,CrossRegs,CrossUniRegs,CrossALUShort,CrossLSShort,CrossTEXShort,CrossALULong,CrossLSLong,CrossTEXLong', file = stats)
|
||||||
test_shaders_helper(stats, shader_dir, update, malisc, keep, backend)
|
test_shaders_helper(stats, shader_dir, update, malisc, keep, backend)
|
||||||
else:
|
else:
|
||||||
test_shaders_helper(None, shader_dir, update, malisc, keep, backend)
|
test_shaders_helper(None, shader_dir, update, malisc, keep, opt, backend)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description = 'Script for regression testing.')
|
parser = argparse.ArgumentParser(description = 'Script for regression testing.')
|
||||||
@ -370,6 +379,9 @@ def main():
|
|||||||
parser.add_argument('--force-no-external-validation',
|
parser.add_argument('--force-no-external-validation',
|
||||||
action = 'store_true',
|
action = 'store_true',
|
||||||
help = 'Disable all external validation.')
|
help = 'Disable all external validation.')
|
||||||
|
parser.add_argument('--opt',
|
||||||
|
action = 'store_true',
|
||||||
|
help = 'Run SPIRV-Tools optimization passes as well.')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if not args.folder:
|
if not args.folder:
|
||||||
@ -382,7 +394,7 @@ def main():
|
|||||||
global force_no_external_validation
|
global force_no_external_validation
|
||||||
force_no_external_validation = args.force_no_external_validation
|
force_no_external_validation = args.force_no_external_validation
|
||||||
|
|
||||||
test_shaders(args.folder, args.update, args.malisc, args.keep, 'msl' if (args.msl or args.metal) else ('hlsl' if args.hlsl else 'glsl'))
|
test_shaders(args.folder, args.update, args.malisc, args.keep, args.opt, 'msl' if (args.msl or args.metal) else ('hlsl' if args.hlsl else 'glsl'))
|
||||||
if args.malisc:
|
if args.malisc:
|
||||||
print('Stats in stats.csv!')
|
print('Stats in stats.csv!')
|
||||||
print('Tests completed!')
|
print('Tests completed!')
|
||||||
|
Loading…
Reference in New Issue
Block a user