Skip to content
This repository was archived by the owner on Jan 27, 2026. It is now read-only.

Commit ed97f77

Browse files
alyssarosenzweig1ace
authored andcommitted
asahi: enable virtgpu support
this updates our virtgpu support to match the upstream protocol, and enables. it is marked for backport since the older Mesa releases already had virtgpu support, just gated off to allow for breaking wire protocol changes (of which there was 1 at the last moment). Upstream virglrenderer MR assigned to marge: https://gitlab.freedesktop.org/virgl/virglrenderer/-/merge_requests/1541 Backport-to: 25.1 Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36580> (cherry picked from commit 20dab5f819f7016b8d7f4e88927855a0e5ff7a61)
1 parent a71f4f4 commit ed97f77

9 files changed

Lines changed: 27 additions & 25 deletions

File tree

.pick_status.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "asahi: enable virtgpu support",
55
"nominated": true,
66
"nomination_type": 4,
7-
"resolution": 0,
7+
"resolution": 1,
88
"main_sha": null,
99
"because_sha": null,
1010
"notes": null

src/asahi/lib/agx_device.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ static const struct debug_named_value agx_debug_options[] = {
8484
void
8585
agx_bo_free(struct agx_device *dev, struct agx_bo *bo)
8686
{
87-
const uint64_t handle = bo->uapi_handle;
87+
const uint64_t handle = bo->handle;
8888

8989
if (bo->_map)
9090
munmap(bo->_map, bo->size);
@@ -521,9 +521,6 @@ agx_open_device(void *memctx, struct agx_device *dev)
521521
dev->is_virtio = false;
522522
dev->ops = agx_device_drm_ops;
523523
} else if (!strcmp(version->name, "virtio_gpu")) {
524-
/* TODO: virtio wire protocol is not stable yet */
525-
return false;
526-
527524
dev->is_virtio = true;
528525
if (!agx_virtio_open_device(dev)) {
529526
fprintf(

src/asahi/lib/agx_device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ struct nir_shader;
6868
struct agx_submit_virt {
6969
uint32_t extres_count;
7070
struct asahi_ccmd_submit_res *extres;
71+
uint32_t ring_idx;
7172
};
7273

7374
typedef struct {

src/asahi/lib/agx_device_virtio.c

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ agx_virtio_bo_bind(struct agx_device *dev, struct drm_asahi_gem_bind_op *ops,
124124

125125
*req = (struct asahi_ccmd_vm_bind_req){
126126
.hdr.cmd = ASAHI_CCMD_VM_BIND,
127-
.hdr.len = sizeof(struct asahi_ccmd_vm_bind_req),
127+
.hdr.len = req_len,
128128
.vm_id = dev->vm_id,
129129
.stride = sizeof(*ops),
130130
.count = count,
@@ -215,12 +215,8 @@ agx_virtio_get_params(struct agx_device *dev, void *buf, size_t size)
215215
sizeof(struct asahi_ccmd_get_params_rsp) + size);
216216

217217
int ret = vdrm_send_req(vdrm, &req.hdr, true);
218-
if (!ret)
219-
return ret;
220-
221-
ret = rsp->ret;
222-
if (ret)
223-
return ret;
218+
if (ret || rsp->ret)
219+
return ret ? ret : rsp->ret;
224220

225221
memcpy(buf, &rsp->payload, size);
226222
return size;
@@ -265,8 +261,7 @@ agx_virtio_submit(struct agx_device *dev, struct drm_asahi_submit *submit,
265261
}
266262

267263
struct vdrm_execbuf_params p = {
268-
/* Signal the host we want to wait for the command to complete */
269-
.ring_idx = 1,
264+
.ring_idx = virt->ring_idx,
270265
.req = &req->hdr,
271266
.num_in_syncobjs = submit->in_sync_count,
272267
.in_syncobjs = vdrm_syncs,
@@ -296,7 +291,7 @@ agx_virtio_open_device(struct agx_device *dev)
296291
{
297292
struct vdrm_device *vdrm;
298293

299-
vdrm = vdrm_device_connect(dev->fd, 2);
294+
vdrm = vdrm_device_connect(dev->fd, 4);
300295
if (!vdrm) {
301296
fprintf(stderr, "could not connect vdrm\n");
302297
return false;

src/asahi/vulkan/hk_queue.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,10 @@ max_commands_per_submit(struct hk_device *dev)
263263
}
264264

265265
static VkResult
266-
queue_submit_single(struct hk_device *dev, struct drm_asahi_submit *submit)
266+
queue_submit_single(struct hk_device *dev, struct drm_asahi_submit *submit,
267+
unsigned ring_idx)
267268
{
268-
struct agx_submit_virt virt = {0};
269+
struct agx_submit_virt virt = {.ring_idx = ring_idx};
269270

270271
if (dev->dev.is_virtio) {
271272
u_rwlock_rdlock(&dev->external_bos.lock);
@@ -296,7 +297,7 @@ queue_submit_single(struct hk_device *dev, struct drm_asahi_submit *submit)
296297
*/
297298
static VkResult
298299
queue_submit_looped(struct hk_device *dev, struct drm_asahi_submit *submit,
299-
unsigned command_count)
300+
unsigned command_count, unsigned ring_idx)
300301
{
301302
uint8_t *cmdbuf = (uint8_t *)(uintptr_t)submit->cmdbuf;
302303
uint32_t offs = 0;
@@ -369,7 +370,7 @@ queue_submit_looped(struct hk_device *dev, struct drm_asahi_submit *submit,
369370
.out_sync_count = has_out_syncs ? submit->out_sync_count : 0,
370371
};
371372

372-
VkResult result = queue_submit_single(dev, &submit_ioctl);
373+
VkResult result = queue_submit_single(dev, &submit_ioctl, ring_idx);
373374
if (result != VK_SUCCESS)
374375
return result;
375376

@@ -885,10 +886,13 @@ queue_submit(struct hk_device *dev, struct hk_queue *queue,
885886
};
886887

887888
VkResult result;
888-
if (command_count <= max_commands_per_submit(dev))
889-
result = queue_submit_single(dev, &submit_ioctl);
890-
else
891-
result = queue_submit_looped(dev, &submit_ioctl, command_count);
889+
if (command_count <= max_commands_per_submit(dev)) {
890+
result =
891+
queue_submit_single(dev, &submit_ioctl, queue->drm.virt_ring_idx);
892+
} else {
893+
result = queue_submit_looped(dev, &submit_ioctl, command_count,
894+
queue->drm.virt_ring_idx);
895+
}
892896

893897
util_dynarray_fini(&payload);
894898
return result;
@@ -978,6 +982,7 @@ hk_queue_init(struct hk_device *dev, struct hk_queue *queue,
978982
queue->vk.driver_submit = hk_queue_submit;
979983

980984
queue->drm.id = agx_create_command_queue(&dev->dev, drm_priority);
985+
queue->drm.virt_ring_idx = drm_priority + 1;
981986

982987
if (drmSyncobjCreate(dev->dev.fd, 0, &queue->drm.syncobj)) {
983988
mesa_loge("drmSyncobjCreate() failed %d\n", errno);

src/asahi/vulkan/hk_queue.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ struct hk_queue {
2222
/* Timeline syncobj backing the queue */
2323
uint32_t syncobj;
2424

25+
/* Ring-idx used with virtgpu, equal to priority + 1 */
26+
uint32_t virt_ring_idx;
27+
2528
/* Current maximum timeline value for the queue's syncobj. If the
2629
* syncobj's value equals timeline_value, then all work is complete.
2730
*/

src/gallium/drivers/asahi/agx_batch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,7 @@ agx_batch_submit(struct agx_context *ctx, struct agx_batch *batch,
659659

660660
uint64_t wait_seqid = p_atomic_read(&screen->flush_wait_seqid);
661661

662-
struct agx_submit_virt virt = {0};
662+
struct agx_submit_virt virt = {.ring_idx = ctx->virt_ring_idx};
663663

664664
/* Elide syncing against our own queue */
665665
if (wait_seqid && wait_seqid == ctx->flush_my_seqid) {

src/gallium/drivers/asahi/agx_pipe.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,6 +1751,7 @@ agx_create_context(struct pipe_screen *screen, void *priv, unsigned flags)
17511751
*/
17521752

17531753
ctx->queue_id = agx_create_command_queue(agx_device(screen), priority);
1754+
ctx->virt_ring_idx = priority + 1;
17541755

17551756
pctx->destroy = agx_destroy_context;
17561757
pctx->flush = agx_flush;

src/gallium/drivers/asahi/agx_state.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ struct agx_context {
634634
} batches;
635635

636636
/* Queue handle */
637-
uint32_t queue_id;
637+
uint32_t queue_id, virt_ring_idx;
638638

639639
struct agx_batch *batch;
640640
struct agx_bo *timestamps;

0 commit comments

Comments
 (0)