Skip to content
Merged
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
9 changes: 4 additions & 5 deletions .agents/skills/prism-regen/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ its own — the generated C++ and HLSL must be rebuilt from it.

## The one thing that goes wrong

`generate_prism_parser.bat` does **not** regenerate code from `.prism` files. It
runs ANTLR over `Prism.g4` to rebuild the *parser*, which is only needed when
the grammar itself changes. Running it after a `.prism` edit appears to succeed
and produces no useful change — which is exactly why it's the trap.
Editing a `.prism` file does nothing until `prismc.exe` runs. The Prism parser
itself is not generated any more (the PEG grammar is compiled into `prismc`,
`sources/Prism/PrismGrammar.h`), so there is no separate parser step to run.

The actual generator is `prismc.exe`, built by the `Prism` project.
The generator is `prismc.exe`, built by the `Prism` project.

## Running the generator

Expand Down
9 changes: 4 additions & 5 deletions .claude/skills/prism-regen/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ its own — the generated C++ and HLSL must be rebuilt from it.

## The one thing that goes wrong

`generate_prism_parser.bat` does **not** regenerate code from `.prism` files. It
runs ANTLR over `Prism.g4` to rebuild the *parser*, which is only needed when
the grammar itself changes. Running it after a `.prism` edit appears to succeed
and produces no useful change — which is exactly why it's the trap.
Editing a `.prism` file does nothing until `prismc.exe` runs. The Prism parser
itself is not generated any more (the PEG grammar is compiled into `prismc`,
`sources/Prism/PrismGrammar.h`), so there is no separate parser step to run.

The actual generator is `prismc.exe`, built by the `Prism` project.
The generator is `prismc.exe`, built by the `Prism` project.

## Running the generator

Expand Down
18 changes: 11 additions & 7 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ generate_project.bat
### Regenerate code from .prism files
Tools → Regenerate Prism code in VS (Prism extension), or run `bin/profile/prismc.exe` from `sources/Prism/`.

### Regenerate the Prism parser (only after changing the Prism.g4 grammar)
```bat
generate_prism_parser.bat
```
### Changing the Prism grammar
The grammar is a cpp-peglib (PEG) string in `sources/Prism/PrismGrammar.h`; there is no generated parser, so a grammar edit
is just a rebuild of the Prism project. `peglib.h` (vcpkg port `cpp-peglib`) is included only by the plain, non-module
`sources/Prism/PrismBridge.cpp` (a header unit of it leaves its static string constants null), which hands `Parsing.cpp` a
small AST (`PrismAst.h`). Keywords are contextual (`!IDCHAR`-guarded tokens), so where a keyword-led alternative follows an
`ID`-led one, order them keyword first (see `rt_stat`, `value_id`). All PSO kinds share one `pso_block`; which statements
each kind takes is checked in `Parsing.cpp` (`PsoKind`), and PSO/node parameters are typed by name in the grammar.
`prismc --check a.prism` parses files without validating or generating anything, for trying grammar changes.

### Build
Open `projects/Spectrum.sln` in Visual Studio 2026. Three configurations: **Debug**, **Profile**, **Retail**.
Expand All @@ -33,7 +37,7 @@ Executables output to `bin/Debug`, `bin/Profile`, `bin/Retail`. The working dire

### Layer Stack (bottom to top)
```
Modules — C++ module wrappers for third-party libraries (assimp, cereal, antlr4, etc.)
Modules — C++ module wrappers for third-party libraries (assimp, cereal, etc.)
Core — Engine foundation: math, serialization, threads, events, filesystem, profiling
HAL — Hardware Abstraction Layer over D3D12: device, queues, resources, descriptors, shaders
RenderSystem — High-level rendering: FrameGraph, materials, lighting, GUI, scene, assets
Expand All @@ -46,13 +50,13 @@ Each layer has a `Defines.h` that chains upward (e.g. `RenderSystem/Defines.h` i
The codebase uses **C++23 modules** (`.ixx` files) extensively. Each subsystem exposes a module interface — for example `HAL.Device.ixx` exports `module HAL:Device`. Headers (`.h`) are used for things that can't be modules (forced includes, third-party interop).

### Prism
Prism is the engine's declaration language: `.prism` files in `sources/Prism/defs/` declare shared GPU/CPU structs and their resource bindings, PSOs, raytracing PSOs, FrameGraph passes, pipelines, enums, constants and HLSL helper functions. `prismc` (an ANTLR4-based compiler, `sources/Prism/`) generates HLSL and C++ from them into `sources/HAL/autogen/`, `sources/RenderSystem/FrameGraph/autogen/` and `workdir/shaders/autogen/`. The language was called SIG (shader input groups) before it grew beyond bindings; the engine-side binding code keeps that name (`HAL/SIG/`, `SlotID`, `Table::`).
Prism is the engine's declaration language: `.prism` files in `sources/Prism/defs/` declare shared GPU/CPU structs and their resource bindings, PSOs, raytracing PSOs, FrameGraph passes, pipelines, enums, constants and HLSL helper functions. `prismc` (a cpp-peglib-based compiler, `sources/Prism/`) generates HLSL and C++ from them into `sources/HAL/autogen/`, `sources/RenderSystem/FrameGraph/autogen/` and `workdir/shaders/autogen/`. The language was called SIG (shader input groups) before it grew beyond bindings; the engine-side binding code keeps that name (`HAL/SIG/`, `SlotID`, `Table::`).

### FrameGraph
The `RenderSystem/FrameGraph` subsystem manages render pass scheduling, automatic resource transitions, and async compute. Render passes declare their resource reads/writes; the FrameGraph resolves barriers and execution order.

### Modules Layer
`sources/Modules/` wraps third-party vcpkg libraries as C++ modules (`.ixx`). Each subfolder (`assimp/`, `cereal/`, `antlr4/`, etc.) contains an `.ixx` that re-exports the library through the module system.
`sources/Modules/` wraps third-party vcpkg libraries as C++ modules (`.ixx`). Each subfolder (`assimp/`, `cereal/`, etc.) contains an `.ixx` that re-exports the library through the module system.

## Key Files
- `main.sharpmake.cs` — all project/solution configuration; edit this to add files, dependencies, or defines
Expand Down
18 changes: 11 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@ generate_project.bat
### Regenerate code from .prism files
Tools → Regenerate Prism code in VS (Prism extension), or run `bin/profile/prismc.exe` from `sources/Prism/`.

### Regenerate the Prism parser (only after changing the Prism.g4 grammar)
```bat
generate_prism_parser.bat
```
### Changing the Prism grammar
The grammar is a cpp-peglib (PEG) string in `sources/Prism/PrismGrammar.h`; there is no generated parser, so a grammar edit
is just a rebuild of the Prism project. `peglib.h` (vcpkg port `cpp-peglib`) is included only by the plain, non-module
`sources/Prism/PrismBridge.cpp` (a header unit of it leaves its static string constants null), which hands `Parsing.cpp` a
small AST (`PrismAst.h`). Keywords are contextual (`!IDCHAR`-guarded tokens), so where a keyword-led alternative follows an
`ID`-led one, order them keyword first (see `rt_stat`, `value_id`). All PSO kinds share one `pso_block`; which statements
each kind takes is checked in `Parsing.cpp` (`PsoKind`), and PSO/node parameters are typed by name in the grammar.
`prismc --check a.prism` parses files without validating or generating anything, for trying grammar changes.

### Build
Open `projects/Spectrum.sln` in Visual Studio 2026. Three configurations: **Debug**, **Profile**, **Retail**.
Expand Down Expand Up @@ -132,7 +136,7 @@ Get-Process MSBuild,VBCSCompiler -ErrorAction SilentlyContinue | Stop-Process -F

### Layer Stack (bottom to top)
```
Modules — C++ module wrappers for third-party libraries (assimp, cereal, antlr4, etc.)
Modules — C++ module wrappers for third-party libraries (assimp, cereal, etc.)
Core — Engine foundation: math, serialization, threads, events, filesystem, profiling
HAL — Hardware Abstraction Layer over D3D12: device, queues, resources, descriptors, shaders
RenderSystem — High-level rendering: FrameGraph, materials, lighting, GUI, scene, assets
Expand All @@ -145,13 +149,13 @@ Each layer has a `Defines.h` that chains upward (e.g. `RenderSystem/Defines.h` i
The codebase uses **C++23 modules** (`.ixx` files) extensively. Each subsystem exposes a module interface — for example `HAL.Device.ixx` exports `module HAL:Device`. Headers (`.h`) are used for things that can't be modules (forced includes, third-party interop).

### Prism
Prism is the engine's declaration language: `.prism` files in `sources/Prism/defs/` declare shared GPU/CPU structs and their resource bindings, PSOs, raytracing PSOs, FrameGraph passes, pipelines, enums, constants and HLSL helper functions. `prismc` (an ANTLR4-based compiler, `sources/Prism/`) generates HLSL and C++ from them into `sources/HAL/autogen/`, `sources/RenderSystem/FrameGraph/autogen/` and `workdir/shaders/autogen/`. The language was called SIG (shader input groups) before it grew beyond bindings; the engine-side binding code keeps that name (`HAL/SIG/`, `SlotID`, `Table::`).
Prism is the engine's declaration language: `.prism` files in `sources/Prism/defs/` declare shared GPU/CPU structs and their resource bindings, PSOs, raytracing PSOs, FrameGraph passes, pipelines, enums, constants and HLSL helper functions. `prismc` (a cpp-peglib-based compiler, `sources/Prism/`) generates HLSL and C++ from them into `sources/HAL/autogen/`, `sources/RenderSystem/FrameGraph/autogen/` and `workdir/shaders/autogen/`. The language was called SIG (shader input groups) before it grew beyond bindings; the engine-side binding code keeps that name (`HAL/SIG/`, `SlotID`, `Table::`).

### FrameGraph
The `RenderSystem/FrameGraph` subsystem manages render pass scheduling, automatic resource transitions, and async compute. Render passes declare their resource reads/writes; the FrameGraph resolves barriers and execution order.

### Modules Layer
`sources/Modules/` wraps third-party vcpkg libraries as C++ modules (`.ixx`). Each subfolder (`assimp/`, `cereal/`, `antlr4/`, etc.) contains an `.ixx` that re-exports the library through the module system.
`sources/Modules/` wraps third-party vcpkg libraries as C++ modules (`.ixx`). Each subfolder (`assimp/`, `cereal/`, etc.) contains an `.ixx` that re-exports the library through the module system.

## Key Files
- `main.sharpmake.cs` — all project/solution configuration; edit this to add files, dependencies, or defines
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
- Runtime-tunable properties (`Variable<T>`) with an in-app debug panel
- CPU/GPU profiling (scoped `PROFILE`/`PROFILE_GPU` markers)
- FrameGraph live debugger: pass/resource inspector, GPU pass timeline with barrier visualization, and a pannable/zoomable resource preview (2D/array/3D/cube textures and buffers)
- Prism, a declaration language for GPU/CPU structs, bindings, PSOs and FrameGraph passes (ANTLR4-driven `prismc` generates HLSL + C++ from `.prism` files), with a Visual Studio extension for highlighting, live diagnostics and navigation
- Prism, a declaration language for GPU/CPU structs, bindings, PSOs and FrameGraph passes (the cpp-peglib-driven `prismc` generates HLSL + C++ from `.prism` files), with a Visual Studio extension for highlighting, live diagnostics and navigation

## Build system

Expand All @@ -58,11 +58,11 @@

- C++23, built extensively around **C++ modules** (`.ixx` module interfaces) rather than classic headers
- Layered module/include architecture (Modules → Core → HAL → RenderSystem → Spectrum), each layer force-including the one below via a chained `Defines.h`
- Third-party libraries (assimp, cereal, antlr4, DirectXTex, DirectStorage, freetype, jinja2cpp, ...) wrapped as C++ modules under `sources/Modules/`
- Third-party libraries (assimp, cereal, DirectXTex, DirectStorage, freetype, jinja2cpp, ...) wrapped as C++ modules under `sources/Modules/`

## Code generation

Large parts of the engine are generated rather than hand-written. The source of truth is **Prism**, the engine's declaration language: `.prism` files in `sources/Prism/defs/` declare GPU/CPU shared structs and their slot bindings, root layouts, graphics/compute/raytracing/work-graph PSOs, FrameGraph passes and pipelines, enums, constants and HLSL helper functions. The `prismc` compiler (`sources/Prism/`, ANTLR4 grammar `Prism.g4`, Jinja2 templates) validates them and generates, into `autogen/` directories that are checked in but never edited by hand:
Large parts of the engine are generated rather than hand-written. The source of truth is **Prism**, the engine's declaration language: `.prism` files in `sources/Prism/defs/` declare GPU/CPU shared structs and their slot bindings, root layouts, graphics/compute/raytracing/work-graph PSOs, FrameGraph passes and pipelines, enums, constants and HLSL helper functions. The `prismc` compiler (`sources/Prism/`, cpp-peglib grammar `PrismGrammar.h`, Jinja2 templates) validates them and generates, into `autogen/` directories that are checked in but never edited by hand:
- **HAL** (`sources/HAL/autogen/`): binding tables and slots, root layouts, PSOs with permutation keys, raytracing PSOs, enums, constants
- **FrameGraph** (`sources/RenderSystem/FrameGraph/autogen/`): per-pass headers with generated setup (resource creation/needs, enable conditions), pipelines, `pass_ids.h`, `resource_ids.h`, `pass_defaults.*`, context dependency tables
- **HLSL** (`workdir/shaders/autogen/`): the matching shader-side structs, layouts, raytracing and work-graph node headers
Expand Down
4 changes: 0 additions & 4 deletions generate_prism_parser.bat

This file was deleted.

39 changes: 39 additions & 0 deletions generate_vsix.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@echo off
REM Builds the Prism language server (Profile) and packs it with the generated highlighting into
REM bin\editor\prism.vsix (double-click that file to install it).
REM
REM generate_vsix.bat build Prism, then bin\editor\prism.vsix
REM generate_vsix.bat --install-user also copy the highlighting-only extension into
REM %USERPROFILE%\.vs\Extensions\Prism (no VSIX needed)
REM
REM Needs Visual Studio with the "Visual Studio extension development" workload, Python, and
REM projects\spectrum.sln (generate_project.bat creates it).
setlocal
cd /d "%~dp0"

if not exist projects\spectrum.sln (
echo projects\spectrum.sln is missing -- run generate_project.bat first.
exit /b 1
)

set MSBUILD=
for /f "usebackq delims=" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe`) do set MSBUILD=%%i
if not defined MSBUILD (
echo MSBuild not found.
exit /b 1
)

REM The extension carries a copy of bin\profile\prismc.exe as its language server, so build it first.
"%MSBUILD%" projects\spectrum.sln /t:Prism /p:Configuration=Profile-D3D12 /p:Platform=x64 /m -nodeReuse:false /nologo /v:minimal
set BUILD_RESULT=%ERRORLEVEL%

REM A lingering MSBuild or compiler server locks files and blocks Visual Studio installers.
powershell -NoProfile -Command "Get-Process MSBuild,VBCSCompiler -ErrorAction SilentlyContinue | Stop-Process -Force"

if not %BUILD_RESULT%==0 (
echo Prism build failed.
exit /b %BUILD_RESULT%
)

python sources\Prism\editor\gen_vs_extension.py %*
exit /b %ERRORLEVEL%
1 change: 0 additions & 1 deletion main.sharpmake.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ public Common() : base(typeof(CustomTarget))
SourceFilesExtensions.Add(".prism");
SourceFilesExtensions.Add(".hlsl");
SourceFilesExtensions.Add(".ixx");
SourceFilesExtensions.Add(".g4");
SourceFilesExtensions.Add(".jinja");

SourceFilesCompileExtensions.Add(".ixx");
Expand Down
2 changes: 1 addition & 1 deletion overview/Barriers.txt
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ Chain:

No grammar change was needed: value_declaration already accepts option_block, and
options are exposed to Jinja generically. Regenerate with bin/debug/prismc.exe
from sources/Prism — generate_prism_parser.bat only rebuilds the ANTLR grammar.
from sources/Prism.


================================================================================
Expand Down
8 changes: 4 additions & 4 deletions overview/Prism.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ groups.
--------------------------------------------------------------------------------

sources/Prism/defs/*.prism the declarations (one file per subsystem)
sources/Prism/Prism.g4 ANTLR grammar
sources/Prism/PrismGrammar.h cpp-peglib (PEG) grammar, compiled into prismc
sources/Prism/templates/ Jinja templates: cpp/ and hlsl/ output
sources/Prism/Main.cpp generator: parse, validate, render templates
sources/Prism/Validate.cpp every semantic check (and the option lists)
Expand Down Expand Up @@ -88,8 +88,8 @@ window) and the exit code is 1. Many come with a suggestion:
ddgi.prism(515,2): error: unknown option [SetupConditon] on PassNode
'DDGIProbeSelect'; did you mean 'SetupCondition'?

generate_prism_parser.bat is NOT a regeneration step — it rebuilds the ANTLR
parser from Prism.g4 and is only needed after a grammar change.
There is no parser-generation step: the PEG grammar is compiled into prismc, so
a grammar change is just a rebuild of the Prism project.


--------------------------------------------------------------------------------
Expand Down Expand Up @@ -649,7 +649,7 @@ Install bin/editor/prism.vsix (built by
`python sources/Prism/editor/gen_vs_extension.py`; needs the VS Installer's
"Visual Studio extension development" workload). It provides:

- syntax highlighting (generated from Prism.g4: keywords, built-in types,
- syntax highlighting (generated from PrismGrammar.h: keywords, built-in types,
formats and [Always]/[RecreateFlags] flags in the #define colour, options,
user-declared names via the language server) with the C++ grammar inside
HLSL bodies
Expand Down
2 changes: 1 addition & 1 deletion sources/Core/Windows/Defines.Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <cstdio> // assert_fail diagnostics (fopen/fprintf)

// The #ifndef guard prevents a redefinition when Core_defs.h is also
// compiled into the same TU (the antlr generated header still imports it).
// compiled into the same TU.
#ifndef CORE_ASSERT_FAIL_DEFINED
#define CORE_ASSERT_FAIL_DEFINED
namespace Core {
Expand Down
2 changes: 1 addition & 1 deletion sources/HAL/autogen/Constants.ixx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Core;
// never need a Table type at all) whenever a new raw const needs one.
import :Autogen.Tables.Dev.TileRecord;

// One `const Name = value;` declaration (Prism.g4's const_definition) per line,
// One `const Name = value;` declaration (PrismGrammar.h's const_definition) per line,
// in .prism declaration order -- a later constant's raw value may reference an
// earlier one by its unqualified name (ordinary C++ initialization-order
// rules), e.g. `const MaxDispatchEntries = `MaxLevels * 2048`;`.
Expand Down
2 changes: 0 additions & 2 deletions sources/Modules/antlr4/antlr4.h

This file was deleted.

3 changes: 0 additions & 3 deletions sources/Modules/antlr4/antlr4.ixx

This file was deleted.

Loading
Loading