mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-22 21:05:58 +01:00
render/vulkan: align staging buffers for texture upload
vkCmdCopyBufferToImage requires that the buffer offset be a multiple of the texel block size, which for single plane uncompressed formats is the same as the number of bytes per pixel. This commit adds an alignment parameter to vulkan_get_stage_span which ensures that the provided span (and the sequence of image copy operations derived which use it) have this alignment.
This commit is contained in:
parent
f0375eed24
commit
c02872e033
3 changed files with 10 additions and 4 deletions
|
@ -231,9 +231,11 @@ bool vulkan_submit_stage_wait(struct wlr_vk_renderer *renderer);
|
||||||
|
|
||||||
// Suballocates a buffer span with the given size that can be mapped
|
// Suballocates a buffer span with the given size that can be mapped
|
||||||
// and used as staging buffer. The allocation is implicitly released when the
|
// and used as staging buffer. The allocation is implicitly released when the
|
||||||
// stage cb has finished execution.
|
// stage cb has finished execution. The start of the span will be a multiple
|
||||||
|
// of the given alignment.
|
||||||
struct wlr_vk_buffer_span vulkan_get_stage_span(
|
struct wlr_vk_buffer_span vulkan_get_stage_span(
|
||||||
struct wlr_vk_renderer *renderer, VkDeviceSize size);
|
struct wlr_vk_renderer *renderer, VkDeviceSize size,
|
||||||
|
VkDeviceSize alignment);
|
||||||
|
|
||||||
// Tries to allocate a texture descriptor set. Will additionally
|
// Tries to allocate a texture descriptor set. Will additionally
|
||||||
// return the pool it was allocated from when successful (for freeing it later).
|
// return the pool it was allocated from when successful (for freeing it later).
|
||||||
|
|
|
@ -200,7 +200,7 @@ static void release_stage_allocations(struct wlr_vk_renderer *renderer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_vk_buffer_span vulkan_get_stage_span(struct wlr_vk_renderer *r,
|
struct wlr_vk_buffer_span vulkan_get_stage_span(struct wlr_vk_renderer *r,
|
||||||
VkDeviceSize size) {
|
VkDeviceSize size, VkDeviceSize alignment) {
|
||||||
// try to find free span
|
// try to find free span
|
||||||
// simple greedy allocation algorithm - should be enough for this usecase
|
// simple greedy allocation algorithm - should be enough for this usecase
|
||||||
// since all allocations are freed together after the frame
|
// since all allocations are freed together after the frame
|
||||||
|
@ -215,6 +215,10 @@ struct wlr_vk_buffer_span vulkan_get_stage_span(struct wlr_vk_renderer *r,
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(start <= buf->buf_size);
|
assert(start <= buf->buf_size);
|
||||||
|
|
||||||
|
// ensure the proposed start is a multiple of alignment
|
||||||
|
start += alignment - 1 - ((start + alignment - 1) % alignment);
|
||||||
|
|
||||||
if (buf->buf_size - start < size) {
|
if (buf->buf_size - start < size) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ static bool write_pixels(struct wlr_vk_texture *texture,
|
||||||
}
|
}
|
||||||
|
|
||||||
// get staging buffer
|
// get staging buffer
|
||||||
struct wlr_vk_buffer_span span = vulkan_get_stage_span(renderer, bsize);
|
struct wlr_vk_buffer_span span = vulkan_get_stage_span(renderer, bsize, bytespb);
|
||||||
if (!span.buffer || span.alloc.size != bsize) {
|
if (!span.buffer || span.alloc.size != bsize) {
|
||||||
wlr_log(WLR_ERROR, "Failed to retrieve staging buffer");
|
wlr_log(WLR_ERROR, "Failed to retrieve staging buffer");
|
||||||
free(copies);
|
free(copies);
|
||||||
|
|
Loading…
Reference in a new issue