drm/i915: implement SNB workaround for lazy global gtt
PIPE_CONTROL on snb needs global gtt mappings in place to workaround a hw gotcha. No other commands need such a workaround. Luckily we can detect a PIPE_CONTROL commands easily because they have a write_domain = I915_GEM_DOMAIN_INSTRUCTION (and nothing else has that). v2: Binding the target of such a reloc into the global gtt actually works instead of binding the source, which is rather pointless ... v3: Kill a superflous has_global_gtt_mapping assignement noticed by Chris Wilson. Reviewed-and-tested-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
74898d7edc
commit
149c84077f
|
@ -273,6 +273,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
|
|||
{
|
||||
struct drm_device *dev = obj->base.dev;
|
||||
struct drm_gem_object *target_obj;
|
||||
struct drm_i915_gem_object *target_i915_obj;
|
||||
uint32_t target_offset;
|
||||
int ret = -EINVAL;
|
||||
|
||||
|
@ -281,7 +282,8 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
|
|||
if (unlikely(target_obj == NULL))
|
||||
return -ENOENT;
|
||||
|
||||
target_offset = to_intel_bo(target_obj)->gtt_offset;
|
||||
target_i915_obj = to_intel_bo(target_obj);
|
||||
target_offset = target_i915_obj->gtt_offset;
|
||||
|
||||
/* The target buffer should have appeared before us in the
|
||||
* exec_object list, so it should have a GTT space bound by now.
|
||||
|
@ -383,6 +385,16 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj,
|
|||
io_mapping_unmap_atomic(reloc_page);
|
||||
}
|
||||
|
||||
/* Sandybridge PPGTT errata: We need a global gtt mapping for MI and
|
||||
* pipe_control writes because the gpu doesn't properly redirect them
|
||||
* through the ppgtt for non_secure batchbuffers. */
|
||||
if (unlikely(IS_GEN6(dev) &&
|
||||
reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION &&
|
||||
!target_i915_obj->has_global_gtt_mapping)) {
|
||||
i915_gem_gtt_bind_object(target_i915_obj,
|
||||
target_i915_obj->cache_level);
|
||||
}
|
||||
|
||||
/* and update the user's relocation entry */
|
||||
reloc->presumed_offset = target_offset;
|
||||
|
||||
|
|
Loading…
Reference in a new issue