SetBindGroup() and uniform buffer dynamic offset

70 views
Skip to first unread message

Jean-Colas Prunier

unread,
Aug 14, 2023, 8:07:53 AM8/14/23
to Dawn Graphics
Hi everyone,

We've experimented with building a UI using Dawn. All primitives in this UI are quads. Because each quad has unique properties such as its position, size, uv coordinates, color, etc. we are using buffers with dynamic offsets to pass that data to the shader.

The sort of limitation I seem to have (unless there's another way of doing this that I am not aware of) is that I can't render the quads in batch because I need to set the offset for each rendered quad. So I need to do something like

```
for (unsigned i = 0; i < num_quads; ++i) {
    pass.SetIndexBuffer(index_buffer_, wgpu::IndexFormat::Uint32, index_offset);
    pass.SetBindGroup(0, bindgroup_, 1, &bindgroup_offset);
    pass.DrawIndexed(6); 
    bindgroup_offset += shader_params_offset;
    index_offset += 6 * sizeof(uint32_t);
}
```

Instead of 
```
pass.SetIndexBuffer(index_buffer_, wgpu::IndexFormat::Uint32, index_offset);
pass.SetBindGroup(0, bindgroup_, 1, &bindgroup_offset, array_stride); // this wouldn't work of course but just to illiustrate the idea
pass.DrawIndexed(num_quads * 2 * 3); 
```
Of course, the second method doesn't work ( with respect to  dynamic buffers) but was wondering if 1) there was a way of making this possible in the current implementation 2) whether you could see this as a possible thing to implement in the future (if this is technically possible with respect to the underlying APIs). The idea would that could just render a batch of triangles and specify a contiguous memory block in which the dynamic buffers for the shaders parameters would be stored (you would also need to indicate some kind of array stride and how many triangles you'd render before stepping forward to the next set of shader parameters in the buffer - at least 2 additional parameters). 

Of course no idea if this is even possible, but to summarize this would be "how could one render a batch of primitive while still taking advantage of dynamic offset for uniform buffers".

Thanks a lot. 

Corentin Wallez

unread,
Aug 15, 2023, 12:56:39 PM8/15/23
to Jean-Colas Prunier, Dawn Graphics
Hey Jean-Colas,

As you figured out there is no way to use SetBindGroup with a dynamic offset + stride for each "quad". However you could take advantage of storage buffers to achieve a similar result: each quad would have an index passed as an input in the vertex shader (either it's just vertex_index / 4, or an extra vertex attribute specifying the index), then use that to index and unsized array in the storage buffer. This sounds very much like "programmable vertex pulling" which some game engines started using once storage buffer-like functionality became available.

Hope this helps!

Corentin

--
You received this message because you are subscribed to the Google Groups "Dawn Graphics" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dawn-graphic...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dawn-graphics/16f6f154-0b2d-4e21-bb4c-8b8daec38849n%40googlegroups.com.

Jean-Colas Prunier

unread,
Aug 18, 2023, 6:29:24 AM8/18/23
to Dawn Graphics

Thanks a lot Corentin.

Great suggestion; it definitely helps).

Thanks for your time.
Reply all
Reply to author
Forward
0 new messages