2 * Copyright 2014, 2015 Red Hat.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #include <sys/socket.h>
27 #include <netinet/in.h>
31 #include <os/os_process.h>
32 #include <util/u_format.h>
33 /* connect to remote socket */
34 #define VTEST_SOCKET_NAME "/tmp/.virgl_test"
36 #include "virgl_vtest_winsys.h"
37 #include "virgl_vtest_public.h"
39 /* block read/write routines */
40 static int virgl_block_write(int fd
, void *buf
, int size
)
47 ret
= write(fd
, ptr
, left
);
56 static int virgl_block_read(int fd
, void *buf
, int size
)
63 ret
= read(fd
, ptr
, left
);
65 fprintf(stderr
, "lost connection to rendering server on %d read %d %d\n", size
, ret
, errno
);
67 return ret
< 0 ? -errno
: 0;
75 static int virgl_vtest_send_init(struct virgl_vtest_winsys
*vws
)
77 uint32_t buf
[VTEST_HDR_SIZE
];
78 const char *nstr
= "virtest";
82 ret
= os_get_process_name(cmdline
, 63);
84 strcpy(cmdline
, nstr
);
85 #if defined(__GLIBC__) || defined(__CYGWIN__)
86 if (!strcmp(cmdline
, "shader_runner")) {
88 /* hack to get better testname */
89 name
= program_invocation_short_name
;
90 name
+= strlen(name
) + 1;
91 strncpy(cmdline
, name
, 63);
94 buf
[VTEST_CMD_LEN
] = strlen(cmdline
) + 1;
95 buf
[VTEST_CMD_ID
] = VCMD_CREATE_RENDERER
;
97 virgl_block_write(vws
->sock_fd
, &buf
, sizeof(buf
));
98 virgl_block_write(vws
->sock_fd
, (void *)cmdline
, strlen(cmdline
) + 1);
102 int virgl_vtest_connect(struct virgl_vtest_winsys
*vws
)
104 struct sockaddr_un un
;
107 sock
= socket(PF_UNIX
, SOCK_STREAM
, 0);
111 memset(&un
, 0, sizeof(un
));
112 un
.sun_family
= AF_UNIX
;
113 snprintf(un
.sun_path
, sizeof(un
.sun_path
), "%s", VTEST_SOCKET_NAME
);
117 if (connect(sock
, (struct sockaddr
*)&un
, sizeof(un
)) < 0) {
120 } while (ret
== -EINTR
);
123 virgl_vtest_send_init(vws
);
127 int virgl_vtest_send_get_caps(struct virgl_vtest_winsys
*vws
,
128 struct virgl_drm_caps
*caps
)
130 uint32_t get_caps_buf
[VTEST_HDR_SIZE
];
131 uint32_t resp_buf
[VTEST_HDR_SIZE
];
134 get_caps_buf
[VTEST_CMD_LEN
] = 0;
135 get_caps_buf
[VTEST_CMD_ID
] = VCMD_GET_CAPS
;
137 virgl_block_write(vws
->sock_fd
, &get_caps_buf
, sizeof(get_caps_buf
));
139 ret
= virgl_block_read(vws
->sock_fd
, resp_buf
, sizeof(resp_buf
));
143 ret
= virgl_block_read(vws
->sock_fd
, &caps
->caps
, sizeof(union virgl_caps
));
148 int virgl_vtest_send_resource_create(struct virgl_vtest_winsys
*vws
,
150 enum pipe_texture_target target
,
160 uint32_t res_create_buf
[VCMD_RES_CREATE_SIZE
], vtest_hdr
[VTEST_HDR_SIZE
];
162 vtest_hdr
[VTEST_CMD_LEN
] = VCMD_RES_CREATE_SIZE
;
163 vtest_hdr
[VTEST_CMD_ID
] = VCMD_RESOURCE_CREATE
;
165 res_create_buf
[VCMD_RES_CREATE_RES_HANDLE
] = handle
;
166 res_create_buf
[VCMD_RES_CREATE_TARGET
] = target
;
167 res_create_buf
[VCMD_RES_CREATE_FORMAT
] = format
;
168 res_create_buf
[VCMD_RES_CREATE_BIND
] = bind
;
169 res_create_buf
[VCMD_RES_CREATE_WIDTH
] = width
;
170 res_create_buf
[VCMD_RES_CREATE_HEIGHT
] = height
;
171 res_create_buf
[VCMD_RES_CREATE_DEPTH
] = depth
;
172 res_create_buf
[VCMD_RES_CREATE_ARRAY_SIZE
] = array_size
;
173 res_create_buf
[VCMD_RES_CREATE_LAST_LEVEL
] = last_level
;
174 res_create_buf
[VCMD_RES_CREATE_NR_SAMPLES
] = nr_samples
;
176 virgl_block_write(vws
->sock_fd
, &vtest_hdr
, sizeof(vtest_hdr
));
177 virgl_block_write(vws
->sock_fd
, &res_create_buf
, sizeof(res_create_buf
));
182 int virgl_vtest_submit_cmd(struct virgl_vtest_winsys
*vws
,
183 struct virgl_vtest_cmd_buf
*cbuf
)
185 uint32_t vtest_hdr
[VTEST_HDR_SIZE
];
187 vtest_hdr
[VTEST_CMD_LEN
] = cbuf
->base
.cdw
;
188 vtest_hdr
[VTEST_CMD_ID
] = VCMD_SUBMIT_CMD
;
190 virgl_block_write(vws
->sock_fd
, &vtest_hdr
, sizeof(vtest_hdr
));
191 virgl_block_write(vws
->sock_fd
, cbuf
->buf
, cbuf
->base
.cdw
* 4);
195 int virgl_vtest_send_resource_unref(struct virgl_vtest_winsys
*vws
,
198 uint32_t vtest_hdr
[VTEST_HDR_SIZE
];
200 vtest_hdr
[VTEST_CMD_LEN
] = 1;
201 vtest_hdr
[VTEST_CMD_ID
] = VCMD_RESOURCE_UNREF
;
204 virgl_block_write(vws
->sock_fd
, &vtest_hdr
, sizeof(vtest_hdr
));
205 virgl_block_write(vws
->sock_fd
, &cmd
, sizeof(cmd
));
209 int virgl_vtest_send_transfer_cmd(struct virgl_vtest_winsys
*vws
,
212 uint32_t level
, uint32_t stride
,
213 uint32_t layer_stride
,
214 const struct pipe_box
*box
,
217 uint32_t vtest_hdr
[VTEST_HDR_SIZE
];
218 uint32_t cmd
[VCMD_TRANSFER_HDR_SIZE
];
219 bool is_put
= (vcmd
== VCMD_TRANSFER_PUT
);
220 vtest_hdr
[VTEST_CMD_LEN
] = VCMD_TRANSFER_HDR_SIZE
+ (is_put
? (data_size
+ 3 / 4) : 0);
221 vtest_hdr
[VTEST_CMD_ID
] = vcmd
;
226 cmd
[3] = layer_stride
;
231 cmd
[8] = box
->height
;
234 virgl_block_write(vws
->sock_fd
, &vtest_hdr
, sizeof(vtest_hdr
));
235 virgl_block_write(vws
->sock_fd
, &cmd
, sizeof(cmd
));
240 int virgl_vtest_send_transfer_put_data(struct virgl_vtest_winsys
*vws
,
244 return virgl_block_write(vws
->sock_fd
, data
, data_size
);
247 int virgl_vtest_recv_transfer_get_data(struct virgl_vtest_winsys
*vws
,
251 const struct pipe_box
*box
, uint32_t format
)
253 void *line
= malloc(stride
);
255 int hblocks
= util_format_get_nblocksy(format
, box
->height
);
257 line
= malloc(stride
);
259 virgl_block_read(vws
->sock_fd
, line
, stride
);
260 memcpy(ptr
, line
, util_format_get_stride(format
, box
->width
));
268 int virgl_vtest_busy_wait(struct virgl_vtest_winsys
*vws
, int handle
,
271 uint32_t vtest_hdr
[VTEST_HDR_SIZE
];
272 uint32_t cmd
[VCMD_BUSY_WAIT_SIZE
];
275 vtest_hdr
[VTEST_CMD_LEN
] = VCMD_BUSY_WAIT_SIZE
;
276 vtest_hdr
[VTEST_CMD_ID
] = VCMD_RESOURCE_BUSY_WAIT
;
277 cmd
[VCMD_BUSY_WAIT_HANDLE
] = handle
;
278 cmd
[VCMD_BUSY_WAIT_FLAGS
] = flags
;
280 virgl_block_write(vws
->sock_fd
, &vtest_hdr
, sizeof(vtest_hdr
));
281 virgl_block_write(vws
->sock_fd
, &cmd
, sizeof(cmd
));
283 ret
= virgl_block_read(vws
->sock_fd
, vtest_hdr
, sizeof(vtest_hdr
));
285 ret
= virgl_block_read(vws
->sock_fd
, result
, sizeof(result
));