first commit
This commit is contained in:
387
AGENTS.md
Normal file
387
AGENTS.md
Normal 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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user