Skip to content

Commit 73b06c8

Browse files
authored
Merge branch 'master' into fix/switch-without-case
2 parents 695944c + 0516f5d commit 73b06c8

File tree

205 files changed

+11211
-574
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

205 files changed

+11211
-574
lines changed

.github/workflows/ci-analytics.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ jobs:
5353
--pr-input /tmp/pr_merges.json \
5454
--output ci_analytics_repo
5555
56+
- name: Generate status page
57+
run: |
58+
python3 extras/ci/analytics/ci_status.py \
59+
--output ci_analytics_repo
60+
5661
- name: Push to analytics repo
5762
run: |
5863
cd ci_analytics_repo

.github/workflows/ci-health.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,17 @@ jobs:
3939
python3 extras/ci/analytics/ci_health.py \
4040
--output ci_analytics_repo
4141
42+
- name: Generate status page
43+
run: |
44+
python3 extras/ci/analytics/ci_status.py \
45+
--output ci_analytics_repo
46+
4247
- name: Push health page
4348
run: |
4449
cd ci_analytics_repo
4550
git config user.name "github-actions[bot]"
4651
git config user.email "github-actions[bot]@users.noreply.github.com"
47-
git add health.html
52+
git add health.html status.html
4853
git add health_snapshots.jsonl 2>/dev/null || true
4954
git diff --cached --quiet || {
5055
git commit -m "Update CI health $(date -u +%Y-%m-%dT%H:%M)" &&
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
name: Sascha Willems Vulkan Shaders (Nightly)
2+
3+
on:
4+
workflow_dispatch:
5+
schedule:
6+
# Run daily at 4 AM UTC (after RTX Remix and coverage runs)
7+
- cron: "0 4 * * *"
8+
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
12+
13+
permissions:
14+
contents: read
15+
actions: read
16+
17+
jobs:
18+
sascha-willems-shader-test:
19+
runs-on: windows-2022
20+
timeout-minutes: 30
21+
22+
defaults:
23+
run:
24+
shell: bash
25+
26+
steps:
27+
- name: Checkout Slang repository
28+
uses: actions/checkout@v4
29+
30+
- name: Add bash to PATH
31+
shell: pwsh
32+
run: |
33+
Add-Content -Path $env:GITHUB_PATH -Value "C:\\Program Files\\Git\\bin"
34+
35+
- name: Download Slang build from latest successful merge queue
36+
env:
37+
GH_TOKEN: ${{ github.token }}
38+
run: |
39+
echo "Finding latest successful merge queue CI run..."
40+
RUN_INFO=$(gh run list --repo ${{ github.repository }} \
41+
--workflow ci.yml --status success --event merge_group --limit 1 \
42+
--json databaseId,headSha,createdAt)
43+
44+
RUN_ID=$(echo "$RUN_INFO" | jq -r '.[0].databaseId')
45+
COMMIT=$(echo "$RUN_INFO" | jq -r '.[0].headSha')
46+
CREATED=$(echo "$RUN_INFO" | jq -r '.[0].createdAt')
47+
48+
if [ -z "$RUN_ID" ] || [ "$RUN_ID" = "null" ]; then
49+
echo "No successful CI run found"
50+
exit 1
51+
fi
52+
53+
echo "Downloading from CI run $RUN_ID (commit: ${COMMIT:0:12}, created: $CREATED)"
54+
gh run download "$RUN_ID" --repo ${{ github.repository }} \
55+
--name slang-build-windows-x86_64-cl-release \
56+
--dir slang-build/
57+
58+
slangcPath=$(find slang-build -name "slangc.exe" -type f | head -1)
59+
if [ -z "$slangcPath" ]; then
60+
echo "slangc.exe not found in artifact"
61+
find slang-build -type f | head -30
62+
exit 1
63+
fi
64+
65+
echo "Found slangc at: $slangcPath"
66+
"$slangcPath" -version
67+
68+
- name: Clone SaschaWillems/Vulkan repository (sparse checkout)
69+
run: |
70+
echo "Cloning SaschaWillems/Vulkan (shaders/slang only)..."
71+
git clone --depth 1 --filter=blob:none --sparse \
72+
https://github.com/SaschaWillems/Vulkan.git SaschaWillems-Vulkan
73+
cd SaschaWillems-Vulkan || exit 1
74+
git sparse-checkout set shaders/slang
75+
commit=$(git rev-parse HEAD)
76+
echo "Using SaschaWillems/Vulkan commit: $commit"
77+
78+
slangCount=$(find shaders/slang -name "*.slang" | wc -l | xargs)
79+
echo "Found $slangCount .slang shader files"
80+
81+
- name: Compile Slang shaders
82+
run: |
83+
echo "Compiling Sascha Willems Vulkan Slang shaders..."
84+
85+
slangcPath=$(find slang-build -name "slangc.exe" -type f | head -1)
86+
./extras/compile-sascha-willems-shaders.sh \
87+
--slangc "$slangcPath" \
88+
--repo SaschaWillems-Vulkan \
89+
--spirv-val
90+
91+
- name: Report results
92+
if: always()
93+
run: |
94+
echo ""
95+
echo "================================================"
96+
if [ "$BUILD_RESULT" = "success" ]; then
97+
echo "Sascha Willems shader test PASSED"
98+
echo "Slang compiler changes are compatible with Sascha Willems Vulkan shaders"
99+
else
100+
echo "Sascha Willems shader test FAILED"
101+
echo "Slang compiler changes may have broken shader compilation"
102+
echo "Review build logs for details"
103+
fi
104+
echo "================================================"
105+
env:
106+
BUILD_RESULT: ${{ job.status }}
107+
108+
# Slack notifications disabled - will be enabled in a follow-up PR
109+
- name: Success notification
110+
id: slack-notify-success
111+
if: false # ${{ github.event_name == 'schedule' && success() }}
112+
uses: slackapi/slack-github-action@v1.26.0
113+
with:
114+
payload: |
115+
{
116+
"Sascha-Willems-Nightly": ":green-check-mark: Sascha Willems shader nightly status: ${{ job.status }}"
117+
}
118+
env:
119+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
120+
121+
- name: Failure notification
122+
id: slack-notify-failure
123+
if: false # ${{ github.event_name == 'schedule' && !success() }}
124+
uses: slackapi/slack-github-action@v1.26.0
125+
with:
126+
payload: |
127+
{
128+
"Sascha-Willems-Nightly": ":alert: :alert: :alert: :alert: :alert: :alert:\nSascha Willems shader nightly status: ${{ job.status }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
129+
}
130+
env:
131+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}

CLAUDE.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,20 @@ python3 ./extras/insttrace.py <debugUID> ./build/Debug/bin/slangc tests/my-test.
209209
- Set `SLANG_RUN_SPIRV_VALIDATION=1` for static validation; use `-skip-spirv-validation` to see SPIRV output even when validation fails
210210
- `slangc -target spirv-asm -emit-spirv-via-glsl` — generate reference SPIRV via GLSL for comparison
211211

212+
#### Assertion Behavior (`SLANG_ASSERT`)
213+
214+
On Windows, assertion failures normally open a modal dialog that blocks execution. Set the `SLANG_ASSERT` environment variable to control this:
215+
216+
| Value | Behavior |
217+
|---|---|
218+
| `system` | Use the system `assert()`, which shows a modal dialog and allows the developers to attach the debugger |
219+
| `debugbreak` | When a debugger is already attached, it will hit a debug-break; fall back to `system` behavior when a debugger is not attached |
220+
| `release-assert-only` | Skip debug-only assertions (`SLANG_ASSERT`, `SLANG_ASSERT_FAILURE`) and continue; `SLANG_RELEASE_ASSERT` still fires |
221+
| *(unset)* | Throws an exception |
222+
223+
The behavior on Windows after an exception is thrown is controlled by a CMake option `SLANG_BOOTSTRAP_IGNORE_ABORT_MSG` or `-ignore-abort-msg` command-line argument.
224+
Both options are highly recommended for unattended automation with LLM workflow.
225+
212226
#### RTX Remix Testing
213227

214228
Use the `/repro-remix` skill or see `extras/repro-remix.md`.

cmake/SlangTarget.cmake

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,13 @@ function(slang_add_target dir type)
413413
)
414414
endif()
415415

416+
if(WIN32)
417+
set_target_properties(
418+
${target}
419+
PROPERTIES VS_DEBUGGER_ENVIRONMENT "SLANG_ASSERT=debugbreak"
420+
)
421+
endif()
422+
416423
#
417424
# Link and include from dependencies
418425
#

docs/language-reference/generics.md

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ Generic parameters declaration:
7474
>
7575
> *`generic-param-decl`* =<br>
7676
> &nbsp;&nbsp;&nbsp;&nbsp;*`generic-value-param-decl`* |<br>
77+
> &nbsp;&nbsp;&nbsp;&nbsp;*`generic-value-param-pack-decl`* |<br>
7778
> &nbsp;&nbsp;&nbsp;&nbsp;*`generic-value-param-trad-decl`* |<br>
79+
> &nbsp;&nbsp;&nbsp;&nbsp;*`generic-value-param-pack-trad-decl`* |<br>
7880
> &nbsp;&nbsp;&nbsp;&nbsp;*`generic-type-param-decl`* |<br>
7981
> &nbsp;&nbsp;&nbsp;&nbsp;*`generic-type-param-pack-decl`*
8082
>
@@ -83,11 +85,19 @@ Generic parameters declaration:
8385
> &nbsp;&nbsp;&nbsp;&nbsp;[**`':'`** *`simple-type-spec`*]<br>
8486
> &nbsp;&nbsp;&nbsp;&nbsp;[**`'='`** *`init-expr`*]<br>
8587
>
88+
> *`generic-value-param-pack-decl`* =<br>
89+
> &nbsp;&nbsp;&nbsp;&nbsp;**`'let'`** **`'each'`** *`identifier`*<br>
90+
> &nbsp;&nbsp;&nbsp;&nbsp;[**`':'`** *`simple-type-spec`*]<br>
91+
>
8692
> *`generic-value-param-trad-decl`* =<br>
8793
> &nbsp;&nbsp;&nbsp;&nbsp;*`simple-type-spec`* <br>
8894
> &nbsp;&nbsp;&nbsp;&nbsp;*`identifier`*<br>
8995
> &nbsp;&nbsp;&nbsp;&nbsp;[**`'='`** *`init-expr`*]<br>
9096
>
97+
> *`generic-value-param-pack-trad-decl`* =<br>
98+
> &nbsp;&nbsp;&nbsp;&nbsp;**`'each'`** *`simple-type-spec`*<br>
99+
> &nbsp;&nbsp;&nbsp;&nbsp;*`identifier`*<br>
100+
>
91101
> *`generic-type-param-decl`* =<br>
92102
> &nbsp;&nbsp;&nbsp;&nbsp;[**`'typename'`**] *`identifier`*<br>
93103
> &nbsp;&nbsp;&nbsp;&nbsp;[**`':'`** *`simple-type-spec`*]<br>
@@ -101,10 +111,17 @@ Generic parameters declaration:
101111
Generic parameter constraint clause:
102112
> *`where-clause`* =<br>
103113
> &nbsp;&nbsp;&nbsp;&nbsp;[**`'optional'`**]<br>
104-
> &nbsp;&nbsp;&nbsp;&nbsp;*`simple-type-spec`*<br>
105-
> &nbsp;&nbsp;&nbsp;&nbsp;(*`generic-type-constraint-decl`*<br>
114+
> &nbsp;&nbsp;&nbsp;&nbsp;*`where-clause-body`*<br>
115+
>
116+
> *`where-clause-body`* =<br>
117+
> &nbsp;&nbsp;&nbsp;&nbsp;*`generic-non-empty-pack-constraint-decl`*<br>
118+
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|(*`simple-type-spec`*<br>
119+
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(*`generic-type-constraint-decl`*<br>
106120
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|*`generic-type-constraint-eq-decl`*<br>
107-
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|*`generic-type-constraint-coercion-decl`*)<br>
121+
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|*`generic-type-constraint-coercion-decl`*))<br>
122+
>
123+
> *`generic-non-empty-pack-constraint-decl`* =<br>
124+
> &nbsp;&nbsp;&nbsp;&nbsp;**`'nonempty'`** **`'('`** *`identifier`* **`')'`**<br>
108125
>
109126
> *`generic-type-constraint-decl`* =<br>
110127
> &nbsp;&nbsp;&nbsp;&nbsp;**`':'`**<br>
@@ -129,10 +146,13 @@ Generic parameter constraint clause:
129146
- *`generic-params-decl`* declares a list of generic parameters.
130147
- *`generic-param-decl`* declares a generic value parameter, type parameter, or type parameter pack.
131148
- *`generic-value-param-decl`* declares a generic value parameter.
149+
- *`generic-value-param-pack-decl`* declares a generic value parameter pack using `let each` syntax.
132150
- *`generic-value-param-trad-decl`* declares a generic value parameter using traditional syntax.
151+
- *`generic-value-param-pack-trad-decl`* declares a generic value parameter pack using traditional syntax.
133152
- *`generic-type-param-decl`* declares a generic type parameter.
134153
- *`generic-type-param-pack-decl`* declares a generic type parameter pack.
135154
- *`where-clause`* is a generic parameter constraint clause.
155+
- *`generic-non-empty-pack-constraint-decl`* declares a non-emptiness requirement on a generic type pack or value pack parameter.
136156
- *`generic-type-constraint-decl`* declares a generic type conformance constraint, requiring the left-hand-side
137157
type expression to conform to one or more constraining type expressions.
138158
- *`generic-type-constraint-eq-decl`* declares a generic type equality constraint, requiring the left-hand-side
@@ -161,6 +181,9 @@ A generic parameter declaration is one of:
161181
- Generic value parameter declaration *`generic-value-param-decl`* or *`generic-value-param-trad-decl`*, which
162182
adds a value parameter with an optional default value. The value type must be a [Boolean](types-fundamental.md#boolean),
163183
an [integer](types-fundamental.md#integer), or an [enumeration (TODO)](TODO.md).
184+
- Generic value parameter pack declaration *`generic-value-param-pack-decl`* or *`generic-value-param-pack-trad-decl`*,
185+
which adds a variadic value parameter pack. A value parameter pack is a variable-length list of generic
186+
value parameters of a single declared type.
164187
- Generic type parameter declaration *`generic-type-param-decl`*, which adds a type parameter with an optional
165188
type constraint and an optional default type. The keyword `typename` is optional.
166189
- Generic type parameter pack declaration *`generic-type-param-pack-decl`*, which adds a type parameter
@@ -189,7 +212,10 @@ The coercion requirement is usable only in generic extensions.
189212

190213
A constraint on a type parameter pack applies to every type in the pack.
191214

192-
Value parameters cannot be constrained.
215+
Type and value parameter packs may also be constrained with `where nonempty(P)`, which requires the pack `P`
216+
to be non-empty at specialization time.
217+
218+
Value parameters that are not packs cannot be constrained.
193219

194220
> 📝 **Remark 1:** In Slang, a conformance requirement `TypeParam : ConstrainingType` means that `TypeParam` must
195221
> have `ConstrainingType` as a base (either directly or transitively), and `ConstrainingType` must be an interface.
@@ -240,6 +266,44 @@ expr // every each-expr is substituted by pack element N-1
240266
In function parameter lists, expand/each constructs must come after all other parameters. There may be
241267
multiple declared expand/each parameters, in which case the type parameter packs must have equal lengths.
242268

269+
### Pack queries
270+
271+
Slang provides the following pack-query operations for type packs, value packs, and tuple-like pack sources:
272+
273+
> *`pack-query-expr`* =<br>
274+
> &nbsp;&nbsp;&nbsp;&nbsp;*`pack-first-expr`* | *`pack-last-expr`* | *`pack-trim-head-expr`* | *`pack-trim-tail-expr`*<br>
275+
>
276+
> *`pack-first-expr`* =<br>
277+
> &nbsp;&nbsp;&nbsp;&nbsp;**`'__first'`** **`'('`** *`expr`* **`')'`**<br>
278+
>
279+
> *`pack-last-expr`* =<br>
280+
> &nbsp;&nbsp;&nbsp;&nbsp;**`'__last'`** **`'('`** *`expr`* **`')'`**<br>
281+
>
282+
> *`pack-trim-head-expr`* =<br>
283+
> &nbsp;&nbsp;&nbsp;&nbsp;**`'__trimHead'`** **`'('`** *`expr`* **`')'`**<br>
284+
>
285+
> *`pack-trim-tail-expr`* =<br>
286+
> &nbsp;&nbsp;&nbsp;&nbsp;**`'__trimTail'`** **`'('`** *`expr`* **`')'`**<br>
287+
288+
- `__first(P)`
289+
- `__last(P)`
290+
- `__trimHead(P)`
291+
- `__trimTail(P)`
292+
293+
`__first(P)` and `__last(P)` are partial operations and require `P` to be known non-empty. For generic pack parameters, non-emptiness can be expressed with:
294+
295+
```hlsl
296+
void foo<each T>() where nonempty(T)
297+
{
298+
// `__first(T)` is well-formed here.
299+
}
300+
```
301+
302+
`__trimHead(P)` and `__trimTail(P)` are total operations and yield an empty pack when applied to an empty pack.
303+
304+
> 📝 **Remark:** The operand of `nonempty(...)` must be a direct reference to a generic type pack or value pack
305+
> parameter declared in the current generic declaration. `optional nonempty(...)` is parsed but rejected as invalid.
306+
243307

244308
## Type Checking
245309

docs/user-guide/06-interfaces-generics.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,36 @@ struct Dims<let each D : int>
11831183
int typeCount<each T>() { return countof(T); }
11841184
```
11851185

1186+
### Builtin Variadic Pack Operators
1187+
1188+
Slang also supports simple pack queries:
1189+
1190+
- `__first(P)` returns the first element of a type pack, value pack, or tuple-like pack source.
1191+
- `__last(P)` returns the last element.
1192+
- `__trimHead(P)` returns the pack with the first element removed.
1193+
- `__trimTail(P)` returns the pack with the last element removed.
1194+
1195+
For example:
1196+
1197+
```csharp
1198+
int firstValue<let each D : int>() where nonempty(D)
1199+
{
1200+
return __first(D);
1201+
}
1202+
1203+
int restCount<let each D : int>()
1204+
{
1205+
return countof(__trimHead(D));
1206+
}
1207+
1208+
struct FirstTypeHolder<each T> where nonempty(T)
1209+
{
1210+
__first(T) value;
1211+
}
1212+
```
1213+
1214+
`__first(...)` and `__last(...)` are only valid on packs that are known to be non-empty. For generic packs, use a `where nonempty(P)` constraint to make that guarantee explicit.
1215+
11861216
Builtin Interfaces
11871217
-----------------------------
11881218

external/glslang

Submodule glslang updated 637 files

0 commit comments

Comments
 (0)