diff options
author | Jason Ekstrand <[email protected]> | 2018-10-14 21:56:34 -0500 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2018-10-18 09:17:39 -0500 |
commit | 7c65cf98441ae0f03640d2feebb5d0e5a83f2721 (patch) | |
tree | 864e6c89b6788d297ea772f68e59164d003089eb /src/vulkan/wsi/wsi_common_display.c | |
parent | 7629c00557c135aae4f0cdfbfa31002b43d8b31e (diff) |
vulkan/wsi: Implement GetPhysicalDevicePresentRectanglesKHR
This got missed during 1.1 enabling because it was defined as an
interaction between device groups and WSI and it wasn't obvious it was
in the delta.
The idea behind it is that it's supposed to provide a hint to the
application in a multi-GPU setup to indicate which regions of the screen
are being scanned out by which GPU so a multi-device split-screen
rendering application can render each part of the screen on the GPU that
will be presenting it and avoid extra bus traffic between GPUs. On a
single-GPU setup or one which doesn't support this present mode, we need
to do something. We choose to return the window size (or a max-size
rect) if the compositor, X server, or crtc is associated with the given
physical device and zero rectangles otherwise.
Reviewed-by: Lionel Landwerlin <[email protected]>
Diffstat (limited to 'src/vulkan/wsi/wsi_common_display.c')
-rw-r--r-- | src/vulkan/wsi/wsi_common_display.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c index c004060a205..2315717ef8e 100644 --- a/src/vulkan/wsi/wsi_common_display.c +++ b/src/vulkan/wsi/wsi_common_display.c @@ -934,6 +934,46 @@ wsi_display_surface_get_present_modes(VkIcdSurfaceBase *surface, return vk_outarray_status(&conn); } +static bool +fds_are_same_gpu(int fd1, int fd2) +{ + if (fd1 == -1 || fd2 == -1) + return false; + + char *fd1_dev = drmGetRenderDeviceNameFromFd(fd1); + char *fd2_dev = drmGetRenderDeviceNameFromFd(fd2); + + int ret = strcmp(fd1_dev, fd2_dev); + + free(fd1_dev); + free(fd2_dev); + + return ret == 0; +} + +static VkResult +wsi_display_surface_get_present_rectangles(VkIcdSurfaceBase *surface_base, + struct wsi_device *wsi_device, + int local_fd, + uint32_t* pRectCount, + VkRect2D* pRects) +{ + VkIcdSurfaceDisplay *surface = (VkIcdSurfaceDisplay *) surface_base; + wsi_display_mode *mode = wsi_display_mode_from_handle(surface->displayMode); + VK_OUTARRAY_MAKE(out, pRects, pRectCount); + + if (fds_are_same_gpu(local_fd, mode->connector->wsi->fd)) { + vk_outarray_append(&out, rect) { + *rect = (VkRect2D) { + .offset = { 0, 0 }, + .extent = { mode->hdisplay, mode->vdisplay }, + }; + } + } + + return vk_outarray_status(&out); +} + static void wsi_display_destroy_buffer(struct wsi_display *wsi, uint32_t buffer) @@ -1810,6 +1850,7 @@ wsi_display_init_wsi(struct wsi_device *wsi_device, wsi->base.get_formats = wsi_display_surface_get_formats; wsi->base.get_formats2 = wsi_display_surface_get_formats2; wsi->base.get_present_modes = wsi_display_surface_get_present_modes; + wsi->base.get_present_rectangles = wsi_display_surface_get_present_rectangles; wsi->base.create_swapchain = wsi_display_surface_create_swapchain; wsi_device->wsi[VK_ICD_WSI_PLATFORM_DISPLAY] = &wsi->base; |