drm/i915: Rebind the buffer if its alignment constraints changes with tiling
Early gen3 and gen2 chipset do not have the relaxed per-surface tiling constraints of the later chipsets, so we need to check that the GTT alignment is correct for the new tiling. If it is not, we need to rebind. Reported-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
parent
a1656b9090
commit
467cffba85
|
@ -1178,6 +1178,9 @@ void i915_gem_detach_phys_object(struct drm_device *dev,
|
||||||
void i915_gem_free_all_phys_object(struct drm_device *dev);
|
void i915_gem_free_all_phys_object(struct drm_device *dev);
|
||||||
void i915_gem_release(struct drm_device *dev, struct drm_file *file);
|
void i915_gem_release(struct drm_device *dev, struct drm_file *file);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj);
|
||||||
|
|
||||||
/* i915_gem_gtt.c */
|
/* i915_gem_gtt.c */
|
||||||
void i915_gem_restore_gtt_mappings(struct drm_device *dev);
|
void i915_gem_restore_gtt_mappings(struct drm_device *dev);
|
||||||
int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj);
|
int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj);
|
||||||
|
|
|
@ -1398,7 +1398,7 @@ i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj)
|
||||||
* Return the required GTT alignment for an object, only taking into account
|
* Return the required GTT alignment for an object, only taking into account
|
||||||
* unfenced tiled surface requirements.
|
* unfenced tiled surface requirements.
|
||||||
*/
|
*/
|
||||||
static uint32_t
|
uint32_t
|
||||||
i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj)
|
i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = obj->base.dev;
|
struct drm_device *dev = obj->base.dev;
|
||||||
|
|
|
@ -349,14 +349,27 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
|
||||||
(obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end &&
|
(obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end &&
|
||||||
i915_gem_object_fence_ok(obj, args->tiling_mode));
|
i915_gem_object_fence_ok(obj, args->tiling_mode));
|
||||||
|
|
||||||
obj->tiling_changed = true;
|
/* Rebind if we need a change of alignment */
|
||||||
obj->tiling_mode = args->tiling_mode;
|
if (!obj->map_and_fenceable) {
|
||||||
obj->stride = args->stride;
|
u32 unfenced_alignment =
|
||||||
|
i915_gem_get_unfenced_gtt_alignment(obj);
|
||||||
|
if (obj->gtt_offset & (unfenced_alignment - 1))
|
||||||
|
ret = i915_gem_object_unbind(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
obj->tiling_changed = true;
|
||||||
|
obj->tiling_mode = args->tiling_mode;
|
||||||
|
obj->stride = args->stride;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/* we have to maintain this existing ABI... */
|
||||||
|
args->stride = obj->stride;
|
||||||
|
args->tiling_mode = obj->tiling_mode;
|
||||||
drm_gem_object_unreference(&obj->base);
|
drm_gem_object_unreference(&obj->base);
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue