Skip to content

Commit

Permalink
MSL: Support using the offline Metal Windows toolchain for validation.
Browse files Browse the repository at this point in the history
  • Loading branch information
HansKristian-Work committed Nov 29, 2023
1 parent e33670e commit a326b3e
Showing 1 changed file with 45 additions and 12 deletions.
57 changes: 45 additions & 12 deletions test_shaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import json
import multiprocessing
import errno
import platform
from functools import partial

class Paths():
Expand Down Expand Up @@ -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
Expand All @@ -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))
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit a326b3e

Please sign in to comment.