Adding xb genspirv to do glsl->.h.
This commit is contained in:
98
xenia-build
98
xenia-build
@@ -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."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user