first commit

This commit is contained in:
2025-12-31 14:22:45 +01:00
commit c78a860098
73 changed files with 30137 additions and 0 deletions

387
AGENTS.md Normal file
View File

@@ -0,0 +1,387 @@
Below is a clean, concise **AGENTS.md “WebGPU Patterns” section** designed specifically for *your custom framework*:
* `Engine`
* `RenderPipeline`
* `Block`
* `RenderPass`
* `Shader`
Not the GPT model logic.
Not embeddings or inference.
Only the architectural usage patterns you want Codex to follow.
You can **copy this directly** into your existing AGENTS.md under “Example Patterns”, or use it to replace that section entirely.
It teaches Codex:
* How your framework is structured
* How passes are created
* How pipelines are assembled
* How shader setup works
* How buffer binding works
* How execution is called
This ensures that Codex will generate compatible new passes, pipelines, and engine bootstraps.
---
# **WEBGPU FRAMEWORK PATTERNS (SHORT, STRICT)**
Codex must follow these exact patterns when creating or modifying WebGPU code using the framework located in `/framework`.
These patterns describe:
* how to extend `RenderPass`
* how to assemble a `Block`
* how to create a `RenderPipeline`
* how to use `Engine`
* how to load WGSL shaders
* how to bind buffers and call `.execute()`
No ML logic included.
Only architectural usage patterns.
---
# paths
```
/framework/RenderPass.js
/framework/WebGpu.js
/framework/Block.js
/framework/EventManager.js
/framework/Camera.js
/framework/Matrix4.js
/framework/vector3.js
```
# **1. RenderPass Pattern**
A pass is always:
* its own file under `passes/`
* a class extending `RenderPass`
* has `create()`, `bindBuffers()`, `execute()`
* loads its shader using `new Shader(this.device)`
* sets WGSL variables using `.setVariable()`
```javascript
import { RenderPass } from "framework/RenderPass.js";
import Shader from "framework/WebGpu.js";
export class ExamplePass extends RenderPass {
async create( ) {
this.shader = new Shader( this.device );
await this.shader.setup( "shaders/example.wgsl" );
}
bindBuffers( ) {
var inputData = this.pipeline.memory.inputData;
// set variable can be normal javascript arrays, also typed arrays.
this.shader.setVariable(
"input1",
[1,2,3,4,5]
);
// set variable can be normal javascript arrays, also typed arrays.
this.shader.setVariable(
"input2",
new Float32Array( [ 1,2,3,4 ] )
);
const texture = this.shader.createTextureFromData(
width,
height,
[ 1,2,3... ]
);
this.shader.setVariable( "texture", texture );
// associate buffer from other shader buffer
const prevLayerBlock = this.pipeline.getBlockByName("blockName");
const pass = prevLayerBlock.getPass("passName");
const buffer = pass.shader.getBuffer("outputVector");
this.shader.setBuffer("inputHiddenState", buffer);
}
async execute( ) {
await this.shader.execute( 1 );
}
}
```
Rules Codex must preserve:
* One blank line between imports.
* Tab-aligned imports before each `from`.
* No arrow functions.
* `await this.shader.setup( path )`.
* `this.shader.setVariable( name, data )` only in `bindBuffers()` or incremental calls.
* `execute()` always calls `this.shader.execute( workgroups )`.
---
# **2. Block Pattern**
A block is a logical grouping of passes.
Codex must:
* create blocks using `new Block( "name", pipeline )`
* attach passes with `block.addPass( "Name", instance )`
* add block to pipeline with `pipeline.addBlock( block )`
```
import { Block } from "/framework/Block.js";
import { ExamplePass } from "../passes/ExamplePass.js";
const block = new Block( "example", this );
const pass = new ExamplePass( );
block.addPass( "Example", pass );
this.addBlock( block );
```
---
# **3. Pipeline Pattern**
A pipeline:
* extends `RenderPipeline`
* constructs blocks in `create()`
* allocates memory buffers on `this.memory`
* always calls `await super.create()` last
* may override `execute()` to chain passes logically
```
import { RenderPipeline } from "/framework/RenderPipeline.js";
import { Block } from "/framework/Block.js";
import { ExamplePass } from "../passes/ExamplePass.js";
export class ExamplePipeline extends RenderPipeline {
async create( ) {
/* Allocate global memory */
this.memory.input = new Float32Array( 1024 );
this.memory.output = new Float32Array( 1024 );
/* Pass block */
const block = new Block( "example", this );
const examplePass = new ExamplePass( );
block.addPass( "Example", examplePass );
this.addBlock( block );
/* Build GPU resources (mandatory) */
await super.create();
}
async execute( ) {
const block = this.blocks[0];
const pass = block.getPass( "Example" );
await pass.execute();
}
}
```
# **3. Camera and eventmanager Pattern**
```
import Matrix4 from "framework/Matrix4.js"
import Vector3 from "framework/Vector3.js"
this.camera = new Camera( [0, 0, 1115], [0, -.3, 0], [0, 1, 0] );
this.eventManager.setup( canvas, this.camera );
const viewMatrixData = this.camera.getViewMatrix();
const projectionMatrixData = Matrix4.createProjectionMatrix( this.camera, this.canvas )
const viewProjectionMatrix = Matrix4.multiply( projectionMatrixData, viewMatrixData );
const cameraWorldMatrix = Matrix4.invert( viewMatrixData );
const cameraPosition = Matrix4.getColumn( cameraWorldMatrix, 3 );
this.renderShader.setVariable( "viewProjectionMatrix", viewProjectionMatrix );
this.renderShader.setVariable( "cameraPosition", cameraPosition );
```
Codex must:
* allocate buffers on `this.memory.*`
* assemble blocks before `super.create()`
* not reorder pipeline structure automatically
---
# **4. Engine Usage Pattern**
The entrypoint must follow this shape whenever Codex creates a new WebGPU project:
```
import { Engine } from "/framework/Engine.js";
import { ExamplePipeline } from "./pipelines/ExamplePipeline.js";
async function main( ) {
const adapter = await navigator.gpu.requestAdapter( );
const device = await adapter.requestDevice( );
const engine = new Engine( device );
/* Pipeline */
const pipeline = new ExamplePipeline( engine );
pipeline.memory.set( "inputData", new Float32Array( 1024 ) );
await pipeline.create();
await pipeline.bindBuffers();
await pipeline.execute();
}
main( );
```
Codex must always:
* request adapter → requestDevice
* create `new Engine(device)`
* instantiate pipeline with `(engine)`
* set memory with `pipeline.memory.set( key, value )`
* call `await pipeline.create()`
* call `await pipeline.bindBuffers()`
* call `await pipeline.execute()`
---
# **5. Shader Usage Pattern**
Codex must use the Shader class exactly like this:
```
this.shader = new Shader( this.device );
await this.shader.setup( "shaders/example.wgsl" );
this.shader.setVariable( "bufferA", floatArray );
await this.shader.execute( workgroups );
```
Always:
* One shader instance per pass
* WGSL path passed to `.setup()`
* `.setVariable()` before `.execute()`
* No arrow functions
* Spaces inside parentheses
---
# **6. Memory Allocation Pattern**
All buffers are allocated as plain typed arrays under:
```
this.memory.X = new Float32Array( size );
```
Codex must never use ArrayBuffer directly unless required.
---
# **7. Execution Flow Rule**
Every pipeline execution must follow:
1. `await pipeline.create()`
2. `await pipeline.bindBuffers()`
3. `await pipeline.execute()`
Never run execute before create.
Never omit bindBuffers if pass needs it.
---
# **8. Codex MUST NOT Generate**
* Raw WebGPU API calls (`device.createBuffer`) unless inside Shader class
* Inline WGSL; always stored in `.wgsl` files
* Arrow functions
* Inline callbacks
* Different architecture than this:
* Engine
* Pipeline
* Block
* RenderPass
* Shader