106 lines
3.6 KiB
Python
106 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Slang Compiler - Command Line Interface
|
|
命令行接口
|
|
"""
|
|
|
|
import argparse
|
|
import os
|
|
|
|
from compiler import SlangCompiler
|
|
from global_vars import *
|
|
|
|
def do_compile_shader(input_file, includes, output_dir):
|
|
global_vars.source_file = input_file
|
|
global_vars.source_file_name = os.path.splitext(os.path.basename(input_file))[0]
|
|
global_vars.source_path = os.path.dirname(input_file)
|
|
global_vars.output_dir = output_dir or global_vars.source_path
|
|
|
|
output_file = os.path.join(global_vars.output_dir, f"{global_vars.source_file_name}.shader.h")
|
|
# 判断时间
|
|
if os.path.exists(output_file):
|
|
output_mtime = os.path.getmtime(output_file)
|
|
input_mtime = os.path.getmtime(input_file)
|
|
if input_mtime <= output_mtime:
|
|
print(f"Output file {output_file} is up-to-date. Skipping compilation.")
|
|
return
|
|
|
|
|
|
shader_infos = ShaderInfos(
|
|
stages={}
|
|
)
|
|
|
|
# 仅保留路径部分
|
|
include_dirs = [
|
|
global_vars.source_path,
|
|
]
|
|
include_dirs.extend(includes)
|
|
global_vars.include_dirs = include_dirs
|
|
|
|
# 创建编译器实例
|
|
compiler = SlangCompiler()
|
|
|
|
# 解析着色器
|
|
print(f"**Parsing** {input_file}...")
|
|
shaders = compiler.parse_slang_shader()
|
|
if not shaders:
|
|
return
|
|
for shader_info in shaders:
|
|
shader_infos.add_shader_info(shader_info)
|
|
|
|
binding_output_file_pathname = os.path.abspath(global_vars.output_dir)
|
|
binding_output_file_pathname = os.path.join(binding_output_file_pathname,
|
|
f"{global_vars.source_file_name}.shader.h")
|
|
|
|
# 生成绑定代码
|
|
print(f"\n**Generating** binding code to {binding_output_file_pathname}...")
|
|
compiler.generate_binding_functions(shader_infos, binding_output_file_pathname)
|
|
print("**Done!**")
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description='SDL3 GPU Slang Compiler')
|
|
|
|
parser.add_argument('-t', '--target', choices=['glsl', 'dxbc', 'msl'],
|
|
required=True, help='Target shader format')
|
|
parser.add_argument('-o', '--output-dir', help='Output path for binding code')
|
|
parser.add_argument('-i', '--include-dir', help='Include path for slang shader')
|
|
parser.add_argument('-d', '--debug', action='store_true', help='Enable debug mode')
|
|
parser.add_argument('-l', '--shader-list', help='List of shaders to compile (comma-separated)')
|
|
|
|
args = parser.parse_args()
|
|
if not args.output_dir:
|
|
output_path = None
|
|
else:
|
|
output_path = os.path.abspath(args.output_dir)
|
|
global_vars.target = TargetFormat(args.target)
|
|
global_vars.debug = args.debug
|
|
|
|
includes = []
|
|
if args.include_dir:
|
|
includes = [os.path.abspath(args.include_dir)]
|
|
|
|
# 获取编译文件的绝对路径
|
|
shader_list = os.path.abspath(args.shader_list)
|
|
with open(shader_list, 'r') as f:
|
|
shader_dirs = [line.strip() for line in f if line.strip()]
|
|
if not shader_dirs:
|
|
print("Shader list is empty.")
|
|
return
|
|
|
|
for shader_dir in shader_dirs:
|
|
if not os.path.exists(shader_dir):
|
|
print(f"Shader directory {shader_dir} does not exist.")
|
|
continue
|
|
# 获取目录下所有的.slang文件
|
|
slang_files = [f for f in os.listdir(shader_dir) if f.endswith('.slang')]
|
|
if not slang_files:
|
|
print(f"No .slang files found in {shader_dir}.")
|
|
continue
|
|
for slang_file in slang_files:
|
|
input_path = os.path.join(shader_dir, slang_file)
|
|
do_compile_shader(input_path, includes, output_path)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main() |