Skip to content

Commit

Permalink
feat(core): add indexed drawing support
Browse files Browse the repository at this point in the history
  • Loading branch information
JMBeresford committed Nov 12, 2023
1 parent c0986d6 commit 29f2cd9
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .changeset/lucky-bears-jump.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@wgpu-kit/core": minor
---

add indexed drawing support
5 changes: 2 additions & 3 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,10 @@
"build": "tsc && vite build",
"preview": "vite preview",
"lint": "eslint --ext .ts ./src",
"test": "vitest"
"test": "vitest run"
},
"dependencies": {
"@webgpu/types": "0.1.34",
"wgsl_reflect": "github:brendan-duncan/wgsl_reflect"
"@webgpu/types": "0.1.34"
},
"devDependencies": {
"@types/uuid": "^9.0.3",
Expand Down
18 changes: 17 additions & 1 deletion packages/core/src/Executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,23 @@ export class Executor extends Mixins {
pass.setPipeline(pipeline.gpuPipeline);
pass.setVertexBuffer(0, vao.gpuBuffer);
pass.setBindGroup(0, bindGroup);
pass.draw(vao.vertexCount, vao.instanceCount);
const indexBuffer = vao.indexBuffer;

if (indexBuffer?.gpuBuffer !== undefined) {
const fmt =
indexBuffer.cpuBuffer instanceof Uint32Array
? "uint32"
: "uint16";
pass.setIndexBuffer(indexBuffer.gpuBuffer, fmt);
pass.drawIndexed(
indexBuffer.indexCount ?? indexBuffer.cpuBuffer.length,
vao.instanceCount,
indexBuffer.firstIndex,
);
} else {
pass.draw(vao.vertexCount, vao.instanceCount);
}

pass.end();
} else if (
pipeline.type === "compute" &&
Expand Down
69 changes: 69 additions & 0 deletions packages/core/src/IndexBuffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { WithGpuBuffer } from "./components/GpuBufferObject";
import { WithDevice } from "./components/Device";
import { WithLabel } from "./components/Label";
import { WithCpuBuffer } from "./components/CpuBuffer";

type IndexArray = Uint16Array | Uint32Array;
const Mixins = WithCpuBuffer(WithGpuBuffer(WithDevice(WithLabel())));

/**
* {@link IndexBuffer} constructor parameters
*/
export type IndexBufferOptions = {
label?: string;
arrayBuffer: IndexArray;
indexCount?: number;
firstIndex?: number;
baseIndex?: number;
};

/**
* An index buffer that is used in a {@link VertexAttributeObject} to
* use indexed drawing.
*/
export class IndexBuffer extends Mixins {
declare cpuBuffer: IndexArray;
indexCount?: number;
firstIndex?: number;
baseIndex?: number;

constructor(options: IndexBufferOptions) {
super();
this.label = options.label;
this.setCpuBuffer(options.arrayBuffer);
this.indexCount = options.indexCount;
this.firstIndex = options.firstIndex;
this.baseIndex = options.baseIndex;
}

setCpuBuffer(indexBuffer: IndexArray) {
this.setCpuBuffer(indexBuffer);
}

setIndexCount(indexCount: number) {
this.indexCount = indexCount;
}

setFirstIndex(firstIndex: number) {
this.firstIndex = firstIndex;
}

setBaseIndex(baseIndex: number) {
this.baseIndex = baseIndex;
}

async updateGpuBuffer() {
const device = await this.getDevice();
const sizeMismatch = this.cpuBuffer.byteLength !== this.gpuBuffer?.size;

if (this.gpuBuffer === undefined || sizeMismatch) {
this.gpuBuffer = device.createBuffer({
usage: GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST,
label: `${this.label ?? "Unlabelled"} Index Buffer`,
size: this.cpuBuffer.byteLength,
});
}

device.queue.writeBuffer(this.gpuBuffer, 0, this.cpuBuffer);
}
}
7 changes: 7 additions & 0 deletions packages/core/src/VertexAttributeObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { WithDevice } from "./components/Device";
import { WithLabel } from "./components/Label";
import type { Attribute } from "./Attribute";
import { WithCpuBuffer } from "./components/CpuBuffer";
import type { IndexBuffer } from "./IndexBuffer";

const Mixins = WithCpuBuffer(WithGpuBuffer(WithDevice(WithLabel())));

Expand All @@ -24,6 +25,7 @@ export class VertexAttributeObject extends Mixins {
layout?: GPUVertexBufferLayout;
vertexCount: number;
instanceCount: number;
indexBuffer?: IndexBuffer;

constructor(options: VAOOptions) {
super();
Expand All @@ -45,6 +47,11 @@ export class VertexAttributeObject extends Mixins {
this.instanceCount = count;
}

async setIndexBuffer(indexBuffer: IndexBuffer) {
this.indexBuffer = indexBuffer;
await this.indexBuffer.updateGpuBuffer();
}

private updateLayout(): void {
if (this.attributes.length === 0) {
return;
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ export * from "./Uniform";
export * from "./VertexAttributeObject";
export * from "./Texture";
export * from "./Sampler";
export * from "./IndexBuffer";
9 changes: 0 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 29f2cd9

Please sign in to comment.