Harbor

branch main
showing the latest snapshot on main
run_golden.sh 2.9 KB · Shell
gpu/shader/tests/run_golden.sh 0755 Raw
#!/usr/bin/env bash
# Golden file test runner for Luma shader compiler
# Usage:
#   ./tests/run_golden.sh           # Run tests (diff against golden files)
#   ./tests/run_golden.sh --update  # Regenerate golden files from current output

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
SHADER_DIR="$SCRIPT_DIR/shaders"
GOLDEN_DIR="$SCRIPT_DIR/golden"
LUMA="${TMPDIR:-/tmp}/gpu_shader_bin"
TEXT_TARGETS="glsl glsl-opengl hlsl msl wgsl"

UPDATE=false
if [[ "${1:-}" == "--update" ]]; then
    UPDATE=true
fi

# Build if needed
if [[ ! -f "$LUMA" ]] || [[ "$PROJECT_DIR/main.odin" -nt "$LUMA" ]] || \
   find "$PROJECT_DIR" -name '*.odin' -newer "$LUMA" 2>/dev/null | grep -q .; then
    echo "Building shader compiler..."
    (cd "$PROJECT_DIR/.." && odin build tools/shader -out:"$LUMA") || { echo "FAIL: build failed"; exit 1; }
fi

PASS=0
FAIL=0
ERRORS=""

for shader in "$SHADER_DIR"/*.luma; do
    name="$(basename "$shader" .luma)"

    # Text backends: golden file comparison
    for target in $TEXT_TARGETS; do
        golden="$GOLDEN_DIR/${name}.${target}"

        output=$("$LUMA" compile "$shader" --target="$target" 2>&1) || {
            FAIL=$((FAIL + 1))
            ERRORS="${ERRORS}FAIL: ${name}.${target} (compile error)\n"
            continue
        }

        if $UPDATE; then
            echo "$output" > "$golden"
            echo "  updated ${name}.${target}"
        else
            if [[ ! -f "$golden" ]]; then
                FAIL=$((FAIL + 1))
                ERRORS="${ERRORS}FAIL: ${name}.${target} (no golden file — run with --update)\n"
                continue
            fi

            diff_output=$(diff -u "$golden" <(echo "$output") 2>&1) || {
                FAIL=$((FAIL + 1))
                ERRORS="${ERRORS}FAIL: ${name}.${target}\n${diff_output}\n\n"
                continue
            }
            PASS=$((PASS + 1))
        fi
    done

    # SPIR-V: validate only (binary comparison is fragile)
    spv_tmp=$(mktemp /tmp/luma_test_XXXXXX.spv)
    if "$LUMA" compile "$shader" --target=spirv -o "$spv_tmp" 2>/dev/null; then
        if command -v spirv-val &>/dev/null; then
            if spirv-val "$spv_tmp" 2>&1; then
                PASS=$((PASS + 1))
                if $UPDATE; then
                    echo "  validated ${name}.spirv"
                fi
            else
                FAIL=$((FAIL + 1))
                ERRORS="${ERRORS}FAIL: ${name}.spirv (spirv-val failed)\n"
            fi
        else
            # spirv-val not available, skip validation
            PASS=$((PASS + 1))
        fi
    else
        FAIL=$((FAIL + 1))
        ERRORS="${ERRORS}FAIL: ${name}.spirv (compile error)\n"
    fi
    rm -f "$spv_tmp"
done

echo ""
if $UPDATE; then
    echo "Golden files updated."
else
    if [[ $FAIL -gt 0 ]]; then
        echo -e "$ERRORS"
    fi
    echo "Results: $PASS passed, $FAIL failed"
    [[ $FAIL -eq 0 ]] || exit 1
fi