dnkl/foot
41
2.0k
Fork
You've already forked foot
244

Use a stride that is a multiple of 256 #2182

Closed
opened 2025年10月02日 16:23:11 +02:00 by mahkoh · 5 comments

Describe your feature request

On integrated GPUs, the compositor might be able to import the buffer created by foot directly and display it without any additional copies compared to dmabuf.

However, AMD hardware requires images to have a stride that is a multiple of 256 which means that this zerocopy path fails for most window sizes because foot uses a tightly packed stride at the moment.

### Describe your feature request On integrated GPUs, the compositor might be able to import the buffer created by foot directly and display it without any additional copies compared to dmabuf. However, AMD hardware requires images to have a stride that is a multiple of 256 which means that this zerocopy path fails for most window sizes because foot uses a tightly packed stride at the moment.
Owner
Copy link

I don't know how to verify we're hitting the zero-copy path, but for starters, I could write a patch that adds, say, tweak.stride-multiple for you to test?

If it works, we can keep it, with a default of 256.

I don't know how to verify we're hitting the zero-copy path, but for starters, I could write a patch that adds, say, `tweak.stride-multiple` for you to test? If it works, we can keep it, with a default of 256.
Author
Copy link

I don't know how to verify we're hitting the zero-copy path

You can run the current master of https://github.com/mahkoh/jay. I'm not aware of any other compositor that tries to do this at the moment.

  1. Enable debug logging: jay set-log-level debug
  2. If you have multiple GPUs, ensure that your integrated GPU is used for rendering: jay randr card 0 primary, the number depends on which GPU is the iGPU
  3. Look at the logs: jay log -f
>I don't know how to verify we're hitting the zero-copy path You can run the current master of https://github.com/mahkoh/jay. I'm not aware of any other compositor that tries to do this at the moment. 1. Enable debug logging: `jay set-log-level debug` 2. If you have multiple GPUs, ensure that your integrated GPU is used for rendering: `jay randr card 0 primary`, the number depends on which GPU is the iGPU 3. Look at the logs: `jay log -f`
Owner
Copy link

Btw, I juse realized; importing one surface is faster if you direct-import it. The downside however is that you can't release the wayland buffer immediately, forcing foot to double-buffer instead. This is slow - in most cases slower than memcpy:ing the buffer. But exact numbers depend on what you're doing and how much changes there are between each frame.

This is obviously only an "issue" if you're releasing buffers immediately at all. If you don't (smithay doesn't - not sure what jay is based on?), then direct import is a win-win. If you do, then it's not an obvious win.

Btw, I juse realized; importing **one** surface is faster if you direct-import it. The downside however is that you can't release the wayland buffer immediately, forcing foot to double-buffer instead. This is slow - in most cases slower than memcpy:ing the buffer. But exact numbers depend on what you're doing and how much changes there are between each frame. This is obviously only an "issue" if you're releasing buffers immediately at all. If you don't (smithay doesn't - not sure what jay is based on?), then direct import is a win-win. If you do, then it's not an obvious win.
Author
Copy link

This is slow - in most cases slower than memcpy:ing the buffer.

The compositor doesn't have access to a faster memcpy implementation than the client.

I've looked into this in the past but foot's requirements are not reasonable. Essentially, foot requires the compositor to perform the copy in the wl_surface.commit handler before processing or sending any other messages. This means that the copy has to be performed synchronously and cannot be offloaded to a helper thread or the GPU. Which means that if foot sends a large update, the entire desktop will lag because the compositor will miss the next vblank.

All shm uploads and downloads in Jay are asynchronously performed on helper threads, if a CPU copy is required; and in vulkan transfer or async compute queues if a GPU copy is required, so that progress on the vulkan graphics queue is not blocked by the up or download. This means that clients using wl_shm will never degrade the performance of the compositor (within reason) even at very large surface size.

There is also the issue that Jay allows the user to change the render API (opengl/vulkan) and the GPU used for rendering at runtime. Which means that I would have to not only perform a copy to GPU memory directly, I would additionally have to perform a copy to a CPU buffer so that I can re-upload the buffer when the GPU context changes.

>This is slow - in most cases slower than memcpy:ing the buffer. The compositor doesn't have access to a faster memcpy implementation than the client. I've looked into this in the past but foot's requirements are not reasonable. Essentially, foot requires the compositor to perform the copy in the wl_surface.commit handler before processing or sending any other messages. This means that the copy has to be performed synchronously and cannot be offloaded to a helper thread or the GPU. Which means that if foot sends a large update, the entire desktop will lag because the compositor will miss the next vblank. All shm uploads and downloads in Jay are asynchronously performed on helper threads, if a CPU copy is required; and in vulkan transfer or async compute queues if a GPU copy is required, so that progress on the vulkan graphics queue is not blocked by the up or download. This means that clients using wl_shm will never degrade the performance of the compositor (within reason) even at very large surface size. There is also the issue that Jay allows the user to change the render API (opengl/vulkan) and the GPU used for rendering at runtime. Which means that I would have to not *only* perform a copy to GPU memory directly, I would additionally have to perform a copy to a CPU buffer so that I can re-upload the buffer when the GPU context changes.
Owner
Copy link

The compositor doesn't have access to a faster memcpy implementation than the client.

You're right. But my main point was simply to make sure you were aware that if jay was doing immediate releases, some of the wins on the compositor side would turn into an increased cost on the client side.

Without direct import, not doing immediate buffer release does mean a decrease in performance, system wide, since you now have to memcpy both in the client, and in the compositor. It's my understanding that this is the reason firefox (and foot) tend to perform badly under niri (something I've noticed myself, to the point where I can't use niri on my 4K monitor).

Essentially, foot requires the compositor to perform the copy in the wl_surface.commit handler before processing or sending any other messages.

You may very well be right - I don't know the details of your compositor. But really, the only requirement is that the buffer is returned to foot before the next frame callback (which is when foot will need a "new" buffer). But perhaps that translates to what you said.

But all of this is really irrelevant; I'm not trying to push anything on anyone, and foot handles buffers not being released immediate just fine. It even handles buffers not being released at all (but eating lots of RAM., obviously). Again, just making sure it's being understood that doing a direct import affects the ability to do immediate releases, and that that affects how the system as a whole performs. You seem to have a good understanding of all of this, so let's just drop this. If you happen to do any system-level benchmarks, either with immediate vs. non-immediate buffer releases, or GPU direct upload vs. copying, I'd be interested in the results.

> The compositor doesn't have access to a faster memcpy implementation than the client. You're right. But my main point was simply to make sure you were aware that **if** jay was doing immediate releases, some of the wins on the compositor side would turn into an increased cost on the client side. Without direct import, not doing immediate buffer release does mean a decrease in performance, system wide, since you now have to memcpy both in the client, and in the compositor. It's my understanding that this is the reason firefox (and foot) tend to perform badly under niri (something I've noticed myself, to the point where I can't use niri on my 4K monitor). > Essentially, foot requires the compositor to perform the copy in the wl_surface.commit handler before processing or sending any other messages. You may very well be right - I don't know the details of your compositor. But really, the only requirement is that the buffer is returned to foot before the next frame callback (which is when foot will need a "new" buffer). But perhaps that translates to what you said. But all of this is really irrelevant; I'm not trying to push anything on anyone, and foot handles buffers not being released immediate just fine. It even handles buffers not being released at all (but eating lots of RAM., obviously). Again, just making sure it's being understood that doing a direct import affects the ability to do immediate releases, and that that affects how the system as a whole performs. You seem to have a good understanding of all of this, so let's just drop this. If you happen to do any system-level benchmarks, either with immediate vs. non-immediate buffer releases, or GPU direct upload vs. copying, I'd be interested in the results.
Sign in to join this conversation.
No Branch/Tag specified
master
osc-5522
sixel-heap-buffer-overflow
releases/1.27
releases/1.26
releases/1.25
releases/1.24
multi-cursor
releases/1.23
pixman-16f-2
releases/1.22
releases/1.21
releases/1.20
releases/1.19
releases/1.18
releases/1.17
releases/1.16
releases/1.15
releases/1.14
releases/1.13
releases/1.12
releases/1.11
releases/1.10
releases/1.9
releases/1.8
releases/1.7
releases/1.6
releases/1.5
releases/1.4
releases/1.3
releases/1.2
releases/1.1
releases/1.0
1.27.0
1.26.1
1.26.0
1.25.0
1.24.0
1.23.1
1.23.0
1.22.3
1.22.2
1.22.1
1.22.0
1.21.0
1.20.2
1.20.1
1.20.0
1.19.0
1.18.1
1.18.0
1.17.2
1.17.1
1.17.0
1.16.2
1.16.1
1.16.0
1.15.3
1.15.2
1.15.1
1.15.0
1.14.0
1.13.1
1.13.0
1.12.1
1.12.0
1.11.0
1.10.3
1.10.2
1.10.1
1.10.0
1.9.2
1.9.1
1.9.0
1.8.2
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.0
1.2.3
1.2.2
1.2.1
1.2.0
1.1.0
1.0.0
0.9.0
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dnkl/foot#2182
Reference in a new issue
dnkl/foot
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?