On Thu, Jan 09, 2014 at 11:01:56AM +0530, akash.goel@xxxxxxxxx wrote: > From: Akash Goel <akash.goel@xxxxxxxxx> > > On VLV, to clear out the contents of Frame buffers allocated from > stolen area, Blitter engine is being used, to avoid the waste of > CPU cycles in doing a sw based memset. > > Signed-off-by: Akash Goel <akash.goel@xxxxxxxxx> > --- > drivers/gpu/drm/i915/i915_gem_stolen.c | 87 ++++++++++++++++++++++++++++++++-- > 1 file changed, 84 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c > index 253a39a..10237c8 100644 > --- a/drivers/gpu/drm/i915/i915_gem_stolen.c > +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c > @@ -371,7 +371,84 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size) > return NULL; > } > > -static void i915_memset_stolen_obj(struct drm_i915_gem_object *obj) > +static int i915_add_clear_obj_cmd(struct drm_i915_gem_object *obj) > +{ > + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; > + struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; Pre-gen6 has the blitter on the RCS ring. > + uint32_t obj_height = (obj->base.size / obj->stride); obj->stride is 0 for untiled buffers, so for more robustness I'd just use 4096 (page size) as stride. For even more robustness I think we should have checks here to make sure that we don't overflow blitter hw limits here. > + u32 offset = i915_gem_obj_ggtt_offset(obj); > + int ret; > + > +#define COLOR_BLIT_OP ((0x2 << 29) | (0x40 << 22) | (0x3 << 20) | 0x3) > +#define COLOR_BLIT_OP_DW1 ((0x3 << 24) | (0xF0 << 16) | (obj->stride)) > +#define COLOR_BLIT_OP_DW2 ((obj_height << 16) | (obj->stride)) > +#define COLOR_BLIT_OP_DW3 (offset) > +#define COLOR_BLIT_OP_DW4 (0x0) These #defines imo don't help readability, everywhere else (kernel/userspace) we construct the cmd dwords in-line in the OUT_BATCH/intel_ring_emit calls. Also please use the existing XY_ blt cmd #defines in i915_reg.h. - Daniel > + > + ret = intel_ring_begin(ring, 6); > + if (ret) > + return ret; > + intel_ring_emit(ring, COLOR_BLIT_OP); > + intel_ring_emit(ring, COLOR_BLIT_OP_DW1); > + intel_ring_emit(ring, COLOR_BLIT_OP_DW2); > + intel_ring_emit(ring, COLOR_BLIT_OP_DW3); > + intel_ring_emit(ring, COLOR_BLIT_OP_DW4); > + intel_ring_emit(ring, MI_NOOP); > + intel_ring_advance(ring); > + > + return 0; > +} > + > +static int i915_memset_stolen_obj_hw(struct drm_i915_gem_object *obj) > +{ > + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; > + struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; > + unsigned alignment = 0; > + bool map_and_fenceable = true; > + bool nonblocking = false; > + u32 seqno; > + int ret; > + > + ret = i915_gem_obj_ggtt_pin(obj, alignment, map_and_fenceable, > + nonblocking); > + if (ret) { > + DRM_ERROR("Mapping of User FB to GTT failed\n"); > + return ret; > + } > + > + /* Adding commands to the blitter ring to > + * clear out the contents of the buffer object > + */ > + ret = i915_add_clear_obj_cmd(obj); > + if (ret) { > + DRM_ERROR("couldn't add commands in blitter ring\n"); > + i915_gem_object_ggtt_unpin(obj); > + return ret; > + } > + > + seqno = intel_ring_get_seqno(ring); > + > + /* Object now in render domain */ > + obj->base.read_domains = I915_GEM_DOMAIN_RENDER; > + obj->base.write_domain = I915_GEM_DOMAIN_RENDER; > + > + i915_vma_move_to_active(i915_gem_obj_to_ggtt(obj), ring); > + > + obj->dirty = 1; > + obj->last_write_seqno = seqno; > + > + /* Unconditionally force add_request to emit a full flush. */ > + ring->gpu_caches_dirty = true; > + > + /* Add a breadcrumb for the completion of the clear request */ > + (void)i915_add_request(ring, NULL); > + > + i915_gem_object_ggtt_unpin(obj); > + > + return 0; > +} > + > +static void i915_memset_stolen_obj_sw(struct drm_i915_gem_object *obj) > { > int ret; > char __iomem *base; > @@ -490,9 +567,13 @@ i915_gem_object_move_to_stolen(struct drm_i915_gem_object *obj) > obj->cache_level = HAS_LLC(dev) ? I915_CACHE_LLC : I915_CACHE_NONE; > > /* Zero-out the contents of the stolen object, otherwise we observe > - * corruptions in the display. > + * corruptions in the display. First try using the blitter engine > + * to clear the buffer contents > */ > - i915_memset_stolen_obj(obj); > + ret = i915_memset_stolen_obj_hw(obj); > + /* fallback to Sw based memset if Hw memset fails */ > + if (ret) > + i915_memset_stolen_obj_sw(obj); > return; > > cleanup: > -- > 1.8.5.2 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Daniel Vetter Software Engineer, Intel Corporation +41 (0) 79 365 57 48 - http://blog.ffwll.ch _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx