render/vulkan: Recycle memory maps for stage spans

Remapping buffers on every use causes a lot of unwanted pagefaults.
Reuse the mapping to significantly speed up the memcpy.
master
Kenny Levinsen 5 months ago committed by Alexander Orzechowski
parent 09603cdb0b
commit 47c578945c

@ -483,6 +483,7 @@ struct wlr_vk_shared_buffer {
VkBuffer buffer; VkBuffer buffer;
VkDeviceMemory memory; VkDeviceMemory memory;
VkDeviceSize buf_size; VkDeviceSize buf_size;
void *cpu_mapping;
struct wl_array allocs; // struct wlr_vk_allocation struct wl_array allocs; // struct wlr_vk_allocation
}; };

@ -187,6 +187,10 @@ static void shared_buffer_destroy(struct wlr_vk_renderer *r,
if (buffer->memory) { if (buffer->memory) {
vkFreeMemory(r->dev->dev, buffer->memory, NULL); vkFreeMemory(r->dev->dev, buffer->memory, NULL);
} }
if (buffer->cpu_mapping) {
vkUnmapMemory(r->dev->dev, buffer->memory);
buffer->cpu_mapping = NULL;
}
wl_list_remove(&buffer->link); wl_list_remove(&buffer->link);
free(buffer); free(buffer);

@ -80,19 +80,19 @@ static bool write_pixels(struct wlr_vk_texture *texture,
return false; return false;
} }
void *vmap; if (!span.buffer->cpu_mapping) {
res = vkMapMemory(dev, span.buffer->memory, span.alloc.start, res = vkMapMemory(dev, span.buffer->memory, 0, VK_WHOLE_SIZE, 0, &span.buffer->cpu_mapping);
bsize, 0, &vmap); if (res != VK_SUCCESS) {
if (res != VK_SUCCESS) { wlr_vk_error("vkMapMemory", res);
wlr_vk_error("vkMapMemory", res); free(copies);
free(copies); return false;
return false; }
} }
char *map = (char *)vmap; char *map = (char*)span.buffer->cpu_mapping + span.alloc.start;
// upload data // upload data
uint32_t buf_off = span.alloc.start + (map - (char *)vmap); uint32_t buf_off = span.alloc.start;
for (int i = 0; i < rects_len; i++) { for (int i = 0; i < rects_len; i++) {
pixman_box32_t rect = rects[i]; pixman_box32_t rect = rects[i];
uint32_t width = rect.x2 - rect.x1; uint32_t width = rect.x2 - rect.x1;
@ -137,9 +137,6 @@ static bool write_pixels(struct wlr_vk_texture *texture,
buf_off += height * packed_stride; buf_off += height * packed_stride;
} }
assert((uint32_t)(map - (char *)vmap) == bsize);
vkUnmapMemory(dev, span.buffer->memory);
// record staging cb // record staging cb
// will be executed before next frame // will be executed before next frame
VkCommandBuffer cb = vulkan_record_stage_cb(renderer); VkCommandBuffer cb = vulkan_record_stage_cb(renderer);

Loading…
Cancel
Save