Spaces:
Running on Zero
Running on Zero
| static uint32_t virtgpu_ioctl_resource_create_blob(virtgpu * gpu, | |
| uint32_t blob_mem, | |
| uint32_t blob_flags, | |
| size_t blob_size, | |
| uint64_t blob_id, | |
| uint32_t * res_id) { | |
| blob_size = align64(blob_size, 4096); | |
| drm_virtgpu_resource_create_blob args = { | |
| .blob_mem = blob_mem, | |
| .blob_flags = blob_flags, | |
| .bo_handle = 0, | |
| .res_handle = 0, | |
| .size = blob_size, | |
| .pad = 0, | |
| .cmd_size = 0, | |
| .cmd = 0, | |
| .blob_id = blob_id, | |
| }; | |
| if (virtgpu_ioctl(gpu, DRM_IOCTL_VIRTGPU_RESOURCE_CREATE_BLOB, &args)) { | |
| return 0; | |
| } | |
| *res_id = args.res_handle; | |
| return args.bo_handle; | |
| } | |
| static void virtgpu_ioctl_gem_close(virtgpu * gpu, uint32_t gem_handle) { | |
| drm_gem_close args = { | |
| .handle = gem_handle, | |
| .pad = 0, | |
| }; | |
| const int ret = virtgpu_ioctl(gpu, DRM_IOCTL_GEM_CLOSE, &args); | |
| assert(!ret); | |
| UNUSED(ret); | |
| } | |
| static void * virtgpu_ioctl_map(virtgpu * gpu, uint32_t gem_handle, size_t size) { | |
| drm_virtgpu_map args = { | |
| .offset = 0, | |
| .handle = gem_handle, | |
| .pad = 0, | |
| }; | |
| if (virtgpu_ioctl(gpu, DRM_IOCTL_VIRTGPU_MAP, &args)) { | |
| return NULL; | |
| } | |
| void * ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, gpu->fd, args.offset); | |
| if (ptr == MAP_FAILED) { | |
| return NULL; | |
| } | |
| return ptr; | |
| } | |
| void virtgpu_shmem_destroy(virtgpu * gpu, virtgpu_shmem * shmem) { | |
| munmap(shmem->mmap_ptr, shmem->mmap_size); | |
| virtgpu_ioctl_gem_close(gpu, shmem->gem_handle); | |
| } | |
| int virtgpu_shmem_create(virtgpu * gpu, size_t size, virtgpu_shmem * shmem) { | |
| size = align64(size, 16384); | |
| uint32_t res_id; | |
| uint32_t gem_handle = virtgpu_ioctl_resource_create_blob(gpu, VIRTGPU_BLOB_MEM_HOST3D, | |
| VIRTGPU_BLOB_FLAG_USE_MAPPABLE, size, 0, &res_id); | |
| if (!gem_handle) { | |
| return 1; | |
| } | |
| void * ptr = virtgpu_ioctl_map(gpu, gem_handle, size); | |
| if (!ptr) { | |
| virtgpu_ioctl_gem_close(gpu, gem_handle); | |
| GGML_LOG_ERROR(GGML_VIRTGPU "%s: virtgpu_ioctl_map failed\n", __func__); | |
| return 1; | |
| } | |
| shmem->res_id = res_id; | |
| shmem->mmap_size = size; | |
| shmem->mmap_ptr = ptr; | |
| shmem->gem_handle = gem_handle; | |
| return 0; | |
| } | |