blob: cb91db092c6bc98ac93bc0ddcd2444ecebdf5415 [file] [log] [blame]
# Emscripten WebGPU port with optional Wagyu extensions
import os
import zlib
from typing import Dict, Optional
OPTIONS = {
'wagyu': "Enable Wagyu extensions (default: false)",
}
_VALID_OPTION_VALUES = {
'wagyu': {'true', 'false'},
}
_opts: Dict[str, Optional[str]] = {
'wagyu': 'false',
}
def _get_base_dir():
return os.path.dirname(os.path.realpath(__file__))
def _get_include_dir():
return os.path.join(_get_base_dir(), 'include')
def _get_src_dir():
return os.path.join(_get_base_dir(), 'src')
def _get_srcs():
return [ _get_src_dir() + '/webgpu.c' ]
def _recurse_dir(path):
for (dirpath, dirnames, filenames) in os.walk(path):
for filename in filenames:
yield os.path.join(dirpath, filename)
def _get_build_files():
return sorted([
__file__,
*_get_srcs(),
*_recurse_dir(_get_include_dir()),
])
# compiler
def _check_option(option, value, error_handler):
if value not in _VALID_OPTION_VALUES[option]:
error_handler(
f'[{option}] can be {list(_VALID_OPTION_VALUES[option])}, got [{value}]'
)
return value
def handle_options(options, error_handler):
for option, value in options.items():
value = value.lower()
_opts[option] = _check_option(option, value, error_handler)
def process_args(ports):
args = ['-isystem', _get_include_dir()]
return args
# linker
def _get_flags(settings):
lib_name_suffix = ''
flags = []
return (lib_name_suffix, flags)
def _get_name(settings):
hash_value = 0
def add(x):
nonlocal hash_value
hash_value = zlib.adler32(x, hash_value)
build_files = _get_build_files()
for filename in build_files:
add(open(filename, 'rb').read())
(lib_name_suffix, _) = _get_flags(settings)
return f'libwebgpu-{hash_value:08x}{lib_name_suffix}.a'
def clear(ports, settings, shared):
shared.cache.erase_lib(_get_name(settings))
def get(ports, settings, shared):
if settings.allowed_settings:
return []
def create(final):
includes = [_get_include_dir()]
(_, flags) = _get_flags(settings)
flags += []
ports.build_port(_get_src_dir(), final, 'webgpu', includes=includes, flags=flags, srcs=_get_srcs())
lib_name = _get_name(settings)
return [shared.cache.get_lib(lib_name, create, what='port')]
def linker_setup(ports, settings):
if settings.USE_WEBGPU:
raise Exception('webgpu-port is not compatible with deprecated Emscripten USE_WEBGPU option')
src_dir = _get_src_dir()
settings.JS_LIBRARIES += [ os.path.join(src_dir, 'library_webgpu_stubs.js') ]
# Ensure the function gets exported
settings.EXPORTED_FUNCTIONS += ['_wgpuWagyuGetCompiledVersion']
if _opts['wagyu'] == 'true':
settings.JS_LIBRARIES += [ os.path.join(src_dir, 'library_webgpu_wagyu_stubs.js') ]