#!/usr/bin/env python3 """embed_spirv.py — compile GLSL shaders to SPIR-V (glslc) and emit one C header. Each input shader (*.vert / *.frag) is compiled to SPIR-V and written into the output header as a `static const uint32_t spv__[]` array plus its byte length, so the Vulkan backend can create shader modules with zero runtime file dependencies (keeps the self-contained exe). Stage is inferred from the file extension. Usage: embed_spirv.py --glslc --out shader1.vert shader2.frag ... """ import argparse, os, subprocess, sys, struct STAGE = {".vert": "vert", ".frag": "frag", ".comp": "comp"} def ident(path): base = os.path.basename(path) name, ext = os.path.splitext(base) return "%s_%s" % (name.replace("-", "_"), STAGE[ext]), STAGE[ext] def main(): ap = argparse.ArgumentParser() ap.add_argument("--glslc", required=True) ap.add_argument("--out", required=True) ap.add_argument("shaders", nargs="+") a = ap.parse_args() os.makedirs(os.path.dirname(a.out), exist_ok=True) out = ["/* Auto-generated by embed_spirv.py — do not edit. */", "#ifndef PSX_VK_SHADERS_SPV_H", "#define PSX_VK_SHADERS_SPV_H", "#include ", ""] for sh in a.shaders: name, stage = ident(sh) spv = sh + ".spv" cmd = [a.glslc, "--target-env=vulkan1.1", "-O", sh, "-o", spv] r = subprocess.run(cmd, capture_output=True, text=True) if r.returncode != 0: sys.stderr.write("glslc failed for %s:\n%s\n" % (sh, r.stderr)) return 1 with open(spv, "rb") as f: data = f.read() os.remove(spv) if len(data) % 4 != 0: sys.stderr.write("SPIR-V for %s not 4-byte aligned\n" % sh) return 1 words = struct.unpack("<%dI" % (len(data) // 4), data) out.append("static const uint32_t spv_%s[] = {" % name) line = " " for w in words: tok = "0x%08x," % w if len(line) + len(tok) > 96: out.append(line); line = " " line += tok if line.strip(): out.append(line) out.append("};") out.append("static const uint32_t spv_%s_size = sizeof(spv_%s);" % (name, name)) out.append("") out.append("#endif") with open(a.out, "w") as f: f.write("\n".join(out)) return 0 if __name__ == "__main__": sys.exit(main())