From: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Engine discovery uAPI allows userspace to probe for engine configuration and features without needing to maintain the internal PCI id based database. This enables removal of code duplications across userspace components. Probing is done via the new DRM_IOCTL_I915_GEM_ENGINE_INFO ioctl which returns the number and information on the specified engine class. Currently only general engine configuration and HEVC feature of the VCS engine can be probed but the uAPI is designed to be generic and extensible. Code is based almost exactly on the earlier proposal on the topic by Jon Bloomfield. Engine class and instance refactoring made recently by Daniele Ceraolo Spurio enabled this to be implemented in an elegant fashion. To probe configuration userspace sets the engine class it wants to query (struct drm_i915_gem_engine_info) and provides an array of drm_i915_engine_info structs which will be filled in by the driver. Userspace also has to tell i915 how many elements are in the array, and the driver will report back the total number of engine instances in any case. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@xxxxxxxxx> Cc: Ben Widawsky <ben@xxxxxxxxxxxx> Cc: Chris Wilson <chris@xxxxxxxxxxxxxxxxxx> Cc: Daniel Vetter <daniel.vetter@xxxxxxxxx> Cc: Joonas Lahtinen <joonas.lahtinen@xxxxxxxxxxxxxxx> Cc: Jon Bloomfield <jon.bloomfield@xxxxxxxxx> Cc: Daniel Charles <daniel.charles@xxxxxxxxx> Cc: "Rogozhkin, Dmitry V" <dmitry.v.rogozhkin@xxxxxxxxx> Cc: Oscar Mateo <oscar.mateo@xxxxxxxxx> Cc: "Gong, Zhipeng" <zhipeng.gong@xxxxxxxxx> Cc: intel-vaapi-media@xxxxxxxxxxxx Cc: mesa-dev@xxxxxxxxxxxxxxxxxxxxx --- drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 3 ++ drivers/gpu/drm/i915/intel_engine_cs.c | 59 ++++++++++++++++++++++++++++++++++ include/uapi/drm/i915_drm.h | 40 +++++++++++++++++++++++ 4 files changed, 103 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index cc7393e65e99..b720c9468adf 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -2607,6 +2607,7 @@ static const struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_GETPARAM, i915_gem_context_getparam_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_RENDER_ALLOW), DRM_IOCTL_DEF_DRV(I915_PERF_OPEN, i915_perf_open_ioctl, DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(I915_GEM_ENGINE_INFO, i915_gem_engine_info_ioctl, DRM_RENDER_ALLOW), }; static struct drm_driver driver = { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 357b6c6c2f04..6eed0e854561 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -3547,6 +3547,9 @@ i915_gem_context_lookup_timeline(struct i915_gem_context *ctx, int i915_perf_open_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +int i915_gem_engine_info_ioctl(struct drm_device *dev, void *data, + struct drm_file *file); + /* i915_gem_evict.c */ int __must_check i915_gem_evict_something(struct i915_address_space *vm, u64 min_size, u64 alignment, diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 402769d9d840..6deaffd34ae0 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c @@ -25,6 +25,7 @@ #include "i915_drv.h" #include "intel_ringbuffer.h" #include "intel_lrc.h" +#include <uapi/drm/i915_drm.h> struct engine_class_info { const char *name; @@ -1189,6 +1190,64 @@ void intel_engines_reset_default_submission(struct drm_i915_private *i915) engine->set_default_submission(engine); } +u8 user_class_map[DRM_I915_ENGINE_CLASS_MAX] = { + [DRM_I915_ENGINE_CLASS_OTHER] = OTHER_CLASS, + [DRM_I915_ENGINE_CLASS_RENDER] = RENDER_CLASS, + [DRM_I915_ENGINE_CLASS_COPY] = COPY_ENGINE_CLASS, + [DRM_I915_ENGINE_CLASS_VIDEO_DECODE] = VIDEO_DECODE_CLASS, + [DRM_I915_ENGINE_CLASS_VIDEO_ENHANCE] = VIDEO_ENHANCEMENT_CLASS, +}; + +int i915_gem_engine_info_ioctl(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_private *i915 = to_i915(dev); + struct drm_i915_gem_engine_info *args = data; + enum drm_i915_gem_engine_class engine_class = args->engine_class; + struct drm_i915_engine_info __user *user_info = + u64_to_user_ptr(args->info_ptr); + struct drm_i915_engine_info info; + struct intel_engine_cs *engine; + enum intel_engine_id id; + u8 class; + + if (args->rsvd) + return -EINVAL; + + switch (engine_class) { + case DRM_I915_ENGINE_CLASS_OTHER: + case DRM_I915_ENGINE_CLASS_RENDER: + case DRM_I915_ENGINE_CLASS_COPY: + case DRM_I915_ENGINE_CLASS_VIDEO_DECODE: + case DRM_I915_ENGINE_CLASS_VIDEO_ENHANCE: + if (engine_class >= DRM_I915_ENGINE_CLASS_MAX) + return -EINVAL; + class = user_class_map[engine_class]; + break; + default: + return -EINVAL; + }; + + args->num_engines = 0; + for_each_engine(engine, i915, id) { + if (class != engine->class) + continue; + + if (++args->num_engines > args->info_size) + continue; + + memset(&info, 0, sizeof(info)); + info.instance = engine->instance; + if (INTEL_GEN(i915) > 8 && id == VCS) + info.info = DRM_I915_ENGINE_HAS_HEVC; + + if (copy_to_user(user_info++, &info, sizeof(info))) + return -EFAULT; + } + + return 0; +} + #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) #include "selftests/mock_engine.c" #endif diff --git a/include/uapi/drm/i915_drm.h b/include/uapi/drm/i915_drm.h index f24a80d2d42e..6058596a9f33 100644 --- a/include/uapi/drm/i915_drm.h +++ b/include/uapi/drm/i915_drm.h @@ -260,6 +260,7 @@ typedef struct _drm_i915_sarea { #define DRM_I915_GEM_CONTEXT_GETPARAM 0x34 #define DRM_I915_GEM_CONTEXT_SETPARAM 0x35 #define DRM_I915_PERF_OPEN 0x36 +#define DRM_I915_GEM_ENGINE_INFO 0x37 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) @@ -315,6 +316,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_GETPARAM, struct drm_i915_gem_context_param) #define DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_CONTEXT_SETPARAM, struct drm_i915_gem_context_param) #define DRM_IOCTL_I915_PERF_OPEN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_PERF_OPEN, struct drm_i915_perf_open_param) +#define DRM_IOCTL_I915_GEM_ENGINE_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_ENGINE_INFO, struct drm_i915_gem_engine_info) /* Allow drivers to submit batchbuffers directly to hardware, relying * on the security mechanisms provided by hardware. @@ -1439,6 +1441,44 @@ enum drm_i915_perf_record_type { DRM_I915_PERF_RECORD_MAX /* non-ABI */ }; +enum drm_i915_gem_engine_class { + DRM_I915_ENGINE_CLASS_OTHER = 0, + DRM_I915_ENGINE_CLASS_RENDER = 1, + DRM_I915_ENGINE_CLASS_COPY = 2, + DRM_I915_ENGINE_CLASS_VIDEO_DECODE = 3, + DRM_I915_ENGINE_CLASS_VIDEO_ENHANCE = 4, + DRM_I915_ENGINE_CLASS_MAX /* non-ABI */ +}; + +struct drm_i915_engine_info { + /** Engine instance number. */ + __u32 instance; + __u32 rsvd; + + /** Engine specific info. */ +#define DRM_I915_ENGINE_HAS_HEVC BIT(0) + __u64 info; +}; + +struct drm_i915_gem_engine_info { + /** in: Engine class to probe (enum drm_i915_gem_engine_class). */ + __u32 engine_class; + + /** out: Actual number of hardware engines. */ + __u32 num_engines; + + /** + * in: Number of struct drm_i915_engine_ifo entries in the provided + * info array. + */ + __u32 info_size; + __u32 rsvd; + + /** in/out: Pointer to array of struct i915_engine_info elements. */ + __u64 info_ptr; + +}; + #if defined(__cplusplus) } #endif -- 2.9.3 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/intel-gfx