You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Proposal: Run all index buffers through a compute shader validator #117
This is because the GPU hardware consumes an index buffer which usually sits in device-local memory, now that index buffer tells which offsets in the vertex buffers to fetch as input data.
This stage is not programmable, hence its impossible to prevent out-of-buffer-bound vertex data to be fetched.
In webGL this is not a problem because the intermediate layer actually checks each index buffer whether it contains out-of-range indices and modifies them while rendering.
However if you plan to allow SSBOs/UAVs and using these outputs as index buffers then the possibility of checking the index buffer validity on the CPU is gone (unless you want to pull the index buffer data before EVERY draw from device local memory, and completely kill perfomance by a factor of >100x).
What I propose
The compute shader can validate the index buffer, create a copy with only valid offsets and use that copy for drawing (GPU2GPU validation).
That way the data stays in device local memory and no unnecessary performance tradeoff happens (unmodified buffers can be not validated).
P.S. Similar applies to Indirect Draw Buffers
Reacted by Manh Nguyen Tien
Activity
devshgraphicsprogramming commented on Nov 16, 2018
To not compromise on performance you could introduce immutable read-only index buffers and indirect draw buffers (indirect draw would need fixed offset alignment to be valid too) that could be analysed once at data filling time and then quickly validated on the CPU before use when the size of the other buffers they are referencing is known
@devshgraphicsprogramming I think we can validate without any extra info (like the read-only index buffers), in theory:
the implementation already needs to track when resources (including buffers used as index buffers) change their usage, in order to validate and insert memory barriers
if it detects a change from, say UAV usage to the index buffer usage, it can insert those compute dispatches for validating the index ranges, or computing the maximum vertex index in the range.
I'm inclined to propose that WebGPU MVP doesn't support index buffers changed on the GPU, since this is quite a bit of headache, but eventually we can do that.
It's possible for me to upload a buffer that has an index that isn't used that's too high, or upload a single buffer that has both Uint8 and Uint16 indexes in it, and I use a separate buffer offset when setting my index buffer. I have done both of these before.
So "the max range of an index buffer" isn't a thing, it's "the max index range of a draw call". WebGL will always keep a shadow buffer on the CPU which is how it can validate this.
I was advocating for a native compute shader to do the validation and correction such that the data never has to do a GPU-CPU roundtrip and also the CPU is not involved in this at all!
I'm inclined to propose that WebGPU MVP doesn't support index buffers changed on the GPU, since this is quite a bit of headache, but eventually we can do that.
Then I'm not quite sure what webGPU brings to the table over webGL 2.0 and how it can do dekstop-class graphics in a browser.
It's possible for me to upload a buffer that has an index that isn't used that's too high, or upload a single buffer that has both Uint8 and Uint16 indexes in it, and I use a separate buffer offset when setting my index buffer. I have done both of these before.
You have to enforce [native] API alignment rules, so you cannot i.e. specify and index buffer offset that is not a multiple of the data type.
Furthermore the validation compute shader would have to run just before the use as index buffer, so it would check for the correct index type and range used.
WebGL will always keep a shadow buffer on the CPU which is how it can validate this.
Yes and that is awful.
if it detects a change from, say UAV usage to the index buffer usage, it can insert those compute dispatches for validating the index ranges, or computing the maximum vertex index in the range.
My idea was to generate a copy of the buffer range with appropriately clamped indices for the particular VAO/GraphicsPipliene(Primitive Assembly and Vertex Format).
I'm inclined to propose that WebGPU MVP doesn't support index buffers changed on the GPU, since this is quite a bit of headache, but eventually we can do that.
Then I'm not quite sure what webGPU brings to the table over webGL 2.0 and how it can do dekstop-class graphics in a browser.
I'm talking about MVP - Minimum Viable Product here. Basically, a usable demo. In an actual 1.0 release we'll absolutely need to support GPU-generated indices, there is no question here. Sorry about being unclear!
devshgraphicsprogramming commented on Nov 21, 2018
Closing. The group decided to do 1) CPU validation of the index range for drawIndexed 2) GPU validation of the index range for drawIndexedIndirect or robust buffer behavior. This avoids the need to run a complex compute shader per index range.
Activity
devshgraphicsprogramming commentedon Nov 16, 2018
To not compromise on performance you could introduce immutable read-only index buffers and indirect draw buffers (indirect draw would need fixed offset
alignmentto be valid too) that could be analysed once at data filling time and then quickly validated on the CPU before use when the size of the other buffers they are referencing is knownkvark commentedon Nov 20, 2018
@devshgraphicsprogramming I think we can validate without any extra info (like the read-only index buffers), in theory:
I'm inclined to propose that WebGPU MVP doesn't support index buffers changed on the GPU, since this is quite a bit of headache, but eventually we can do that.
magcius commentedon Nov 20, 2018
It's possible for me to upload a buffer that has an index that isn't used that's too high, or upload a single buffer that has both Uint8 and Uint16 indexes in it, and I use a separate buffer offset when setting my index buffer. I have done both of these before.
So "the max range of an index buffer" isn't a thing, it's "the max index range of a draw call". WebGL will always keep a shadow buffer on the CPU which is how it can validate this.
kvark commentedon Nov 20, 2018
Keeping a CPU copy of the buffer and validating it for cases where it's populated by the GPU makes that population rather useless...
devshgraphicsprogramming commentedon Nov 20, 2018
I was advocating for a native compute shader to do the validation and correction such that the data never has to do a GPU-CPU roundtrip and also the CPU is not involved in this at all!
Then I'm not quite sure what webGPU brings to the table over webGL 2.0 and how it can do dekstop-class graphics in a browser.
You have to enforce [native] API alignment rules, so you cannot i.e. specify and index buffer offset that is not a multiple of the data type.
Furthermore the validation compute shader would have to run just before the use as index buffer, so it would check for the correct index type and range used.
Yes and that is awful.
My idea was to generate a copy of the buffer range with appropriately
clampedindices for the particular VAO/GraphicsPipliene(Primitive Assembly and Vertex Format).kvark commentedon Nov 20, 2018
I'm talking about MVP - Minimum Viable Product here. Basically, a usable demo. In an actual 1.0 release we'll absolutely need to support GPU-generated indices, there is no question here. Sorry about being unclear!
devshgraphicsprogramming commentedon Nov 21, 2018
In that case I can rest easy.
Kangz commentedon Sep 2, 2021
Closing. The group decided to do 1) CPU validation of the index range for
drawIndexed2) GPU validation of the index range fordrawIndexedIndirector robust buffer behavior. This avoids the need to run a complex compute shader per index range.Run tests serially in cmdline runner (gpuweb#121)