diff options
-rw-r--r-- | src/amd/vulkan/radv_wsi.c | 14 | ||||
-rw-r--r-- | src/intel/vulkan/anv_wsi.c | 14 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common.c | 14 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common.h | 7 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_display.c | 41 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_private.h | 5 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_wayland.c | 21 | ||||
-rw-r--r-- | src/vulkan/wsi/wsi_common_x11.c | 61 |
8 files changed, 177 insertions, 0 deletions
diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c index 8b165ea3916..43103a4ef85 100644 --- a/src/amd/vulkan/radv_wsi.c +++ b/src/amd/vulkan/radv_wsi.c @@ -284,3 +284,17 @@ VkResult radv_GetDeviceGroupSurfacePresentModesKHR( return VK_SUCCESS; } + +VkResult radv_GetPhysicalDevicePresentRectanglesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pRectCount, + VkRect2D* pRects) +{ + RADV_FROM_HANDLE(radv_physical_device, device, physicalDevice); + + return wsi_common_get_present_rectangles(&device->wsi_device, + device->local_fd, + surface, + pRectCount, pRects); +} diff --git a/src/intel/vulkan/anv_wsi.c b/src/intel/vulkan/anv_wsi.c index 1c9a54804e8..5d672c211c4 100644 --- a/src/intel/vulkan/anv_wsi.c +++ b/src/intel/vulkan/anv_wsi.c @@ -293,3 +293,17 @@ VkResult anv_GetDeviceGroupSurfacePresentModesKHR( return VK_SUCCESS; } + +VkResult anv_GetPhysicalDevicePresentRectanglesKHR( + VkPhysicalDevice physicalDevice, + VkSurfaceKHR surface, + uint32_t* pRectCount, + VkRect2D* pRects) +{ + ANV_FROM_HANDLE(anv_physical_device, device, physicalDevice); + + return wsi_common_get_present_rectangles(&device->wsi_device, + device->local_fd, + surface, + pRectCount, pRects); +} diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c index 1e3c4e0028b..ad4b8c9075e 100644 --- a/src/vulkan/wsi/wsi_common.c +++ b/src/vulkan/wsi/wsi_common.c @@ -804,6 +804,20 @@ wsi_common_get_surface_present_modes(struct wsi_device *wsi_device, } VkResult +wsi_common_get_present_rectangles(struct wsi_device *wsi_device, + int local_fd, + VkSurfaceKHR _surface, + uint32_t* pRectCount, + VkRect2D* pRects) +{ + ICD_FROM_HANDLE(VkIcdSurfaceBase, surface, _surface); + struct wsi_interface *iface = wsi_device->wsi[surface->platform]; + + return iface->get_present_rectangles(surface, wsi_device, local_fd, + pRectCount, pRects); +} + +VkResult wsi_common_create_swapchain(struct wsi_device *wsi, VkDevice device, int fd, diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h index 424330de566..5b69c573d9e 100644 --- a/src/vulkan/wsi/wsi_common.h +++ b/src/vulkan/wsi/wsi_common.h @@ -200,6 +200,13 @@ wsi_common_get_surface_present_modes(struct wsi_device *wsi_device, VkPresentModeKHR *pPresentModes); VkResult +wsi_common_get_present_rectangles(struct wsi_device *wsi, + int local_fd, + VkSurfaceKHR surface, + uint32_t* pRectCount, + VkRect2D* pRects); + +VkResult wsi_common_get_surface_capabilities2ext( struct wsi_device *wsi_device, VkSurfaceKHR surface, 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; diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h index accc1170163..d8290b69331 100644 --- a/src/vulkan/wsi/wsi_common_private.h +++ b/src/vulkan/wsi/wsi_common_private.h @@ -118,6 +118,11 @@ struct wsi_interface { VkResult (*get_present_modes)(VkIcdSurfaceBase *surface, uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes); + VkResult (*get_present_rectangles)(VkIcdSurfaceBase *surface, + struct wsi_device *wsi_device, + int local_fd, + uint32_t* pRectCount, + VkRect2D* pRects); VkResult (*create_swapchain)(VkIcdSurfaceBase *surface, VkDevice device, struct wsi_device *wsi_device, diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index 67d5f8d4c80..dccb530dae3 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -601,6 +601,26 @@ wsi_wl_surface_get_present_modes(VkIcdSurfaceBase *surface, return VK_SUCCESS; } +static VkResult +wsi_wl_surface_get_present_rectangles(VkIcdSurfaceBase *surface, + struct wsi_device *wsi_device, + int local_fd, + uint32_t* pRectCount, + VkRect2D* pRects) +{ + VK_OUTARRAY_MAKE(out, pRects, pRectCount); + + vk_outarray_append(&out, rect) { + /* We don't know a size so just return the usual "I don't know." */ + *rect = (VkRect2D) { + .offset = { 0, 0 }, + .extent = { -1, -1 }, + }; + } + + return vk_outarray_status(&out); +} + VkResult wsi_create_wl_surface(const VkAllocationCallbacks *pAllocator, const VkWaylandSurfaceCreateInfoKHR *pCreateInfo, VkSurfaceKHR *pSurface) @@ -1012,6 +1032,7 @@ wsi_wl_init_wsi(struct wsi_device *wsi_device, wsi->base.get_formats = wsi_wl_surface_get_formats; wsi->base.get_formats2 = wsi_wl_surface_get_formats2; wsi->base.get_present_modes = wsi_wl_surface_get_present_modes; + wsi->base.get_present_rectangles = wsi_wl_surface_get_present_rectangles; wsi->base.create_swapchain = wsi_wl_surface_create_swapchain; wsi_device->wsi[VK_ICD_WSI_PLATFORM_WAYLAND] = &wsi->base; diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c index 75aa83bb7b4..8c621ddf568 100644 --- a/src/vulkan/wsi/wsi_common_x11.c +++ b/src/vulkan/wsi/wsi_common_x11.c @@ -599,6 +599,66 @@ x11_surface_get_present_modes(VkIcdSurfaceBase *surface, VK_INCOMPLETE : VK_SUCCESS; } +static bool +x11_surface_is_local_to_gpu(struct wsi_device *wsi_dev, + int local_fd, + xcb_connection_t *conn) +{ + struct wsi_x11_connection *wsi_conn = + wsi_x11_get_connection(wsi_dev, conn); + + if (!wsi_conn) + return false; + + if (!wsi_x11_check_for_dri3(wsi_conn)) + return false; + + if (!wsi_x11_check_dri3_compatible(conn, local_fd)) + return false; + + return true; +} + +static VkResult +x11_surface_get_present_rectangles(VkIcdSurfaceBase *icd_surface, + struct wsi_device *wsi_device, + int local_fd, + uint32_t* pRectCount, + VkRect2D* pRects) +{ + xcb_connection_t *conn = x11_surface_get_connection(icd_surface); + xcb_window_t window = x11_surface_get_window(icd_surface); + VK_OUTARRAY_MAKE(out, pRects, pRectCount); + + if (x11_surface_is_local_to_gpu(wsi_device, local_fd, conn)) { + vk_outarray_append(&out, rect) { + xcb_generic_error_t *err = NULL; + xcb_get_geometry_cookie_t geom_cookie = xcb_get_geometry(conn, window); + xcb_get_geometry_reply_t *geom = + xcb_get_geometry_reply(conn, geom_cookie, &err); + free(err); + if (geom) { + *rect = (VkRect2D) { + .offset = { 0, 0 }, + .extent = { geom->width, geom->height }, + }; + } else { + /* This can happen if the client didn't wait for the configure event + * to come back from the compositor. In that case, we don't know the + * size of the window so we just return valid "I don't know" stuff. + */ + *rect = (VkRect2D) { + .offset = { 0, 0 }, + .extent = { -1, -1 }, + }; + } + free(geom); + } + } + + return vk_outarray_status(&out); +} + VkResult wsi_create_xcb_surface(const VkAllocationCallbacks *pAllocator, const VkXcbSurfaceCreateInfoKHR *pCreateInfo, VkSurfaceKHR *pSurface) @@ -1470,6 +1530,7 @@ wsi_x11_init_wsi(struct wsi_device *wsi_device, wsi->base.get_formats = x11_surface_get_formats; wsi->base.get_formats2 = x11_surface_get_formats2; wsi->base.get_present_modes = x11_surface_get_present_modes; + wsi->base.get_present_rectangles = x11_surface_get_present_rectangles; wsi->base.create_swapchain = x11_surface_create_swapchain; wsi_device->wsi[VK_ICD_WSI_PLATFORM_XCB] = &wsi->base; |