arb_program_interface_query: set vs_input2[1][0] as valid name
[piglit.git] / tests / wayland / wayland-dmabuf-target.c
blobfb5f5e4034ce824c95dba96837370450b01c1e37
1 /*
2 * Copyright 2021 Eric Engestrom
3 * Copyright 2023 Collabora, Ltd.
4 * SPDX-License-Identifier: MIT
5 */
7 #include <assert.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <stdbool.h>
11 #include <sys/stat.h>
12 #include <unistd.h>
14 #include <xf86drm.h>
15 #include <wayland-client.h>
16 #include "linux-dmabuf-unstable-v1-client-protocol.h"
18 #include "piglit-util.h"
21 #define MIN(a, b) ((a) < (b) ? (a) : (b))
23 struct wayland_display_target {
24 unsigned int roundtrips_needed;
25 struct wl_display *dpy;
26 struct wl_registry *registry;
27 struct zwp_linux_dmabuf_v1 *dmabuf;
28 struct zwp_linux_dmabuf_feedback_v1 *feedback;
29 bool feedback_done;
30 char *primary_driver_name;
34 static int
35 open_drm_by_devid(dev_t devid)
37 drmDevice *device;
38 int ret = -1;
39 int err;
41 err = drmGetDeviceFromDevId(devid, 0, &device);
42 if (err != 0) {
43 printf("libdrm reports no devices for our devid\n");
44 piglit_report_result(PIGLIT_FAIL);
47 if (device->available_nodes & (1 << DRM_NODE_RENDER))
48 ret = open(device->nodes[DRM_NODE_RENDER], O_RDWR);
49 if (ret == -1 && device->available_nodes & (1 << DRM_NODE_PRIMARY))
50 ret = open(device->nodes[DRM_NODE_PRIMARY], O_RDWR);
51 if (ret == -1) {
52 printf("Couldn't open any libdrm devices for our devid\n");
53 piglit_report_result(PIGLIT_FAIL);
56 drmFreeDevice(&device);
58 return ret;
62 static void
63 feedback_handle_done(void *_data, struct zwp_linux_dmabuf_feedback_v1 *feedback)
65 struct wayland_display_target *data = _data;
67 /* We've got all our feedback events now, so we can remove the roundtrip we
68 * added when binding the interface */
69 data->feedback_done = true;
72 static void
73 feedback_handle_format_table(void *_data,
74 struct zwp_linux_dmabuf_feedback_v1 *feedback,
75 int fd, uint32_t size)
77 /* We don't need the format table for anything */
78 close(fd);
81 static void
82 feedback_handle_main_device(void *_data,
83 struct zwp_linux_dmabuf_feedback_v1 *feedback,
84 struct wl_array *dev_array)
86 struct wayland_display_target *data = _data;
87 drmVersionPtr version;
88 dev_t dev;
89 int fd;
91 /* This is basically a malformed compositor */
92 if (dev_array->size != sizeof(dev)) {
93 printf("Expected main_device size to be %zu (dev_t), but it was %zu\n",
94 sizeof(dev), dev_array->size);
95 piglit_report_result(PIGLIT_FAIL);
98 memcpy(&dev, dev_array->data, sizeof(dev));
99 fd = open_drm_by_devid(dev);
100 if (fd < 0) {
101 printf("Couldn't open DRM device for main_device\n");
102 piglit_report_result(PIGLIT_FAIL);
105 version = drmGetVersion(fd);
106 if (!version || !version->name_len || !version->name) {
107 printf("drmGetVersion failed\n");
108 piglit_report_result(PIGLIT_FAIL);
111 data->primary_driver_name = malloc(version->name_len + 1);
112 assert(data->primary_driver_name);
113 memcpy(data->primary_driver_name, version->name, version->name_len);
114 data->primary_driver_name[version->name_len] = '\0';
116 drmFreeVersion(version);
117 close(fd);
120 static void
121 feedback_handle_tranche_done(void *_data,
122 struct zwp_linux_dmabuf_feedback_v1 *feedback)
124 /* We don't care about the content of the format/modifier tranches */
127 static void
128 feedback_handle_tranche_target_device(void *_data,
129 struct zwp_linux_dmabuf_feedback_v1 *feedback,
130 struct wl_array *dev_arr)
132 /* We don't care about per-tranche target devices (e.g. scanout) */
135 static void
136 feedback_handle_tranche_formats(void *_data,
137 struct zwp_linux_dmabuf_feedback_v1 *feedback,
138 struct wl_array *indices)
140 /* We don't care about per-tranche formats */
143 static void
144 feedback_handle_tranche_flags(void *_data,
145 struct zwp_linux_dmabuf_feedback_v1 *feedback,
146 uint32_t flags)
148 /* We don't care about per-tranche flags */
151 static const struct zwp_linux_dmabuf_feedback_v1_listener feedback_listener = {
152 feedback_handle_done,
153 feedback_handle_format_table,
154 feedback_handle_main_device,
155 feedback_handle_tranche_done,
156 feedback_handle_tranche_target_device,
157 feedback_handle_tranche_formats,
158 feedback_handle_tranche_flags,
161 static void
162 registry_handle_global(void *_data, struct wl_registry *registry,
163 uint32_t name, const char *interface, uint32_t version)
165 struct wayland_display_target *data = _data;
167 if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0 && version >= 4) {
168 data->dmabuf = wl_registry_bind(data->registry, name,
169 &zwp_linux_dmabuf_v1_interface,
170 MIN(version, 4));
171 data->feedback = zwp_linux_dmabuf_v1_get_default_feedback(data->dmabuf);
172 zwp_linux_dmabuf_feedback_v1_add_listener(data->feedback,
173 &feedback_listener,
174 data);
175 /* Need another roundtrip to collect the feedback events */
176 data->roundtrips_needed++;
180 static void
181 registry_handle_remove(void *_data, struct wl_registry *registry, uint32_t name)
185 static const struct wl_registry_listener registry_listener = {
186 registry_handle_global,
187 registry_handle_remove
192 main(void)
194 const char *expected_driver_name = NULL;
195 struct wayland_display_target data;
197 memset(&data, 0, sizeof(data));
199 expected_driver_name = getenv("PIGLIT_WAYLAND_EXPECTED_DRIVER");
200 if (!expected_driver_name) {
201 printf("$PIGLIT_WAYLAND_EXPECTED_DRIVER must be set to run this test\n");
202 piglit_report_result(PIGLIT_SKIP);
205 /* Connect to $WAYLAND_DISPLAY or $WAYLAND_SOCKET */
206 data.dpy = wl_display_connect(NULL);
207 if (!data.dpy) {
208 printf("Could not connect to Wayland display\n");
209 piglit_report_result(PIGLIT_SKIP);
212 /* The registry advertises the available interfaces */
213 data.registry = wl_display_get_registry(data.dpy);
214 assert(data.registry);
215 wl_registry_add_listener(data.registry, &registry_listener, &data);
217 /* Listen for the wl_registry advertisements to get supported interfaces */
218 wl_display_roundtrip(data.dpy);
220 if (!data.dmabuf) {
221 printf("zwp_linux_dmabuf_v1 is not available\n");
222 piglit_report_result(PIGLIT_SKIP);
225 /* Wait until we receive the zwp_linux_dmabuf_feedback_v1.done event */
226 while (!data.feedback_done)
227 wl_display_roundtrip(data.dpy);
229 if (!data.primary_driver_name ||
230 strcmp(data.primary_driver_name, expected_driver_name) != 0) {
231 printf("Got driver name %s, wanted %s\n", data.primary_driver_name,
232 expected_driver_name);
233 piglit_report_result(PIGLIT_FAIL);
236 free(data.primary_driver_name);
237 zwp_linux_dmabuf_feedback_v1_destroy(data.feedback);
238 zwp_linux_dmabuf_v1_destroy(data.dmabuf);
239 wl_registry_destroy(data.registry);
240 wl_display_disconnect(data.dpy);
242 piglit_report_result(PIGLIT_PASS);