Skip to content
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

Reading vertex buffer in metal can generate 2 integer ops per byte loaded #7027

Open
PWhiddy opened this issue Jan 29, 2025 · 2 comments
Open
Labels
area: naga back-end Outputs of naga shader conversion area: performance How fast things go backend: metal Issues with Metal lang: Metal Metal Shading Language

Comments

@PWhiddy
Copy link
Contributor

PWhiddy commented Jan 29, 2025

It seems that for some reason that the naga generated shader for reading a vertex buffer in metal involves interpreting the input as bytes, then taking each byte one at a time, expanding it to u32 and shift/adding to unpack it into its final value. For vertices with a lot of attributes, this really starts to rack up.

Image Image

Is this expected behavior? It seems like it would either be able to read the attributes by interpreting the buffer as structs or by casting each of the attributes. Am I misunderstanding something? When rendering a lot of vertices this seems to be adding billions of operations to my VS.

macos, wgpu version 24.0.0

@PWhiddy PWhiddy changed the title Reading vertex buffer in metal can generate 2 integer ops per byte loaded. Reading vertex buffer in metal can generate 2 integer ops per byte loaded Jan 29, 2025
@PWhiddy
Copy link
Contributor Author

PWhiddy commented Jan 29, 2025

In my case with a large number of vertices and vertex attribute data (6M & 96 bytes respectively) swapping out the vertex buffer with a regular storage buffer of structs and manually pulling them resulted in ~20% speedup.

@cwfitzgerald cwfitzgerald added area: performance How fast things go backend: metal Issues with Metal area: naga back-end Outputs of naga shader conversion lang: Metal Metal Shading Language labels Jan 30, 2025
@cwfitzgerald
Copy link
Member

I believe this is expected right now, unfortunately. Vertex buffers are quite unconstrained in their alignment/stride/offsets so the only way to emulate this on top of storage buffers is through using a byte buffer. We might(?) be able to sometimes use a buffer of u32. I'm surprised that metal's compiler isn't getting rid of all this, but maybe that's too optimistic.

We need to switch to vertex pulling because we need to bounds check vertex buffers. This sounds like a good candidate for something that can be turned off with create_shader_module_trusted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: naga back-end Outputs of naga shader conversion area: performance How fast things go backend: metal Issues with Metal lang: Metal Metal Shading Language
Projects
Status: Todo
Development

No branches or pull requests

2 participants