-
-
Notifications
You must be signed in to change notification settings - Fork 12
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
Using vec3
in BindGroupLayout gives error during draw.
#7
Comments
Yeah I bumped into that one too: dgel/examples/material-phong.js Lines 448 to 452 in 9a85955
I haven't had much time to figure out but tried based on glsl spec Lines 140 to 166 in 228fde8
|
Stumbled across this lib/issue in earlier research and thought I'd share my solution. Think of std140 like Tetris, but you're filling equal chunks of memory to 16 bytes:
Here, I pad before vec2s/more complex uniforms to fill in empty space left by primitives. For an ideal buffer size, pack uniforms by length descending so that you can stack vec2s and primitives towards the end to minimize wasted space. const uniforms = Object.values({
time: 0,
uv: [0, 1],
position: [1, 2, 3],
color: [1, 1, 0, 1],
})
// Pad to 16 byte chunks of 2, 4 (std140 layout)
const pad2 = (n) => n + (n % 2)
const pad4 = (n) => n + ((4 - (n % 4)) % 4)
// Calculate packing size
const length = pad4(
uniforms.reduce(
(n, u) => n + (typeof u === 'number' ? 1 : u.length <= 2 ? pad2(u.length) : pad4(u.length)),
0,
),
)
const data = new Float32Array(length)
// Pack data
let offset = 0
for (const uniform of uniforms) {
if (typeof uniform === 'number') {
data[offset] = uniform
offset += 1 // leave empty space to stack primitives
} else {
const pad = uniform.length <= 2 ? pad2 : pad4
offset = pad(offset) // fill in empty space
data.set(uniform, offset)
offset += pad(uniform.length)
}
}
// Create buffer (don't need to re-align to 4 bytes)
const buffer = device.createBuffer({
size: data.byteLength,
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
mappedAtCreation: true,
})
// Map packed buffer
new Float32Array(buffer.getMappedRange()).set(data)
buffer.unmap()
device.queue.writeBuffer(buffer, 0, data)
// Usage in bind group/layout
const bindGroup = device.createBindGroup({
layout: pipeline.getBindGroupLayout(0),
entries: [
{
binding: 0,
resource: {
buffer,
},
},
],
}) |
Looks like wgsl is also matching the std140 alignment so fixing glsl alignment should fix wgsl too here: https://www.w3.org/TR/WGSL/#alignment-and-size
|
I was not able to spot exactly where the issue happens, but was able to work around it by making all Uniforms within a BindGroupLayout
vec4
instead ofvec3
.When using
vec3
I would get:Binding sizes are too small for bind group 0
For reference the current bindgrouplayout I'm using:
const circlesBindGroupLayout = new BindGroupLayout([ { buffer: {}, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, name: "Circles", uniforms: [ new Uniform("D_a", "vec4"), new Uniform("D_A", "vec4"), new Uniform("D_b", "vec4"), new Uniform("D_B", "vec4"), new Uniform("dimensions", "vec4") ], }, ]); return circlesBindGroupLayout;
The text was updated successfully, but these errors were encountered: