diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c index aa07cada107..312dfad20aa 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -1031,7 +1031,7 @@ wsi_display_image_init(VkDevice device_h, return VK_ERROR_DEVICE_LOST; VkResult result = wsi_create_native_image(&chain->base, create_info, - 0, NULL, NULL, + 0, NULL, NULL, NULL, &image->base); if (result != VK_SUCCESS) return result; diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c index d9f445c93ef..496143c6f52 100644 --- a/src/vulkan/wsi/wsi_common_drm.c +++ b/src/vulkan/wsi/wsi_common_drm.c @@ -107,6 +107,7 @@ wsi_create_native_image(const struct wsi_swapchain *chain, uint32_t num_modifier_lists, const uint32_t *num_modifiers, const uint64_t *const *modifiers, + uint8_t *(alloc_shm)(struct wsi_image *image, unsigned size), struct wsi_image *image) { const struct wsi_device *wsi = chain->wsi; @@ -297,6 +298,19 @@ wsi_create_native_image(const struct wsi_swapchain *chain, VkMemoryRequirements reqs; wsi->GetImageMemoryRequirements(chain->device, image->image, &reqs); + void *sw_host_ptr = NULL; + if (alloc_shm) { + VkSubresourceLayout layout; + + wsi->GetImageSubresourceLayout(chain->device, image->image, + &(VkImageSubresource) { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .arrayLayer = 0, + }, &layout); + sw_host_ptr = (*alloc_shm)(image, layout.size); + } + const struct wsi_memory_allocate_info memory_wsi_info = { .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA, .pNext = NULL, @@ -313,9 +327,14 @@ wsi_create_native_image(const struct wsi_swapchain *chain, .image = image->image, .buffer = VK_NULL_HANDLE, }; + const VkImportMemoryHostPointerInfoEXT host_ptr_info = { + .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT, + .pNext = &memory_dedicated_info, + .pHostPointer = sw_host_ptr, + }; const VkMemoryAllocateInfo memory_info = { .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .pNext = &memory_dedicated_info, + .pNext = sw_host_ptr ? (void *)&host_ptr_info : (void *)&memory_dedicated_info, .allocationSize = reqs.size, .memoryTypeIndex = select_memory_type(wsi, true, reqs.memoryTypeBits), }; diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h index 1fe8211f9cb..f08002abfaf 100644 --- a/src/vulkan/wsi/wsi_common_private.h +++ b/src/vulkan/wsi/wsi_common_private.h @@ -94,6 +94,7 @@ wsi_create_native_image(const struct wsi_swapchain *chain, uint32_t num_modifier_lists, const uint32_t *num_modifiers, const uint64_t *const *modifiers, + uint8_t *(alloc_shm)(struct wsi_image *image, unsigned size), struct wsi_image *image); VkResult diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index 5e9faa93135..4d16ba60098 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -1015,7 +1015,7 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, result = wsi_create_native_image(&chain->base, pCreateInfo, chain->num_drm_modifiers > 0 ? 1 : 0, &chain->num_drm_modifiers, - &chain->drm_modifiers, &image->base); + &chain->drm_modifiers, NULL, &image->base); if (result != VK_SUCCESS) return result; diff --git a/src/vulkan/wsi/wsi_common_win32.c b/src/vulkan/wsi/wsi_common_win32.c index c62de45c881..78d92206563 100644 --- a/src/vulkan/wsi/wsi_common_win32.c +++ b/src/vulkan/wsi/wsi_common_win32.c @@ -301,6 +301,7 @@ wsi_create_native_image(const struct wsi_swapchain *chain, uint32_t num_modifier_lists, const uint32_t *num_modifiers, const uint64_t *const *modifiers, + uint8_t *(alloc_shm)(struct wsi_image *image, unsigned size), struct wsi_image *image) { const struct wsi_device *wsi = chain->wsi; @@ -432,7 +433,7 @@ wsi_win32_image_init(VkDevice device_h, struct wsi_win32_swapchain *chain = (struct wsi_win32_swapchain *) drv_chain; VkResult result = wsi_create_native_image(&chain->base, create_info, - 0, NULL, NULL, + 0, NULL, NULL, NULL, &image->base); if (result != VK_SUCCESS) return result; diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 0aa76f943ac..8b5592bf297 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -833,6 +833,9 @@ struct x11_image { struct xshmfence * shm_fence; uint32_t sync_fence; uint32_t serial; + xcb_shm_seg_t shmseg; + uint32_t shmid; + uint8_t * shmaddr; }; struct x11_swapchain { @@ -1338,6 +1341,29 @@ fail: return NULL; } +static uint8_t * +alloc_shm(struct wsi_image *imagew, unsigned size) +{ +#ifdef HAVE_SYS_SHM_H + struct x11_image *image = (struct x11_image *)imagew; + image->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0600); + if (image->shmid < 0) + return NULL; + + uint8_t *addr = (uint8_t *)shmat(image->shmid, 0, 0); + /* mark the segment immediately for deletion to avoid leaks */ + shmctl(image->shmid, IPC_RMID, 0); + + if (addr == (uint8_t *) -1) + return NULL; + + image->shmaddr = addr; + return addr; +#else + return NULL; +#endif +} + static VkResult x11_image_init(VkDevice device_h, struct x11_swapchain *chain, const VkSwapchainCreateInfoKHR *pCreateInfo, @@ -1356,6 +1382,7 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain, } else { result = wsi_create_native_image(&chain->base, pCreateInfo, num_tranches, num_modifiers, modifiers, + chain->has_mit_shm ? &alloc_shm : NULL, &image->base); } if (result < 0) @@ -1463,6 +1490,10 @@ x11_image_finish(struct x11_swapchain *chain, } wsi_destroy_image(&chain->base, &image->base); +#ifdef HAVE_SYS_SHM_H + if (image->shmaddr) + shmdt(image->shmaddr); +#endif } static void