0058-vulkan-wsi-make-the-display-FD-available.patch 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. From d370e0dc9a60f70abe7d150837a2f816be2f1dee Mon Sep 17 00:00:00 2001
  2. From: Brendan King <Brendan.King@imgtec.com>
  3. Date: Thu, 17 Jun 2021 17:17:07 +0100
  4. Subject: [PATCH] vulkan/wsi: make the display FD available
  5. Pass the display FD to the Vulkan image create and memory
  6. allocation functions when allocating swapchain images.
  7. ---
  8. src/vulkan/wsi/wsi_common.h | 14 +++
  9. src/vulkan/wsi/wsi_common_display.c | 2 +-
  10. src/vulkan/wsi/wsi_common_drm.c | 22 ++++-
  11. src/vulkan/wsi/wsi_common_private.h | 2 +
  12. src/vulkan/wsi/wsi_common_wayland.c | 127 ++++++++++++++++++++++------
  13. src/vulkan/wsi/wsi_common_x11.c | 42 ++++++---
  14. 6 files changed, 169 insertions(+), 40 deletions(-)
  15. diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
  16. index d5367db..c2563c6 100644
  17. --- a/src/vulkan/wsi/wsi_common.h
  18. +++ b/src/vulkan/wsi/wsi_common.h
  19. @@ -37,6 +37,8 @@
  20. #define VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA (VkStructureType)1000001003
  21. #define VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA (VkStructureType)1000001005
  22. #define VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA (VkStructureType)1000001006
  23. +#define VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO2_MESA (VkStructureType)1000001007
  24. +#define VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA (VkStructureType)1000001008
  25. /* This is always chained to VkImageCreateInfo when a wsi image is created.
  26. * It indicates that the image can be transitioned to/from
  27. @@ -75,6 +77,18 @@ struct wsi_memory_signal_submit_info {
  28. VkDeviceMemory memory;
  29. };
  30. +struct wsi_image_create_info2 {
  31. + VkStructureType sType;
  32. + const void *pNext;
  33. + int display_fd;
  34. +};
  35. +
  36. +struct wsi_memory_allocate_info2 {
  37. + VkStructureType sType;
  38. + const void *pNext;
  39. + int display_fd;
  40. +};
  41. +
  42. struct wsi_fence {
  43. VkDevice device;
  44. const struct wsi_device *wsi_device;
  45. diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
  46. index 71a84e5..f135b4e 100644
  47. --- a/src/vulkan/wsi/wsi_common_display.c
  48. +++ b/src/vulkan/wsi/wsi_common_display.c
  49. @@ -1032,7 +1032,7 @@ wsi_display_image_init(VkDevice device_h,
  50. VkResult result = wsi_create_native_image(&chain->base, create_info,
  51. 0, NULL, NULL, false,
  52. - &image->base);
  53. + wsi->fd, &image->base);
  54. if (result != VK_SUCCESS)
  55. return result;
  56. diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c
  57. index aabb761..6201891 100644
  58. --- a/src/vulkan/wsi/wsi_common_drm.c
  59. +++ b/src/vulkan/wsi/wsi_common_drm.c
  60. @@ -113,6 +113,7 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
  61. const uint32_t *num_modifiers,
  62. const uint64_t *const *modifiers,
  63. bool host_visible,
  64. + int display_fd,
  65. struct wsi_image *image)
  66. {
  67. const struct wsi_device *wsi = chain->wsi;
  68. @@ -170,6 +171,12 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
  69. __vk_append_struct(&image_info, &image_format_list);
  70. }
  71. + struct wsi_image_create_info2 image_wsi_info2 = {
  72. + .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO2_MESA,
  73. + .display_fd = display_fd,
  74. + };
  75. + __vk_append_struct(&image_info, &image_wsi_info2);
  76. +
  77. VkImageDrmFormatModifierListCreateInfoEXT image_modifier_list;
  78. uint32_t image_modifier_count = 0, modifier_prop_count = 0;
  79. @@ -308,9 +315,14 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
  80. .pNext = NULL,
  81. .implicit_sync = true,
  82. };
  83. + const struct wsi_memory_allocate_info2 memory_wsi_info2 = {
  84. + .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA,
  85. + .pNext = &memory_wsi_info,
  86. + .display_fd = display_fd,
  87. + };
  88. const VkExportMemoryAllocateInfo memory_export_info = {
  89. .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
  90. - .pNext = &memory_wsi_info,
  91. + .pNext = &memory_wsi_info2,
  92. .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
  93. };
  94. const VkMemoryDedicatedAllocateInfo memory_dedicated_info = {
  95. @@ -440,6 +452,7 @@ VkResult
  96. wsi_create_prime_image(const struct wsi_swapchain *chain,
  97. const VkSwapchainCreateInfoKHR *pCreateInfo,
  98. bool use_modifier,
  99. + int display_fd,
  100. struct wsi_image *image)
  101. {
  102. const struct wsi_device *wsi = chain->wsi;
  103. @@ -480,9 +493,14 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
  104. .pNext = NULL,
  105. .implicit_sync = true,
  106. };
  107. + const struct wsi_memory_allocate_info2 memory_wsi_info2 = {
  108. + .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA,
  109. + .pNext = &memory_wsi_info,
  110. + .display_fd = display_fd,
  111. + };
  112. const VkExportMemoryAllocateInfo prime_memory_export_info = {
  113. .sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
  114. - .pNext = &memory_wsi_info,
  115. + .pNext = &memory_wsi_info2,
  116. .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
  117. };
  118. const VkMemoryDedicatedAllocateInfo prime_memory_dedicated_info = {
  119. diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h
  120. index 5ad087b..e463281 100644
  121. --- a/src/vulkan/wsi/wsi_common_private.h
  122. +++ b/src/vulkan/wsi/wsi_common_private.h
  123. @@ -95,12 +95,14 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
  124. const uint32_t *num_modifiers,
  125. const uint64_t *const *modifiers,
  126. bool host_visible,
  127. + int display_fd,
  128. struct wsi_image *image);
  129. VkResult
  130. wsi_create_prime_image(const struct wsi_swapchain *chain,
  131. const VkSwapchainCreateInfoKHR *pCreateInfo,
  132. bool use_modifier,
  133. + int display_fd,
  134. struct wsi_image *image);
  135. void
  136. diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
  137. index 983833e..1109d3f 100644
  138. --- a/src/vulkan/wsi/wsi_common_wayland.c
  139. +++ b/src/vulkan/wsi/wsi_common_wayland.c
  140. @@ -32,6 +32,8 @@
  141. #include <pthread.h>
  142. #include <poll.h>
  143. #include <sys/mman.h>
  144. +#include <fcntl.h>
  145. +#include <xf86drm.h>
  146. #include "drm-uapi/drm_fourcc.h"
  147. @@ -82,6 +84,9 @@ struct wsi_wl_display {
  148. struct wsi_wayland *wsi_wl;
  149. + int fd;
  150. + bool authenticated;
  151. +
  152. /* Points to formats in wsi_wl_display_drm or wsi_wl_display_dmabuf */
  153. struct u_vector * formats;
  154. @@ -261,10 +266,52 @@ wsi_wl_display_add_wl_shm_format(struct wsi_wl_display *display,
  155. }
  156. }
  157. +static int
  158. +open_display_device(const char *name)
  159. +{
  160. + int fd;
  161. +
  162. +#ifdef O_CLOEXEC
  163. + fd = open(name, O_RDWR | O_CLOEXEC);
  164. + if (fd != -1 || errno != EINVAL) {
  165. + return fd;
  166. + }
  167. +#endif
  168. +
  169. + fd = open(name, O_RDWR);
  170. + if (fd != -1) {
  171. + long flags = fcntl(fd, F_GETFD);
  172. +
  173. + if (flags != -1) {
  174. + if (!fcntl(fd, F_SETFD, flags | FD_CLOEXEC))
  175. + return fd;
  176. + }
  177. + close (fd);
  178. + }
  179. +
  180. + return -1;
  181. +}
  182. static void
  183. drm_handle_device(void *data, struct wl_drm *drm, const char *name)
  184. {
  185. + struct wsi_wl_display *display = data;
  186. + const int fd = open_display_device(name);
  187. +
  188. + if (fd != -1) {
  189. + if (drmGetNodeTypeFromFd(fd) != DRM_NODE_RENDER) {
  190. + drm_magic_t magic;
  191. +
  192. + if (drmGetMagic(fd, &magic)) {
  193. + close(fd);
  194. + return;
  195. + }
  196. + wl_drm_authenticate(drm, magic);
  197. + } else {
  198. + display->authenticated = true;
  199. + }
  200. + display->fd = fd;
  201. + }
  202. }
  203. static uint32_t
  204. @@ -346,6 +393,9 @@ drm_handle_format(void *data, struct wl_drm *drm, uint32_t wl_format)
  205. static void
  206. drm_handle_authenticated(void *data, struct wl_drm *drm)
  207. {
  208. + struct wsi_wl_display *display = data;
  209. +
  210. + display->authenticated = true;
  211. }
  212. static void
  213. @@ -487,6 +537,9 @@ wsi_wl_display_finish(struct wsi_wl_display *display)
  214. wl_proxy_wrapper_destroy(display->wl_display_wrapper);
  215. if (display->queue)
  216. wl_event_queue_destroy(display->queue);
  217. +
  218. + if (display->fd != -1)
  219. + close(display->fd);
  220. }
  221. static VkResult
  222. @@ -501,6 +554,7 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
  223. display->wsi_wl = wsi_wl;
  224. display->wl_display = wl_display;
  225. display->sw = sw;
  226. + display->fd = -1;
  227. if (get_format_list) {
  228. if (!u_vector_init(&display->swrast.formats, sizeof(VkFormat), 8) ||
  229. @@ -542,41 +596,60 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
  230. /* Round-trip to get wl_drms and zwp_linux_dmabuf_v1 globals */
  231. wl_display_roundtrip_queue(display->wl_display, display->queue);
  232. + if (!display->drm.wl_drm && !display->dmabuf.wl_dmabuf && !display->swrast.wl_shm) {
  233. + result = VK_ERROR_SURFACE_LOST_KHR;
  234. + goto fail_registry;
  235. + }
  236. +
  237. /* Round-trip again to get formats, modifiers and capabilities */
  238. - if (display->drm.wl_drm || display->dmabuf.wl_dmabuf || display->swrast.wl_shm)
  239. - wl_display_roundtrip_queue(display->wl_display, display->queue);
  240. + wl_display_roundtrip_queue(display->wl_display, display->queue);
  241. - if (wsi_wl->wsi->force_bgra8_unorm_first) {
  242. - /* Find BGRA8_UNORM in the list and swap it to the first position if we
  243. - * can find it. Some apps get confused if SRGB is first in the list.
  244. - */
  245. - VkFormat *first_fmt = u_vector_head(display->formats);
  246. - VkFormat *iter_fmt;
  247. - u_vector_foreach(iter_fmt, display->formats) {
  248. - if (*iter_fmt == VK_FORMAT_B8G8R8A8_UNORM) {
  249. - *iter_fmt = *first_fmt;
  250. - *first_fmt = VK_FORMAT_B8G8R8A8_UNORM;
  251. - break;
  252. - }
  253. - }
  254. + if (display->fd == -1) {
  255. + result = VK_ERROR_SURFACE_LOST_KHR;
  256. + goto fail_registry;
  257. }
  258. - /* Prefer the linux-dmabuf protocol if available */
  259. - if (display->sw)
  260. - display->formats = &display->swrast.formats;
  261. - else if (display->dmabuf.wl_dmabuf) {
  262. - display->formats = &display->dmabuf.formats;
  263. - } else if (display->drm.wl_drm &&
  264. - (display->drm.capabilities & WL_DRM_CAPABILITY_PRIME)) {
  265. - /* We need prime support for wl_drm */
  266. - display->formats = &display->drm.formats;
  267. - }
  268. + wl_display_roundtrip_queue(display->wl_display, display->queue);
  269. - if (!display->formats) {
  270. + if (!display->authenticated) {
  271. result = VK_ERROR_SURFACE_LOST_KHR;
  272. goto fail_registry;
  273. }
  274. + if (get_format_list) {
  275. + /* Prefer the linux-dmabuf protocol if available */
  276. + if (display->sw)
  277. + display->formats = &display->swrast.formats;
  278. + else if(display->dmabuf.wl_dmabuf &&
  279. + u_vector_length(&display->dmabuf.formats)) {
  280. + display->formats = &display->dmabuf.formats;
  281. + } else if (display->drm.wl_drm &&
  282. + display->drm.capabilities & WL_DRM_CAPABILITY_PRIME) {
  283. + display->formats = &display->drm.formats;
  284. + }
  285. +
  286. + if (!display->formats) {
  287. + result = VK_ERROR_SURFACE_LOST_KHR;
  288. + goto fail_registry;
  289. + }
  290. +
  291. + if (wsi_wl->wsi->force_bgra8_unorm_first) {
  292. + /* Find BGRA8_UNORM in the list and swap it to the first position if
  293. + * we can find it. Some apps get confused if SRGB is first in the
  294. + * list.
  295. + */
  296. + VkFormat *first_fmt = u_vector_tail(display->formats);
  297. + VkFormat *iter_fmt;
  298. + u_vector_foreach(iter_fmt, display->formats) {
  299. + if (*iter_fmt == VK_FORMAT_B8G8R8A8_UNORM) {
  300. + *iter_fmt = *first_fmt;
  301. + *first_fmt = VK_FORMAT_B8G8R8A8_UNORM;
  302. + break;
  303. + }
  304. + }
  305. + }
  306. + }
  307. +
  308. /* We don't need this anymore */
  309. wl_registry_destroy(registry);
  310. @@ -1075,7 +1148,7 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain,
  311. chain->num_drm_modifiers > 0 ? 1 : 0,
  312. &chain->num_drm_modifiers,
  313. &chain->drm_modifiers, false,
  314. - &image->base);
  315. + display->fd, &image->base);
  316. if (result != VK_SUCCESS)
  317. return result;
  318. diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
  319. index eb639d6..ba64e26 100644
  320. --- a/src/vulkan/wsi/wsi_common_x11.c
  321. +++ b/src/vulkan/wsi/wsi_common_x11.c
  322. @@ -1303,7 +1303,8 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
  323. const VkAllocationCallbacks* pAllocator,
  324. const uint64_t *const *modifiers,
  325. const uint32_t *num_modifiers,
  326. - int num_tranches, struct x11_image *image)
  327. + int num_tranches, int display_fd,
  328. + struct x11_image *image)
  329. {
  330. xcb_void_cookie_t cookie;
  331. VkResult result;
  332. @@ -1311,11 +1312,12 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
  333. if (chain->base.use_prime_blit) {
  334. bool use_modifier = num_tranches > 0;
  335. - result = wsi_create_prime_image(&chain->base, pCreateInfo, use_modifier, &image->base);
  336. + result = wsi_create_prime_image(&chain->base, pCreateInfo, use_modifier,
  337. + display_fd, &image->base);
  338. } else {
  339. result = wsi_create_native_image(&chain->base, pCreateInfo,
  340. num_tranches, num_modifiers, modifiers,
  341. - chain->base.wsi->sw,
  342. + chain->base.wsi->sw, display_fd,
  343. &image->base);
  344. }
  345. if (result < 0)
  346. @@ -1687,14 +1689,34 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
  347. modifiers, num_modifiers, &num_tranches,
  348. pAllocator);
  349. +
  350. uint32_t image = 0;
  351. - for (; image < chain->base.image_count; image++) {
  352. - result = x11_image_init(device, chain, pCreateInfo, pAllocator,
  353. - (const uint64_t *const *)modifiers,
  354. - num_modifiers, num_tranches,
  355. - &chain->images[image]);
  356. - if (result != VK_SUCCESS)
  357. - goto fail_init_images;
  358. + {
  359. + int display_fd = -1;
  360. +
  361. + if (!wsi_device->sw) {
  362. + xcb_screen_iterator_t screen_iter =
  363. + xcb_setup_roots_iterator(xcb_get_setup(conn));
  364. + xcb_screen_t *screen = screen_iter.data;
  365. +
  366. + display_fd = wsi_dri3_open(conn, screen->root, None);
  367. + }
  368. +
  369. + for (; image < chain->base.image_count; image++) {
  370. + result = x11_image_init(device, chain, pCreateInfo, pAllocator,
  371. + (const uint64_t *const *)modifiers,
  372. + num_modifiers, num_tranches,
  373. + display_fd, &chain->images[image]);
  374. + if (result != VK_SUCCESS) {
  375. + if (display_fd >= 0)
  376. + close(display_fd);
  377. +
  378. + goto fail_init_images;
  379. + }
  380. + }
  381. +
  382. + if (display_fd >= 0)
  383. + close(display_fd);
  384. }
  385. if ((chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR ||