From 03da2929aae3a917ee3ab3a5d44b0ae9e136cfc6 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Wed, 18 Jul 2018 13:16:12 +0300 Subject: [PATCH] [D3D12] Add HLSL building to xenia-build --- src/xenia/ui/d3d12/shaders/immediate.vs.hlsl | 21 +++++ xenia-build | 88 ++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 src/xenia/ui/d3d12/shaders/immediate.vs.hlsl diff --git a/src/xenia/ui/d3d12/shaders/immediate.vs.hlsl b/src/xenia/ui/d3d12/shaders/immediate.vs.hlsl new file mode 100644 index 000000000..afc3f6d1b --- /dev/null +++ b/src/xenia/ui/d3d12/shaders/immediate.vs.hlsl @@ -0,0 +1,21 @@ +float2 scale : register(b0); + +struct vs_input { + float2 pos : POSITION; + float2 uv : TEXCOORD; + float4 color : COLOR; +}; + +struct vs_output { + float4 pos : SV_Position; + float2 uv : TEXCOORD0; + float4 color : TEXCOORD1; +}; + +vs_output main(vs_input input) { + vs_output output; + output.pos = float4(scale * input.pos, 0.0, 1.0); + output.uv = input.uv; + output.color = input.color; + return output; +} diff --git a/xenia-build b/xenia-build index 080d97d1b..44222de25 100755 --- a/xenia-build +++ b/xenia-build @@ -420,6 +420,7 @@ def discover_commands(subparsers): } if sys.platform == 'win32': commands['devenv'] = DevenvCommand(subparsers) + commands['buildhlsl'] = BuildHlslCommand(subparsers) return commands @@ -746,6 +747,93 @@ class GenSpirvCommand(Command): return 0 +class BuildHlslCommand(Command): + """'buildhlsl' command.""" + + def __init__(self, subparsers, *args, **kwargs): + super(BuildHlslCommand, self).__init__( + subparsers, + name='buildhlsl', + help_short='Generates Direct3D shader binaries and header files.', + help_long=''' + Generates the .cso/.h binaries under src/xenia/*/d3d12/shaders/bin/. + Run after modifying any .vs.hlsl/.ps.hlsl/.gs.hlsl/.cs.hlsl files. + ''', + *args, **kwargs) + + def execute(self, args, pass_args, cwd): + print('Building Direct3D shaders...') + print('') + + windows_sdk_bin_path = os.path.join(os.environ['ProgramFiles(x86)'], + 'Windows Kits/10/bin/x64') + fxc = os.path.join(windows_sdk_bin_path, 'fxc') + + # Ensure we have the tools. + if not os.path.exists(windows_sdk_bin_path): + print('ERROR: could not find Windows 10 SDK binaries') + return 1 + elif not has_bin(fxc): + print('ERROR: could not find fxc') + return 1 + + src_files = [os.path.join(root, name) + for root, dirs, files in os.walk('src') + for name in files + if (name.endswith('.vs.hlsl') or + name.endswith('.ps.hlsl') or + name.endswith('.gs.hlsl') or + name.endswith('.cs.hlsl'))] + + # TODO(Triang3l): Handle any_errors. + any_errors = False + for src_file in src_files: + print('- %s' % (src_file)) + src_name = os.path.splitext(os.path.basename(src_file))[0] + identifier = os.path.basename(src_file)[:-5].replace('.', '_') + + bin_path = os.path.join(os.path.dirname(src_file), 'bin') + if not os.path.exists(bin_path): + os.mkdir(bin_path) + cso_file = os.path.join(bin_path, identifier) + '.cso' + txt_file = os.path.join(bin_path, identifier) + '.txt' + h_file = os.path.join(bin_path, identifier) + '.h' + + # HLSL source -> .cso binary and DXBC disassembly. + shell_call([ + fxc, + '/nologo', + '/T', identifier[-2:] + '_5_0', + '/Fo', cso_file, + '/Fc', txt_file, + src_file, + ]) + + # bin2c so we get a header file we can compile in. + with open(h_file, 'w') as out_file: + out_file.write('// generated from `xb buildhlsl`\n') + out_file.write('// source: %s\n' % os.path.basename(src_file)) + out_file.write('const uint8_t %s[] = {' % (identifier)) + with open(cso_file, 'rb') as in_file: + index = 0 + c = in_file.read(1) + while len(c) != 0: + if index % 12 == 0: + out_file.write('\n ') + else: + out_file.write(' ') + index += 1 + out_file.write('0x%02X,' % ord(c)) + c = in_file.read(1) + out_file.write('\n};\n') + + if any_errors: + print('ERROR: failed to build one or more shaders.') + return 1 + + return 0 + + class TestCommand(BaseBuildCommand): """'test' command."""