diff options
author | Marc-André Lureau <marcandre.lureau@gmail.com> | 2015-03-12 16:52:31 +0100 |
---|---|---|
committer | Dave Airlie <airlied@gmail.com> | 2015-03-13 14:14:10 +1000 |
commit | 0b27e44304cd3bee8f0a0fedb4f970872dfa584f (patch) | |
tree | 404a25e7d618145e0ec7b88e62cff02c7f172781 /vtest | |
parent | e9ca2d4ad3cc7d210a7a2a35f62cf3d781b3000e (diff) |
vtest: start adding vtest framework
The idea is to have a unix socket and possible shmem protocol
between a renderering server and local gallium sw driver.
This could be used to validate virgl without qemu with piglit.
Diffstat (limited to 'vtest')
-rw-r--r-- | vtest/Makefile.am | 19 | ||||
-rw-r--r-- | vtest/vtest.h | 8 | ||||
-rw-r--r-- | vtest/vtest_renderer.c | 40 | ||||
-rw-r--r-- | vtest/vtest_server.c | 104 |
4 files changed, 171 insertions, 0 deletions
diff --git a/vtest/Makefile.am b/vtest/Makefile.am new file mode 100644 index 0000000..003744f --- /dev/null +++ b/vtest/Makefile.am @@ -0,0 +1,19 @@ +AM_CFLAGS = \ + -I$(top_srcdir)/src/gallium/drivers/virgl \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ + -I$(top_srcdir)/src/gallium/drivers \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src \ + $(DEFINES) \ + $(PIC_FLAGS) \ + $(LIBDRM_CFLAGS) \ + $(EPOXY_CFLAGS) \ + $(VISIBILITY_CFLAGS) \ + $(CODE_COVERAGE_CFLAGS) + +noinst_PROGRAMS = vtest_server + +vtest_server_SOURCES = vtest_server.c vtest_renderer.c + +vtest_server_LDADD = $(top_builddir)/src/libvirglrenderer.la diff --git a/vtest/vtest.h b/vtest/vtest.h new file mode 100644 index 0000000..2453ca3 --- /dev/null +++ b/vtest/vtest.h @@ -0,0 +1,8 @@ +#ifndef VTEST_H +#define VTEST_H + +int vtest_create_renderer(int fd); + +int vtest_send_caps(void); +#endif + diff --git a/vtest/vtest_renderer.c b/vtest/vtest_renderer.c new file mode 100644 index 0000000..75b6506 --- /dev/null +++ b/vtest/vtest_renderer.c @@ -0,0 +1,40 @@ +#include <stdlib.h> +#include <unistd.h> +#include "virglrenderer.h" + +struct virgl_renderer_callbacks vtest_cbs = { + .version = 1, + // .write_fence = vtest_write_fence, +}; + +struct vtest_renderer { + int remote_fd; +}; + +struct vtest_renderer renderer; + +int vtest_create_renderer(int fd) +{ + renderer.remote_fd = fd; + virgl_renderer_init(&renderer, VIRGL_RENDERER_USE_EGL, &vtest_cbs); +} + +int vtest_send_caps(void) +{ + uint32_t max_ver, max_size; + void *caps_buf; + uint32_t hdr_buf[2]; + virgl_renderer_get_cap_set(1, &max_ver, &max_size); + + caps_buf = malloc(max_size); + if (!caps_buf) + return -1; + + virgl_renderer_fill_caps(1, 1, caps_buf); + + hdr_buf[0] = max_size + 1; + hdr_buf[1] = 1; + write(renderer.remote_fd, hdr_buf, 8); + write(renderer.remote_fd, caps_buf, max_size); + return 0; +} diff --git a/vtest/vtest_server.c b/vtest/vtest_server.c new file mode 100644 index 0000000..1b6ea4d --- /dev/null +++ b/vtest/vtest_server.c @@ -0,0 +1,104 @@ +#include <stdio.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <sys/un.h> + +#include "vtest.h" +static int vtest_open_socket(const char *path) +{ + struct sockaddr_un un; + int sock; + + sock = socket(PF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + return -1; + } + + memset(&un, 0, sizeof(un)); + un.sun_family = AF_UNIX; + + snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); + + unlink(un.sun_path); + + if (bind(sock, (struct sockaddr *)&un, sizeof(un)) < 0) { + goto err; + } + + if (listen(sock, 1) < 0){ + goto err; + } + + return sock; + err: + close(sock); + return -1; +} + +int wait_for_socket_accept(int sock) +{ + fd_set read_fds; + int new_fd; + int ret; + FD_ZERO(&read_fds); + FD_SET(sock, &read_fds); + + ret = select(sock + 1, &read_fds, NULL, NULL, NULL); + if (ret < 0) + return ret; + + if (FD_ISSET(sock, &read_fds)) { + new_fd = accept(sock, NULL, NULL); + return new_fd; + } + return -1; +} + +int wait_for_socket_read(int sock) +{ + fd_set read_fds; + + int ret; + FD_ZERO(&read_fds); + FD_SET(sock, &read_fds); + + ret = select(sock + 1, &read_fds, NULL, NULL, NULL); + if (ret < 0) + return ret; + + if (FD_ISSET(sock, &read_fds)) { + return 0; + } + return -1; +} + +int main(void) +{ + int sock, new_fd, ret; + uint32_t header[2]; + sock = vtest_open_socket("/tmp/.virgl_test"); + + new_fd = wait_for_socket_accept(sock); + +again: + ret = wait_for_socket_read(new_fd); + if (ret < 0) + goto err; + + vtest_create_renderer(new_fd); + ret = read(new_fd, &header, 2 * sizeof(uint32_t)); + + if (ret == 8) { + fprintf(stderr, "got %d %d\n", header[0], header[1]); + + if (header[1] == 1) { + vtest_send_caps(); + } + goto again; + } +err: + close(new_fd); + close(sock); +} |