Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 34 additions & 11 deletions .github/actions/prepare-shaders/action.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,51 @@
name: "Prepare Shaders"
description: "Prepare shaders for validation or analysis (requires setup-build-environment to be called first)"
description: "Copy shaders into build/ALL/aio/Shaders for validation. Uses direct robocopy rather than cmake so the action needs no MSVC toolchain."

inputs:
cmake-preset:
description: "The CMake configure/build preset to use."
description: "Unused — kept for API compatibility. Shaders are now copied directly without invoking cmake."
required: false
default: "ALL"
output-dir:
description: "Destination directory for the assembled shader tree."
required: false
default: "build/ALL/aio/Shaders"

runs:
using: "composite"
steps:
- name: Prepare shaders
uses: lukka/run-cmake@v10
with:
configurePreset: ${{ inputs.cmake-preset }}
configurePresetAdditionalArgs: "['-DBUILD_SHADER_TESTS=OFF']"
buildPreset: ${{ inputs.cmake-preset }}
buildPresetAdditionalArgs: "['--target prepare_shaders']"
# Copy shaders without invoking cmake or requiring a C++ toolchain.
# Matches the logic of the cmake prepare_shaders target:
# 1. package/Shaders/** → <output-dir>/
# 2. features/*/Shaders/** → <output-dir>/ (Tests/ excluded)
- name: Copy shaders
shell: pwsh
run: |
$dest = "${{ inputs.output-dir }}"
New-Item -ItemType Directory -Force -Path $dest | Out-Null

# Package base shaders
robocopy "package/Shaders" $dest /E /COPY:DAT /NFL /NDL /NJH /NJS /R:1 /W:1
$rc = $LASTEXITCODE; if ($rc -ge 8) { throw "robocopy package/Shaders failed (rc=$rc)" }

# Feature shaders (skip Tests subdirectories)
Get-ChildItem -Path features -Filter "Shaders" -Recurse -Directory |
Where-Object { $_.FullName -notmatch '\\Tests($|\\)' } |
ForEach-Object {
robocopy $_.FullName $dest /E /COPY:DAT /NFL /NDL /NJH /NJS /R:1 /W:1 /XD "$($_.FullName)\Tests"
$rc = $LASTEXITCODE; if ($rc -ge 8) { throw "robocopy $($_.FullName) failed (rc=$rc)" }
}

$count = (Get-ChildItem -Recurse -File -Path $dest).Count
Write-Host "Prepared $count shader files in $dest"

- name: Setup Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: "3.11"
cache: "pip"
cache-dependency-path: ".github/configs/hlslkit-requirements.txt"

- name: Install hlslkit
run: pip install git+https://github.com/alandtse/hlslkit.git
run: pip install -r .github/configs/hlslkit-requirements.txt
shell: bash
6 changes: 5 additions & 1 deletion .github/actions/setup-build-environment/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,11 @@ runs:
uses: actions/cache@v5
with:
path: ${{ inputs.build-dir }}
key: ${{ runner.os }}-cmake-msvc-${{ steps.msvc_version.outputs.version }}-${{ inputs.cache-key-suffix }}-${{ github.event.inputs.cache-key-suffix || 'default' }}-${{ hashFiles('.gitmodules', 'extern/**', 'CMakePresets.json', 'vcpkg.json', 'vcpkg-configuration.json') }}
# Use submodule HEAD refs instead of hashing all of extern/** (~79 MB)
# to avoid slow hash computation on every cache lookup.
# actions/checkout with submodules:recursive writes .git/modules/<name>/HEAD
# for each submodule; hashing those 3 small files detects any submodule SHA change.
key: ${{ runner.os }}-cmake-msvc-${{ steps.msvc_version.outputs.version }}-${{ inputs.cache-key-suffix }}-${{ github.event.inputs.cache-key-suffix || 'default' }}-${{ hashFiles('.gitmodules', '.git/modules/CommonLibSSE-NG/HEAD', '.git/modules/FidelityFX-SDK/HEAD', '.git/modules/Streamline-DX12/HEAD', 'CMakePresets.json', 'vcpkg.json', 'vcpkg-configuration.json') }}
restore-keys: |
${{ runner.os }}-cmake-msvc-${{ steps.msvc_version.outputs.version }}-${{ inputs.cache-key-suffix }}-${{ github.event.inputs.cache-key-suffix || 'default' }}-
${{ runner.os }}-cmake-msvc-${{ steps.msvc_version.outputs.version }}-${{ inputs.cache-key-suffix }}-
Expand Down
5 changes: 5 additions & 0 deletions .github/configs/hlslkit-requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# hlslkit is pinned by commit hash so the pip wheel cache key is stable.
# To update: find the latest commit on https://github.com/alandtse/hlslkit
# and replace the @<hash> below, then delete the stale cache entry in
# GitHub → Actions → Caches so the next CI run rebuilds the wheel.
hlslkit @ git+https://github.com/alandtse/hlslkit.git@d30266d2d5280a2d8c5bef1949c5a8ae1d550c60
12 changes: 4 additions & 8 deletions .github/workflows/_shared-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -142,19 +142,15 @@ jobs:
with:
ref: ${{ inputs.ref }}
repository: ${{ inputs.repository }}
submodules: recursive
# Shader validation only needs source files — submodules (CommonLibSSE-NG,
# FidelityFX, Streamline) are C++ dependencies not required here.
submodules: false

- name: Check for HLSL Changes
id: check-hlsl
uses: ./.github/actions/check-hlsl-changes
with:
hlsl-should-build: ${{ inputs.hlsl-should-build }}
- name: Setup Build Environment
id: setup
if: steps.check-hlsl.outputs.skip != 'true'
uses: ./.github/actions/setup-build-environment
with:
cache-key-suffix: "validation-${{ matrix.config.name }}${{ inputs.cache-key-suffix }}"
- name: Prepare shaders
if: steps.check-hlsl.outputs.skip != 'true'
uses: ./.github/actions/prepare-shaders
Expand Down Expand Up @@ -195,7 +191,7 @@ jobs:
echo "fxc.exe not found - shader validation requires fxc.exe. Set --fxc to a valid path or ensure fxc.exe is in PATH." >&2
exit 1
fi
hlslkit-compile --fxc "${{ steps.find_fxc.outputs.fxc_path }}" --shader-dir build/ALL/aio/Shaders --output-dir build/ShaderCache --config ${{ matrix.config.file }} --max-warnings 0 --suppress-warnings X1519
hlslkit-compile --fxc "${{ steps.find_fxc.outputs.fxc_path }}" --shader-dir build/ALL/aio/Shaders --output-dir build/ShaderCache --config ${{ matrix.config.file }} --max-warnings 0 --suppress-warnings X1519 --jobs $(nproc) --strip-debug-defines

- name: Upload shader validation logs
if: failure() && steps.check-hlsl.outputs.skip != 'true'
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/ci-manual-test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: "Manual CI Test (branch build)"

# Runs the full build from THIS branch's ref using workflow_dispatch.
# Unlike pull_request_target (which resolves workflow/action files from BASE),
# workflow_dispatch resolves everything from the selected ref — so this
# actually exercises changes to _shared-build.yaml, setup-build-environment,
# prepare-shaders, and any other action files on the branch.
#
# Usage: Actions → "Manual CI Test" → Run workflow → select branch
on:
workflow_dispatch:
inputs:
run-cpp:
description: "Run C++ plugin build"
type: boolean
default: true
run-shader-validation:
description: "Run HLSL shader validation"
type: boolean
default: true
run-shader-tests:
description: "Run shader unit tests"
type: boolean
default: true

permissions:
contents: read

jobs:
build:
name: Build and Validate
uses: ./.github/workflows/_shared-build.yaml
with:
ref: ${{ github.ref }}
repository: ${{ github.repository }}
run-cpp: ${{ inputs.run-cpp }}
run-shader-validation: ${{ inputs.run-shader-validation }}
run-shader-tests: ${{ inputs.run-shader-tests }}
hlsl-should-build: "true"
shader-tests-should-build: "true"
cache-key-suffix: "-manual-test"
23 changes: 20 additions & 3 deletions BuildRelease.bat
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
@echo off

set preset="ALL"
if NOT "%1" == "" (
set skip_configure=0

:parse_args
if "%1"=="" goto done_args
if /I "%1"=="--build-only" (
set skip_configure=1
shift
goto parse_args
)
if not "%1"=="" (
set preset=%1
shift
goto parse_args
)
:done_args

echo Running preset %preset%

cmake -S . --preset=%preset%
if %ERRORLEVEL% NEQ 0 exit 1
if "%skip_configure%"=="1" (
echo Skipping CMake configure ^(--build-only^)
) else (
cmake -S . --preset=%preset%
if %ERRORLEVEL% NEQ 0 exit 1
)

cmake --build --preset=%preset%
if %ERRORLEVEL% NEQ 0 exit 1
21 changes: 21 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@
"AUTO_PLUGIN_DEPLOYMENT": "OFF"
},
"inherits": "skyrim"
},
{
"name": "ALL-FastDev",
"description": "Like ALL but disables zip packaging so the configure step is leaner",
"cacheVariables": {
"ENABLE_SKYRIM_AE": "ON",
"ENABLE_SKYRIM_SE": "ON",
"ENABLE_SKYRIM_VR": "ON",
"AUTO_PLUGIN_DEPLOYMENT": "OFF",
"ZIP_TO_DIST": "OFF",
"AIO_ZIP_TO_DIST": "OFF",
"BUILD_SHADER_TESTS": "OFF"
},
"inherits": "skyrim"
}
],
"buildPresets": [
Expand Down Expand Up @@ -115,6 +129,13 @@
"configurePreset": "ALL",
"configuration": "Debug",
"targets": ["CommunityShaders", "AIO"]
},
{
"name": "FastDev",
"description": "RelWithDebInfo build: /O2 optimisation but NO LTO/LTCG and no zip packaging. Typical link is 3-4x faster than Release. Use for rapid shader/feature iteration.",
"configurePreset": "ALL-FastDev",
"configuration": "RelWithDebInfo",
"targets": ["CommunityShaders", "PREPARE_AIO"]
}
]
}
3 changes: 3 additions & 0 deletions cmake/XSEPlugin.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ target_precompile_headers(

set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_DEBUG OFF)
# RelWithDebInfo is the fast-iteration developer config; skip LTO so
# link time stays short while keeping /O2 optimisation for realistic perf.
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO OFF)

set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_STATIC_RUNTIME ON)
Expand Down
Loading
Loading