From 549d938621b2b948ac176a42b0202b10e61e6399 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 2 Aug 2021 05:32:44 +1000 Subject: [PATCH] Update to mesa 21.1.5 + vk wsi fixes Resolves: rhbz#1970253 --- mesa-vk-wsi-sw-fixes.patch | 403 +++++++++++++++++++++++++++++++++++++ mesa.spec | 7 +- sources | 2 +- 3 files changed, 410 insertions(+), 2 deletions(-) create mode 100644 mesa-vk-wsi-sw-fixes.patch diff --git a/mesa-vk-wsi-sw-fixes.patch b/mesa-vk-wsi-sw-fixes.patch new file mode 100644 index 0000000..a72e411 --- /dev/null +++ b/mesa-vk-wsi-sw-fixes.patch @@ -0,0 +1,403 @@ +diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c +index e2a7d337ecf..bc4d87611e0 100644 +--- a/src/vulkan/wsi/wsi_common_wayland.c ++++ b/src/vulkan/wsi/wsi_common_wayland.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include "drm-uapi/drm_fourcc.h" + +@@ -44,9 +45,15 @@ + #include + #include + #include ++#include + + struct wsi_wayland; + ++struct wsi_wl_display_swrast { ++ struct wl_shm * wl_shm; ++ struct u_vector formats; ++}; ++ + struct wsi_wl_display_drm { + struct wl_drm * wl_drm; + struct u_vector formats; +@@ -69,6 +76,7 @@ struct wsi_wl_display { + struct wl_display * wl_display_wrapper; + struct wl_event_queue * queue; + ++ struct wsi_wl_display_swrast swrast; + struct wsi_wl_display_drm drm; + struct wsi_wl_display_dmabuf dmabuf; + +@@ -79,6 +87,8 @@ struct wsi_wl_display { + + /* Only used for displays created by wsi_wl_display_create */ + uint32_t refcount; ++ ++ bool sw; + }; + + struct wsi_wayland { +@@ -183,6 +193,40 @@ wsi_wl_display_add_wl_format(struct wsi_wl_display *display, + } + } + ++static void ++wsi_wl_display_add_wl_shm_format(struct wsi_wl_display *display, ++ struct u_vector *formats, ++ uint32_t wl_shm_format) ++{ ++ switch (wl_shm_format) { ++ case WL_SHM_FORMAT_XBGR8888: ++ wsi_wl_display_add_vk_format(display, formats, ++ VK_FORMAT_R8G8B8_SRGB); ++ wsi_wl_display_add_vk_format(display, formats, ++ VK_FORMAT_R8G8B8_UNORM); ++ FALLTHROUGH; ++ case WL_SHM_FORMAT_ABGR8888: ++ wsi_wl_display_add_vk_format(display, formats, ++ VK_FORMAT_R8G8B8A8_SRGB); ++ wsi_wl_display_add_vk_format(display, formats, ++ VK_FORMAT_R8G8B8A8_UNORM); ++ break; ++ case WL_SHM_FORMAT_XRGB8888: ++ wsi_wl_display_add_vk_format(display, formats, ++ VK_FORMAT_B8G8R8_SRGB); ++ wsi_wl_display_add_vk_format(display, formats, ++ VK_FORMAT_B8G8R8_UNORM); ++ FALLTHROUGH; ++ case WL_SHM_FORMAT_ARGB8888: ++ wsi_wl_display_add_vk_format(display, formats, ++ VK_FORMAT_B8G8R8A8_SRGB); ++ wsi_wl_display_add_vk_format(display, formats, ++ VK_FORMAT_B8G8R8A8_UNORM); ++ break; ++ } ++} ++ ++ + static void + drm_handle_device(void *data, struct wl_drm *drm, const char *name) + { +@@ -232,6 +276,23 @@ wl_drm_format_for_vk_format(VkFormat vk_format, bool alpha) + } + } + ++static uint32_t ++wl_shm_format_for_vk_format(VkFormat vk_format, bool alpha) ++{ ++ switch (vk_format) { ++ case VK_FORMAT_R8G8B8A8_UNORM: ++ case VK_FORMAT_R8G8B8A8_SRGB: ++ return alpha ? WL_SHM_FORMAT_ABGR8888 : WL_SHM_FORMAT_XBGR8888; ++ case VK_FORMAT_B8G8R8A8_UNORM: ++ case VK_FORMAT_B8G8R8A8_SRGB: ++ return alpha ? WL_SHM_FORMAT_ARGB8888 : WL_SHM_FORMAT_XRGB8888; ++ ++ default: ++ assert(!"Unsupported Vulkan format"); ++ return 0; ++ } ++} ++ + static void + drm_handle_format(void *data, struct wl_drm *drm, uint32_t wl_format) + { +@@ -311,12 +372,34 @@ static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = { + dmabuf_handle_modifier, + }; + ++static void ++shm_handle_format(void *data, struct wl_shm *shm, uint32_t format) ++{ ++ struct wsi_wl_display *display = data; ++ if (display->swrast.formats.element_size == 0) ++ return; ++ ++ wsi_wl_display_add_wl_shm_format(display, &display->swrast.formats, format); ++} ++ ++static const struct wl_shm_listener shm_listener = { ++ .format = shm_handle_format ++}; ++ + static void + registry_handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, uint32_t version) + { + struct wsi_wl_display *display = data; + ++ if (display->sw) { ++ if (strcmp(interface, "wl_shm") == 0) { ++ display->swrast.wl_shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); ++ wl_shm_add_listener(display->swrast.wl_shm, &shm_listener, display); ++ } ++ return; ++ } ++ + if (strcmp(interface, "wl_drm") == 0) { + assert(display->drm.wl_drm == NULL); + +@@ -348,10 +431,13 @@ wsi_wl_display_finish(struct wsi_wl_display *display) + { + assert(display->refcount == 0); + ++ u_vector_finish(&display->swrast.formats); + u_vector_finish(&display->drm.formats); + u_vector_finish(&display->dmabuf.formats); + u_vector_finish(&display->dmabuf.modifiers.argb8888); + u_vector_finish(&display->dmabuf.modifiers.xrgb8888); ++ if (display->swrast.wl_shm) ++ wl_shm_destroy(display->swrast.wl_shm); + if (display->drm.wl_drm) + wl_drm_destroy(display->drm.wl_drm); + if (display->dmabuf.wl_dmabuf) +@@ -366,16 +452,18 @@ static VkResult + wsi_wl_display_init(struct wsi_wayland *wsi_wl, + struct wsi_wl_display *display, + struct wl_display *wl_display, +- bool get_format_list) ++ bool get_format_list, bool sw) + { + VkResult result = VK_SUCCESS; + memset(display, 0, sizeof(*display)); + + display->wsi_wl = wsi_wl; + display->wl_display = wl_display; ++ display->sw = sw; + + if (get_format_list) { +- if (!u_vector_init(&display->drm.formats, sizeof(VkFormat), 8) || ++ if (!u_vector_init(&display->swrast.formats, sizeof(VkFormat), 8) || ++ !u_vector_init(&display->drm.formats, sizeof(VkFormat), 8) || + !u_vector_init(&display->dmabuf.formats, sizeof(VkFormat), 8) || + !u_vector_init(&display->dmabuf.modifiers.argb8888, + sizeof(uint64_t), 32) || +@@ -414,7 +502,7 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl, + wl_display_roundtrip_queue(display->wl_display, display->queue); + + /* Round-trip again to get formats, modifiers and capabilities */ +- if (display->drm.wl_drm || display->dmabuf.wl_dmabuf) ++ if (display->drm.wl_drm || display->dmabuf.wl_dmabuf || display->swrast.wl_shm) + wl_display_roundtrip_queue(display->wl_display, display->queue); + + if (wsi_wl->wsi->force_bgra8_unorm_first) { +@@ -432,8 +520,10 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl, + } + } + ++ if (display->sw) ++ display->formats = &display->swrast.formats; + /* We need prime support for wl_drm */ +- if (display->drm.wl_drm && ++ else if (display->drm.wl_drm && + (display->drm.capabilities & WL_DRM_CAPABILITY_PRIME)) { + display->formats = &display->drm.formats; + } else if (display->dmabuf.wl_dmabuf) { +@@ -463,6 +553,7 @@ fail: + + static VkResult + wsi_wl_display_create(struct wsi_wayland *wsi, struct wl_display *wl_display, ++ bool sw, + struct wsi_wl_display **display_out) + { + struct wsi_wl_display *display = +@@ -471,7 +562,8 @@ wsi_wl_display_create(struct wsi_wayland *wsi, struct wl_display *wl_display, + if (!display) + return VK_ERROR_OUT_OF_HOST_MEMORY; + +- VkResult result = wsi_wl_display_init(wsi, display, wl_display, true); ++ VkResult result = wsi_wl_display_init(wsi, display, wl_display, true, ++ sw); + if (result != VK_SUCCESS) { + vk_free(wsi->alloc, display); + return result; +@@ -509,7 +601,8 @@ wsi_wl_get_presentation_support(struct wsi_device *wsi_device, + (struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND]; + + struct wsi_wl_display display; +- VkResult ret = wsi_wl_display_init(wsi, &display, wl_display, false); ++ VkResult ret = wsi_wl_display_init(wsi, &display, wl_display, false, ++ wsi_device->sw); + if (ret == VK_SUCCESS) + wsi_wl_display_finish(&display); + +@@ -612,7 +705,8 @@ wsi_wl_surface_get_formats(VkIcdSurfaceBase *icd_surface, + (struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND]; + + struct wsi_wl_display display; +- if (wsi_wl_display_init(wsi, &display, surface->display, true)) ++ if (wsi_wl_display_init(wsi, &display, surface->display, true, ++ wsi_device->sw)) + return VK_ERROR_SURFACE_LOST_KHR; + + VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount); +@@ -642,7 +736,8 @@ wsi_wl_surface_get_formats2(VkIcdSurfaceBase *icd_surface, + (struct wsi_wayland *)wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND]; + + struct wsi_wl_display display; +- if (wsi_wl_display_init(wsi, &display, surface->display, true)) ++ if (wsi_wl_display_init(wsi, &display, surface->display, true, ++ wsi_device->sw)) + return VK_ERROR_SURFACE_LOST_KHR; + + VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount); +@@ -722,10 +817,12 @@ struct wsi_wl_image { + struct wsi_image base; + struct wl_buffer * buffer; + bool busy; ++ void * data_ptr; ++ uint32_t data_size; + }; + + struct wsi_wl_swapchain { +- struct wsi_swapchain base; ++ struct wsi_swapchain base; + + struct wsi_wl_display *display; + +@@ -742,6 +839,7 @@ struct wsi_wl_swapchain { + VkExtent2D extent; + VkFormat vk_format; + uint32_t drm_format; ++ uint32_t shm_format; + + uint32_t num_drm_modifiers; + const uint64_t * drm_modifiers; +@@ -859,6 +957,23 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain, + { + struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain; + ++ if (chain->display->sw) { ++ struct wsi_wl_image *image = &chain->images[image_index]; ++ void *dptr = image->data_ptr; ++ void *sptr; ++ chain->base.wsi->MapMemory(chain->base.device, ++ image->base.memory, ++ 0, 0, 0, &sptr); ++ ++ for (unsigned r = 0; r < chain->extent.height; r++) { ++ memcpy(dptr, sptr, image->base.row_pitches[0]); ++ dptr += image->base.row_pitches[0]; ++ sptr += image->base.row_pitches[0]; ++ } ++ chain->base.wsi->UnmapMemory(chain->base.device, ++ image->base.memory); ++ ++ } + if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR) { + while (!chain->fifo_ready) { + int ret = wl_display_dispatch_queue(chain->display->wl_display, +@@ -928,7 +1043,31 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, + if (result != VK_SUCCESS) + return result; + +- if (!chain->drm_wrapper) { ++ if (display->sw) { ++ int fd, stride; ++ ++ stride = image->base.row_pitches[0]; ++ image->data_size = stride * chain->extent.height; ++ ++ /* Create a shareable buffer */ ++ fd = os_create_anonymous_file(image->data_size, NULL); ++ if (fd < 0) ++ goto fail_image; ++ ++ image->data_ptr = mmap(NULL, image->data_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); ++ if (image->data_ptr == MAP_FAILED) { ++ close(fd); ++ goto fail_image; ++ } ++ /* Share it in a wl_buffer */ ++ struct wl_shm_pool *pool = wl_shm_create_pool(display->swrast.wl_shm, fd, image->data_size); ++ wl_proxy_set_queue((struct wl_proxy *)pool, display->queue); ++ image->buffer = wl_shm_pool_create_buffer(pool, 0, chain->extent.width, ++ chain->extent.height, stride, ++ chain->shm_format); ++ wl_shm_pool_destroy(pool); ++ close(fd); ++ } else if (!chain->drm_wrapper) { + /* Only request modifiers if we have dmabuf, else it must be implicit. */ + assert(display->dmabuf.wl_dmabuf); + assert(image->base.drm_modifier != DRM_FORMAT_MOD_INVALID); +@@ -995,6 +1134,8 @@ wsi_wl_swapchain_destroy(struct wsi_swapchain *wsi_chain, + if (chain->images[i].buffer) { + wl_buffer_destroy(chain->images[i].buffer); + wsi_destroy_image(&chain->base, &chain->images[i].base); ++ if (chain->images[i].data_ptr) ++ munmap(chain->images[i].data_ptr, chain->images[i].data_size); + } + } + +@@ -1049,8 +1190,10 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, + /* Mark a bunch of stuff as NULL. This way we can just call + * destroy_swapchain for cleanup. + */ +- for (uint32_t i = 0; i < num_images; i++) ++ for (uint32_t i = 0; i < num_images; i++) { + chain->images[i].buffer = NULL; ++ chain->images[i].data_ptr = NULL; ++ } + chain->surface = NULL; + chain->drm_wrapper = NULL; + chain->frame = NULL; +@@ -1066,7 +1209,10 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, + chain->base.image_count = num_images; + chain->extent = pCreateInfo->imageExtent; + chain->vk_format = pCreateInfo->imageFormat; +- chain->drm_format = wl_drm_format_for_vk_format(chain->vk_format, alpha); ++ if (wsi_device->sw) ++ chain->shm_format = wl_shm_format_for_vk_format(chain->vk_format, alpha); ++ else ++ chain->drm_format = wl_drm_format_for_vk_format(chain->vk_format, alpha); + + if (pCreateInfo->oldSwapchain) { + /* If we have an oldSwapchain parameter, copy the display struct over +@@ -1076,7 +1222,8 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, + chain->display = wsi_wl_display_ref(old_chain->display); + } else { + chain->display = NULL; +- result = wsi_wl_display_create(wsi, surface->display, &chain->display); ++ result = wsi_wl_display_create(wsi, surface->display, ++ wsi_device->sw, &chain->display); + if (result != VK_SUCCESS) + goto fail; + } +diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c +index 54769b81ccc..fa0c3d997dc 100644 +--- a/src/vulkan/wsi/wsi_common_x11.c ++++ b/src/vulkan/wsi/wsi_common_x11.c +@@ -439,8 +439,10 @@ VkBool32 wsi_get_physical_device_xcb_presentation_support( + if (!wsi_conn) + return false; + +- if (!wsi_x11_check_for_dri3(wsi_conn)) +- return false; ++ if (!wsi_device->sw) { ++ if (!wsi_x11_check_for_dri3(wsi_conn)) ++ return false; ++ } + + unsigned visual_depth; + if (!connection_get_visualtype(connection, visual_id, &visual_depth)) +@@ -484,9 +486,11 @@ x11_surface_get_support(VkIcdSurfaceBase *icd_surface, + if (!wsi_conn) + return VK_ERROR_OUT_OF_HOST_MEMORY; + +- if (!wsi_x11_check_for_dri3(wsi_conn)) { +- *pSupported = false; +- return VK_SUCCESS; ++ if (!wsi_device->sw) { ++ if (!wsi_x11_check_for_dri3(wsi_conn)) { ++ *pSupported = false; ++ return VK_SUCCESS; ++ } + } + + unsigned visual_depth; diff --git a/mesa.spec b/mesa.spec index 4d81512..088cc05 100644 --- a/mesa.spec +++ b/mesa.spec @@ -56,7 +56,7 @@ Name: mesa Summary: Mesa graphics libraries -%global ver 21.1.3 +%global ver 21.1.5 Version: %{lua:ver = string.gsub(rpm.expand("%{ver}"), "-", "~"); print(ver)} Release: 1%{?dist} License: MIT @@ -68,6 +68,8 @@ Source0: https://mesa.freedesktop.org/archive/%{name}-%{ver}.tar.xz # Fedora opts to ignore the optional part of clause 2 and treat that code as 2 clause BSD. Source1: Mesa-MLAA-License-Clarification-Email.txt +Patch1: mesa-vk-wsi-sw-fixes.patch + BuildRequires: meson >= 0.45 BuildRequires: gcc BuildRequires: gcc-c++ @@ -608,6 +610,9 @@ popd %endif %changelog +* Mon Aug 02 2021 Dave Airlie - 21.1.5-1 +- Update to mesa 21.1.5 + vk wsi fixes + * Fri Jul 09 2021 Dave Airlie - 21.1.3-1 - Update to mesa 21.1.3 to fix wl_drm diff --git a/sources b/sources index f4d7471..7269e3b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (mesa-21.1.3.tar.xz) = 8ca6d5516035484ea2a63bc6338794003ef167239ab0c220f8d3693f97f9725b46fc9d9a704c4ba11b83197d4b8e5f658d65ef0cce1e0957f5e58bd13726b9e0 +SHA512 (mesa-21.1.5.tar.xz) = ad777d872530bdd8798f712ed3becb78e902d8cf4d6dc9a27994b07847cc90723a90303c96b296be9233c837866bb0014220c6c770a02093759254d10eadecb9