CultMath tools: get-glslang.ps1 (pinned 16.6.0) and compile-glsl.ps1
compile-glsl.ps1 writes the wrapper a WebGL2 consumer writes (#version 300 es, highp precision, the library by concatenation, one call of every public function) and compiles it with glslang; -Body replaces the calls, for the negative control. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d2ff33085f
commit
34a9329db5
4 changed files with 102 additions and 0 deletions
46
packages/cultmath/tools/compile-glsl.ps1
Normal file
46
packages/cultmath/tools/compile-glsl.ps1
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
param(
|
||||
# A GLSL source to append after the generated wrapper's library instead of the call-every-function
|
||||
# body; tools\compile-glsl.ps1 -Body 'float x = lerp(0.0, 1.0, 0.5);' is the negative control.
|
||||
[string]$Body = "",
|
||||
[string]$GlslangPath = ""
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
|
||||
if (-not $GlslangPath) {
|
||||
$found = Get-ChildItem -LiteralPath (Join-Path $repoRoot ".tools\glslang\current") -Recurse -File -Include "glslang.exe", "glslangValidator.exe" -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if ($found) { $GlslangPath = $found.FullName }
|
||||
}
|
||||
|
||||
# The wrapper is what a WebGL2 consumer writes: its own #version line and precision, then the library
|
||||
# by string concatenation (GLSL has no #include), then a fragment shader that calls every public
|
||||
# function once with zero arguments of its declared types.
|
||||
$library = Get-Content -LiteralPath (Join-Path $repoRoot "shaders\CultMath.glsl") -Raw
|
||||
$calls = foreach ($match in [regex]::Matches($library, '(?m)^\w+\s+(cultmath_\w+)\s*\(([^)]*)\)')) {
|
||||
$arguments = foreach ($parameter in ($match.Groups[2].Value -split ',')) {
|
||||
$type = ($parameter.Trim() -split '\s+')[0]
|
||||
if ($type -eq 'int' -or $type -like 'ivec*') { "$type(0)" }
|
||||
elseif ($type -eq 'uint' -or $type -like 'uvec*') { "$type(0u)" }
|
||||
else { "$type(0.0)" }
|
||||
}
|
||||
" $($match.Groups[1].Value)($($arguments -join ', '));"
|
||||
}
|
||||
if (-not $Body) {
|
||||
$Body = $calls -join "`n"
|
||||
}
|
||||
|
||||
$wrapper = "#version 300 es`nprecision highp float;`nprecision highp int;`n$library`nout vec4 cultmathColor;`nvoid main()`n{`n$Body`n cultmathColor = vec4(0.0);`n}`n"
|
||||
$wrapperPath = Join-Path $repoRoot ".tools\glsl\cultmath-wrapper.frag"
|
||||
New-Item -ItemType Directory -Force -Path (Split-Path -Parent $wrapperPath) | Out-Null
|
||||
[System.IO.File]::WriteAllText($wrapperPath, $wrapper)
|
||||
Write-Host "wrapper: $wrapperPath ($(@($calls).Count) functions)"
|
||||
|
||||
if (-not $GlslangPath -or -not (Test-Path $GlslangPath)) {
|
||||
throw "glslang not found. Run tools\get-glslang.ps1 first or pass -GlslangPath."
|
||||
}
|
||||
|
||||
& $GlslangPath -S frag $wrapperPath
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "glslang failed with exit code $LASTEXITCODE."
|
||||
}
|
||||
7
packages/cultmath/tools/compile-glsl.ps1.meta
Normal file
7
packages/cultmath/tools/compile-glsl.ps1.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 81a35b09c28246fe8d52cf8996540a46
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
42
packages/cultmath/tools/get-glslang.ps1
Normal file
42
packages/cultmath/tools/get-glslang.ps1
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
param(
|
||||
[string]$InstallRoot = ".tools\glslang"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..")
|
||||
$installPath = Join-Path $repoRoot $InstallRoot
|
||||
New-Item -ItemType Directory -Force -Path $installPath | Out-Null
|
||||
|
||||
# Pinned: the GLSL compile check means this front end (Khronos glslang 16.6.0). The hash is the
|
||||
# SHA256 digest GitHub publishes for this asset of KhronosGroup/glslang release 16.6.0.
|
||||
$zipName = "glslang-16.6.0-windows-x86_64-release.zip"
|
||||
$zipUrl = "https://github.com/KhronosGroup/glslang/releases/download/16.6.0/$zipName"
|
||||
$zipSha256 = "82BF434E69B9BB4829DE7E2B4BC2C5E7A7861E53D66CF75E5CC70F5F694A8D9B"
|
||||
|
||||
$zipPath = Join-Path $installPath $zipName
|
||||
Remove-Item -LiteralPath $zipPath -Force -ErrorAction SilentlyContinue
|
||||
|
||||
& curl.exe -L --retry 5 --retry-delay 2 --fail -o $zipPath $zipUrl
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "curl.exe failed with exit code $LASTEXITCODE."
|
||||
}
|
||||
|
||||
$actualSha256 = (Get-FileHash -LiteralPath $zipPath -Algorithm SHA256).Hash
|
||||
if ($actualSha256 -ne $zipSha256) {
|
||||
Remove-Item -LiteralPath $zipPath -Force
|
||||
throw "$zipName SHA256 is $actualSha256, expected $zipSha256."
|
||||
}
|
||||
|
||||
$currentPath = Join-Path $installPath "current"
|
||||
Remove-Item -LiteralPath $currentPath -Recurse -Force -ErrorAction SilentlyContinue
|
||||
New-Item -ItemType Directory -Force -Path $currentPath | Out-Null
|
||||
Expand-Archive -LiteralPath $zipPath -DestinationPath $currentPath -Force
|
||||
|
||||
$glslangPath = Get-ChildItem -LiteralPath $currentPath -Recurse -File -Include "glslang.exe", "glslangValidator.exe" | Select-Object -First 1
|
||||
if (-not $glslangPath) {
|
||||
throw "glslang executable was not found after extraction."
|
||||
}
|
||||
|
||||
& $glslangPath.FullName --version
|
||||
Write-Host "glslang installed at $($glslangPath.FullName)"
|
||||
7
packages/cultmath/tools/get-glslang.ps1.meta
Normal file
7
packages/cultmath/tools/get-glslang.ps1.meta
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 37d057d5ae6847b7b4689d36514b3dc9
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Loading…
Reference in a new issue