Commit c2ff7370 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Adjust obj tiling vs. fb modifier rules

Currently we require the object to be X tiled if the fb is X
tiled. The argument is supposedly FBC GTT tracking. But
actually that no longer holds water since FBC supports
Y tiling as well on SKL+.

A better rule IMO is to require that if there is a fence, the
fb modifier match the object tiling mode. But if the object is linear,
we can allow the fb modifier to be anything. The idea being that
if the user set the tiling mode on the object, presumably the intention
is to actually use the fence for CPU access. But if the tiling mode is
not set, the user has no intention of using a fence (and can't actually
since we disallow tiling mode changes when there are framebuffers
associated with the object).

On gen2/3 we must keep to the rule that the object and fb
must be either both linear or both X tiled. No mixing allowed
since the display engine itself will use the fence if it's present.

v2: Fix typos
v3: Rebase due to i915_gem_object_get_tiling() & co.
Reviewed-by: default avatarMatthew Auld <matthew.auld@intel.com>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470821001-25272-7-git-send-email-ville.syrjala@linux.intel.comReviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 72618ebf
...@@ -15202,23 +15202,26 @@ static int intel_framebuffer_init(struct drm_device *dev, ...@@ -15202,23 +15202,26 @@ static int intel_framebuffer_init(struct drm_device *dev,
struct drm_i915_gem_object *obj) struct drm_i915_gem_object *obj)
{ {
struct drm_i915_private *dev_priv = to_i915(dev); struct drm_i915_private *dev_priv = to_i915(dev);
unsigned int tiling = i915_gem_object_get_tiling(obj);
int ret; int ret;
u32 pitch_limit, stride_alignment; u32 pitch_limit, stride_alignment;
WARN_ON(!mutex_is_locked(&dev->struct_mutex)); WARN_ON(!mutex_is_locked(&dev->struct_mutex));
if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) { if (mode_cmd->flags & DRM_MODE_FB_MODIFIERS) {
/* Enforce that fb modifier and tiling mode match, but only for /*
* X-tiled. This is needed for FBC. */ * If there's a fence, enforce that
if (!!(i915_gem_object_get_tiling(obj) == I915_TILING_X) != * the fb modifier and tiling mode match.
!!(mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED)) { */
if (tiling != I915_TILING_NONE &&
tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
DRM_DEBUG("tiling_mode doesn't match fb modifier\n"); DRM_DEBUG("tiling_mode doesn't match fb modifier\n");
return -EINVAL; return -EINVAL;
} }
} else { } else {
if (i915_gem_object_get_tiling(obj) == I915_TILING_X) if (tiling == I915_TILING_X) {
mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED; mode_cmd->modifier[0] = I915_FORMAT_MOD_X_TILED;
else if (i915_gem_object_get_tiling(obj) == I915_TILING_Y) { } else if (tiling == I915_TILING_Y) {
DRM_DEBUG("No Y tiling for legacy addfb\n"); DRM_DEBUG("No Y tiling for legacy addfb\n");
return -EINVAL; return -EINVAL;
} }
...@@ -15242,6 +15245,16 @@ static int intel_framebuffer_init(struct drm_device *dev, ...@@ -15242,6 +15245,16 @@ static int intel_framebuffer_init(struct drm_device *dev,
return -EINVAL; return -EINVAL;
} }
/*
* gen2/3 display engine uses the fence if present,
* so the tiling mode must match the fb modifier exactly.
*/
if (INTEL_INFO(dev_priv)->gen < 4 &&
tiling != intel_fb_modifier_to_tiling(mode_cmd->modifier[0])) {
DRM_DEBUG("tiling_mode must match fb modifier exactly on gen2/3\n");
return -EINVAL;
}
stride_alignment = intel_fb_stride_alignment(dev_priv, stride_alignment = intel_fb_stride_alignment(dev_priv,
mode_cmd->modifier[0], mode_cmd->modifier[0],
mode_cmd->pixel_format); mode_cmd->pixel_format);
...@@ -15261,7 +15274,11 @@ static int intel_framebuffer_init(struct drm_device *dev, ...@@ -15261,7 +15274,11 @@ static int intel_framebuffer_init(struct drm_device *dev,
return -EINVAL; return -EINVAL;
} }
if (mode_cmd->modifier[0] == I915_FORMAT_MOD_X_TILED && /*
* If there's a fence, enforce that
* the fb pitch and fence stride match.
*/
if (tiling != I915_TILING_NONE &&
mode_cmd->pitches[0] != i915_gem_object_get_stride(obj)) { mode_cmd->pitches[0] != i915_gem_object_get_stride(obj)) {
DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n", DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n",
mode_cmd->pitches[0], mode_cmd->pitches[0],
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment