Skip to content

WIP - Support vertex pulling #16826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
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
35 changes: 34 additions & 1 deletion packages/dev/core/src/Engines/webgpuEngine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1613,7 +1613,11 @@ export class WebGPUEngine extends ThinWebGPUEngine {
view = data;
}

const dataBuffer = this._bufferManager.createBuffer(view, WebGPUConstants.BufferUsage.Vertex | WebGPUConstants.BufferUsage.CopyDst, label);
const dataBuffer = this._bufferManager.createBuffer(
view,
WebGPUConstants.BufferUsage.Vertex | WebGPUConstants.BufferUsage.CopyDst | WebGPUConstants.BufferUsage.Storage,
label
);
return dataBuffer;
}

Expand Down Expand Up @@ -3693,6 +3697,35 @@ export class WebGPUEngine extends ThinWebGPUEngine {
this._currentMaterialContext.textureState = textureState;

const pipeline = this._cacheRenderPipeline.getRenderPipeline(fillMode, this._currentEffect!, this.currentSampleCount, textureState);

// Compare the vertex buffers that we have to the ones that are bound to the pipeline.
// If there are vertex buffers that are not bound to the pipeline, AND they're used
// by the shader, we will bind them to the current draw context.
const availableVertexBuffers: { [key: string]: VertexBuffer } = (this._cacheRenderPipeline as any)._vertexBuffers;
const appliedVertexBuffers = this._cacheRenderPipeline.vertexBuffers;
const vertexBufferNames = Object.keys(availableVertexBuffers);
if (Object.keys(availableVertexBuffers).length !== appliedVertexBuffers.length) {
const unboundVertexBuffers: { [key: string]: VertexBuffer } = {};
for (let i = 0; i < vertexBufferNames.length; i++) {
const name = vertexBufferNames[i];
if (appliedVertexBuffers.findIndex((v) => v === availableVertexBuffers[name]) === -1) {
unboundVertexBuffers[name] = availableVertexBuffers[name];
}
}
if (Object.keys(unboundVertexBuffers).length > 0) {
for (const unboundVertexBufferName of Object.keys(unboundVertexBuffers)) {
if (webgpuPipelineContext.shaderProcessingContext.bufferNames.findIndex((name) => name === unboundVertexBufferName) !== -1) {
this._currentDrawContext.buffers[unboundVertexBufferName] = unboundVertexBuffers[unboundVertexBufferName].effectiveBuffer as WebGPUDataBuffer;
}
}
}
// TODO - handle binding index buffer.
// if (webgpuPipelineContext.shaderProcessingContext.bufferNames.findIndex((name) => name === "indices") !== -1) {
// const indexBuffer = this._currentIndexBuffer ? this._currentIndexBuffer : (this._cacheRenderPipeline as any)._indexBuffer;
// this._currentDrawContext.buffers["indices"] = indexBuffer as WebGPUDataBuffer;
// }
}

const bindGroups = this._cacheBindGroups.getBindGroups(webgpuPipelineContext, this._currentDrawContext, this._currentMaterialContext);

if (!this._snapshotRendering.record) {
Expand Down
6 changes: 6 additions & 0 deletions packages/dev/core/src/Materials/material.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,12 @@ export class Material implements IAnimatable, IClipPlanesHolder {

protected _forceGLSL = false;

/**
* Tells the engine to draw geometry using vertex pulling instead of index drawing. This will automatically
* set the vertex buffers as storage buffers and make them accessible to the vertex shader.
*/
public useVertexPulling = false;

/** @internal */
public get _supportGlowLayer() {
return false;
Expand Down
4 changes: 4 additions & 0 deletions packages/dev/core/src/Meshes/mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2054,13 +2054,17 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {

const scene = this.getScene();
const engine = scene.getEngine();
const material = subMesh.getMaterial();

if ((this._unIndexed && fillMode !== Material.WireFrameFillMode) || fillMode == Material.PointFillMode) {
// or triangles as points
engine.drawArraysType(fillMode, subMesh.verticesStart, subMesh.verticesCount, this.forcedInstanceCount || instancesCount);
} else if (fillMode == Material.WireFrameFillMode) {
// Triangles as wireframe
engine.drawElementsType(fillMode, 0, subMesh._linesIndexCount, this.forcedInstanceCount || instancesCount);
} else if (material && material.useVertexPulling) {
// We're rendering the number of indices in the index buffer but the vertex shader is handling the data itself.
engine.drawArraysType(fillMode, subMesh.indexStart, subMesh.indexCount, this.forcedInstanceCount || instancesCount);
} else {
engine.drawElementsType(fillMode, subMesh.indexStart, subMesh.indexCount, this.forcedInstanceCount || instancesCount);
}
Expand Down