*/
#include <wayland-client.h>
-#include <wayland-drm-client-protocol.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#include "util/vk_util.h"
#include "wsi_common_wayland.h"
+#include "wayland-drm-client-protocol.h"
#include <util/hash_table.h>
#include <util/u_vector.h>
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
struct wsi_wl_display * display;
struct wl_event_queue * queue;
struct wl_surface * surface;
+ uint32_t surface_version;
VkExtent2D extent;
VkFormat vk_format;
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;
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);
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);