mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 09:08:10 +02:00
asahi: Virt UABI update
Support timestamp extensions & fix a bunch of missing/broken things we were dragging along. Signed-off-by: Asahi Lina <lina@asahilina.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/32759>
This commit is contained in:
parent
0d5db3238b
commit
e281293508
2 changed files with 160 additions and 31 deletions
|
|
@ -88,6 +88,7 @@ agx_virtio_bo_alloc(struct agx_device *dev, size_t size, size_t align,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Note: optional, can zero out for not mapping for sparse */
|
||||
req.addr = va->addr;
|
||||
req.blob_id = blob_id;
|
||||
req.vm_id = dev->vm_id;
|
||||
|
|
@ -123,28 +124,86 @@ agx_virtio_bo_bind(struct agx_device *dev, struct agx_bo *bo, uint64_t addr,
|
|||
size_t size_B, uint64_t offset_B, uint32_t flags,
|
||||
bool unbind)
|
||||
{
|
||||
assert(offset_B == 0 && "TODO: need to extend virtgpu");
|
||||
|
||||
struct asahi_ccmd_gem_bind_req req = {
|
||||
.op = unbind ? ASAHI_BIND_OP_UNBIND : ASAHI_BIND_OP_BIND,
|
||||
.flags = flags,
|
||||
.vm_id = dev->vm_id,
|
||||
.res_id = bo->vbo_res_id,
|
||||
.size = size_B,
|
||||
.addr = addr,
|
||||
.hdr.cmd = ASAHI_CCMD_GEM_BIND,
|
||||
.hdr.len = sizeof(struct asahi_ccmd_gem_bind_req),
|
||||
};
|
||||
.bind = {
|
||||
.op = unbind ? ASAHI_BIND_OP_UNBIND : ASAHI_BIND_OP_BIND,
|
||||
.flags = flags,
|
||||
.vm_id = dev->vm_id,
|
||||
.handle = bo->vbo_res_id,
|
||||
.offset = offset_B,
|
||||
.range = size_B,
|
||||
.addr = addr,
|
||||
}};
|
||||
|
||||
int ret = vdrm_send_req(dev->vdrm, &req.hdr, false);
|
||||
if (ret) {
|
||||
fprintf(stderr, "DRM_IOCTL_ASAHI_GEM_BIND failed: %d (handle=%d)\n", ret,
|
||||
fprintf(stderr, "ASAHI_CCMD_GEM_BIND failed: %d (handle=%d)\n", ret,
|
||||
bo->handle);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
agx_virtio_bo_bind_object(struct agx_device *dev, struct agx_bo *bo,
|
||||
uint32_t *object_handle, size_t size_B,
|
||||
uint64_t offset_B, uint32_t flags)
|
||||
{
|
||||
struct asahi_ccmd_gem_bind_object_req req = {
|
||||
.hdr.cmd = ASAHI_CCMD_GEM_BIND_OBJECT,
|
||||
.hdr.len = sizeof(struct asahi_ccmd_gem_bind_object_req),
|
||||
.bind = {
|
||||
.op = ASAHI_BIND_OBJECT_OP_BIND,
|
||||
.flags = flags,
|
||||
.vm_id = 0,
|
||||
.handle = bo->vbo_res_id,
|
||||
.offset = offset_B,
|
||||
.range = size_B,
|
||||
}};
|
||||
|
||||
struct asahi_ccmd_gem_bind_object_rsp *rsp;
|
||||
|
||||
rsp = vdrm_alloc_rsp(dev->vdrm, &req.hdr,
|
||||
sizeof(struct asahi_ccmd_gem_bind_object_rsp));
|
||||
|
||||
int ret = vdrm_send_req(dev->vdrm, &req.hdr, true);
|
||||
if (ret || rsp->ret) {
|
||||
fprintf(stderr,
|
||||
"ASAHI_CCMD_GEM_BIND_OBJECT bind failed: %d:%d (handle=%d)\n", ret, rsp->ret,
|
||||
bo->handle);
|
||||
}
|
||||
|
||||
if (!rsp->ret)
|
||||
*object_handle = rsp->object_handle;
|
||||
|
||||
return rsp->ret;
|
||||
}
|
||||
|
||||
static int
|
||||
agx_virtio_bo_unbind_object(struct agx_device *dev, uint32_t object_handle,
|
||||
uint32_t flags)
|
||||
{
|
||||
struct asahi_ccmd_gem_bind_object_req req = {
|
||||
.hdr.cmd = ASAHI_CCMD_GEM_BIND_OBJECT,
|
||||
.hdr.len = sizeof(struct asahi_ccmd_gem_bind_object_req),
|
||||
.bind = {
|
||||
.op = ASAHI_BIND_OBJECT_OP_UNBIND,
|
||||
.flags = flags,
|
||||
.object_handle = object_handle,
|
||||
}};
|
||||
|
||||
int ret = vdrm_send_req(dev->vdrm, &req.hdr, false);
|
||||
if (ret) {
|
||||
fprintf(stderr,
|
||||
"ASAHI_CCMD_GEM_BIND_OBJECT unbind failed: %d (handle=%d)\n", ret,
|
||||
object_handle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
agx_virtio_bo_mmap(struct agx_device *dev, struct agx_bo *bo)
|
||||
{
|
||||
|
|
@ -167,16 +226,22 @@ agx_virtio_get_params(struct agx_device *dev, void *buf, size_t size)
|
|||
};
|
||||
struct asahi_ccmd_get_params_rsp *rsp;
|
||||
|
||||
rsp =
|
||||
vdrm_alloc_rsp(vdrm, &req.hdr, sizeof(struct asahi_ccmd_get_params_rsp));
|
||||
rsp = vdrm_alloc_rsp(vdrm, &req.hdr,
|
||||
sizeof(struct asahi_ccmd_get_params_rsp) + size);
|
||||
|
||||
int ret = vdrm_send_req(vdrm, &req.hdr, true);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (rsp->virt_uabi_version != ASAHI_PROTO_UNSTABLE_UABI_VERSION) {
|
||||
fprintf(stderr, "Virt UABI mismatch: Host %d, Mesa %d\n",
|
||||
rsp->virt_uabi_version, ASAHI_PROTO_UNSTABLE_UABI_VERSION);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = rsp->ret;
|
||||
if (!ret) {
|
||||
memcpy(buf, &rsp->params, size);
|
||||
memcpy(buf, &rsp->payload, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
|
@ -184,6 +249,18 @@ out:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
agx_virtio_serialize_attachments(char **ptr, uint64_t attachments,
|
||||
uint32_t count)
|
||||
{
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
size_t attachments_size = sizeof(struct drm_asahi_attachment) * count;
|
||||
memcpy(*ptr, (char *)(uintptr_t)attachments, attachments_size);
|
||||
*ptr += attachments_size;
|
||||
}
|
||||
|
||||
static int
|
||||
agx_virtio_submit(struct agx_device *dev, struct drm_asahi_submit *submit,
|
||||
struct agx_submit_virt *virt)
|
||||
|
|
@ -199,8 +276,18 @@ agx_virtio_submit(struct agx_device *dev, struct drm_asahi_submit *submit,
|
|||
for (int i = 0; i < submit->command_count; i++) {
|
||||
switch (commands[i].cmd_type) {
|
||||
case DRM_ASAHI_CMD_COMPUTE: {
|
||||
struct drm_asahi_cmd_compute *compute =
|
||||
(struct drm_asahi_cmd_compute *)(uintptr_t)commands[i].cmd_buffer;
|
||||
req_len += sizeof(struct drm_asahi_command) +
|
||||
sizeof(struct drm_asahi_cmd_compute);
|
||||
req_len += compute->attachment_count *
|
||||
sizeof(struct drm_asahi_attachment);
|
||||
|
||||
if (compute->extensions) {
|
||||
assert(*(uint32_t *)(uintptr_t)compute->extensions ==
|
||||
ASAHI_COMPUTE_EXT_TIMESTAMPS);
|
||||
req_len += sizeof(struct drm_asahi_cmd_compute_user_timestamps);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -211,6 +298,14 @@ agx_virtio_submit(struct agx_device *dev, struct drm_asahi_submit *submit,
|
|||
sizeof(struct drm_asahi_cmd_render);
|
||||
req_len += render->fragment_attachment_count *
|
||||
sizeof(struct drm_asahi_attachment);
|
||||
req_len += render->vertex_attachment_count *
|
||||
sizeof(struct drm_asahi_attachment);
|
||||
|
||||
if (render->extensions) {
|
||||
assert(*(uint32_t *)(uintptr_t)render->extensions ==
|
||||
ASAHI_RENDER_EXT_TIMESTAMPS);
|
||||
req_len += sizeof(struct drm_asahi_cmd_render_user_timestamps);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -241,14 +336,39 @@ agx_virtio_submit(struct agx_device *dev, struct drm_asahi_submit *submit,
|
|||
commands[i].cmd_buffer_size);
|
||||
ptr += commands[i].cmd_buffer_size;
|
||||
|
||||
if (commands[i].cmd_type == DRM_ASAHI_CMD_RENDER) {
|
||||
switch (commands[i].cmd_type) {
|
||||
case DRM_ASAHI_CMD_RENDER: {
|
||||
struct drm_asahi_cmd_render *render =
|
||||
(struct drm_asahi_cmd_render *)(uintptr_t)commands[i].cmd_buffer;
|
||||
size_t fragments_size = sizeof(struct drm_asahi_attachment) *
|
||||
render->fragment_attachment_count;
|
||||
memcpy(ptr, (char *)(uintptr_t)render->fragment_attachments,
|
||||
fragments_size);
|
||||
ptr += fragments_size;
|
||||
agx_virtio_serialize_attachments(&ptr, render->vertex_attachments,
|
||||
render->vertex_attachment_count);
|
||||
agx_virtio_serialize_attachments(&ptr, render->fragment_attachments,
|
||||
render->fragment_attachment_count);
|
||||
if (render->extensions) {
|
||||
struct drm_asahi_cmd_render_user_timestamps *ext =
|
||||
(struct drm_asahi_cmd_render_user_timestamps *)(uintptr_t)
|
||||
render->extensions;
|
||||
assert(!ext->next);
|
||||
memcpy(ptr, (void *)ext, sizeof(*ext));
|
||||
ptr += sizeof(*ext);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DRM_ASAHI_CMD_COMPUTE: {
|
||||
struct drm_asahi_cmd_compute *compute =
|
||||
(struct drm_asahi_cmd_compute *)(uintptr_t)commands[i].cmd_buffer;
|
||||
agx_virtio_serialize_attachments(&ptr, compute->attachments,
|
||||
compute->attachment_count);
|
||||
if (compute->extensions) {
|
||||
struct drm_asahi_cmd_compute_user_timestamps *ext =
|
||||
(struct drm_asahi_cmd_compute_user_timestamps *)(uintptr_t)
|
||||
compute->extensions;
|
||||
assert(!ext->next);
|
||||
memcpy(ptr, (void *)ext, sizeof(*ext));
|
||||
ptr += sizeof(*ext);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -296,6 +416,8 @@ const agx_device_ops_t agx_virtio_device_ops = {
|
|||
.bo_mmap = agx_virtio_bo_mmap,
|
||||
.get_params = agx_virtio_get_params,
|
||||
.submit = agx_virtio_submit,
|
||||
.bo_bind_object = agx_virtio_bo_bind_object,
|
||||
.bo_unbind_object = agx_virtio_bo_unbind_object,
|
||||
};
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
#ifndef ASAHI_PROTO_H_
|
||||
#define ASAHI_PROTO_H_
|
||||
|
||||
#define ASAHI_PROTO_UNSTABLE_UABI_VERSION 1
|
||||
|
||||
/**
|
||||
* Defines the layout of shmem buffer used for host->guest communication.
|
||||
*/
|
||||
|
|
@ -37,12 +39,13 @@ enum asahi_ccmd {
|
|||
ASAHI_CCMD_GEM_NEW,
|
||||
ASAHI_CCMD_GEM_BIND,
|
||||
ASAHI_CCMD_SUBMIT,
|
||||
ASAHI_CCMD_GEM_BIND_OBJECT,
|
||||
};
|
||||
|
||||
#define ASAHI_CCMD(_cmd, _len) \
|
||||
(struct vdrm_ccmd_req) \
|
||||
{ \
|
||||
.cmd = ASAHI_CCMD_##_cmd, .len = (_len), \
|
||||
#define ASAHI_CCMD(_cmd, _len) \
|
||||
(struct vdrm_ccmd_req) \
|
||||
{ \
|
||||
.cmd = ASAHI_CCMD_##_cmd, .len = (_len), \
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -90,7 +93,8 @@ DEFINE_CAST(vdrm_ccmd_req, asahi_ccmd_get_params_req)
|
|||
struct asahi_ccmd_get_params_rsp {
|
||||
struct vdrm_ccmd_rsp hdr;
|
||||
int32_t ret;
|
||||
struct drm_asahi_params_global params;
|
||||
uint32_t virt_uabi_version;
|
||||
uint8_t payload[];
|
||||
};
|
||||
|
||||
struct asahi_ccmd_gem_new_req {
|
||||
|
|
@ -106,18 +110,20 @@ DEFINE_CAST(vdrm_ccmd_req, asahi_ccmd_gem_new_req)
|
|||
|
||||
struct asahi_ccmd_gem_bind_req {
|
||||
struct vdrm_ccmd_req hdr;
|
||||
uint32_t op;
|
||||
uint32_t flags;
|
||||
uint32_t vm_id;
|
||||
uint32_t res_id;
|
||||
uint64_t size;
|
||||
uint64_t addr;
|
||||
struct drm_asahi_gem_bind bind;
|
||||
};
|
||||
DEFINE_CAST(vdrm_ccmd_req, asahi_ccmd_gem_bind_req)
|
||||
|
||||
struct asahi_ccmd_gem_bind_rsp {
|
||||
struct asahi_ccmd_gem_bind_object_req {
|
||||
struct vdrm_ccmd_req hdr;
|
||||
struct drm_asahi_gem_bind_object bind;
|
||||
};
|
||||
DEFINE_CAST(vdrm_ccmd_req, asahi_ccmd_gem_bind_object_req)
|
||||
|
||||
struct asahi_ccmd_gem_bind_object_rsp {
|
||||
struct vdrm_ccmd_rsp hdr;
|
||||
int32_t ret;
|
||||
uint32_t object_handle;
|
||||
};
|
||||
|
||||
#define ASAHI_EXTRES_READ 0x01
|
||||
|
|
@ -130,6 +136,7 @@ struct asahi_ccmd_submit_res {
|
|||
|
||||
struct asahi_ccmd_submit_req {
|
||||
struct vdrm_ccmd_req hdr;
|
||||
uint32_t flags;
|
||||
uint32_t queue_id;
|
||||
uint32_t result_res_id;
|
||||
uint32_t command_count;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue