On Tue, Mar 7, 2023 at 3:28 PM Asahi Lina lina@asahilina.net wrote:
Adds the Asahi GPU driver UAPI. Note: this API is not yet stable and therefore not ready for merging!
Signed-off-by: Asahi Lina lina@asahilina.net
include/uapi/drm/asahi_drm.h | 556 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 556 insertions(+)
diff --git a/include/uapi/drm/asahi_drm.h b/include/uapi/drm/asahi_drm.h new file mode 100644 index 000000000000..7b15b486d03d --- /dev/null +++ b/include/uapi/drm/asahi_drm.h @@ -0,0 +1,556 @@ +/* SPDX-License-Identifier: MIT */ +/*
- Copyright (C) The Asahi Linux Contributors
- Heavily inspired by xe_drm.h.
- */
+#ifndef _ASAHI_DRM_H_ +#define _ASAHI_DRM_H_
+#include "drm.h"
+#if defined(__cplusplus) +extern "C" { +#endif
+#define DRM_ASAHI_UNSTABLE_UABI_VERSION 10006
+#define DRM_ASAHI_GET_PARAMS 0x00 +#define DRM_ASAHI_VM_CREATE 0x01 +#define DRM_ASAHI_VM_DESTROY 0x02 +#define DRM_ASAHI_GEM_CREATE 0x03 +#define DRM_ASAHI_GEM_MMAP_OFFSET 0x04 +#define DRM_ASAHI_GEM_BIND 0x05 +#define DRM_ASAHI_QUEUE_CREATE 0x06 +#define DRM_ASAHI_QUEUE_DESTROY 0x07 +#define DRM_ASAHI_SUBMIT 0x08 +#define DRM_ASAHI_GET_TIME 0x09
+#define DRM_ASAHI_MAX_CLUSTERS 32
+struct drm_asahi_params_global {
__u32 unstable_uabi_version;__u32 pad0;__u64 feat_compat;__u64 feat_incompat;__u32 gpu_generation;__u32 gpu_variant;__u32 gpu_revision;__u32 chip_id;__u32 num_dies;__u32 num_clusters_total;__u32 num_cores_per_cluster;__u32 num_frags_per_cluster;__u32 num_gps_per_cluster;__u32 num_cores_total_active;__u64 core_masks[DRM_ASAHI_MAX_CLUSTERS];__u32 vm_page_size;__u32 pad1;__u64 vm_user_start;__u64 vm_user_end;__u64 vm_shader_start;__u64 vm_shader_end;__u32 max_syncs_per_submission;__u32 max_commands_per_submission;__u32 max_commands_in_flight;__u32 max_attachments;__u32 timer_frequency_hz;__u32 min_frequency_khz;__u32 max_frequency_khz;__u32 max_power_mw;__u32 result_render_size;__u32 result_compute_size;+};
+/* +enum drm_asahi_feat_compat { +}; +*/
+enum drm_asahi_feat_incompat {
DRM_ASAHI_FEAT_MANDATORY_ZS_COMPRESSION = (1UL) << 0,+};
+struct drm_asahi_get_params {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @param: Parameter group to fetch (MBZ) */__u32 param_group;/** @pad: MBZ */__u32 pad;/** @value: User pointer to write parameter struct */__u64 pointer;/** @value: Size of user buffer, max size supported on return */__u64 size;+};
+struct drm_asahi_vm_create {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @value: Returned VM ID */__u32 vm_id;/** @pad: MBZ */__u32 pad;+};
+struct drm_asahi_vm_destroy {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @value: VM ID to be destroyed */__u32 vm_id;/** @pad: MBZ */__u32 pad;+};
+#define ASAHI_GEM_WRITEBACK (1L << 0) +#define ASAHI_GEM_VM_PRIVATE (1L << 1)
+struct drm_asahi_gem_create {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @size: Size of the BO */__u64 size;/** @flags: BO creation flags */__u32 flags;/** @handle: VM ID to assign to the BO, if ASAHI_GEM_VM_PRIVATE is set. */__u32 vm_id;/** @handle: Returned GEM handle for the BO */__u32 handle;+};
+struct drm_asahi_gem_mmap_offset {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @handle: Handle for the object being mapped. */__u32 handle;/** @flags: Must be zero */__u32 flags;/** @offset: The fake offset to use for subsequent mmap call */__u64 offset;+};
+enum drm_asahi_bind_op {
ASAHI_BIND_OP_BIND = 0,ASAHI_BIND_OP_UNBIND = 1,ASAHI_BIND_OP_UNBIND_ALL = 2,+};
+#define ASAHI_BIND_READ (1L << 0) +#define ASAHI_BIND_WRITE (1L << 1)
+struct drm_asahi_gem_bind {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @obj: Bind operation */__u32 op;/** @flags: One or more of ASAHI_BIND_* */__u32 flags;/** @obj: GEM object to bind */__u32 handle;/** @vm_id: The ID of the VM to bind to */__u32 vm_id;/** @offset: Offset into the object */__u64 offset;/** @range: Number of bytes from the object to bind to addr */__u64 range;/** @addr: Address to bind to */__u64 addr;+};
+enum drm_asahi_cmd_type {
DRM_ASAHI_CMD_RENDER = 0,DRM_ASAHI_CMD_BLIT = 1,DRM_ASAHI_CMD_COMPUTE = 2,+};
+/* Note: this is an enum so that it can be resolved by Rust bindgen. */ +enum drm_asahi_queue_cap {
DRM_ASAHI_QUEUE_CAP_RENDER = (1UL << DRM_ASAHI_CMD_RENDER),DRM_ASAHI_QUEUE_CAP_BLIT = (1UL << DRM_ASAHI_CMD_BLIT),DRM_ASAHI_QUEUE_CAP_COMPUTE = (1UL << DRM_ASAHI_CMD_COMPUTE),+};
+struct drm_asahi_queue_create {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @flags: MBZ */__u32 flags;/** @vm_id: The ID of the VM this queue is bound to */__u32 vm_id;/** @type: Bitmask of DRM_ASAHI_QUEUE_CAP_* */__u32 queue_caps;/** @priority: Queue priority, 0-3 */__u32 priority;/** @queue_id: The returned queue ID */__u32 queue_id;+};
+struct drm_asahi_queue_destroy {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @queue_id: The queue ID to be destroyed */__u32 queue_id;+};
+enum drm_asahi_sync_type {
DRM_ASAHI_SYNC_SYNCOBJ = 0,DRM_ASAHI_SYNC_TIMELINE_SYNCOBJ = 1,+};
+struct drm_asahi_sync {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @sync_type: One of drm_asahi_sync_type */__u32 sync_type;/** @handle: The sync object handle */__u32 handle;/** @timeline_value: Timeline value for timeline sync objects */__u64 timeline_value;+};
+enum drm_asahi_subqueue {
DRM_ASAHI_SUBQUEUE_RENDER = 0, /* Also blit */DRM_ASAHI_SUBQUEUE_COMPUTE = 1,DRM_ASAHI_SUBQUEUE_COUNT = 2,+};
+#define DRM_ASAHI_BARRIER_NONE ~(0U)
+struct drm_asahi_command {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @type: One of drm_asahi_cmd_type */__u32 cmd_type;/** @flags: Flags for command submission */__u32 flags;/** @cmdbuf: Pointer to the appropriate command buffer structure */__u64 cmd_buffer;/** @cmdbuf: Size of the command buffer structure */__u64 cmd_buffer_size;/** @cmdbuf: Offset into the result BO to return information about this command */__u64 result_offset;/** @cmdbuf: Size of the result data structure */__u64 result_size;/** @barriers: Array of command indices per subqueue to wait on */__u32 barriers[DRM_ASAHI_SUBQUEUE_COUNT];+};
+struct drm_asahi_submit {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @in_syncs: An optional array of drm_asahi_sync to wait on before starting this job. */__u64 in_syncs;/** @in_syncs: An optional array of drm_asahi_sync objects to signal upon completion. */__u64 out_syncs;/** @commands: Pointer to the drm_asahi_command array of commands to submit. */__u64 commands;/** @flags: Flags for command submission (MBZ) */__u32 flags;/** @queue_id: The queue ID to be submitted to */__u32 queue_id;/** @result_handle: An optional BO handle to place result data in */__u32 result_handle;/** @in_sync_count: Number of sync objects to wait on before starting this job. */__u32 in_sync_count;/** @in_sync_count: Number of sync objects to signal upon completion of this job. */__u32 out_sync_count;/** @pad: Number of commands to be submitted */__u32 command_count;+};
+/* FIXME: This doesn't make any sense, figure out exactly what the attachment flags are */ +#define ASAHI_ATTACHMENT_C 0 +#define ASAHI_ATTACHMENT_Z 1 +#define ASAHI_ATTACHMENT_S 2
+struct drm_asahi_attachment {
__u32 type;__u32 size;__u64 pointer;+};
+#define ASAHI_RENDER_NO_CLEAR_PIPELINE_TEXTURES (1UL << 0) +#define ASAHI_RENDER_SET_WHEN_RELOADING_Z_OR_S (1UL << 1) +#define ASAHI_RENDER_MEMORYLESS_RTS_USED (1UL << 2) /* Not yet implemented */ +#define ASAHI_RENDER_PROCESS_EMPTY_TILES (1UL << 3) +#define ASAHI_RENDER_NO_VERTEX_CLUSTERING (1UL << 4)
+struct drm_asahi_cmd_render {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;__u64 flags;__u64 encoder_ptr;__u64 attachments;__u32 attachment_count;__u32 pad;__u64 depth_buffer_1;__u64 depth_buffer_2;__u64 depth_buffer_3;__u64 depth_meta_buffer_1;__u64 depth_meta_buffer_2;__u64 depth_meta_buffer_3;__u64 stencil_buffer_1;__u64 stencil_buffer_2;__u64 stencil_buffer_3;__u64 stencil_meta_buffer_1;__u64 stencil_meta_buffer_2;__u64 stencil_meta_buffer_3;__u64 scissor_array;__u64 depth_bias_array;__u64 visibility_result_buffer;__u64 zls_ctrl;__u64 ppp_multisamplectl;__u32 ppp_ctrl;__u32 fb_width;__u32 fb_height;__u32 utile_width;__u32 utile_height;__u32 samples;__u32 layers;__u32 encoder_id;__u32 cmd_ta_id;__u32 cmd_3d_id;__u32 iogpu_unk_49;__u32 iogpu_unk_212;__u32 iogpu_unk_214;__u32 merge_upper_x;__u32 merge_upper_y;__u32 load_pipeline;__u32 load_pipeline_bind;__u32 store_pipeline;__u32 store_pipeline_bind;__u32 partial_reload_pipeline;__u32 partial_reload_pipeline_bind;__u32 partial_store_pipeline;__u32 partial_store_pipeline_bind;__u32 depth_dimensions;__u32 isp_bgobjdepth;__u32 isp_bgobjvals;+};
+struct drm_asahi_cmd_compute {
__u64 flags;__u64 encoder_ptr;__u64 encoder_end;__u64 attachments;__u32 attachment_count;__u32 pad;__u64 buffer_descriptor;__u32 buffer_descriptor_size; /* ? */__u32 ctx_switch_prog;__u32 encoder_id;__u32 cmd_id;__u32 iogpu_unk_40;__u32 iogpu_unk_44;+};
+enum drm_asahi_status {
DRM_ASAHI_STATUS_PENDING = 0,DRM_ASAHI_STATUS_COMPLETE,DRM_ASAHI_STATUS_UNKNOWN_ERROR,DRM_ASAHI_STATUS_TIMEOUT,DRM_ASAHI_STATUS_FAULT,DRM_ASAHI_STATUS_KILLED,DRM_ASAHI_STATUS_NO_DEVICE,+};
+enum drm_asahi_fault {
DRM_ASAHI_FAULT_NONE = 0,DRM_ASAHI_FAULT_UNKNOWN,DRM_ASAHI_FAULT_UNMAPPED,DRM_ASAHI_FAULT_AF_FAULT,DRM_ASAHI_FAULT_WRITE_ONLY,DRM_ASAHI_FAULT_READ_ONLY,DRM_ASAHI_FAULT_NO_ACCESS,+};
+struct drm_asahi_result_info {
/** @status: One of enum drm_asahi_status */__u32 status;/** @reason: One of drm_asahi_fault_type */__u32 fault_type;/** @unit: Unit number, hardware dependent */__u32 unit;/** @sideband: Sideband information, hardware dependent */__u32 sideband;/** @level: Page table level at which the fault occurred, hardware dependent */__u8 level;/** @read: Fault was a read */__u8 is_read;/** @pad: MBZ */__u16 pad;/** @unk_5: Extra bits, hardware dependent */__u32 extra;/** @address: Fault address, cache line aligned */__u64 address;+};
+#define DRM_ASAHI_RESULT_RENDER_TVB_GROW_OVF (1UL << 0) +#define DRM_ASAHI_RESULT_RENDER_TVB_GROW_MIN (1UL << 1) +#define DRM_ASAHI_RESULT_RENDER_TVB_OVERFLOWED (1UL << 2)
+struct drm_asahi_result_render {
/** @address: Common result information */struct drm_asahi_result_info info;/** @flags: Zero or more of of DRM_ASAHI_RESULT_RENDER_* */__u64 flags;/** @vertex_ts_start: Timestamp of the start of vertex processing */__u64 vertex_ts_start;/** @vertex_ts_end: Timestamp of the end of vertex processing */__u64 vertex_ts_end;/** @fragment_ts_start: Timestamp of the start of fragment processing */__u64 fragment_ts_start;/** @fragment_ts_end: Timestamp of the end of fragment processing */__u64 fragment_ts_end;/** @tvb_size_bytes: TVB size at the start of this render */__u64 tvb_size_bytes;/** @tvb_usage_bytes: Total TVB usage in bytes for this render */__u64 tvb_usage_bytes;/** @num_tvb_overflows: Number of TVB overflows that occurred for this render */__u32 num_tvb_overflows;+};
+struct drm_asahi_result_compute {
/** @address: Common result information */struct drm_asahi_result_info info;/** @flags: Zero or more of of DRM_ASAHI_RESULT_COMPUTE_* */__u64 flags;/** @ts_start: Timestamp of the start of this compute command */__u64 ts_start;/** @vertex_ts_end: Timestamp of the end of this compute command */__u64 ts_end;+};
+struct drm_asahi_get_time {
/** @extensions: Pointer to the first extension struct, if any */__u64 extensions;/** @flags: MBZ. */__u64 flags;/** @tv_sec: On return, seconds part of a point in time */__s64 tv_sec;/** @tv_nsec: On return, nanoseconds part of a point in time */__s64 tv_nsec;/** @gpu_timestamp: On return, the GPU timestamp at that point in time */__u64 gpu_timestamp;+};
+/* Note: this is an enum so that it can be resolved by Rust bindgen. */ +enum {
- DRM_IOCTL_ASAHI_GET_PARAMS = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_GET_PARAMS, struct drm_asahi_get_params),
- DRM_IOCTL_ASAHI_VM_CREATE = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_VM_CREATE, struct drm_asahi_vm_create),
- DRM_IOCTL_ASAHI_VM_DESTROY = DRM_IOW(DRM_COMMAND_BASE + DRM_ASAHI_VM_DESTROY, struct drm_asahi_vm_destroy),
- DRM_IOCTL_ASAHI_GEM_CREATE = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_GEM_CREATE, struct drm_asahi_gem_create),
- DRM_IOCTL_ASAHI_GEM_MMAP_OFFSET = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_GEM_MMAP_OFFSET, struct drm_asahi_gem_mmap_offset),
- DRM_IOCTL_ASAHI_GEM_BIND = DRM_IOW(DRM_COMMAND_BASE + DRM_ASAHI_GEM_BIND, struct drm_asahi_gem_bind),
- DRM_IOCTL_ASAHI_QUEUE_CREATE = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_QUEUE_CREATE, struct drm_asahi_queue_create),
- DRM_IOCTL_ASAHI_QUEUE_DESTROY = DRM_IOW(DRM_COMMAND_BASE + DRM_ASAHI_QUEUE_DESTROY, struct drm_asahi_queue_destroy),
- DRM_IOCTL_ASAHI_SUBMIT = DRM_IOW(DRM_COMMAND_BASE + DRM_ASAHI_SUBMIT, struct drm_asahi_submit),
- DRM_IOCTL_ASAHI_GET_TIME = DRM_IOWR(DRM_COMMAND_BASE + DRM_ASAHI_GET_TIME, struct drm_asahi_get_time),
+};
heh.. I had the same issue in mesa and wasn't thinking of doing this instead
+#if defined(__cplusplus) +} +#endif
+#endif /* _ASAHI_DRM_H_ */
-- 2.35.1