修复dxil没有签名的问题

This commit is contained in:
daiqingshuang
2025-06-11 14:32:56 +08:00
parent 181e56f6b3
commit e4c9d42a60
5 changed files with 75 additions and 13 deletions

View File

@@ -12,8 +12,10 @@ from typing import List, Dict
from binding_manager import BindingManager
from code_generator import CodeGenerator
from compiler_cmd import make_cmd
from exe_finder import dxc_path
from global_vars import global_vars
from shader_parser import ShaderParser
from shader_types import ShaderInfo, TargetFormat
from shader_types import ShaderInfo, TargetFormat, ShaderStage
class SDL3GPUSlangCompiler:
@@ -47,23 +49,62 @@ class SDL3GPUSlangCompiler:
try:
# 编译着色器
cmd = make_cmd(tmp_path, target, shader_info.stage, shader_info.entry_point, output_path)
if target == TargetFormat.DXIL:
cmd = make_cmd(tmp_path, TargetFormat.HLSL_DX12, shader_info.stage, shader_info.entry_point, output_path)
else:
cmd = make_cmd(tmp_path, target, shader_info.stage, shader_info.entry_point, output_path)
print(f"Compiling shader with command: {' '.join(cmd)}")
shader_file = output_path
subprocess.run(cmd, check=True)
print(f"Shader compiled successfully")
# 如果目标是DXIL则需要签名
if global_vars.target == TargetFormat.DXIL:
with tempfile.NamedTemporaryFile(mode='w', suffix='.cso', delete=False, encoding='utf8') as tmp:
signed_shader = tmp.name
self._compile_dxil(shader_info, shader_file, signed_shader)
shader_file = signed_shader
# 生成绑定信息
binding_info = self.binding_manager.generate_binding_info(shader_info, target, output_path)
binding_info = self.binding_manager.generate_binding_info(shader_info, target, shader_file)
return binding_info
finally:
# 清理临时文件
os.unlink(tmp_path)
os.unlink(signed_shader)
os.unlink(output_path)
def generate_binding_functions(self, binding_infos: List[Dict], output_path: str):
"""生成C/C++绑定函数"""
self.code_generator.generate_binding_functions(binding_infos, output_path)
def _compile_dxil(self, shader_info: ShaderInfo, input_file: str, output_file: str):
"""编译DXIL着色器"""
# 根据stage选择不同的-T参数
if shader_info.stage == ShaderStage.VERTEX:
t = 'vs_6_6'
elif shader_info.stage == ShaderStage.FRAGMENT:
t = 'ps_6_6'
elif shader_info.stage == ShaderStage.COMPUTE:
t = 'cs_6_6'
else:
raise ValueError(f"Unsupported shader stage: {shader_info.stage}")
dxc_cmd = [
dxc_path,
'-T', t,
'-E', shader_info.entry_point,
'-Fo', output_file,
input_file
]
result = subprocess.run(dxc_cmd, check=True)
if result.stdout:
print(f"Stdout: {result.stdout}")
if result.stderr is None:
print(f"Signed shader compiled successfully")
else:
raise RuntimeError(f"Failed to compile DXIL shader: {result.stderr.decode('utf-8')}")

View File

@@ -2,10 +2,9 @@
"""
SDL3_GPU Slang Compiler - Command Generation
"""
from exe_finder import slangc_path
from global_vars import global_vars
from shader_types import TargetFormat, ShaderStage
from slangc_finder import slangc_path
def make_cmd(source_file: str, target: TargetFormat, stage: ShaderStage, entry_point: str, output_path: str):
"""生成编译命令"""
@@ -13,7 +12,9 @@ def make_cmd(source_file: str, target: TargetFormat, stage: ShaderStage, entry_p
TargetFormat.SPIRV: 'spirv',
TargetFormat.DXIL: 'dxil',
TargetFormat.DXBC: 'dxbc',
TargetFormat.MSL: 'metal'
TargetFormat.MSL: 'metal',
TargetFormat.HLSL_DX12: 'hlsl',
TargetFormat.HLSL_DX11: 'hlsl',
}[target]
stage_flag = {
@@ -35,9 +36,9 @@ def make_cmd(source_file: str, target: TargetFormat, stage: ShaderStage, entry_p
for include_path in global_vars.include_dirs:
cmd.extend(['-I', include_path])
if target == TargetFormat.DXIL:
cmd.extend(['-profile', 'sm_6_0'])
elif target == TargetFormat.DXBC:
if target == TargetFormat.DXIL or target == TargetFormat.HLSL_DX12:
cmd.extend(['-profile', 'sm_6_6'])
elif target == TargetFormat.DXBC or target == TargetFormat.HLSL_DX11:
cmd.extend(['-profile', 'sm_5_1'])
return cmd

View File

@@ -90,3 +90,18 @@ compiler.slangc_path = r'C:\\path\\to\\slangc.exe'
""")
slangc_path = SlangcFinder.find_slangc()
# 如果是windows系统检查DXC编译器
if os.name == 'nt':
# 查找dxcapsviewer.exe路径, 避免查找dxc时找到Vulkan SDK的dxc.exe
dxcapsviewer_path = shutil.which('dxcapsviewer.exe')
if dxcapsviewer_path:
# dxc.exe一般与dxcapsviewer.exe在同一目录
dxc_path = os.path.join(os.path.dirname(dxcapsviewer_path), 'dxc.exe')
# 检查dxc.exe是否存在
if not os.path.isfile(dxc_path):
print("Warning: dxc.exe not found in the same directory as dxcapsviewer.exe.")
dxc_path = None
else:
# 如果没有找到dxcapsviewer.exe尝试直接查找dxc.exe
dxc_path = shutil.which('dxc.exe')

View File

@@ -30,7 +30,10 @@ def main():
global_vars.source_file_name = os.path.splitext(os.path.basename(input_path))[0]
global_vars.source_path = os.path.dirname(input_path)
global_vars.output_dir = os.path.abspath(args.output_dir)
global_vars.target = target = TargetFormat(args.target)
global_vars.target = TargetFormat(args.target)
# if global_vars.target == TargetFormat.DXIL:
# global_vars.target = TargetFormat.DXBC
# print("Warning: DXIL target is not supported, using DXBC instead.")
# 仅保留路径部分
include_dirs = [
@@ -54,7 +57,7 @@ def main():
for name, shader_info in shaders.items():
print(f"**Compiling** {name}...")
binding_info = compiler.compile_shader(shader_info, target)
binding_info = compiler.compile_shader(shader_info, global_vars.target)
binding_infos.append(binding_info)
binding_output_file_pathname = os.path.abspath(args.output_dir)

View File

@@ -26,6 +26,8 @@ class TargetFormat(Enum):
DXIL = "dxil"
DXBC = "dxbc"
MSL = "msl"
HLSL_DX12 = "hlsl"
HLSL_DX11 = "hlsl"
@dataclass
class Resource: