MSL: Support using the offline Metal Windows toolchain for validation.

This commit is contained in:
Hans-Kristian Arntzen 2023-11-28 15:53:27 +01:00
parent e33670e794
commit a326b3ea3b

View File

@ -29,6 +29,7 @@ import codecs
import json
import multiprocessing
import errno
import platform
from functools import partial
class Paths():
@ -100,8 +101,14 @@ def get_shader_stats(shader):
def print_msl_compiler_version():
try:
subprocess.check_call(['xcrun', '--sdk', 'iphoneos', 'metal', '--version'])
print('... are the Metal compiler characteristics.\n') # display after so xcrun FNF is silent
if platform.system() == 'Darwin':
subprocess.check_call(['xcrun', '--sdk', 'iphoneos', 'metal', '--version'])
print('... are the Metal compiler characteristics.\n') # display after so xcrun FNF is silent
else:
# Use Metal Windows toolkit to test on Linux (Wine) and Windows.
print('Running on non-macOS system.')
subprocess.check_call(['metal', '-x', 'metal', '--version'])
except OSError as e:
if (e.errno != errno.ENOENT): # Ignore xcrun not found error
raise
@ -111,9 +118,13 @@ def print_msl_compiler_version():
def msl_compiler_supports_version(version):
try:
subprocess.check_call(['xcrun', '--sdk', 'macosx', 'metal', '-x', 'metal', version, '-'],
stdin = subprocess.DEVNULL, stdout = subprocess.DEVNULL, stderr = subprocess.DEVNULL)
print('Current SDK supports MSL {0}. Enabling validation for MSL {0} shaders.'.format(version))
if platform.system() == 'Darwin':
subprocess.check_call(['xcrun', '--sdk', 'macosx', 'metal', '-x', 'metal', version, '-'],
stdin = subprocess.DEVNULL, stdout = subprocess.DEVNULL, stderr = subprocess.DEVNULL)
print('Current SDK supports MSL {0}. Enabling validation for MSL {0} shaders.'.format(version))
else:
print('Running on {}, assuming {} is supported.'.format(platform.system(), version))
# If we're running on non-macOS system, assume it's supported.
return True
except OSError as e:
print('Failed to check if MSL {} is not supported. It probably is not.'.format(version))
@ -180,18 +191,30 @@ def path_to_msl_standard_cli(shader):
else:
return '10200'
ignore_win_metal_tool = False
def validate_shader_msl(shader, opt):
msl_path = reference_path(shader[0], shader[1], opt)
global ignore_win_metal_tool
try:
if '.ios.' in msl_path:
msl_os = 'iphoneos'
else:
msl_os = 'macosx'
subprocess.check_call(['xcrun', '--sdk', msl_os, 'metal', '-x', 'metal', path_to_msl_standard(msl_path), '-Werror', '-Wno-unused-variable', msl_path])
print('Compiled Metal shader: ' + msl_path) # display after so xcrun FNF is silent
if platform.system() == 'Darwin':
subprocess.check_call(['xcrun', '--sdk', msl_os, 'metal', '-x', 'metal', path_to_msl_standard(msl_path), '-Werror', '-Wno-unused-variable', msl_path])
print('Compiled Metal shader: ' + msl_path) # display after so xcrun FNF is silent
elif not ignore_win_metal_tool:
# Use Metal Windows toolkit to test on Linux (Wine) and Windows. Running offline tool on Linux gets weird.
# Normal winepath doesn't work, it must be Z:/abspath *exactly* for some bizarre reason.
target_path = msl_path if platform.system == 'Windows' else ('Z:' + os.path.abspath(msl_path))
subprocess.check_call(['metal', '-x', 'metal', path_to_msl_standard(msl_path), '-Werror', '-Wno-unused-variable', target_path])
except OSError as oe:
if (oe.errno != errno.ENOENT): # Ignore xcrun not found error
if (oe.errno != errno.ENOENT): # Ignore xcrun or metal not found error
raise
print('metal toolkit does not exist, ignoring further attempts to use it.')
ignore_win_metal_tool = True
except subprocess.CalledProcessError:
print('Error compiling Metal shader: ' + msl_path)
raise RuntimeError('Failed to compile Metal shader')
@ -882,10 +905,20 @@ def test_shader_msl(stats, shader, args, paths):
# executable from Xcode using args: `--msl --entry main --output msl_path spirv_path`.
# print('SPRIV shader: ' + spirv)
shader_is_msl22 = 'msl22' in joined_path
shader_is_msl23 = 'msl23' in joined_path
shader_is_msl24 = 'msl24' in joined_path
skip_validation = (shader_is_msl22 and (not args.msl22)) or (shader_is_msl23 and (not args.msl23)) or (shader_is_msl24 and (not args.msl24))
shader_is_msl22 = '.msl22.' in joined_path
shader_is_msl23 = '.msl23.' in joined_path
shader_is_msl24 = '.msl24.' in joined_path
shader_is_msl30 = '.msl3.' in joined_path
shader_is_msl31 = '.msl31.' in joined_path
skip_validation = (shader_is_msl22 and (not args.msl22)) or \
(shader_is_msl23 and (not args.msl23)) or \
(shader_is_msl24 and (not args.msl24)) or \
(shader_is_msl30 and (not args.msl30)) or \
(shader_is_msl31 and (not args.msl31))
if skip_validation:
print('Skipping validation for {} due to lack of toolchain support.'.format(joined_path))
if '.invalid.' in joined_path:
skip_validation = True