render/vulkan: use non-coherent memory for read_pixels()

The spec for VkMemoryPropertyFlagBits says:

> device coherent accesses may be slower than equivalent accesses
> without device coherence [...] it is generally inadvisable to
> use device coherent or device uncached memory except when really
> needed

We don't really need coherent memory so let's not require it and
invalidate the memory range after mapping instead.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3868
master
Simon Ser 3 months ago
parent 5432108846
commit 52dce29e06

@ -1224,7 +1224,6 @@ bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer,
int mem_type = vulkan_find_mem_type(vk_renderer->dev, int mem_type = vulkan_find_mem_type(vk_renderer->dev,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
VK_MEMORY_PROPERTY_HOST_CACHED_BIT, VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
mem_reqs.memoryTypeBits); mem_reqs.memoryTypeBits);
if (mem_type < 0) { if (mem_type < 0) {
@ -1361,6 +1360,19 @@ bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer,
return false; return false;
} }
VkMappedMemoryRange mem_range = {
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.memory = dst_img_memory,
.offset = 0,
.size = VK_WHOLE_SIZE,
};
res = vkInvalidateMappedMemoryRanges(dev, 1, &mem_range);
if (res != VK_SUCCESS) {
wlr_vk_error("vkInvalidateMappedMemoryRanges", res);
vkUnmapMemory(dev, dst_img_memory);
return false;
}
const char *d = (const char *)v + img_sub_layout.offset; const char *d = (const char *)v + img_sub_layout.offset;
unsigned char *p = (unsigned char *)data + dst_y * stride; unsigned char *p = (unsigned char *)data + dst_y * stride;
uint32_t bytes_per_pixel = pixel_format_info->bytes_per_block; uint32_t bytes_per_pixel = pixel_format_info->bytes_per_block;
@ -1376,6 +1388,7 @@ bool vulkan_read_pixels(struct wlr_vk_renderer *vk_renderer,
vkUnmapMemory(dev, dst_img_memory); vkUnmapMemory(dev, dst_img_memory);
// Don't need to free anything else, since memory and image are cached // Don't need to free anything else, since memory and image are cached
return true; return true;
free_memory: free_memory:
vkFreeMemory(dev, dst_img_memory, NULL); vkFreeMemory(dev, dst_img_memory, NULL);
destroy_image: destroy_image:

Loading…
Cancel
Save