ADD: shader compile script
This commit is contained in:
@@ -1,9 +1,10 @@
|
|||||||
$COMMON = @("--target-env=vulkan1.3", "-O", "-g", "-Werror", "-I", "shaders")
|
param(
|
||||||
|
[ValidateSet("Debug", "Release", "RelWithDebInfo")]
|
||||||
|
[string]$Config = "RelWithDebInfo",
|
||||||
|
[string]$Python = "python"
|
||||||
|
)
|
||||||
|
|
||||||
Get-ChildItem -Path "shaders" -Include *.frag,*.vert,*.comp,*.geom,*.tesc,*.tese,*.mesh,*.task,*.rgen,*.rint,*.rahit,*.rchit,*.rmiss,*.rcall -Recurse |
|
$script_dir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||||
ForEach-Object {
|
$py = Join-Path $script_dir "compile_shaders.py"
|
||||||
$extra = @()
|
|
||||||
if ($_.Extension -eq ".mesh") { $extra += "-fshader-stage=mesh" }
|
& $Python $py --config $Config
|
||||||
elseif ($_.Extension -eq ".task") { $extra += "-fshader-stage=task" }
|
|
||||||
glslc $_.FullName @COMMON @extra -o "$($_.FullName).spv"
|
|
||||||
}
|
|
||||||
|
|||||||
145
compile_shaders.py
Normal file
145
compile_shaders.py
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import argparse, os, subprocess, sys
|
||||||
|
from pathlib import Path
|
||||||
|
from shutil import which
|
||||||
|
|
||||||
|
SHADER_EXTS = {
|
||||||
|
".frag", ".vert", ".comp", ".geom", ".tesc", ".tese",
|
||||||
|
".mesh", ".task",
|
||||||
|
".rgen", ".rint", ".rahit", ".rchit", ".rmiss", ".rcall",
|
||||||
|
}
|
||||||
|
|
||||||
|
PROFILE_FLAGS = {
|
||||||
|
"Debug": ["-g"],
|
||||||
|
"Release": ["-O"],
|
||||||
|
# Matches the old `compile_shaders.ps1` defaults (-O + -g).
|
||||||
|
"RelWithDebInfo": ["-O", "-g"],
|
||||||
|
}
|
||||||
|
|
||||||
|
STAGE_FLAGS_BY_EXT = {
|
||||||
|
".mesh": ["-fshader-stage=mesh"],
|
||||||
|
".task": ["-fshader-stage=task"],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def find_glslc(user_path):
|
||||||
|
if user_path:
|
||||||
|
return user_path
|
||||||
|
|
||||||
|
env_glslc = os.environ.get("GLSLC")
|
||||||
|
if env_glslc:
|
||||||
|
return env_glslc
|
||||||
|
|
||||||
|
vulkan_sdk = os.environ.get("VULKAN_SDK")
|
||||||
|
if vulkan_sdk:
|
||||||
|
sdk = Path(vulkan_sdk)
|
||||||
|
candidates = [
|
||||||
|
sdk / "Bin" / "glslc.exe",
|
||||||
|
sdk / "Bin" / "glslc",
|
||||||
|
sdk / "bin" / "glslc.exe",
|
||||||
|
sdk / "bin" / "glslc",
|
||||||
|
]
|
||||||
|
for c in candidates:
|
||||||
|
if c.exists():
|
||||||
|
return str(c)
|
||||||
|
|
||||||
|
for name in ("glslc", "glslc.exe"):
|
||||||
|
p = which(name)
|
||||||
|
if p:
|
||||||
|
return p
|
||||||
|
|
||||||
|
sys.exit(
|
||||||
|
"ERROR: `glslc` not found. Install the Vulkan SDK and ensure `glslc` is on PATH,\n"
|
||||||
|
" or set `VULKAN_SDK`, `GLSLC`, or pass `--glslc /path/to/glslc`."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
p = argparse.ArgumentParser(description="Compile GLSL shaders under shaders/ to .spv next to sources.")
|
||||||
|
cfg = p.add_mutually_exclusive_group()
|
||||||
|
cfg.add_argument("--debug", action="store_true", help="Debug profile (adds -g, no -O).")
|
||||||
|
cfg.add_argument("--release", action="store_true", help="Release profile (adds -O, no -g).")
|
||||||
|
p.add_argument(
|
||||||
|
"--config",
|
||||||
|
choices=list(PROFILE_FLAGS.keys()),
|
||||||
|
default="RelWithDebInfo",
|
||||||
|
help="Compilation profile (default: RelWithDebInfo).",
|
||||||
|
)
|
||||||
|
p.add_argument("--shader-dir", default="shaders", help="Shader source directory (default: shaders).")
|
||||||
|
p.add_argument("--glslc", default=None, help="Path to glslc (default: auto-detect).")
|
||||||
|
p.add_argument("--target-env", default="vulkan1.3", help="Vulkan target env for glslc (default: vulkan1.3).")
|
||||||
|
p.add_argument("--no-werror", action="store_true", help="Do not pass -Werror.")
|
||||||
|
p.add_argument("--quiet", action="store_true", help="Only print errors.")
|
||||||
|
return p.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def collect_sources(shader_dir: Path):
|
||||||
|
return sorted([p for p in shader_dir.rglob("*") if p.is_file() and p.suffix.lower() in SHADER_EXTS])
|
||||||
|
|
||||||
|
|
||||||
|
def compile_one(glslc: str, src: Path, shader_dir: Path, args) -> int:
|
||||||
|
out_path = src.parent / f"{src.name}.spv"
|
||||||
|
stage_flags = STAGE_FLAGS_BY_EXT.get(src.suffix.lower(), [])
|
||||||
|
|
||||||
|
cmd = [
|
||||||
|
glslc,
|
||||||
|
str(src),
|
||||||
|
f"--target-env={args.target_env}",
|
||||||
|
"-I", str(shader_dir),
|
||||||
|
*PROFILE_FLAGS[args.config],
|
||||||
|
*stage_flags,
|
||||||
|
]
|
||||||
|
if not args.no_werror:
|
||||||
|
cmd.append("-Werror")
|
||||||
|
cmd += ["-o", str(out_path)]
|
||||||
|
|
||||||
|
if not args.quiet:
|
||||||
|
print(subprocess.list2cmdline(cmd))
|
||||||
|
|
||||||
|
proc = subprocess.run(cmd, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
if proc.stdout and not args.quiet:
|
||||||
|
sys.stdout.write(proc.stdout)
|
||||||
|
if proc.returncode != 0:
|
||||||
|
if proc.stderr:
|
||||||
|
sys.stderr.write(proc.stderr)
|
||||||
|
elif proc.stderr and not args.quiet:
|
||||||
|
sys.stderr.write(proc.stderr)
|
||||||
|
return proc.returncode
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
args = parse_args()
|
||||||
|
|
||||||
|
if args.debug:
|
||||||
|
args.config = "Debug"
|
||||||
|
elif args.release:
|
||||||
|
args.config = "Release"
|
||||||
|
|
||||||
|
repo_root = Path(__file__).resolve().parent
|
||||||
|
shader_dir = (repo_root / args.shader_dir).resolve()
|
||||||
|
if not shader_dir.exists():
|
||||||
|
sys.stderr.write(f"ERROR: shader dir not found: {shader_dir}\n")
|
||||||
|
return 2
|
||||||
|
|
||||||
|
glslc = find_glslc(args.glslc)
|
||||||
|
|
||||||
|
sources = collect_sources(shader_dir)
|
||||||
|
if not sources:
|
||||||
|
if not args.quiet:
|
||||||
|
print(f"No shaders found under {shader_dir}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
failed = 0
|
||||||
|
for src in sources:
|
||||||
|
rc = compile_one(glslc, src, shader_dir, args)
|
||||||
|
if rc != 0:
|
||||||
|
failed += 1
|
||||||
|
|
||||||
|
if failed:
|
||||||
|
sys.stderr.write(f"ERROR: {failed} shader(s) failed to compile.\n")
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
@@ -23,7 +23,8 @@
|
|||||||
- Shaders
|
- Shaders
|
||||||
- CMake compiles GLSL via `glslangValidator` to SPIR‑V targeting Vulkan 1.2:
|
- CMake compiles GLSL via `glslangValidator` to SPIR‑V targeting Vulkan 1.2:
|
||||||
- Files under `shaders/*.vert|*.frag|*.comp` are rebuilt on `cmake --build`.
|
- Files under `shaders/*.vert|*.frag|*.comp` are rebuilt on `cmake --build`.
|
||||||
- Windows helper: `./compile_shaders.ps1` uses `glslc` with `--target-env=vulkan1.3` and supports additional stages (mesh/task/ray tracing).
|
- Helper: `./compile_shaders.py --config Debug|Release` uses `glslc` with `--target-env=vulkan1.3` and supports additional stages (mesh/task/ray tracing).
|
||||||
|
- Windows shim: `./compile_shaders.ps1 -Config Debug|Release` (calls the Python script).
|
||||||
- Ensure `glslangValidator`/`glslc` is on `PATH`. See `docs/SHADERS.md`.
|
- Ensure `glslangValidator`/`glslc` is on `PATH`. See `docs/SHADERS.md`.
|
||||||
|
|
||||||
- Windows SDK note
|
- Windows SDK note
|
||||||
@@ -41,4 +42,3 @@
|
|||||||
- Validation Layers
|
- Validation Layers
|
||||||
- Enabled in Debug (`kUseValidationLayers = true` in `src/core/config.h`).
|
- Enabled in Debug (`kUseValidationLayers = true` in `src/core/config.h`).
|
||||||
- Disable by building Release or toggling the flag during local experimentation.
|
- Disable by building Release or toggling the flag during local experimentation.
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,9 @@
|
|||||||
|
|
||||||
- Build integration
|
- Build integration
|
||||||
- CMake invokes `glslangValidator -V` for `*.vert`, `*.frag`, `*.comp` targeting Vulkan 1.2.
|
- CMake invokes `glslangValidator -V` for `*.vert`, `*.frag`, `*.comp` targeting Vulkan 1.2.
|
||||||
- Windows PowerShell helper `compile_shaders.ps1` uses `glslc` targeting Vulkan 1.3 and supports additional stages:
|
- Helper `compile_shaders.py` uses `glslc` targeting Vulkan 1.3 and supports additional stages:
|
||||||
- `.mesh` (`-fshader-stage=mesh`), `.task`, and ray tracing stages (`.rgen`, `.rmiss`, `.rchit`, `.rahit`, `.rint`, `.rcall`).
|
- `.mesh` (`-fshader-stage=mesh`), `.task`, and ray tracing stages (`.rgen`, `.rmiss`, `.rchit`, `.rahit`, `.rint`, `.rcall`).
|
||||||
|
- Windows shim: `compile_shaders.ps1 -Config Debug|Release|RelWithDebInfo`.
|
||||||
- Keep `glslangValidator`/`glslc` on `PATH` and ensure your Vulkan SDK is installed.
|
- Keep `glslangValidator`/`glslc` on `PATH` and ensure your Vulkan SDK is installed.
|
||||||
|
|
||||||
- Hot reload
|
- Hot reload
|
||||||
@@ -55,4 +56,3 @@ GLSL Includes
|
|||||||
| `input_structures.glsl` | SceneData UBO, material bindings, light structs |
|
| `input_structures.glsl` | SceneData UBO, material bindings, light structs |
|
||||||
| `lighting_common.glsl` | BRDF evaluation, point light helpers |
|
| `lighting_common.glsl` | BRDF evaluation, point light helpers |
|
||||||
| `ibl_common.glsl` | IBL split-sum, SH irradiance |
|
| `ibl_common.glsl` | IBL split-sum, SH irradiance |
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user