Mesa (main): vulkan/wsi: Support tiled CPU images
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Jul 7 18:47:59 UTC 2022
Module: Mesa
Branch: main
Commit: 124848bf9efa1cc5d8a3cdfc654e0c03d57540e3
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=124848bf9efa1cc5d8a3cdfc654e0c03d57540e3
Author: Jason Ekstrand <jason.ekstrand at collabora.com>
Date: Wed Jul 6 18:04:58 2022 -0500
vulkan/wsi: Support tiled CPU images
Some drivers such as lavapipe are 100% fine with using linear for WSI
images. Most HW drivers, however, would rather render tiled and eat a
blit.
Reviewed-by: Jesse Natalie <jenatali at microsoft.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/17388>
---
src/gallium/frontends/lavapipe/lvp_wsi.c | 1 +
src/vulkan/wsi/wsi_common.c | 97 ++++++++++++++++++++++++++------
src/vulkan/wsi/wsi_common.h | 3 +
3 files changed, 83 insertions(+), 18 deletions(-)
diff --git a/src/gallium/frontends/lavapipe/lvp_wsi.c b/src/gallium/frontends/lavapipe/lvp_wsi.c
index 39d4f826fa8..2305d6f267f 100644
--- a/src/gallium/frontends/lavapipe/lvp_wsi.c
+++ b/src/gallium/frontends/lavapipe/lvp_wsi.c
@@ -43,6 +43,7 @@ lvp_init_wsi(struct lvp_physical_device *physical_device)
if (result != VK_SUCCESS)
return result;
+ physical_device->wsi_device.wants_linear = true;
physical_device->vk.wsi_device = &physical_device->wsi_device;
return VK_SUCCESS;
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
index ecd13d9dfe7..11989a71ba9 100644
--- a/src/vulkan/wsi/wsi_common.c
+++ b/src/vulkan/wsi/wsi_common.c
@@ -265,7 +265,11 @@ wsi_swapchain_init(const struct wsi_device *wsi,
chain->wsi = wsi;
chain->device = _device;
chain->alloc = *pAllocator;
+
chain->use_buffer_blit = use_buffer_blit;
+ if (wsi->sw && !wsi->wants_linear)
+ chain->use_buffer_blit = true;
+
chain->buffer_blit_queue = VK_NULL_HANDLE;
if (use_buffer_blit && wsi->get_buffer_blit_queue)
chain->buffer_blit_queue = wsi->get_buffer_blit_queue(_device);
@@ -550,8 +554,10 @@ wsi_destroy_image(const struct wsi_swapchain *chain,
close(image->dma_buf_fd);
#endif
- if (image->cpu_map != NULL)
- wsi->UnmapMemory(chain->device, image->memory);
+ if (image->cpu_map != NULL) {
+ wsi->UnmapMemory(chain->device, image->buffer.buffer != VK_NULL_HANDLE ?
+ image->buffer.memory : image->memory);
+ }
if (image->buffer.blit_cmd_buffers) {
int cmd_buffer_count =
@@ -1343,24 +1349,42 @@ wsi_create_buffer_image_mem(const struct wsi_swapchain *chain,
.pNext = NULL,
.implicit_sync = implicit_sync,
};
- const VkExportMemoryAllocateInfo memory_export_info = {
- .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
- .pNext = &memory_wsi_info,
- .handleTypes = handle_types,
- };
const VkMemoryDedicatedAllocateInfo buf_mem_dedicated_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
- .pNext = &memory_export_info,
+ .pNext = &memory_wsi_info,
.image = VK_NULL_HANDLE,
.buffer = image->buffer.buffer,
};
- const VkMemoryAllocateInfo buf_mem_info = {
+ VkMemoryAllocateInfo buf_mem_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = &buf_mem_dedicated_info,
.allocationSize = info->linear_size,
.memoryTypeIndex =
info->select_buffer_memory_type(wsi, reqs.memoryTypeBits),
};
+
+ void *sw_host_ptr = NULL;
+ if (info->alloc_shm)
+ sw_host_ptr = info->alloc_shm(image, info->linear_size);
+
+ VkExportMemoryAllocateInfo memory_export_info;
+ VkImportMemoryHostPointerInfoEXT host_ptr_info;
+ if (sw_host_ptr != NULL) {
+ host_ptr_info = (VkImportMemoryHostPointerInfoEXT) {
+ .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
+ .pHostPointer = sw_host_ptr,
+ .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
+ };
+ __vk_append_struct(&buf_mem_info, &host_ptr_info);
+ } else if (handle_types != 0) {
+ memory_export_info = (VkExportMemoryAllocateInfo) {
+ .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
+ .pNext = &memory_wsi_info,
+ .handleTypes = handle_types,
+ };
+ __vk_append_struct(&buf_mem_info, &memory_export_info);
+ }
+
result = wsi->AllocateMemory(chain->device, &buf_mem_info,
&chain->alloc, &image->buffer.memory);
if (result != VK_SUCCESS)
@@ -1540,9 +1564,9 @@ wsi_configure_buffer_image(UNUSED const struct wsi_swapchain *chain,
}
static VkResult
-wsi_create_cpu_image_mem(const struct wsi_swapchain *chain,
- const struct wsi_image_info *info,
- struct wsi_image *image)
+wsi_create_cpu_linear_image_mem(const struct wsi_swapchain *chain,
+ const struct wsi_image_info *info,
+ struct wsi_image *image)
{
const struct wsi_device *wsi = chain->wsi;
VkResult result;
@@ -1604,6 +1628,26 @@ wsi_create_cpu_image_mem(const struct wsi_swapchain *chain,
return VK_SUCCESS;
}
+static VkResult
+wsi_create_cpu_buffer_image_mem(const struct wsi_swapchain *chain,
+ const struct wsi_image_info *info,
+ struct wsi_image *image)
+{
+ VkResult result;
+
+ result = wsi_create_buffer_image_mem(chain, info, image, 0,
+ false /* implicit_sync */);
+ if (result != VK_SUCCESS)
+ return result;
+
+ result = chain->wsi->MapMemory(chain->device, image->buffer.memory,
+ 0, VK_WHOLE_SIZE, 0, &image->cpu_map);
+ if (result != VK_SUCCESS)
+ return result;
+
+ return VK_SUCCESS;
+}
+
VkResult
wsi_configure_cpu_image(const struct wsi_swapchain *chain,
const VkSwapchainCreateInfoKHR *pCreateInfo,
@@ -1611,16 +1655,33 @@ wsi_configure_cpu_image(const struct wsi_swapchain *chain,
unsigned size),
struct wsi_image_info *info)
{
- const VkExternalMemoryHandleTypeFlags handle_type =
+ const VkExternalMemoryHandleTypeFlags handle_types =
alloc_shm ? VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT : 0;
- VkResult result = wsi_configure_image(chain, pCreateInfo,
- handle_type, info);
- if (result != VK_SUCCESS)
- return result;
+ if (chain->use_buffer_blit) {
+ VkResult result = wsi_configure_buffer_image(chain, pCreateInfo,
+ 1 /* stride_align */,
+ 1 /* size_align */,
+ info);
+ if (result != VK_SUCCESS)
+ return result;
+
+ info->select_buffer_memory_type = wsi_select_host_memory_type;
+ info->select_image_memory_type = wsi_select_device_memory_type;
+ info->create_mem = wsi_create_cpu_buffer_image_mem;
+ } else {
+ VkResult result = wsi_configure_image(chain, pCreateInfo,
+ handle_types, info);
+ if (result != VK_SUCCESS)
+ return result;
+
+ /* Force the image to be linear */
+ info->create.tiling = VK_IMAGE_TILING_LINEAR;
+
+ info->create_mem = wsi_create_cpu_linear_image_mem;
+ }
info->alloc_shm = alloc_shm;
- info->create_mem = wsi_create_cpu_image_mem;
return VK_SUCCESS;
}
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index 0d50385ddd1..efd3e765200 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -140,6 +140,9 @@ struct wsi_device {
bool sw;
+ /* Set to true if the implementation is ok with linear WSI images. */
+ bool wants_linear;
+
/* Signals the semaphore such that any wait on the semaphore will wait on
* any reads or writes on the give memory object. This is used to
* implement the semaphore signal operation in vkAcquireNextImage. This
More information about the mesa-commit
mailing list