1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright 2019 Google LLC 3bf215546Sopenharmony_ci * SPDX-License-Identifier: MIT 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * based in part on virgl which is: 6bf215546Sopenharmony_ci * Copyright 2014, 2015 Red Hat. 7bf215546Sopenharmony_ci */ 8bf215546Sopenharmony_ci 9bf215546Sopenharmony_ci#include <errno.h> 10bf215546Sopenharmony_ci#include <netinet/in.h> 11bf215546Sopenharmony_ci#include <poll.h> 12bf215546Sopenharmony_ci#include <sys/mman.h> 13bf215546Sopenharmony_ci#include <sys/socket.h> 14bf215546Sopenharmony_ci#include <sys/types.h> 15bf215546Sopenharmony_ci#include <sys/un.h> 16bf215546Sopenharmony_ci#include <unistd.h> 17bf215546Sopenharmony_ci 18bf215546Sopenharmony_ci#include "util/os_file.h" 19bf215546Sopenharmony_ci#include "util/sparse_array.h" 20bf215546Sopenharmony_ci#include "util/u_process.h" 21bf215546Sopenharmony_ci#define VIRGL_RENDERER_UNSTABLE_APIS 22bf215546Sopenharmony_ci#include "virtio-gpu/virglrenderer_hw.h" 23bf215546Sopenharmony_ci#include "vtest/vtest_protocol.h" 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#include "vn_renderer_internal.h" 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci#define VTEST_PCI_VENDOR_ID 0x1af4 28bf215546Sopenharmony_ci#define VTEST_PCI_DEVICE_ID 0x1050 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_cistruct vtest; 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_cistruct vtest_shmem { 33bf215546Sopenharmony_ci struct vn_renderer_shmem base; 34bf215546Sopenharmony_ci}; 35bf215546Sopenharmony_ci 36bf215546Sopenharmony_cistruct vtest_bo { 37bf215546Sopenharmony_ci struct vn_renderer_bo base; 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci uint32_t blob_flags; 40bf215546Sopenharmony_ci /* might be closed after mmap */ 41bf215546Sopenharmony_ci int res_fd; 42bf215546Sopenharmony_ci}; 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_cistruct vtest_sync { 45bf215546Sopenharmony_ci struct vn_renderer_sync base; 46bf215546Sopenharmony_ci}; 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_cistruct vtest { 49bf215546Sopenharmony_ci struct vn_renderer base; 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci struct vn_instance *instance; 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci mtx_t sock_mutex; 54bf215546Sopenharmony_ci int sock_fd; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci uint32_t protocol_version; 57bf215546Sopenharmony_ci uint32_t max_sync_queue_count; 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci struct { 60bf215546Sopenharmony_ci enum virgl_renderer_capset id; 61bf215546Sopenharmony_ci uint32_t version; 62bf215546Sopenharmony_ci struct virgl_renderer_capset_venus data; 63bf215546Sopenharmony_ci } capset; 64bf215546Sopenharmony_ci 65bf215546Sopenharmony_ci uint32_t shmem_blob_mem; 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci struct util_sparse_array shmem_array; 68bf215546Sopenharmony_ci struct util_sparse_array bo_array; 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci struct vn_renderer_shmem_cache shmem_cache; 71bf215546Sopenharmony_ci}; 72bf215546Sopenharmony_ci 73bf215546Sopenharmony_cistatic int 74bf215546Sopenharmony_civtest_connect_socket(struct vn_instance *instance, const char *path) 75bf215546Sopenharmony_ci{ 76bf215546Sopenharmony_ci struct sockaddr_un un; 77bf215546Sopenharmony_ci int sock; 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_ci sock = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); 80bf215546Sopenharmony_ci if (sock < 0) { 81bf215546Sopenharmony_ci vn_log(instance, "failed to create a socket"); 82bf215546Sopenharmony_ci return -1; 83bf215546Sopenharmony_ci } 84bf215546Sopenharmony_ci 85bf215546Sopenharmony_ci memset(&un, 0, sizeof(un)); 86bf215546Sopenharmony_ci un.sun_family = AF_UNIX; 87bf215546Sopenharmony_ci memcpy(un.sun_path, path, strlen(path)); 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci if (connect(sock, (struct sockaddr *)&un, sizeof(un)) == -1) { 90bf215546Sopenharmony_ci vn_log(instance, "failed to connect to %s: %s", path, strerror(errno)); 91bf215546Sopenharmony_ci close(sock); 92bf215546Sopenharmony_ci return -1; 93bf215546Sopenharmony_ci } 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci return sock; 96bf215546Sopenharmony_ci} 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_cistatic void 99bf215546Sopenharmony_civtest_read(struct vtest *vtest, void *buf, size_t size) 100bf215546Sopenharmony_ci{ 101bf215546Sopenharmony_ci do { 102bf215546Sopenharmony_ci const ssize_t ret = read(vtest->sock_fd, buf, size); 103bf215546Sopenharmony_ci if (unlikely(ret < 0)) { 104bf215546Sopenharmony_ci vn_log(vtest->instance, 105bf215546Sopenharmony_ci "lost connection to rendering server on %zu read %zi %d", 106bf215546Sopenharmony_ci size, ret, errno); 107bf215546Sopenharmony_ci abort(); 108bf215546Sopenharmony_ci } 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci buf += ret; 111bf215546Sopenharmony_ci size -= ret; 112bf215546Sopenharmony_ci } while (size); 113bf215546Sopenharmony_ci} 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_cistatic int 116bf215546Sopenharmony_civtest_receive_fd(struct vtest *vtest) 117bf215546Sopenharmony_ci{ 118bf215546Sopenharmony_ci char cmsg_buf[CMSG_SPACE(sizeof(int))]; 119bf215546Sopenharmony_ci char dummy; 120bf215546Sopenharmony_ci struct msghdr msg = { 121bf215546Sopenharmony_ci .msg_iov = 122bf215546Sopenharmony_ci &(struct iovec){ 123bf215546Sopenharmony_ci .iov_base = &dummy, 124bf215546Sopenharmony_ci .iov_len = sizeof(dummy), 125bf215546Sopenharmony_ci }, 126bf215546Sopenharmony_ci .msg_iovlen = 1, 127bf215546Sopenharmony_ci .msg_control = cmsg_buf, 128bf215546Sopenharmony_ci .msg_controllen = sizeof(cmsg_buf), 129bf215546Sopenharmony_ci }; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci if (recvmsg(vtest->sock_fd, &msg, 0) < 0) { 132bf215546Sopenharmony_ci vn_log(vtest->instance, "recvmsg failed: %s", strerror(errno)); 133bf215546Sopenharmony_ci abort(); 134bf215546Sopenharmony_ci } 135bf215546Sopenharmony_ci 136bf215546Sopenharmony_ci struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); 137bf215546Sopenharmony_ci if (!cmsg || cmsg->cmsg_level != SOL_SOCKET || 138bf215546Sopenharmony_ci cmsg->cmsg_type != SCM_RIGHTS) { 139bf215546Sopenharmony_ci vn_log(vtest->instance, "invalid cmsghdr"); 140bf215546Sopenharmony_ci abort(); 141bf215546Sopenharmony_ci } 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci return *((int *)CMSG_DATA(cmsg)); 144bf215546Sopenharmony_ci} 145bf215546Sopenharmony_ci 146bf215546Sopenharmony_cistatic void 147bf215546Sopenharmony_civtest_write(struct vtest *vtest, const void *buf, size_t size) 148bf215546Sopenharmony_ci{ 149bf215546Sopenharmony_ci do { 150bf215546Sopenharmony_ci const ssize_t ret = write(vtest->sock_fd, buf, size); 151bf215546Sopenharmony_ci if (unlikely(ret < 0)) { 152bf215546Sopenharmony_ci vn_log(vtest->instance, 153bf215546Sopenharmony_ci "lost connection to rendering server on %zu write %zi %d", 154bf215546Sopenharmony_ci size, ret, errno); 155bf215546Sopenharmony_ci abort(); 156bf215546Sopenharmony_ci } 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci buf += ret; 159bf215546Sopenharmony_ci size -= ret; 160bf215546Sopenharmony_ci } while (size); 161bf215546Sopenharmony_ci} 162bf215546Sopenharmony_ci 163bf215546Sopenharmony_cistatic void 164bf215546Sopenharmony_civtest_vcmd_create_renderer(struct vtest *vtest, const char *name) 165bf215546Sopenharmony_ci{ 166bf215546Sopenharmony_ci const size_t size = strlen(name) + 1; 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 169bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = size; 170bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_CREATE_RENDERER; 171bf215546Sopenharmony_ci 172bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 173bf215546Sopenharmony_ci vtest_write(vtest, name, size); 174bf215546Sopenharmony_ci} 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_cistatic bool 177bf215546Sopenharmony_civtest_vcmd_ping_protocol_version(struct vtest *vtest) 178bf215546Sopenharmony_ci{ 179bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 180bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_PING_PROTOCOL_VERSION_SIZE; 181bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_PING_PROTOCOL_VERSION; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 184bf215546Sopenharmony_ci 185bf215546Sopenharmony_ci /* send a dummy busy wait to avoid blocking in vtest_read in case ping 186bf215546Sopenharmony_ci * protocol version is not supported 187bf215546Sopenharmony_ci */ 188bf215546Sopenharmony_ci uint32_t vcmd_busy_wait[VCMD_BUSY_WAIT_SIZE]; 189bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_BUSY_WAIT_SIZE; 190bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_RESOURCE_BUSY_WAIT; 191bf215546Sopenharmony_ci vcmd_busy_wait[VCMD_BUSY_WAIT_HANDLE] = 0; 192bf215546Sopenharmony_ci vcmd_busy_wait[VCMD_BUSY_WAIT_FLAGS] = 0; 193bf215546Sopenharmony_ci 194bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 195bf215546Sopenharmony_ci vtest_write(vtest, vcmd_busy_wait, sizeof(vcmd_busy_wait)); 196bf215546Sopenharmony_ci 197bf215546Sopenharmony_ci uint32_t dummy; 198bf215546Sopenharmony_ci vtest_read(vtest, vtest_hdr, sizeof(vtest_hdr)); 199bf215546Sopenharmony_ci if (vtest_hdr[VTEST_CMD_ID] == VCMD_PING_PROTOCOL_VERSION) { 200bf215546Sopenharmony_ci /* consume the dummy busy wait result */ 201bf215546Sopenharmony_ci vtest_read(vtest, vtest_hdr, sizeof(vtest_hdr)); 202bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_ID] == VCMD_RESOURCE_BUSY_WAIT); 203bf215546Sopenharmony_ci vtest_read(vtest, &dummy, sizeof(dummy)); 204bf215546Sopenharmony_ci return true; 205bf215546Sopenharmony_ci } else { 206bf215546Sopenharmony_ci /* no ping protocol version support */ 207bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_ID] == VCMD_RESOURCE_BUSY_WAIT); 208bf215546Sopenharmony_ci vtest_read(vtest, &dummy, sizeof(dummy)); 209bf215546Sopenharmony_ci return false; 210bf215546Sopenharmony_ci } 211bf215546Sopenharmony_ci} 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_cistatic uint32_t 214bf215546Sopenharmony_civtest_vcmd_protocol_version(struct vtest *vtest) 215bf215546Sopenharmony_ci{ 216bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 217bf215546Sopenharmony_ci uint32_t vcmd_protocol_version[VCMD_PROTOCOL_VERSION_SIZE]; 218bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_PROTOCOL_VERSION_SIZE; 219bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_PROTOCOL_VERSION; 220bf215546Sopenharmony_ci vcmd_protocol_version[VCMD_PROTOCOL_VERSION_VERSION] = 221bf215546Sopenharmony_ci VTEST_PROTOCOL_VERSION; 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 224bf215546Sopenharmony_ci vtest_write(vtest, vcmd_protocol_version, sizeof(vcmd_protocol_version)); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci vtest_read(vtest, vtest_hdr, sizeof(vtest_hdr)); 227bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_LEN] == VCMD_PROTOCOL_VERSION_SIZE); 228bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_ID] == VCMD_PROTOCOL_VERSION); 229bf215546Sopenharmony_ci vtest_read(vtest, vcmd_protocol_version, sizeof(vcmd_protocol_version)); 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci return vcmd_protocol_version[VCMD_PROTOCOL_VERSION_VERSION]; 232bf215546Sopenharmony_ci} 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_cistatic uint32_t 235bf215546Sopenharmony_civtest_vcmd_get_param(struct vtest *vtest, enum vcmd_param param) 236bf215546Sopenharmony_ci{ 237bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 238bf215546Sopenharmony_ci uint32_t vcmd_get_param[VCMD_GET_PARAM_SIZE]; 239bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_GET_PARAM_SIZE; 240bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_GET_PARAM; 241bf215546Sopenharmony_ci vcmd_get_param[VCMD_GET_PARAM_PARAM] = param; 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 244bf215546Sopenharmony_ci vtest_write(vtest, vcmd_get_param, sizeof(vcmd_get_param)); 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci vtest_read(vtest, vtest_hdr, sizeof(vtest_hdr)); 247bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_LEN] == 2); 248bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_ID] == VCMD_GET_PARAM); 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci uint32_t resp[2]; 251bf215546Sopenharmony_ci vtest_read(vtest, resp, sizeof(resp)); 252bf215546Sopenharmony_ci 253bf215546Sopenharmony_ci return resp[0] ? resp[1] : 0; 254bf215546Sopenharmony_ci} 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_cistatic bool 257bf215546Sopenharmony_civtest_vcmd_get_capset(struct vtest *vtest, 258bf215546Sopenharmony_ci enum virgl_renderer_capset id, 259bf215546Sopenharmony_ci uint32_t version, 260bf215546Sopenharmony_ci void *capset, 261bf215546Sopenharmony_ci size_t capset_size) 262bf215546Sopenharmony_ci{ 263bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 264bf215546Sopenharmony_ci uint32_t vcmd_get_capset[VCMD_GET_CAPSET_SIZE]; 265bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_GET_CAPSET_SIZE; 266bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_GET_CAPSET; 267bf215546Sopenharmony_ci vcmd_get_capset[VCMD_GET_CAPSET_ID] = id; 268bf215546Sopenharmony_ci vcmd_get_capset[VCMD_GET_CAPSET_VERSION] = version; 269bf215546Sopenharmony_ci 270bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 271bf215546Sopenharmony_ci vtest_write(vtest, vcmd_get_capset, sizeof(vcmd_get_capset)); 272bf215546Sopenharmony_ci 273bf215546Sopenharmony_ci vtest_read(vtest, vtest_hdr, sizeof(vtest_hdr)); 274bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_ID] == VCMD_GET_CAPSET); 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ci uint32_t valid; 277bf215546Sopenharmony_ci vtest_read(vtest, &valid, sizeof(valid)); 278bf215546Sopenharmony_ci if (!valid) 279bf215546Sopenharmony_ci return false; 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci size_t read_size = (vtest_hdr[VTEST_CMD_LEN] - 1) * 4; 282bf215546Sopenharmony_ci if (capset_size >= read_size) { 283bf215546Sopenharmony_ci vtest_read(vtest, capset, read_size); 284bf215546Sopenharmony_ci memset(capset + read_size, 0, capset_size - read_size); 285bf215546Sopenharmony_ci } else { 286bf215546Sopenharmony_ci vtest_read(vtest, capset, capset_size); 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci char temp[256]; 289bf215546Sopenharmony_ci read_size -= capset_size; 290bf215546Sopenharmony_ci while (read_size) { 291bf215546Sopenharmony_ci const size_t temp_size = MIN2(read_size, ARRAY_SIZE(temp)); 292bf215546Sopenharmony_ci vtest_read(vtest, temp, temp_size); 293bf215546Sopenharmony_ci read_size -= temp_size; 294bf215546Sopenharmony_ci } 295bf215546Sopenharmony_ci } 296bf215546Sopenharmony_ci 297bf215546Sopenharmony_ci return true; 298bf215546Sopenharmony_ci} 299bf215546Sopenharmony_ci 300bf215546Sopenharmony_cistatic void 301bf215546Sopenharmony_civtest_vcmd_context_init(struct vtest *vtest, 302bf215546Sopenharmony_ci enum virgl_renderer_capset capset_id) 303bf215546Sopenharmony_ci{ 304bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 305bf215546Sopenharmony_ci uint32_t vcmd_context_init[VCMD_CONTEXT_INIT_SIZE]; 306bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_CONTEXT_INIT_SIZE; 307bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_CONTEXT_INIT; 308bf215546Sopenharmony_ci vcmd_context_init[VCMD_CONTEXT_INIT_CAPSET_ID] = capset_id; 309bf215546Sopenharmony_ci 310bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 311bf215546Sopenharmony_ci vtest_write(vtest, vcmd_context_init, sizeof(vcmd_context_init)); 312bf215546Sopenharmony_ci} 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_cistatic uint32_t 315bf215546Sopenharmony_civtest_vcmd_resource_create_blob(struct vtest *vtest, 316bf215546Sopenharmony_ci enum vcmd_blob_type type, 317bf215546Sopenharmony_ci uint32_t flags, 318bf215546Sopenharmony_ci VkDeviceSize size, 319bf215546Sopenharmony_ci vn_object_id blob_id, 320bf215546Sopenharmony_ci int *res_fd) 321bf215546Sopenharmony_ci{ 322bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 323bf215546Sopenharmony_ci uint32_t vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_SIZE]; 324bf215546Sopenharmony_ci 325bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_RES_CREATE_BLOB_SIZE; 326bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_RESOURCE_CREATE_BLOB; 327bf215546Sopenharmony_ci 328bf215546Sopenharmony_ci vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_TYPE] = type; 329bf215546Sopenharmony_ci vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_FLAGS] = flags; 330bf215546Sopenharmony_ci vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_SIZE_LO] = (uint32_t)size; 331bf215546Sopenharmony_ci vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_SIZE_HI] = 332bf215546Sopenharmony_ci (uint32_t)(size >> 32); 333bf215546Sopenharmony_ci vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_ID_LO] = (uint32_t)blob_id; 334bf215546Sopenharmony_ci vcmd_res_create_blob[VCMD_RES_CREATE_BLOB_ID_HI] = 335bf215546Sopenharmony_ci (uint32_t)(blob_id >> 32); 336bf215546Sopenharmony_ci 337bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 338bf215546Sopenharmony_ci vtest_write(vtest, vcmd_res_create_blob, sizeof(vcmd_res_create_blob)); 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci vtest_read(vtest, vtest_hdr, sizeof(vtest_hdr)); 341bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_LEN] == 1); 342bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_ID] == VCMD_RESOURCE_CREATE_BLOB); 343bf215546Sopenharmony_ci 344bf215546Sopenharmony_ci uint32_t res_id; 345bf215546Sopenharmony_ci vtest_read(vtest, &res_id, sizeof(res_id)); 346bf215546Sopenharmony_ci 347bf215546Sopenharmony_ci *res_fd = vtest_receive_fd(vtest); 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci return res_id; 350bf215546Sopenharmony_ci} 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_cistatic void 353bf215546Sopenharmony_civtest_vcmd_resource_unref(struct vtest *vtest, uint32_t res_id) 354bf215546Sopenharmony_ci{ 355bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 356bf215546Sopenharmony_ci uint32_t vcmd_res_unref[VCMD_RES_UNREF_SIZE]; 357bf215546Sopenharmony_ci 358bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_RES_UNREF_SIZE; 359bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_RESOURCE_UNREF; 360bf215546Sopenharmony_ci vcmd_res_unref[VCMD_RES_UNREF_RES_HANDLE] = res_id; 361bf215546Sopenharmony_ci 362bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 363bf215546Sopenharmony_ci vtest_write(vtest, vcmd_res_unref, sizeof(vcmd_res_unref)); 364bf215546Sopenharmony_ci} 365bf215546Sopenharmony_ci 366bf215546Sopenharmony_cistatic uint32_t 367bf215546Sopenharmony_civtest_vcmd_sync_create(struct vtest *vtest, uint64_t initial_val) 368bf215546Sopenharmony_ci{ 369bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 370bf215546Sopenharmony_ci uint32_t vcmd_sync_create[VCMD_SYNC_CREATE_SIZE]; 371bf215546Sopenharmony_ci 372bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_SYNC_CREATE_SIZE; 373bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_SYNC_CREATE; 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci vcmd_sync_create[VCMD_SYNC_CREATE_VALUE_LO] = (uint32_t)initial_val; 376bf215546Sopenharmony_ci vcmd_sync_create[VCMD_SYNC_CREATE_VALUE_HI] = 377bf215546Sopenharmony_ci (uint32_t)(initial_val >> 32); 378bf215546Sopenharmony_ci 379bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 380bf215546Sopenharmony_ci vtest_write(vtest, vcmd_sync_create, sizeof(vcmd_sync_create)); 381bf215546Sopenharmony_ci 382bf215546Sopenharmony_ci vtest_read(vtest, vtest_hdr, sizeof(vtest_hdr)); 383bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_LEN] == 1); 384bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_ID] == VCMD_SYNC_CREATE); 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci uint32_t sync_id; 387bf215546Sopenharmony_ci vtest_read(vtest, &sync_id, sizeof(sync_id)); 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci return sync_id; 390bf215546Sopenharmony_ci} 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_cistatic void 393bf215546Sopenharmony_civtest_vcmd_sync_unref(struct vtest *vtest, uint32_t sync_id) 394bf215546Sopenharmony_ci{ 395bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 396bf215546Sopenharmony_ci uint32_t vcmd_sync_unref[VCMD_SYNC_UNREF_SIZE]; 397bf215546Sopenharmony_ci 398bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_SYNC_UNREF_SIZE; 399bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_SYNC_UNREF; 400bf215546Sopenharmony_ci vcmd_sync_unref[VCMD_SYNC_UNREF_ID] = sync_id; 401bf215546Sopenharmony_ci 402bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 403bf215546Sopenharmony_ci vtest_write(vtest, vcmd_sync_unref, sizeof(vcmd_sync_unref)); 404bf215546Sopenharmony_ci} 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_cistatic uint64_t 407bf215546Sopenharmony_civtest_vcmd_sync_read(struct vtest *vtest, uint32_t sync_id) 408bf215546Sopenharmony_ci{ 409bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 410bf215546Sopenharmony_ci uint32_t vcmd_sync_read[VCMD_SYNC_READ_SIZE]; 411bf215546Sopenharmony_ci 412bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_SYNC_READ_SIZE; 413bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_SYNC_READ; 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci vcmd_sync_read[VCMD_SYNC_READ_ID] = sync_id; 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 418bf215546Sopenharmony_ci vtest_write(vtest, vcmd_sync_read, sizeof(vcmd_sync_read)); 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci vtest_read(vtest, vtest_hdr, sizeof(vtest_hdr)); 421bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_LEN] == 2); 422bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_ID] == VCMD_SYNC_READ); 423bf215546Sopenharmony_ci 424bf215546Sopenharmony_ci uint64_t val; 425bf215546Sopenharmony_ci vtest_read(vtest, &val, sizeof(val)); 426bf215546Sopenharmony_ci 427bf215546Sopenharmony_ci return val; 428bf215546Sopenharmony_ci} 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_cistatic void 431bf215546Sopenharmony_civtest_vcmd_sync_write(struct vtest *vtest, uint32_t sync_id, uint64_t val) 432bf215546Sopenharmony_ci{ 433bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 434bf215546Sopenharmony_ci uint32_t vcmd_sync_write[VCMD_SYNC_WRITE_SIZE]; 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_SYNC_WRITE_SIZE; 437bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_SYNC_WRITE; 438bf215546Sopenharmony_ci 439bf215546Sopenharmony_ci vcmd_sync_write[VCMD_SYNC_WRITE_ID] = sync_id; 440bf215546Sopenharmony_ci vcmd_sync_write[VCMD_SYNC_WRITE_VALUE_LO] = (uint32_t)val; 441bf215546Sopenharmony_ci vcmd_sync_write[VCMD_SYNC_WRITE_VALUE_HI] = (uint32_t)(val >> 32); 442bf215546Sopenharmony_ci 443bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 444bf215546Sopenharmony_ci vtest_write(vtest, vcmd_sync_write, sizeof(vcmd_sync_write)); 445bf215546Sopenharmony_ci} 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_cistatic int 448bf215546Sopenharmony_civtest_vcmd_sync_wait(struct vtest *vtest, 449bf215546Sopenharmony_ci uint32_t flags, 450bf215546Sopenharmony_ci int poll_timeout, 451bf215546Sopenharmony_ci struct vn_renderer_sync *const *syncs, 452bf215546Sopenharmony_ci const uint64_t *vals, 453bf215546Sopenharmony_ci uint32_t count) 454bf215546Sopenharmony_ci{ 455bf215546Sopenharmony_ci const uint32_t timeout = poll_timeout >= 0 && poll_timeout <= INT32_MAX 456bf215546Sopenharmony_ci ? poll_timeout 457bf215546Sopenharmony_ci : UINT32_MAX; 458bf215546Sopenharmony_ci 459bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 460bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = VCMD_SYNC_WAIT_SIZE(count); 461bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_SYNC_WAIT; 462bf215546Sopenharmony_ci 463bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 464bf215546Sopenharmony_ci vtest_write(vtest, &flags, sizeof(flags)); 465bf215546Sopenharmony_ci vtest_write(vtest, &timeout, sizeof(timeout)); 466bf215546Sopenharmony_ci for (uint32_t i = 0; i < count; i++) { 467bf215546Sopenharmony_ci const uint64_t val = vals[i]; 468bf215546Sopenharmony_ci const uint32_t sync[3] = { 469bf215546Sopenharmony_ci syncs[i]->sync_id, 470bf215546Sopenharmony_ci (uint32_t)val, 471bf215546Sopenharmony_ci (uint32_t)(val >> 32), 472bf215546Sopenharmony_ci }; 473bf215546Sopenharmony_ci vtest_write(vtest, sync, sizeof(sync)); 474bf215546Sopenharmony_ci } 475bf215546Sopenharmony_ci 476bf215546Sopenharmony_ci vtest_read(vtest, vtest_hdr, sizeof(vtest_hdr)); 477bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_LEN] == 0); 478bf215546Sopenharmony_ci assert(vtest_hdr[VTEST_CMD_ID] == VCMD_SYNC_WAIT); 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci return vtest_receive_fd(vtest); 481bf215546Sopenharmony_ci} 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_cistatic void 484bf215546Sopenharmony_cisubmit_cmd2_sizes(const struct vn_renderer_submit *submit, 485bf215546Sopenharmony_ci size_t *header_size, 486bf215546Sopenharmony_ci size_t *cs_size, 487bf215546Sopenharmony_ci size_t *sync_size) 488bf215546Sopenharmony_ci{ 489bf215546Sopenharmony_ci if (!submit->batch_count) { 490bf215546Sopenharmony_ci *header_size = 0; 491bf215546Sopenharmony_ci *cs_size = 0; 492bf215546Sopenharmony_ci *sync_size = 0; 493bf215546Sopenharmony_ci return; 494bf215546Sopenharmony_ci } 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci *header_size = sizeof(uint32_t) + 497bf215546Sopenharmony_ci sizeof(struct vcmd_submit_cmd2_batch) * submit->batch_count; 498bf215546Sopenharmony_ci 499bf215546Sopenharmony_ci *cs_size = 0; 500bf215546Sopenharmony_ci *sync_size = 0; 501bf215546Sopenharmony_ci for (uint32_t i = 0; i < submit->batch_count; i++) { 502bf215546Sopenharmony_ci const struct vn_renderer_submit_batch *batch = &submit->batches[i]; 503bf215546Sopenharmony_ci assert(batch->cs_size % sizeof(uint32_t) == 0); 504bf215546Sopenharmony_ci *cs_size += batch->cs_size; 505bf215546Sopenharmony_ci *sync_size += (sizeof(uint32_t) + sizeof(uint64_t)) * batch->sync_count; 506bf215546Sopenharmony_ci } 507bf215546Sopenharmony_ci 508bf215546Sopenharmony_ci assert(*header_size % sizeof(uint32_t) == 0); 509bf215546Sopenharmony_ci assert(*cs_size % sizeof(uint32_t) == 0); 510bf215546Sopenharmony_ci assert(*sync_size % sizeof(uint32_t) == 0); 511bf215546Sopenharmony_ci} 512bf215546Sopenharmony_ci 513bf215546Sopenharmony_cistatic void 514bf215546Sopenharmony_civtest_vcmd_submit_cmd2(struct vtest *vtest, 515bf215546Sopenharmony_ci const struct vn_renderer_submit *submit) 516bf215546Sopenharmony_ci{ 517bf215546Sopenharmony_ci size_t header_size; 518bf215546Sopenharmony_ci size_t cs_size; 519bf215546Sopenharmony_ci size_t sync_size; 520bf215546Sopenharmony_ci submit_cmd2_sizes(submit, &header_size, &cs_size, &sync_size); 521bf215546Sopenharmony_ci const size_t total_size = header_size + cs_size + sync_size; 522bf215546Sopenharmony_ci if (!total_size) 523bf215546Sopenharmony_ci return; 524bf215546Sopenharmony_ci 525bf215546Sopenharmony_ci uint32_t vtest_hdr[VTEST_HDR_SIZE]; 526bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_LEN] = total_size / sizeof(uint32_t); 527bf215546Sopenharmony_ci vtest_hdr[VTEST_CMD_ID] = VCMD_SUBMIT_CMD2; 528bf215546Sopenharmony_ci vtest_write(vtest, vtest_hdr, sizeof(vtest_hdr)); 529bf215546Sopenharmony_ci 530bf215546Sopenharmony_ci /* write batch count and batch headers */ 531bf215546Sopenharmony_ci const uint32_t batch_count = submit->batch_count; 532bf215546Sopenharmony_ci size_t cs_offset = header_size; 533bf215546Sopenharmony_ci size_t sync_offset = cs_offset + cs_size; 534bf215546Sopenharmony_ci vtest_write(vtest, &batch_count, sizeof(batch_count)); 535bf215546Sopenharmony_ci for (uint32_t i = 0; i < submit->batch_count; i++) { 536bf215546Sopenharmony_ci const struct vn_renderer_submit_batch *batch = &submit->batches[i]; 537bf215546Sopenharmony_ci struct vcmd_submit_cmd2_batch dst = { 538bf215546Sopenharmony_ci .cmd_offset = cs_offset / sizeof(uint32_t), 539bf215546Sopenharmony_ci .cmd_size = batch->cs_size / sizeof(uint32_t), 540bf215546Sopenharmony_ci .sync_offset = sync_offset / sizeof(uint32_t), 541bf215546Sopenharmony_ci .sync_count = batch->sync_count, 542bf215546Sopenharmony_ci }; 543bf215546Sopenharmony_ci if (!batch->sync_queue_cpu) { 544bf215546Sopenharmony_ci dst.flags = VCMD_SUBMIT_CMD2_FLAG_SYNC_QUEUE; 545bf215546Sopenharmony_ci dst.sync_queue_index = batch->sync_queue_index; 546bf215546Sopenharmony_ci dst.sync_queue_id = batch->vk_queue_id; 547bf215546Sopenharmony_ci } 548bf215546Sopenharmony_ci vtest_write(vtest, &dst, sizeof(dst)); 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_ci cs_offset += batch->cs_size; 551bf215546Sopenharmony_ci sync_offset += 552bf215546Sopenharmony_ci (sizeof(uint32_t) + sizeof(uint64_t)) * batch->sync_count; 553bf215546Sopenharmony_ci } 554bf215546Sopenharmony_ci 555bf215546Sopenharmony_ci /* write cs */ 556bf215546Sopenharmony_ci if (cs_size) { 557bf215546Sopenharmony_ci for (uint32_t i = 0; i < submit->batch_count; i++) { 558bf215546Sopenharmony_ci const struct vn_renderer_submit_batch *batch = &submit->batches[i]; 559bf215546Sopenharmony_ci if (batch->cs_size) 560bf215546Sopenharmony_ci vtest_write(vtest, batch->cs_data, batch->cs_size); 561bf215546Sopenharmony_ci } 562bf215546Sopenharmony_ci } 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ci /* write syncs */ 565bf215546Sopenharmony_ci for (uint32_t i = 0; i < submit->batch_count; i++) { 566bf215546Sopenharmony_ci const struct vn_renderer_submit_batch *batch = &submit->batches[i]; 567bf215546Sopenharmony_ci 568bf215546Sopenharmony_ci for (uint32_t j = 0; j < batch->sync_count; j++) { 569bf215546Sopenharmony_ci const uint64_t val = batch->sync_values[j]; 570bf215546Sopenharmony_ci const uint32_t sync[3] = { 571bf215546Sopenharmony_ci batch->syncs[j]->sync_id, 572bf215546Sopenharmony_ci (uint32_t)val, 573bf215546Sopenharmony_ci (uint32_t)(val >> 32), 574bf215546Sopenharmony_ci }; 575bf215546Sopenharmony_ci vtest_write(vtest, sync, sizeof(sync)); 576bf215546Sopenharmony_ci } 577bf215546Sopenharmony_ci } 578bf215546Sopenharmony_ci} 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_cistatic VkResult 581bf215546Sopenharmony_civtest_sync_write(struct vn_renderer *renderer, 582bf215546Sopenharmony_ci struct vn_renderer_sync *_sync, 583bf215546Sopenharmony_ci uint64_t val) 584bf215546Sopenharmony_ci{ 585bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 586bf215546Sopenharmony_ci struct vtest_sync *sync = (struct vtest_sync *)_sync; 587bf215546Sopenharmony_ci 588bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 589bf215546Sopenharmony_ci vtest_vcmd_sync_write(vtest, sync->base.sync_id, val); 590bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 591bf215546Sopenharmony_ci 592bf215546Sopenharmony_ci return VK_SUCCESS; 593bf215546Sopenharmony_ci} 594bf215546Sopenharmony_ci 595bf215546Sopenharmony_cistatic VkResult 596bf215546Sopenharmony_civtest_sync_read(struct vn_renderer *renderer, 597bf215546Sopenharmony_ci struct vn_renderer_sync *_sync, 598bf215546Sopenharmony_ci uint64_t *val) 599bf215546Sopenharmony_ci{ 600bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 601bf215546Sopenharmony_ci struct vtest_sync *sync = (struct vtest_sync *)_sync; 602bf215546Sopenharmony_ci 603bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 604bf215546Sopenharmony_ci *val = vtest_vcmd_sync_read(vtest, sync->base.sync_id); 605bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 606bf215546Sopenharmony_ci 607bf215546Sopenharmony_ci return VK_SUCCESS; 608bf215546Sopenharmony_ci} 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_cistatic VkResult 611bf215546Sopenharmony_civtest_sync_reset(struct vn_renderer *renderer, 612bf215546Sopenharmony_ci struct vn_renderer_sync *sync, 613bf215546Sopenharmony_ci uint64_t initial_val) 614bf215546Sopenharmony_ci{ 615bf215546Sopenharmony_ci /* same as write */ 616bf215546Sopenharmony_ci return vtest_sync_write(renderer, sync, initial_val); 617bf215546Sopenharmony_ci} 618bf215546Sopenharmony_ci 619bf215546Sopenharmony_cistatic void 620bf215546Sopenharmony_civtest_sync_destroy(struct vn_renderer *renderer, 621bf215546Sopenharmony_ci struct vn_renderer_sync *_sync) 622bf215546Sopenharmony_ci{ 623bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 624bf215546Sopenharmony_ci struct vtest_sync *sync = (struct vtest_sync *)_sync; 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 627bf215546Sopenharmony_ci vtest_vcmd_sync_unref(vtest, sync->base.sync_id); 628bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 629bf215546Sopenharmony_ci 630bf215546Sopenharmony_ci free(sync); 631bf215546Sopenharmony_ci} 632bf215546Sopenharmony_ci 633bf215546Sopenharmony_cistatic VkResult 634bf215546Sopenharmony_civtest_sync_create(struct vn_renderer *renderer, 635bf215546Sopenharmony_ci uint64_t initial_val, 636bf215546Sopenharmony_ci uint32_t flags, 637bf215546Sopenharmony_ci struct vn_renderer_sync **out_sync) 638bf215546Sopenharmony_ci{ 639bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci struct vtest_sync *sync = calloc(1, sizeof(*sync)); 642bf215546Sopenharmony_ci if (!sync) 643bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 644bf215546Sopenharmony_ci 645bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 646bf215546Sopenharmony_ci sync->base.sync_id = vtest_vcmd_sync_create(vtest, initial_val); 647bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 648bf215546Sopenharmony_ci 649bf215546Sopenharmony_ci *out_sync = &sync->base; 650bf215546Sopenharmony_ci return VK_SUCCESS; 651bf215546Sopenharmony_ci} 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_cistatic void 654bf215546Sopenharmony_civtest_bo_invalidate(struct vn_renderer *renderer, 655bf215546Sopenharmony_ci struct vn_renderer_bo *bo, 656bf215546Sopenharmony_ci VkDeviceSize offset, 657bf215546Sopenharmony_ci VkDeviceSize size) 658bf215546Sopenharmony_ci{ 659bf215546Sopenharmony_ci /* nop */ 660bf215546Sopenharmony_ci} 661bf215546Sopenharmony_ci 662bf215546Sopenharmony_cistatic void 663bf215546Sopenharmony_civtest_bo_flush(struct vn_renderer *renderer, 664bf215546Sopenharmony_ci struct vn_renderer_bo *bo, 665bf215546Sopenharmony_ci VkDeviceSize offset, 666bf215546Sopenharmony_ci VkDeviceSize size) 667bf215546Sopenharmony_ci{ 668bf215546Sopenharmony_ci /* nop */ 669bf215546Sopenharmony_ci} 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_cistatic void * 672bf215546Sopenharmony_civtest_bo_map(struct vn_renderer *renderer, struct vn_renderer_bo *_bo) 673bf215546Sopenharmony_ci{ 674bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 675bf215546Sopenharmony_ci struct vtest_bo *bo = (struct vtest_bo *)_bo; 676bf215546Sopenharmony_ci const bool mappable = bo->blob_flags & VCMD_BLOB_FLAG_MAPPABLE; 677bf215546Sopenharmony_ci const bool shareable = bo->blob_flags & VCMD_BLOB_FLAG_SHAREABLE; 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci /* not thread-safe but is fine */ 680bf215546Sopenharmony_ci if (!bo->base.mmap_ptr && mappable) { 681bf215546Sopenharmony_ci /* We wrongly assume that mmap(dma_buf) and vkMapMemory(VkDeviceMemory) 682bf215546Sopenharmony_ci * are equivalent when the blob type is VCMD_BLOB_TYPE_HOST3D. While we 683bf215546Sopenharmony_ci * check for VCMD_PARAM_HOST_COHERENT_DMABUF_BLOB, we know vtest can 684bf215546Sopenharmony_ci * lie. 685bf215546Sopenharmony_ci */ 686bf215546Sopenharmony_ci void *ptr = mmap(NULL, bo->base.mmap_size, PROT_READ | PROT_WRITE, 687bf215546Sopenharmony_ci MAP_SHARED, bo->res_fd, 0); 688bf215546Sopenharmony_ci if (ptr == MAP_FAILED) { 689bf215546Sopenharmony_ci vn_log(vtest->instance, "failed to mmap %d of size %zu rw: %s", 690bf215546Sopenharmony_ci bo->res_fd, bo->base.mmap_size, strerror(errno)); 691bf215546Sopenharmony_ci } else { 692bf215546Sopenharmony_ci bo->base.mmap_ptr = ptr; 693bf215546Sopenharmony_ci /* we don't need the fd anymore */ 694bf215546Sopenharmony_ci if (!shareable) { 695bf215546Sopenharmony_ci close(bo->res_fd); 696bf215546Sopenharmony_ci bo->res_fd = -1; 697bf215546Sopenharmony_ci } 698bf215546Sopenharmony_ci } 699bf215546Sopenharmony_ci } 700bf215546Sopenharmony_ci 701bf215546Sopenharmony_ci return bo->base.mmap_ptr; 702bf215546Sopenharmony_ci} 703bf215546Sopenharmony_ci 704bf215546Sopenharmony_cistatic int 705bf215546Sopenharmony_civtest_bo_export_dma_buf(struct vn_renderer *renderer, 706bf215546Sopenharmony_ci struct vn_renderer_bo *_bo) 707bf215546Sopenharmony_ci{ 708bf215546Sopenharmony_ci const struct vtest_bo *bo = (struct vtest_bo *)_bo; 709bf215546Sopenharmony_ci const bool shareable = bo->blob_flags & VCMD_BLOB_FLAG_SHAREABLE; 710bf215546Sopenharmony_ci return shareable ? os_dupfd_cloexec(bo->res_fd) : -1; 711bf215546Sopenharmony_ci} 712bf215546Sopenharmony_ci 713bf215546Sopenharmony_cistatic bool 714bf215546Sopenharmony_civtest_bo_destroy(struct vn_renderer *renderer, struct vn_renderer_bo *_bo) 715bf215546Sopenharmony_ci{ 716bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 717bf215546Sopenharmony_ci struct vtest_bo *bo = (struct vtest_bo *)_bo; 718bf215546Sopenharmony_ci 719bf215546Sopenharmony_ci if (bo->base.mmap_ptr) 720bf215546Sopenharmony_ci munmap(bo->base.mmap_ptr, bo->base.mmap_size); 721bf215546Sopenharmony_ci if (bo->res_fd >= 0) 722bf215546Sopenharmony_ci close(bo->res_fd); 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 725bf215546Sopenharmony_ci vtest_vcmd_resource_unref(vtest, bo->base.res_id); 726bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 727bf215546Sopenharmony_ci 728bf215546Sopenharmony_ci return true; 729bf215546Sopenharmony_ci} 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_cistatic uint32_t 732bf215546Sopenharmony_civtest_bo_blob_flags(VkMemoryPropertyFlags flags, 733bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags external_handles) 734bf215546Sopenharmony_ci{ 735bf215546Sopenharmony_ci uint32_t blob_flags = 0; 736bf215546Sopenharmony_ci if (flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) 737bf215546Sopenharmony_ci blob_flags |= VCMD_BLOB_FLAG_MAPPABLE; 738bf215546Sopenharmony_ci if (external_handles) 739bf215546Sopenharmony_ci blob_flags |= VCMD_BLOB_FLAG_SHAREABLE; 740bf215546Sopenharmony_ci if (external_handles & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT) 741bf215546Sopenharmony_ci blob_flags |= VCMD_BLOB_FLAG_CROSS_DEVICE; 742bf215546Sopenharmony_ci 743bf215546Sopenharmony_ci return blob_flags; 744bf215546Sopenharmony_ci} 745bf215546Sopenharmony_ci 746bf215546Sopenharmony_cistatic VkResult 747bf215546Sopenharmony_civtest_bo_create_from_device_memory( 748bf215546Sopenharmony_ci struct vn_renderer *renderer, 749bf215546Sopenharmony_ci VkDeviceSize size, 750bf215546Sopenharmony_ci vn_object_id mem_id, 751bf215546Sopenharmony_ci VkMemoryPropertyFlags flags, 752bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags external_handles, 753bf215546Sopenharmony_ci struct vn_renderer_bo **out_bo) 754bf215546Sopenharmony_ci{ 755bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 756bf215546Sopenharmony_ci const uint32_t blob_flags = vtest_bo_blob_flags(flags, external_handles); 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 759bf215546Sopenharmony_ci int res_fd; 760bf215546Sopenharmony_ci uint32_t res_id = vtest_vcmd_resource_create_blob( 761bf215546Sopenharmony_ci vtest, VCMD_BLOB_TYPE_HOST3D, blob_flags, size, mem_id, &res_fd); 762bf215546Sopenharmony_ci assert(res_id > 0 && res_fd >= 0); 763bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 764bf215546Sopenharmony_ci 765bf215546Sopenharmony_ci struct vtest_bo *bo = util_sparse_array_get(&vtest->bo_array, res_id); 766bf215546Sopenharmony_ci *bo = (struct vtest_bo){ 767bf215546Sopenharmony_ci .base = { 768bf215546Sopenharmony_ci .refcount = VN_REFCOUNT_INIT(1), 769bf215546Sopenharmony_ci .res_id = res_id, 770bf215546Sopenharmony_ci .mmap_size = size, 771bf215546Sopenharmony_ci }, 772bf215546Sopenharmony_ci .res_fd = res_fd, 773bf215546Sopenharmony_ci .blob_flags = blob_flags, 774bf215546Sopenharmony_ci }; 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci *out_bo = &bo->base; 777bf215546Sopenharmony_ci 778bf215546Sopenharmony_ci return VK_SUCCESS; 779bf215546Sopenharmony_ci} 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_cistatic void 782bf215546Sopenharmony_civtest_shmem_destroy_now(struct vn_renderer *renderer, 783bf215546Sopenharmony_ci struct vn_renderer_shmem *_shmem) 784bf215546Sopenharmony_ci{ 785bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 786bf215546Sopenharmony_ci struct vtest_shmem *shmem = (struct vtest_shmem *)_shmem; 787bf215546Sopenharmony_ci 788bf215546Sopenharmony_ci munmap(shmem->base.mmap_ptr, shmem->base.mmap_size); 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 791bf215546Sopenharmony_ci vtest_vcmd_resource_unref(vtest, shmem->base.res_id); 792bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 793bf215546Sopenharmony_ci} 794bf215546Sopenharmony_ci 795bf215546Sopenharmony_cistatic void 796bf215546Sopenharmony_civtest_shmem_destroy(struct vn_renderer *renderer, 797bf215546Sopenharmony_ci struct vn_renderer_shmem *shmem) 798bf215546Sopenharmony_ci{ 799bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 800bf215546Sopenharmony_ci 801bf215546Sopenharmony_ci if (vn_renderer_shmem_cache_add(&vtest->shmem_cache, shmem)) 802bf215546Sopenharmony_ci return; 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_ci vtest_shmem_destroy_now(&vtest->base, shmem); 805bf215546Sopenharmony_ci} 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_cistatic struct vn_renderer_shmem * 808bf215546Sopenharmony_civtest_shmem_create(struct vn_renderer *renderer, size_t size) 809bf215546Sopenharmony_ci{ 810bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 811bf215546Sopenharmony_ci 812bf215546Sopenharmony_ci struct vn_renderer_shmem *cached_shmem = 813bf215546Sopenharmony_ci vn_renderer_shmem_cache_get(&vtest->shmem_cache, size); 814bf215546Sopenharmony_ci if (cached_shmem) { 815bf215546Sopenharmony_ci cached_shmem->refcount = VN_REFCOUNT_INIT(1); 816bf215546Sopenharmony_ci return cached_shmem; 817bf215546Sopenharmony_ci } 818bf215546Sopenharmony_ci 819bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 820bf215546Sopenharmony_ci int res_fd; 821bf215546Sopenharmony_ci uint32_t res_id = vtest_vcmd_resource_create_blob( 822bf215546Sopenharmony_ci vtest, vtest->shmem_blob_mem, VCMD_BLOB_FLAG_MAPPABLE, size, 0, 823bf215546Sopenharmony_ci &res_fd); 824bf215546Sopenharmony_ci assert(res_id > 0 && res_fd >= 0); 825bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 826bf215546Sopenharmony_ci 827bf215546Sopenharmony_ci void *ptr = 828bf215546Sopenharmony_ci mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, res_fd, 0); 829bf215546Sopenharmony_ci close(res_fd); 830bf215546Sopenharmony_ci if (ptr == MAP_FAILED) { 831bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 832bf215546Sopenharmony_ci vtest_vcmd_resource_unref(vtest, res_id); 833bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 834bf215546Sopenharmony_ci return NULL; 835bf215546Sopenharmony_ci } 836bf215546Sopenharmony_ci 837bf215546Sopenharmony_ci struct vtest_shmem *shmem = 838bf215546Sopenharmony_ci util_sparse_array_get(&vtest->shmem_array, res_id); 839bf215546Sopenharmony_ci *shmem = (struct vtest_shmem){ 840bf215546Sopenharmony_ci .base = { 841bf215546Sopenharmony_ci .refcount = VN_REFCOUNT_INIT(1), 842bf215546Sopenharmony_ci .res_id = res_id, 843bf215546Sopenharmony_ci .mmap_size = size, 844bf215546Sopenharmony_ci .mmap_ptr = ptr, 845bf215546Sopenharmony_ci }, 846bf215546Sopenharmony_ci }; 847bf215546Sopenharmony_ci 848bf215546Sopenharmony_ci return &shmem->base; 849bf215546Sopenharmony_ci} 850bf215546Sopenharmony_ci 851bf215546Sopenharmony_cistatic VkResult 852bf215546Sopenharmony_cisync_wait_poll(int fd, int poll_timeout) 853bf215546Sopenharmony_ci{ 854bf215546Sopenharmony_ci struct pollfd pollfd = { 855bf215546Sopenharmony_ci .fd = fd, 856bf215546Sopenharmony_ci .events = POLLIN, 857bf215546Sopenharmony_ci }; 858bf215546Sopenharmony_ci int ret; 859bf215546Sopenharmony_ci do { 860bf215546Sopenharmony_ci ret = poll(&pollfd, 1, poll_timeout); 861bf215546Sopenharmony_ci } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_ci if (ret < 0 || (ret > 0 && !(pollfd.revents & POLLIN))) { 864bf215546Sopenharmony_ci return (ret < 0 && errno == ENOMEM) ? VK_ERROR_OUT_OF_HOST_MEMORY 865bf215546Sopenharmony_ci : VK_ERROR_DEVICE_LOST; 866bf215546Sopenharmony_ci } 867bf215546Sopenharmony_ci 868bf215546Sopenharmony_ci return ret ? VK_SUCCESS : VK_TIMEOUT; 869bf215546Sopenharmony_ci} 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_cistatic int 872bf215546Sopenharmony_citimeout_to_poll_timeout(uint64_t timeout) 873bf215546Sopenharmony_ci{ 874bf215546Sopenharmony_ci const uint64_t ns_per_ms = 1000000; 875bf215546Sopenharmony_ci const uint64_t ms = (timeout + ns_per_ms - 1) / ns_per_ms; 876bf215546Sopenharmony_ci if (!ms && timeout) 877bf215546Sopenharmony_ci return -1; 878bf215546Sopenharmony_ci return ms <= INT_MAX ? ms : -1; 879bf215546Sopenharmony_ci} 880bf215546Sopenharmony_ci 881bf215546Sopenharmony_cistatic VkResult 882bf215546Sopenharmony_civtest_wait(struct vn_renderer *renderer, const struct vn_renderer_wait *wait) 883bf215546Sopenharmony_ci{ 884bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 885bf215546Sopenharmony_ci const uint32_t flags = wait->wait_any ? VCMD_SYNC_WAIT_FLAG_ANY : 0; 886bf215546Sopenharmony_ci const int poll_timeout = timeout_to_poll_timeout(wait->timeout); 887bf215546Sopenharmony_ci 888bf215546Sopenharmony_ci /* 889bf215546Sopenharmony_ci * vtest_vcmd_sync_wait (and some other sync commands) is executed after 890bf215546Sopenharmony_ci * all prior commands are dispatched. That is far from ideal. 891bf215546Sopenharmony_ci * 892bf215546Sopenharmony_ci * In virtio-gpu, a drm_syncobj wait ioctl is executed immediately. It 893bf215546Sopenharmony_ci * works because it uses virtio-gpu interrupts as a side channel. vtest 894bf215546Sopenharmony_ci * needs a side channel to perform well. 895bf215546Sopenharmony_ci * 896bf215546Sopenharmony_ci * virtio-gpu or vtest, we should also set up a 1-byte coherent memory that 897bf215546Sopenharmony_ci * is set to non-zero by GPU after the syncs signal. That would allow us 898bf215546Sopenharmony_ci * to do a quick check (or spin a bit) before waiting. 899bf215546Sopenharmony_ci */ 900bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 901bf215546Sopenharmony_ci const int fd = 902bf215546Sopenharmony_ci vtest_vcmd_sync_wait(vtest, flags, poll_timeout, wait->syncs, 903bf215546Sopenharmony_ci wait->sync_values, wait->sync_count); 904bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 905bf215546Sopenharmony_ci 906bf215546Sopenharmony_ci VkResult result = sync_wait_poll(fd, poll_timeout); 907bf215546Sopenharmony_ci close(fd); 908bf215546Sopenharmony_ci 909bf215546Sopenharmony_ci return result; 910bf215546Sopenharmony_ci} 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_cistatic VkResult 913bf215546Sopenharmony_civtest_submit(struct vn_renderer *renderer, 914bf215546Sopenharmony_ci const struct vn_renderer_submit *submit) 915bf215546Sopenharmony_ci{ 916bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 917bf215546Sopenharmony_ci 918bf215546Sopenharmony_ci mtx_lock(&vtest->sock_mutex); 919bf215546Sopenharmony_ci vtest_vcmd_submit_cmd2(vtest, submit); 920bf215546Sopenharmony_ci mtx_unlock(&vtest->sock_mutex); 921bf215546Sopenharmony_ci 922bf215546Sopenharmony_ci return VK_SUCCESS; 923bf215546Sopenharmony_ci} 924bf215546Sopenharmony_ci 925bf215546Sopenharmony_cistatic void 926bf215546Sopenharmony_civtest_init_renderer_info(struct vtest *vtest) 927bf215546Sopenharmony_ci{ 928bf215546Sopenharmony_ci struct vn_renderer_info *info = &vtest->base.info; 929bf215546Sopenharmony_ci 930bf215546Sopenharmony_ci info->drm.has_primary = false; 931bf215546Sopenharmony_ci info->drm.primary_major = 0; 932bf215546Sopenharmony_ci info->drm.primary_minor = 0; 933bf215546Sopenharmony_ci info->drm.has_render = false; 934bf215546Sopenharmony_ci info->drm.render_major = 0; 935bf215546Sopenharmony_ci info->drm.render_minor = 0; 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_ci info->pci.vendor_id = VTEST_PCI_VENDOR_ID; 938bf215546Sopenharmony_ci info->pci.device_id = VTEST_PCI_DEVICE_ID; 939bf215546Sopenharmony_ci 940bf215546Sopenharmony_ci info->has_dma_buf_import = false; 941bf215546Sopenharmony_ci info->has_cache_management = false; 942bf215546Sopenharmony_ci info->has_external_sync = false; 943bf215546Sopenharmony_ci info->has_implicit_fencing = false; 944bf215546Sopenharmony_ci 945bf215546Sopenharmony_ci info->max_sync_queue_count = vtest->max_sync_queue_count; 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_ci const struct virgl_renderer_capset_venus *capset = &vtest->capset.data; 948bf215546Sopenharmony_ci info->wire_format_version = capset->wire_format_version; 949bf215546Sopenharmony_ci info->vk_xml_version = capset->vk_xml_version; 950bf215546Sopenharmony_ci info->vk_ext_command_serialization_spec_version = 951bf215546Sopenharmony_ci capset->vk_ext_command_serialization_spec_version; 952bf215546Sopenharmony_ci info->vk_mesa_venus_protocol_spec_version = 953bf215546Sopenharmony_ci capset->vk_mesa_venus_protocol_spec_version; 954bf215546Sopenharmony_ci info->supports_blob_id_0 = capset->supports_blob_id_0; 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci /* ensure vk_extension_mask is large enough to hold all capset masks */ 957bf215546Sopenharmony_ci STATIC_ASSERT(sizeof(info->vk_extension_mask) >= 958bf215546Sopenharmony_ci sizeof(capset->vk_extension_mask1)); 959bf215546Sopenharmony_ci memcpy(info->vk_extension_mask, capset->vk_extension_mask1, 960bf215546Sopenharmony_ci sizeof(capset->vk_extension_mask1)); 961bf215546Sopenharmony_ci 962bf215546Sopenharmony_ci info->allow_vk_wait_syncs = capset->allow_vk_wait_syncs; 963bf215546Sopenharmony_ci} 964bf215546Sopenharmony_ci 965bf215546Sopenharmony_cistatic void 966bf215546Sopenharmony_civtest_destroy(struct vn_renderer *renderer, 967bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc) 968bf215546Sopenharmony_ci{ 969bf215546Sopenharmony_ci struct vtest *vtest = (struct vtest *)renderer; 970bf215546Sopenharmony_ci 971bf215546Sopenharmony_ci vn_renderer_shmem_cache_fini(&vtest->shmem_cache); 972bf215546Sopenharmony_ci 973bf215546Sopenharmony_ci if (vtest->sock_fd >= 0) { 974bf215546Sopenharmony_ci shutdown(vtest->sock_fd, SHUT_RDWR); 975bf215546Sopenharmony_ci close(vtest->sock_fd); 976bf215546Sopenharmony_ci } 977bf215546Sopenharmony_ci 978bf215546Sopenharmony_ci mtx_destroy(&vtest->sock_mutex); 979bf215546Sopenharmony_ci util_sparse_array_finish(&vtest->shmem_array); 980bf215546Sopenharmony_ci util_sparse_array_finish(&vtest->bo_array); 981bf215546Sopenharmony_ci 982bf215546Sopenharmony_ci vk_free(alloc, vtest); 983bf215546Sopenharmony_ci} 984bf215546Sopenharmony_ci 985bf215546Sopenharmony_cistatic VkResult 986bf215546Sopenharmony_civtest_init_capset(struct vtest *vtest) 987bf215546Sopenharmony_ci{ 988bf215546Sopenharmony_ci vtest->capset.id = VIRGL_RENDERER_CAPSET_VENUS; 989bf215546Sopenharmony_ci vtest->capset.version = 0; 990bf215546Sopenharmony_ci 991bf215546Sopenharmony_ci if (!vtest_vcmd_get_capset(vtest, vtest->capset.id, vtest->capset.version, 992bf215546Sopenharmony_ci &vtest->capset.data, 993bf215546Sopenharmony_ci sizeof(vtest->capset.data))) { 994bf215546Sopenharmony_ci vn_log(vtest->instance, "no venus capset"); 995bf215546Sopenharmony_ci return VK_ERROR_INITIALIZATION_FAILED; 996bf215546Sopenharmony_ci } 997bf215546Sopenharmony_ci 998bf215546Sopenharmony_ci return VK_SUCCESS; 999bf215546Sopenharmony_ci} 1000bf215546Sopenharmony_ci 1001bf215546Sopenharmony_cistatic VkResult 1002bf215546Sopenharmony_civtest_init_params(struct vtest *vtest) 1003bf215546Sopenharmony_ci{ 1004bf215546Sopenharmony_ci uint32_t val = 1005bf215546Sopenharmony_ci vtest_vcmd_get_param(vtest, VCMD_PARAM_MAX_SYNC_QUEUE_COUNT); 1006bf215546Sopenharmony_ci if (!val) { 1007bf215546Sopenharmony_ci vn_log(vtest->instance, "no sync queue support"); 1008bf215546Sopenharmony_ci return VK_ERROR_INITIALIZATION_FAILED; 1009bf215546Sopenharmony_ci } 1010bf215546Sopenharmony_ci vtest->max_sync_queue_count = val; 1011bf215546Sopenharmony_ci 1012bf215546Sopenharmony_ci return VK_SUCCESS; 1013bf215546Sopenharmony_ci} 1014bf215546Sopenharmony_ci 1015bf215546Sopenharmony_cistatic VkResult 1016bf215546Sopenharmony_civtest_init_protocol_version(struct vtest *vtest) 1017bf215546Sopenharmony_ci{ 1018bf215546Sopenharmony_ci const uint32_t min_protocol_version = 3; 1019bf215546Sopenharmony_ci 1020bf215546Sopenharmony_ci const uint32_t ver = vtest_vcmd_ping_protocol_version(vtest) 1021bf215546Sopenharmony_ci ? vtest_vcmd_protocol_version(vtest) 1022bf215546Sopenharmony_ci : 0; 1023bf215546Sopenharmony_ci if (ver < min_protocol_version) { 1024bf215546Sopenharmony_ci vn_log(vtest->instance, "vtest protocol version (%d) too old", ver); 1025bf215546Sopenharmony_ci return VK_ERROR_INITIALIZATION_FAILED; 1026bf215546Sopenharmony_ci } 1027bf215546Sopenharmony_ci 1028bf215546Sopenharmony_ci vtest->protocol_version = ver; 1029bf215546Sopenharmony_ci 1030bf215546Sopenharmony_ci return VK_SUCCESS; 1031bf215546Sopenharmony_ci} 1032bf215546Sopenharmony_ci 1033bf215546Sopenharmony_cistatic VkResult 1034bf215546Sopenharmony_civtest_init(struct vtest *vtest) 1035bf215546Sopenharmony_ci{ 1036bf215546Sopenharmony_ci util_sparse_array_init(&vtest->shmem_array, sizeof(struct vtest_shmem), 1037bf215546Sopenharmony_ci 1024); 1038bf215546Sopenharmony_ci util_sparse_array_init(&vtest->bo_array, sizeof(struct vtest_bo), 1024); 1039bf215546Sopenharmony_ci 1040bf215546Sopenharmony_ci mtx_init(&vtest->sock_mutex, mtx_plain); 1041bf215546Sopenharmony_ci vtest->sock_fd = 1042bf215546Sopenharmony_ci vtest_connect_socket(vtest->instance, VTEST_DEFAULT_SOCKET_NAME); 1043bf215546Sopenharmony_ci if (vtest->sock_fd < 0) 1044bf215546Sopenharmony_ci return VK_ERROR_INITIALIZATION_FAILED; 1045bf215546Sopenharmony_ci 1046bf215546Sopenharmony_ci const char *renderer_name = util_get_process_name(); 1047bf215546Sopenharmony_ci if (!renderer_name) 1048bf215546Sopenharmony_ci renderer_name = "venus"; 1049bf215546Sopenharmony_ci vtest_vcmd_create_renderer(vtest, renderer_name); 1050bf215546Sopenharmony_ci 1051bf215546Sopenharmony_ci VkResult result = vtest_init_protocol_version(vtest); 1052bf215546Sopenharmony_ci if (result == VK_SUCCESS) 1053bf215546Sopenharmony_ci result = vtest_init_params(vtest); 1054bf215546Sopenharmony_ci if (result == VK_SUCCESS) 1055bf215546Sopenharmony_ci result = vtest_init_capset(vtest); 1056bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1057bf215546Sopenharmony_ci return result; 1058bf215546Sopenharmony_ci 1059bf215546Sopenharmony_ci /* see virtgpu_init_shmem_blob_mem */ 1060bf215546Sopenharmony_ci vtest->shmem_blob_mem = vtest->capset.data.supports_blob_id_0 1061bf215546Sopenharmony_ci ? VCMD_BLOB_TYPE_HOST3D 1062bf215546Sopenharmony_ci : VCMD_BLOB_TYPE_GUEST; 1063bf215546Sopenharmony_ci 1064bf215546Sopenharmony_ci vn_renderer_shmem_cache_init(&vtest->shmem_cache, &vtest->base, 1065bf215546Sopenharmony_ci vtest_shmem_destroy_now); 1066bf215546Sopenharmony_ci 1067bf215546Sopenharmony_ci vtest_vcmd_context_init(vtest, vtest->capset.id); 1068bf215546Sopenharmony_ci 1069bf215546Sopenharmony_ci vtest_init_renderer_info(vtest); 1070bf215546Sopenharmony_ci 1071bf215546Sopenharmony_ci vtest->base.ops.destroy = vtest_destroy; 1072bf215546Sopenharmony_ci vtest->base.ops.submit = vtest_submit; 1073bf215546Sopenharmony_ci vtest->base.ops.wait = vtest_wait; 1074bf215546Sopenharmony_ci 1075bf215546Sopenharmony_ci vtest->base.shmem_ops.create = vtest_shmem_create; 1076bf215546Sopenharmony_ci vtest->base.shmem_ops.destroy = vtest_shmem_destroy; 1077bf215546Sopenharmony_ci 1078bf215546Sopenharmony_ci vtest->base.bo_ops.create_from_device_memory = 1079bf215546Sopenharmony_ci vtest_bo_create_from_device_memory; 1080bf215546Sopenharmony_ci vtest->base.bo_ops.create_from_dma_buf = NULL; 1081bf215546Sopenharmony_ci vtest->base.bo_ops.destroy = vtest_bo_destroy; 1082bf215546Sopenharmony_ci vtest->base.bo_ops.export_dma_buf = vtest_bo_export_dma_buf; 1083bf215546Sopenharmony_ci vtest->base.bo_ops.map = vtest_bo_map; 1084bf215546Sopenharmony_ci vtest->base.bo_ops.flush = vtest_bo_flush; 1085bf215546Sopenharmony_ci vtest->base.bo_ops.invalidate = vtest_bo_invalidate; 1086bf215546Sopenharmony_ci 1087bf215546Sopenharmony_ci vtest->base.sync_ops.create = vtest_sync_create; 1088bf215546Sopenharmony_ci vtest->base.sync_ops.create_from_syncobj = NULL; 1089bf215546Sopenharmony_ci vtest->base.sync_ops.destroy = vtest_sync_destroy; 1090bf215546Sopenharmony_ci vtest->base.sync_ops.export_syncobj = NULL; 1091bf215546Sopenharmony_ci vtest->base.sync_ops.reset = vtest_sync_reset; 1092bf215546Sopenharmony_ci vtest->base.sync_ops.read = vtest_sync_read; 1093bf215546Sopenharmony_ci vtest->base.sync_ops.write = vtest_sync_write; 1094bf215546Sopenharmony_ci 1095bf215546Sopenharmony_ci return VK_SUCCESS; 1096bf215546Sopenharmony_ci} 1097bf215546Sopenharmony_ci 1098bf215546Sopenharmony_ciVkResult 1099bf215546Sopenharmony_civn_renderer_create_vtest(struct vn_instance *instance, 1100bf215546Sopenharmony_ci const VkAllocationCallbacks *alloc, 1101bf215546Sopenharmony_ci struct vn_renderer **renderer) 1102bf215546Sopenharmony_ci{ 1103bf215546Sopenharmony_ci struct vtest *vtest = vk_zalloc(alloc, sizeof(*vtest), VN_DEFAULT_ALIGN, 1104bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE); 1105bf215546Sopenharmony_ci if (!vtest) 1106bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 1107bf215546Sopenharmony_ci 1108bf215546Sopenharmony_ci vtest->instance = instance; 1109bf215546Sopenharmony_ci vtest->sock_fd = -1; 1110bf215546Sopenharmony_ci 1111bf215546Sopenharmony_ci VkResult result = vtest_init(vtest); 1112bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 1113bf215546Sopenharmony_ci vtest_destroy(&vtest->base, alloc); 1114bf215546Sopenharmony_ci return result; 1115bf215546Sopenharmony_ci } 1116bf215546Sopenharmony_ci 1117bf215546Sopenharmony_ci *renderer = &vtest->base; 1118bf215546Sopenharmony_ci 1119bf215546Sopenharmony_ci return VK_SUCCESS; 1120bf215546Sopenharmony_ci} 1121