drm/vc4: Add get/set tiling ioctls.
This allows mesa to set the tiling format for a BO and have that tiling format be respected by mesa on the other side of an import/export (and by vc4 scanout in the kernel), without defining a protocol to pass the tiling through userspace. Signed-off-by: Eric Anholt <eric@anholt.net> Link: http://patchwork.freedesktop.org/patch/msgid/20170608001336.12842-2-eric@anholt.net Acked-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
98830d91da
commit
83753117f1
|
@ -343,6 +343,7 @@ void vc4_free_object(struct drm_gem_object *gem_bo)
|
|||
bo->validated_shader = NULL;
|
||||
}
|
||||
|
||||
bo->t_format = false;
|
||||
bo->free_time = jiffies;
|
||||
list_add(&bo->size_head, cache_list);
|
||||
list_add(&bo->unref_head, &vc4->bo_cache.time_list);
|
||||
|
@ -568,6 +569,88 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* vc4_set_tiling_ioctl() - Sets the tiling modifier for a BO.
|
||||
* @dev: DRM device
|
||||
* @data: ioctl argument
|
||||
* @file_priv: DRM file for this fd
|
||||
*
|
||||
* The tiling state of the BO decides the default modifier of an fb if
|
||||
* no specific modifier was set by userspace, and the return value of
|
||||
* vc4_get_tiling_ioctl() (so that userspace can treat a BO it
|
||||
* received from dmabuf as the same tiling format as the producer
|
||||
* used).
|
||||
*/
|
||||
int vc4_set_tiling_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_vc4_set_tiling *args = data;
|
||||
struct drm_gem_object *gem_obj;
|
||||
struct vc4_bo *bo;
|
||||
bool t_format;
|
||||
|
||||
if (args->flags != 0)
|
||||
return -EINVAL;
|
||||
|
||||
switch (args->modifier) {
|
||||
case DRM_FORMAT_MOD_NONE:
|
||||
t_format = false;
|
||||
break;
|
||||
case DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED:
|
||||
t_format = true;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
|
||||
if (!gem_obj) {
|
||||
DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
|
||||
return -ENOENT;
|
||||
}
|
||||
bo = to_vc4_bo(gem_obj);
|
||||
bo->t_format = t_format;
|
||||
|
||||
drm_gem_object_unreference_unlocked(gem_obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* vc4_get_tiling_ioctl() - Gets the tiling modifier for a BO.
|
||||
* @dev: DRM device
|
||||
* @data: ioctl argument
|
||||
* @file_priv: DRM file for this fd
|
||||
*
|
||||
* Returns the tiling modifier for a BO as set by vc4_set_tiling_ioctl().
|
||||
*/
|
||||
int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv)
|
||||
{
|
||||
struct drm_vc4_get_tiling *args = data;
|
||||
struct drm_gem_object *gem_obj;
|
||||
struct vc4_bo *bo;
|
||||
|
||||
if (args->flags != 0 || args->modifier != 0)
|
||||
return -EINVAL;
|
||||
|
||||
gem_obj = drm_gem_object_lookup(file_priv, args->handle);
|
||||
if (!gem_obj) {
|
||||
DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
|
||||
return -ENOENT;
|
||||
}
|
||||
bo = to_vc4_bo(gem_obj);
|
||||
|
||||
if (bo->t_format)
|
||||
args->modifier = DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED;
|
||||
else
|
||||
args->modifier = DRM_FORMAT_MOD_NONE;
|
||||
|
||||
drm_gem_object_unreference_unlocked(gem_obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vc4_bo_cache_init(struct drm_device *dev)
|
||||
{
|
||||
struct vc4_dev *vc4 = to_vc4_dev(dev);
|
||||
|
|
|
@ -138,6 +138,8 @@ static const struct drm_ioctl_desc vc4_drm_ioctls[] = {
|
|||
DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl,
|
||||
DRM_ROOT_ONLY),
|
||||
DRM_IOCTL_DEF_DRV(VC4_GET_PARAM, vc4_get_param_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(VC4_SET_TILING, vc4_set_tiling_ioctl, DRM_RENDER_ALLOW),
|
||||
DRM_IOCTL_DEF_DRV(VC4_GET_TILING, vc4_get_tiling_ioctl, DRM_RENDER_ALLOW),
|
||||
};
|
||||
|
||||
static struct drm_driver vc4_drm_driver = {
|
||||
|
|
|
@ -148,6 +148,8 @@ struct vc4_bo {
|
|||
*/
|
||||
uint64_t write_seqno;
|
||||
|
||||
bool t_format;
|
||||
|
||||
/* List entry for the BO's position in either
|
||||
* vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list
|
||||
*/
|
||||
|
@ -470,6 +472,10 @@ int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
|
|||
struct drm_file *file_priv);
|
||||
int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int vc4_set_tiling_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int vc4_get_tiling_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
|
||||
|
|
|
@ -202,11 +202,50 @@ static int vc4_atomic_commit(struct drm_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct drm_framebuffer *vc4_fb_create(struct drm_device *dev,
|
||||
struct drm_file *file_priv,
|
||||
const struct drm_mode_fb_cmd2 *mode_cmd)
|
||||
{
|
||||
struct drm_mode_fb_cmd2 mode_cmd_local;
|
||||
|
||||
/* If the user didn't specify a modifier, use the
|
||||
* vc4_set_tiling_ioctl() state for the BO.
|
||||
*/
|
||||
if (!(mode_cmd->flags & DRM_MODE_FB_MODIFIERS)) {
|
||||
struct drm_gem_object *gem_obj;
|
||||
struct vc4_bo *bo;
|
||||
|
||||
gem_obj = drm_gem_object_lookup(file_priv,
|
||||
mode_cmd->handles[0]);
|
||||
if (!gem_obj) {
|
||||
DRM_ERROR("Failed to look up GEM BO %d\n",
|
||||
mode_cmd->handles[0]);
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
bo = to_vc4_bo(gem_obj);
|
||||
|
||||
mode_cmd_local = *mode_cmd;
|
||||
|
||||
if (bo->t_format) {
|
||||
mode_cmd_local.modifier[0] =
|
||||
DRM_FORMAT_MOD_BROADCOM_VC4_T_TILED;
|
||||
} else {
|
||||
mode_cmd_local.modifier[0] = DRM_FORMAT_MOD_NONE;
|
||||
}
|
||||
|
||||
drm_gem_object_unreference_unlocked(gem_obj);
|
||||
|
||||
mode_cmd = &mode_cmd_local;
|
||||
}
|
||||
|
||||
return drm_fb_cma_create(dev, file_priv, mode_cmd);
|
||||
}
|
||||
|
||||
static const struct drm_mode_config_funcs vc4_mode_funcs = {
|
||||
.output_poll_changed = vc4_output_poll_changed,
|
||||
.atomic_check = drm_atomic_helper_check,
|
||||
.atomic_commit = vc4_atomic_commit,
|
||||
.fb_create = drm_fb_cma_create,
|
||||
.fb_create = vc4_fb_create,
|
||||
};
|
||||
|
||||
int vc4_kms_load(struct drm_device *dev)
|
||||
|
|
|
@ -38,6 +38,8 @@ extern "C" {
|
|||
#define DRM_VC4_CREATE_SHADER_BO 0x05
|
||||
#define DRM_VC4_GET_HANG_STATE 0x06
|
||||
#define DRM_VC4_GET_PARAM 0x07
|
||||
#define DRM_VC4_SET_TILING 0x08
|
||||
#define DRM_VC4_GET_TILING 0x09
|
||||
|
||||
#define DRM_IOCTL_VC4_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SUBMIT_CL, struct drm_vc4_submit_cl)
|
||||
#define DRM_IOCTL_VC4_WAIT_SEQNO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_WAIT_SEQNO, struct drm_vc4_wait_seqno)
|
||||
|
@ -47,6 +49,8 @@ extern "C" {
|
|||
#define DRM_IOCTL_VC4_CREATE_SHADER_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_CREATE_SHADER_BO, struct drm_vc4_create_shader_bo)
|
||||
#define DRM_IOCTL_VC4_GET_HANG_STATE DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_HANG_STATE, struct drm_vc4_get_hang_state)
|
||||
#define DRM_IOCTL_VC4_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_PARAM, struct drm_vc4_get_param)
|
||||
#define DRM_IOCTL_VC4_SET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_SET_TILING, struct drm_vc4_set_tiling)
|
||||
#define DRM_IOCTL_VC4_GET_TILING DRM_IOWR(DRM_COMMAND_BASE + DRM_VC4_GET_TILING, struct drm_vc4_get_tiling)
|
||||
|
||||
struct drm_vc4_submit_rcl_surface {
|
||||
__u32 hindex; /* Handle index, or ~0 if not present. */
|
||||
|
@ -295,6 +299,18 @@ struct drm_vc4_get_param {
|
|||
__u64 value;
|
||||
};
|
||||
|
||||
struct drm_vc4_get_tiling {
|
||||
__u32 handle;
|
||||
__u32 flags;
|
||||
__u64 modifier;
|
||||
};
|
||||
|
||||
struct drm_vc4_set_tiling {
|
||||
__u32 handle;
|
||||
__u32 flags;
|
||||
__u64 modifier;
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue