X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fvulkan%2Fwsi%2Fwsi_common_wayland.c;h=5c72c8aa2364b68bc997d095ade878111761d3aa;hb=56901c9ea4d419aad68fd75b0e89aff600730587;hp=67ac0b8372e80d5295ca53ce6d98d962a3dad475;hpb=f695735ed61ea2f11f0fdf032a8ad2c99b6b064c;p=mesa.git diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index 67ac0b8372e..5c72c8aa236 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -22,7 +22,6 @@ */ #include -#include #include #include @@ -32,7 +31,9 @@ #include #include +#include "util/vk_util.h" #include "wsi_common_wayland.h" +#include "wayland-drm-client-protocol.h" #include #include @@ -412,28 +413,17 @@ wsi_wl_surface_get_formats(VkIcdSurfaceBase *icd_surface, if (!display) return VK_ERROR_OUT_OF_HOST_MEMORY; - if (pSurfaceFormats == NULL) { - *pSurfaceFormatCount = u_vector_length(&display->formats); - return VK_SUCCESS; - } + VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount); - uint32_t count = 0; - VkFormat *f; - u_vector_foreach(f, &display->formats) { - if (count == *pSurfaceFormatCount) - return VK_INCOMPLETE; - - pSurfaceFormats[count++] = (VkSurfaceFormatKHR) { - .format = *f, - /* TODO: We should get this from the compositor somehow */ - .colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR, - }; + VkFormat *disp_fmt; + u_vector_foreach(disp_fmt, &display->formats) { + vk_outarray_append(&out, out_fmt) { + out_fmt->format = *disp_fmt; + out_fmt->colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + } } - assert(*pSurfaceFormatCount <= count); - *pSurfaceFormatCount = count; - - return VK_SUCCESS; + return vk_outarray_status(&out); } static VkResult @@ -488,6 +478,7 @@ struct wsi_wl_swapchain { struct wsi_wl_display * display; struct wl_event_queue * queue; struct wl_surface * surface; + uint32_t surface_version; VkExtent2D extent; VkFormat vk_format; @@ -578,7 +569,8 @@ static const struct wl_callback_listener frame_listener = { static VkResult wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain, - uint32_t image_index) + uint32_t image_index, + const VkPresentRegionKHR *damage) { struct wsi_wl_swapchain *chain = (struct wsi_wl_swapchain *)wsi_chain; @@ -593,7 +585,19 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain, assert(image_index < chain->base.image_count); wl_surface_attach(chain->surface, chain->images[image_index].buffer, 0, 0); - wl_surface_damage(chain->surface, 0, 0, INT32_MAX, INT32_MAX); + + if (chain->surface_version >= 4 && damage && + damage->pRectangles && damage->rectangleCount > 0) { + for (unsigned i = 0; i < damage->rectangleCount; i++) { + const VkRectLayerKHR *rect = &damage->pRectangles[i]; + assert(rect->layer == 0); + wl_surface_damage_buffer(chain->surface, + rect->offset.x, rect->offset.y, + rect->extent.width, rect->extent.height); + } + } else { + wl_surface_damage(chain->surface, 0, 0, INT32_MAX, INT32_MAX); + } if (chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR) { struct wl_callback *frame = wl_surface_frame(chain->surface); @@ -730,6 +734,7 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface, chain->base.image_count = num_images; chain->base.needs_linear_copy = false; chain->surface = surface->surface; + chain->surface_version = wl_proxy_get_version((void *)surface->surface); chain->extent = pCreateInfo->imageExtent; chain->vk_format = pCreateInfo->imageFormat; chain->drm_format = wl_drm_format_for_vk_format(chain->vk_format, alpha);