Skip to content

Commit 44198f8

Browse files
mvaligurskyMartin Valigursky
andauthored
Validate shader vertex attributes are available in vertex buffers (#7431)
* Validate shader vertex attributes are available in vertex buffers * only in debug build --------- Co-authored-by: Martin Valigursky <[email protected]>
1 parent 66ed5ec commit 44198f8

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

src/platform/graphics/graphics-device.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { ScopeSpace } from './scope-space.js';
1818
import { VertexBuffer } from './vertex-buffer.js';
1919
import { VertexFormat } from './vertex-format.js';
2020
import { StencilParameters } from './stencil-parameters.js';
21+
import { DebugGraphics } from './debug-graphics.js';
2122

2223
/**
2324
* @import { Compute } from './compute.js'
@@ -30,6 +31,8 @@ import { StencilParameters } from './stencil-parameters.js';
3031
* @import { Texture } from './texture.js'
3132
*/
3233

34+
const _tempSet = new Set();
35+
3336
/**
3437
* The graphics device manages the underlying graphics context. It is responsible for submitting
3538
* render state changes and graphics primitives to the hardware. A graphics device is tied to a
@@ -1011,6 +1014,38 @@ class GraphicsDevice extends EventHandler {
10111014
}
10121015
return undefined;
10131016
}
1017+
1018+
/**
1019+
* Validate that all attributes required by the shader are present in the currently assigned
1020+
* vertex buffers.
1021+
*
1022+
* @param {Shader} shader - The shader to validate.
1023+
* @param {VertexFormat} vb0Format - The format of the first vertex buffer.
1024+
* @param {VertexFormat} vb1Format - The format of the second vertex buffer.
1025+
* @protected
1026+
*/
1027+
validateAttributes(shader, vb0Format, vb1Format) {
1028+
1029+
Debug.call(() => {
1030+
// add all attribute names from vertex formats to the set
1031+
_tempSet.clear();
1032+
vb0Format?.elements.forEach(element => _tempSet.add(element.name));
1033+
vb1Format?.elements.forEach(element => _tempSet.add(element.name));
1034+
1035+
// this is an object, we need to iterator over keys and make sure the value is in the temp set
1036+
const attributes = shader.definition.attributes;
1037+
for (const name in attributes) {
1038+
const value = attributes[name];
1039+
if (!_tempSet.has(value)) {
1040+
Debug.errorOnce(`Attribute [${name}: ${value}] required by the shader is not present in the currently assigned vertex buffers, while rendering [${DebugGraphics.toString()}]`, {
1041+
shader,
1042+
vb0Format,
1043+
vb1Format
1044+
});
1045+
}
1046+
}
1047+
});
1048+
}
10141049
}
10151050

10161051
export { GraphicsDevice };

src/platform/graphics/webgl/webgl-graphics-device.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,6 +1729,8 @@ class WebglGraphicsDevice extends GraphicsDevice {
17291729
const samplers = shader.impl.samplers;
17301730
const uniforms = shader.impl.uniforms;
17311731

1732+
Debug.call(() => this.validateAttributes(this.shader, this.vertexBuffers[0]?.format, this.vertexBuffers[1]?.format));
1733+
17321734
// vertex buffers
17331735
if (!keepBuffers) {
17341736
this.setBuffers();

src/platform/graphics/webgpu/webgpu-graphics-device.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,8 @@ class WebgpuGraphicsDevice extends GraphicsDevice {
564564
}
565565
}
566566

567+
Debug.call(() => this.validateAttributes(this.shader, vb0?.format, vb1?.format));
568+
567569
// render pipeline
568570
const pipeline = this.renderPipeline.get(primitive, vb0?.format, vb1?.format, this.shader, this.renderTarget,
569571
this.bindGroupFormats, this.blendState, this.depthState, this.cullMode,

0 commit comments

Comments
 (0)