diff --git a/.pick_status.json b/.pick_status.json index a64fb4bb960..0122631c7db 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -3884,7 +3884,7 @@ "description": "asahi: enable virtgpu support", "nominated": true, "nomination_type": 4, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/asahi/lib/agx_device.c b/src/asahi/lib/agx_device.c index 745685c0e8d..88ac6c10cd2 100644 --- a/src/asahi/lib/agx_device.c +++ b/src/asahi/lib/agx_device.c @@ -83,7 +83,7 @@ static const struct debug_named_value agx_debug_options[] = { void agx_bo_free(struct agx_device *dev, struct agx_bo *bo) { - const uint64_t handle = bo->uapi_handle; + const uint64_t handle = bo->handle; if (bo->_map) munmap(bo->_map, bo->size); @@ -505,9 +505,6 @@ agx_open_device(void *memctx, struct agx_device *dev) dev->is_virtio = false; dev->ops = agx_device_drm_ops; } else if (!strcmp(version->name, "virtio_gpu")) { - /* TODO: virtio wire protocol is not stable yet */ - return false; - dev->is_virtio = true; if (!agx_virtio_open_device(dev)) { fprintf( diff --git a/src/asahi/lib/agx_device.h b/src/asahi/lib/agx_device.h index aabebec93ff..bb286c90cfc 100644 --- a/src/asahi/lib/agx_device.h +++ b/src/asahi/lib/agx_device.h @@ -67,6 +67,7 @@ struct nir_shader; struct agx_submit_virt { uint32_t extres_count; struct asahi_ccmd_submit_res *extres; + uint32_t ring_idx; }; typedef struct { diff --git a/src/asahi/lib/agx_device_virtio.c b/src/asahi/lib/agx_device_virtio.c index 347faa4e26c..148f7b0a1e5 100644 --- a/src/asahi/lib/agx_device_virtio.c +++ b/src/asahi/lib/agx_device_virtio.c @@ -124,7 +124,7 @@ agx_virtio_bo_bind(struct agx_device *dev, struct drm_asahi_gem_bind_op *ops, *req = (struct asahi_ccmd_vm_bind_req){ .hdr.cmd = ASAHI_CCMD_VM_BIND, - .hdr.len = sizeof(struct asahi_ccmd_vm_bind_req), + .hdr.len = req_len, .vm_id = dev->vm_id, .stride = sizeof(*ops), .count = count, @@ -215,12 +215,8 @@ agx_virtio_get_params(struct agx_device *dev, void *buf, size_t size) sizeof(struct asahi_ccmd_get_params_rsp) + size); int ret = vdrm_send_req(vdrm, &req.hdr, true); - if (!ret) - return ret; - - ret = rsp->ret; - if (ret) - return ret; + if (ret || rsp->ret) + return ret ? ret : rsp->ret; memcpy(buf, &rsp->payload, size); return size; @@ -265,8 +261,7 @@ agx_virtio_submit(struct agx_device *dev, struct drm_asahi_submit *submit, } struct vdrm_execbuf_params p = { - /* Signal the host we want to wait for the command to complete */ - .ring_idx = 1, + .ring_idx = virt->ring_idx, .req = &req->hdr, .num_in_syncobjs = submit->in_sync_count, .in_syncobjs = vdrm_syncs, @@ -296,7 +291,7 @@ agx_virtio_open_device(struct agx_device *dev) { struct vdrm_device *vdrm; - vdrm = vdrm_device_connect(dev->fd, 2); + vdrm = vdrm_device_connect(dev->fd, 4); if (!vdrm) { fprintf(stderr, "could not connect vdrm\n"); return false; diff --git a/src/asahi/vulkan/hk_queue.c b/src/asahi/vulkan/hk_queue.c index 36ee2b2a2e8..6fc88f4f439 100644 --- a/src/asahi/vulkan/hk_queue.c +++ b/src/asahi/vulkan/hk_queue.c @@ -250,9 +250,10 @@ max_commands_per_submit(struct hk_device *dev) } static VkResult -queue_submit_single(struct hk_device *dev, struct drm_asahi_submit *submit) +queue_submit_single(struct hk_device *dev, struct drm_asahi_submit *submit, + unsigned ring_idx) { - struct agx_submit_virt virt = {0}; + struct agx_submit_virt virt = {.ring_idx = ring_idx}; if (dev->dev.is_virtio) { u_rwlock_rdlock(&dev->external_bos.lock); @@ -283,7 +284,7 @@ queue_submit_single(struct hk_device *dev, struct drm_asahi_submit *submit) */ static VkResult queue_submit_looped(struct hk_device *dev, struct drm_asahi_submit *submit, - unsigned command_count) + unsigned command_count, unsigned ring_idx) { uint8_t *cmdbuf = (uint8_t *)(uintptr_t)submit->cmdbuf; uint32_t offs = 0; @@ -356,7 +357,7 @@ queue_submit_looped(struct hk_device *dev, struct drm_asahi_submit *submit, .out_sync_count = has_out_syncs ? submit->out_sync_count : 0, }; - VkResult result = queue_submit_single(dev, &submit_ioctl); + VkResult result = queue_submit_single(dev, &submit_ioctl, ring_idx); if (result != VK_SUCCESS) return result; @@ -871,10 +872,13 @@ queue_submit(struct hk_device *dev, struct hk_queue *queue, }; VkResult result; - if (command_count <= max_commands_per_submit(dev)) - result = queue_submit_single(dev, &submit_ioctl); - else - result = queue_submit_looped(dev, &submit_ioctl, command_count); + if (command_count <= max_commands_per_submit(dev)) { + result = + queue_submit_single(dev, &submit_ioctl, queue->drm.virt_ring_idx); + } else { + result = queue_submit_looped(dev, &submit_ioctl, command_count, + queue->drm.virt_ring_idx); + } util_dynarray_fini(&payload); return result; @@ -964,6 +968,7 @@ hk_queue_init(struct hk_device *dev, struct hk_queue *queue, queue->vk.driver_submit = hk_queue_submit; queue->drm.id = agx_create_command_queue(&dev->dev, drm_priority); + queue->drm.virt_ring_idx = drm_priority + 1; if (drmSyncobjCreate(dev->dev.fd, 0, &queue->drm.syncobj)) { mesa_loge("drmSyncobjCreate() failed %d\n", errno); diff --git a/src/asahi/vulkan/hk_queue.h b/src/asahi/vulkan/hk_queue.h index b1073a03f3d..f45c8ed92e0 100644 --- a/src/asahi/vulkan/hk_queue.h +++ b/src/asahi/vulkan/hk_queue.h @@ -22,6 +22,9 @@ struct hk_queue { /* Timeline syncobj backing the queue */ uint32_t syncobj; + /* Ring-idx used with virtgpu, equal to priority + 1 */ + uint32_t virt_ring_idx; + /* Current maximum timeline value for the queue's syncobj. If the * syncobj's value equals timeline_value, then all work is complete. */ diff --git a/src/gallium/drivers/asahi/agx_batch.c b/src/gallium/drivers/asahi/agx_batch.c index 6d61c85470d..666944cf2a6 100644 --- a/src/gallium/drivers/asahi/agx_batch.c +++ b/src/gallium/drivers/asahi/agx_batch.c @@ -659,7 +659,7 @@ agx_batch_submit(struct agx_context *ctx, struct agx_batch *batch, uint64_t wait_seqid = p_atomic_read(&screen->flush_wait_seqid); - struct agx_submit_virt virt = {0}; + struct agx_submit_virt virt = {.ring_idx = ctx->virt_ring_idx}; /* Elide syncing against our own queue */ if (wait_seqid && wait_seqid == ctx->flush_my_seqid) { diff --git a/src/gallium/drivers/asahi/agx_pipe.c b/src/gallium/drivers/asahi/agx_pipe.c index 76d0c9f79ba..e7ad683581b 100644 --- a/src/gallium/drivers/asahi/agx_pipe.c +++ b/src/gallium/drivers/asahi/agx_pipe.c @@ -1762,6 +1762,7 @@ agx_create_context(struct pipe_screen *screen, void *priv, unsigned flags) */ ctx->queue_id = agx_create_command_queue(agx_device(screen), priority); + ctx->virt_ring_idx = priority + 1; pctx->destroy = agx_destroy_context; pctx->flush = agx_flush; diff --git a/src/gallium/drivers/asahi/agx_state.h b/src/gallium/drivers/asahi/agx_state.h index e6dd33aaf27..da39a02141a 100644 --- a/src/gallium/drivers/asahi/agx_state.h +++ b/src/gallium/drivers/asahi/agx_state.h @@ -642,7 +642,7 @@ struct agx_context { } batches; /* Queue handle */ - uint32_t queue_id; + uint32_t queue_id, virt_ring_idx; struct agx_batch *batch; struct agx_bo *timestamps;