aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2015-02-05 09:41:52 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2015-02-13 17:28:12 -0500
commite3eb3250d84ef97b766312345774367b6a310db8 (patch)
tree7220c957097ad78df34d6d2aeacc8afdadb1a9d4 /drivers/gpu/drm
parent17d5538d54c9f9d6e2b44e07d4d577304e22c17a (diff)
drm: add support for tiled/compressed/etc modifier in addfb2
In DRM/KMS we are lacking a good way to deal with tiled/compressed formats. Especially in the case of dmabuf/prime buffer sharing, where we cannot always rely on under-the-hood flags passed to driver specific gem-create ioctl to pass around these extra flags. The proposal is to add a per-plane format modifier. This allows to, if necessary, use different tiling patters for sub-sampled planes, etc. The format modifiers are added at the end of the ioctl struct, so for legacy userspace it will be zero padded. v1: original v1.5: increase modifier to 64b v2: Incorporate review comments from the big thread, plus a few more. - Add a getcap so that userspace doesn't have to jump through hoops. - Allow modifiers only when a flag is set. That way drivers know when they're dealing with old userspace and need to fish out e.g. tiling from other information. - After rolling out checks for ->modifier to all drivers I've decided that this is way too fragile and needs an explicit opt-in flag. So do that instead. - Add a define (just for documentation really) for the "NONE" modifier. Imo we don't need to add mask #defines since drivers really should only do exact matches against values defined with fourcc_mod_code. - Drop the Samsung tiling modifier on Rob's request since he's not yet sure whether that one is accurate. v3: - Also add a new ->modifier[] array to struct drm_framebuffer and fill it in drm_helper_mode_fill_fb_struct. Requested by Tvrkto Uruslin. - Remove TODO in comment and add code comment that modifiers should be properly documented, requested by Rob. Cc: Rob Clark <robdclark@gmail.com> Cc: Tvrtko Ursulin <tvrtko.ursulin@linux.intel.com> Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Cc: Daniel Stone <daniel@fooishbar.org> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: Michel Dänzer <michel@daenzer.net> Signed-off-by: Rob Clark <robdclark@gmail.com> (v1.5) Reviewed-by: Rob Clark <robdclark@gmail.com> Reviewed-by: Daniel Stone <daniels@collabora.com> Acked-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Daniel Vetter <daniel.vetter@intel.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/drm_crtc.c14
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c1
-rw-r--r--drivers/gpu/drm/drm_ioctl.c3
3 files changed, 17 insertions, 1 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index ad2934ba0bd2..b15d720eda4c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -3314,6 +3314,12 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
3314 DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i); 3314 DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);
3315 return -EINVAL; 3315 return -EINVAL;
3316 } 3316 }
3317
3318 if (r->modifier[i] && !(r->flags & DRM_MODE_FB_MODIFIERS)) {
3319 DRM_DEBUG_KMS("bad fb modifier %llu for plane %d\n",
3320 r->modifier[i], i);
3321 return -EINVAL;
3322 }
3317 } 3323 }
3318 3324
3319 return 0; 3325 return 0;
@@ -3327,7 +3333,7 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
3327 struct drm_framebuffer *fb; 3333 struct drm_framebuffer *fb;
3328 int ret; 3334 int ret;
3329 3335
3330 if (r->flags & ~DRM_MODE_FB_INTERLACED) { 3336 if (r->flags & ~(DRM_MODE_FB_INTERLACED | DRM_MODE_FB_MODIFIERS)) {
3331 DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags); 3337 DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags);
3332 return ERR_PTR(-EINVAL); 3338 return ERR_PTR(-EINVAL);
3333 } 3339 }
@@ -3343,6 +3349,12 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev,
3343 return ERR_PTR(-EINVAL); 3349 return ERR_PTR(-EINVAL);
3344 } 3350 }
3345 3351
3352 if (r->flags & DRM_MODE_FB_MODIFIERS &&
3353 !dev->mode_config.allow_fb_modifiers) {
3354 DRM_DEBUG_KMS("driver does not support fb modifiers\n");
3355 return ERR_PTR(-EINVAL);
3356 }
3357
3346 ret = framebuffer_check(r); 3358 ret = framebuffer_check(r);
3347 if (ret) 3359 if (ret)
3348 return ERR_PTR(ret); 3360 return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index b1979e7bdc88..3053aab968f9 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -837,6 +837,7 @@ void drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
837 for (i = 0; i < 4; i++) { 837 for (i = 0; i < 4; i++) {
838 fb->pitches[i] = mode_cmd->pitches[i]; 838 fb->pitches[i] = mode_cmd->pitches[i];
839 fb->offsets[i] = mode_cmd->offsets[i]; 839 fb->offsets[i] = mode_cmd->offsets[i];
840 fb->modifier[i] = mode_cmd->modifier[i];
840 } 841 }
841 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth, 842 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &fb->depth,
842 &fb->bits_per_pixel); 843 &fb->bits_per_pixel);
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
index 3785d66721f2..a6d773a61c2d 100644
--- a/drivers/gpu/drm/drm_ioctl.c
+++ b/drivers/gpu/drm/drm_ioctl.c
@@ -321,6 +321,9 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_
321 else 321 else
322 req->value = 64; 322 req->value = 64;
323 break; 323 break;
324 case DRM_CAP_ADDFB2_MODIFIERS:
325 req->value = dev->mode_config.allow_fb_modifiers;
326 break;
324 default: 327 default:
325 return -EINVAL; 328 return -EINVAL;
326 } 329 }