Adding xb genspirv to do glsl->.h.

This commit is contained in:
Ben Vanik
2016-02-20 16:24:42 -08:00
parent 5759f82276
commit 769c58a9b2
12 changed files with 310 additions and 11 deletions

View File

@@ -396,6 +396,7 @@ def discover_commands(subparsers):
'pull': PullCommand(subparsers),
'premake': PremakeCommand(subparsers),
'build': BuildCommand(subparsers),
'genspirv': GenSpirvCommand(subparsers),
'gentests': GenTestsCommand(subparsers),
'test': TestCommand(subparsers),
'gputest': GpuTestCommand(subparsers),
@@ -623,6 +624,103 @@ class BuildCommand(BaseBuildCommand):
return result
class GenSpirvCommand(Command):
"""'genspirv' command."""
def __init__(self, subparsers, *args, **kwargs):
super(GenSpirvCommand, self).__init__(
subparsers,
name='genspirv',
help_short='Generates SPIR-V binaries and header files.',
help_long='''
Generates the .spv/.h binaries under src/xenia/*/vulkan/shaders/bin/).
Run after modifying any .vert/.geom/.frag files.
''',
*args, **kwargs)
def execute(self, args, pass_args, cwd):
print('Generating SPIR-V binaries...')
print('')
# TODO(benvanik): actually find vulkan SDK. Env var? etc?
vulkan_sdk_path = 'C:\\VulkanSDK\\1.0.3.1'
vulkan_bin_path = os.path.join(vulkan_sdk_path, 'bin')
glslang = os.path.join(vulkan_bin_path, 'glslangValidator')
spirv_dis = os.path.join(vulkan_bin_path, 'spirv-dis')
spirv_remap = os.path.join(vulkan_bin_path, 'spirv-remap')
# Ensure we have the tools.
if not os.path.exists(vulkan_sdk_path):
print('ERROR: could not find the Vulkan SDK')
return 1
elif not has_bin(glslang):
print('ERROR: could not find glslangValidator')
return 1
elif not has_bin(spirv_dis):
print('ERROR: could not find spirv-dis')
return 1
elif not has_bin(spirv_remap):
print('ERROR: could not find spirv-remap')
return 1
src_files = [os.path.join(root, name)
for root, dirs, files in os.walk('src')
for name in files
if (name.endswith('.vert') or name.endswith('.geom') or
name.endswith('.frag'))]
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).replace('.', '_')
bin_path = os.path.join(os.path.dirname(src_file), 'bin')
spv_file = os.path.join(bin_path, identifier) + '.spv'
txt_file = os.path.join(bin_path, identifier) + '.txt'
h_file = os.path.join(bin_path, identifier) + '.h'
# GLSL source -> .spv binary
shell_call([
glslang,
'-V', src_file,
'-o', spv_file,
])
# Disassemble binary into human-readable text.
shell_call([
spirv_dis,
'-o', txt_file,
spv_file,
])
# TODO(benvanik): remap?
# bin2c so we get a header file we can compile in.
with open(h_file, 'wb') as out_file:
out_file.write('// generated from `xb genspirv`\n')
out_file.write('// source: %s\n' % os.path.basename(src_file))
out_file.write('const uint8_t %s[] = {' % (identifier))
with open(spv_file, 'rb') as in_file:
index = 0
c = in_file.read(1)
while c != '':
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 SPIR-V files.')
return 1
return 0
class TestCommand(BaseBuildCommand):
"""'test' command."""