Backlog/tools/scripts/cookShaders.py

114 lines
3.4 KiB
Python

#!/user/bin/env python3
# invokes shadercross
# and builds shaders for samples
import os
import subprocess
from sys import platform
origDir = os.path.abspath(os.path.dirname(__file__))
repoRoot = os.path.abspath(os.path.join(origDir, "../../"))
engineRoot = os.path.abspath(os.path.join(repoRoot, 'engine'))
libRoot = os.path.abspath(os.path.join(repoRoot, 'lib'))
# a little explanation on how we find the content dir
# 1. check the path we ran this from, if there is a folder called content/ use that.
# 2. if not, walk up the dir from the current dir until we encounter
# contentDir.txt
# then use the relative path from that
contentDir = os.path.abspath(os.path.join('.', 'content/'))
lastPath = None
if not os.path.isdir(contentDir):
newPath = os.path.abspath('.')
while newPath != lastPath:
dirTxtPath = os.path.join(newPath, 'content.txt')
if os.path.exists(dirTxtPath):
print(dirTxtPath)
with open(dirTxtPath) as f:
relPath = f.read().strip()
contentDir = os.path.abspath(os.path.join(newPath, relPath))
break
newPath = os.path.abspath(os.path.join('../'))
lastPath = newPath
print("content target dir: ", contentDir)
shadercrossDir = os.path.join(libRoot, 'sdl3/shadercross/bin')
if platform == "linux" or platform == "linux2":
shadercrossDir = os.path.join(shadercrossDir, 'linux')
elif platform == "darwin":
shadercrossDir = os.path.join(shadercrossDir, 'osx')
elif platform == "win32":
shadercrossDir = os.path.join(shadercrossDir, 'win64')
shadercross = os.path.join(shadercrossDir, 'shadercross')
def discoverShaders():
rv = []
itemlist = os.listdir(engineRoot)
for x in itemlist:
modRoot = os.path.abspath(os.path.join(engineRoot, x))
if os.path.isdir(modRoot):
shaderRoot = os.path.abspath(os.path.join(modRoot, 'shaders/'))
if os.path.isdir(os.path.join(modRoot, 'shaders/')):
for x in os.listdir(shaderRoot):
if x.endswith(".hlsl"):
rv.append(os.path.abspath(os.path.join(shaderRoot, x)))
return rv
def cookList(inputFiles):
# general cooking flow I think for shaders is
# they will go under
cookedRoot = os.path.join(contentDir, '_shaders')
# we cook into 3 formats
# spirv
# msl
# dxil
outputFormats = [
('dxil', []),
('spv', []),
('msl', []),
]
spvs = []
for fmt in outputFormats:
outdir = os.path.join(cookedRoot, fmt[0])
for f in inputFiles:
basefile = f[:-5]
outfile = os.path.abspath(os.path.join(outdir, os.path.basename(basefile) + '.' + fmt[0] ))
os.makedirs(os.path.dirname(outfile), exist_ok=True)
cmd = [shadercross, f] + fmt[1] + [ '-o', outfile ]
if 'spv' == fmt[0]:
spvs.append((outfile, os.path.dirname(f)))
print(cmd)
subprocess.run(cmd)
# run spirv-cross and generate .json files
for f in spvs:
basefile = f[0][:-4]
outfile = os.path.join(f[1], os.path.basename(basefile) + '.json' )
os.makedirs(os.path.dirname(outfile), exist_ok=True)
assert os.path.getsize(f[0]) > 1
cmd = ['spirv-cross', f[0], '--reflect', '--output', outfile ]
print(cmd)
subprocess.run(cmd)
if __name__ == '__main__':
inputFiles = discoverShaders()
print(inputFiles)
cookList(inputFiles)