Created
April 3, 2025 09:23
-
-
Save alvinhochun/426ed7f450702c103139f5986635e2a2 to your computer and use it in GitHub Desktop.
Picasso wrapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import pathlib | |
import re | |
import subprocess | |
from typing import Optional, List | |
def picasso( | |
files: List[str], out: str, header: Optional[str] = None, no_nop: bool = False | |
) -> None: | |
cmd = [ | |
"picasso", | |
"--out=" + out, | |
*(["--header" + header] if header else []), | |
*(["--no-nop"] if no_nop else []), | |
*files, | |
] | |
result = subprocess.run(cmd) | |
result.check_returncode() | |
IDENTIFIER_FILTER_REGEX = re.compile(r"[^A-Za-z0-9]+") | |
def filename_to_identifier(file: str) -> str: | |
name = pathlib.Path(file).stem | |
return IDENTIFIER_FILTER_REGEX.sub("_", name) | |
DVLE_EMITTING_DIRECTIVES = set( | |
[ | |
# "uniform", | |
"fvec", | |
"ivec", | |
"bool", | |
# "const", | |
"constf", | |
"consti", | |
"constfa", | |
"in", | |
"out", | |
"entry", | |
# "nodvle", | |
"gsh", | |
# "setfi", | |
"setf", | |
"seti", | |
"setb", | |
] | |
) | |
NON_DVLE_DIRECTIVES = set( | |
[ | |
"proc", | |
"else", | |
"end", | |
"alias", | |
] | |
) | |
DIRECTIVE_REGEX = re.compile(r"^\s*\.(\w+)") | |
def is_program_emit_dvle(path: str) -> bool: | |
has_dvle_directive = False | |
with open(path, "r", encoding="utf8") as file: | |
while line := file.readline(): | |
line = line.strip() | |
if line.startswith(";"): | |
# comment | |
continue | |
if match := DIRECTIVE_REGEX.match(line): | |
directive = match[1] | |
if directive == "nodvle": | |
return False | |
if directive in DVLE_EMITTING_DIRECTIVES: | |
has_dvle_directive = True | |
elif directive not in NON_DVLE_DIRECTIVES: | |
raise RuntimeError( | |
f"Unexpected directive '.{directive}' in shader file '{path}'" | |
) | |
return has_dvle_directive | |
def main() -> None: | |
parser = argparse.ArgumentParser( | |
prog="picasso_wrapper", | |
description="Wrapper for picasso that generates an additional header (ends in '.dvle.h') with enum constants for indexing the DVLE of each program.", | |
add_help=False, | |
) | |
parser.add_argument("-o", "--out", required=True) | |
parser.add_argument("-h", "--header") | |
parser.add_argument("-n", "--no-nop", action="store_true") | |
parser.add_argument("files", nargs="+") | |
args = parser.parse_args() | |
# if args.help: | |
names = [filename_to_identifier(f).upper() for f in args.files] | |
unique_names = set() | |
for name, path in zip(names, args.files): | |
if name in unique_names: | |
raise argparse.ArgumentError( | |
None, f"File '{path}' produces duplicate constant name {name}." | |
) | |
unique_names.add(name) | |
picasso(args.files, args.out, args.header, args.no_nop) | |
bin_name = filename_to_identifier(args.out).upper() | |
file_content = "" | |
file_content += f"/* Generated by {pathlib.Path(__file__).name} - do not edit */\n" | |
file_content += "#pragma once\n\n" | |
file_content += f"/** DVLE indices for the programs in '{args.out}' */\n" | |
file_content += f"enum {bin_name}_DVLE_enum {{\n" | |
for name, path in zip(names, args.files): | |
if is_program_emit_dvle(path): | |
file_content += f"\t{bin_name}_DVLE_{name}, /**< {path} */\n" | |
else: | |
file_content += f"\t/* '{path}' does not emit a DVLE entry */\n" | |
file_content += "};\n" | |
old_content = "" | |
out_file = pathlib.Path(args.out).with_suffix(".dvle.h") | |
try: | |
with open(out_file, "r", encoding="utf8", newline="\n") as file: | |
old_content = file.read() | |
except: | |
pass | |
# Skip writing file if nothing's changed (avoid unnecessary rebuilds) | |
if old_content == file_content: | |
return | |
with open(out_file, "w", encoding="utf8", newline="\n") as file: | |
file.write(file_content) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment