Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e510a8e authored by Chris Wilson's avatar Chris Wilson
Browse files

drm/i915: Repack fence tiling mode and stride into a single integer



In the previous commit, we moved the obj->tiling_mode out of a bitfield
and into its own integer so that we could safely use READ_ONCE(). Let us
now repair some of that damage by sharing the tiling_mode with its
companion, the fence stride.

v2: New magic

Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1470388464-28458-18-git-send-email-chris@chris-wilson.co.uk
parent deeb1519
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ static char get_pin_flag(struct drm_i915_gem_object *obj)

static char get_tiling_flag(struct drm_i915_gem_object *obj)
{
	switch (obj->tiling_mode) {
	switch (i915_gem_object_get_tiling(obj)) {
	default:
	case I915_TILING_NONE: return ' ';
	case I915_TILING_X: return 'X';
+23 −7
Original line number Diff line number Diff line
@@ -2214,13 +2214,11 @@ struct drm_i915_gem_object {

	atomic_t frontbuffer_bits;

	/**
	 * Current tiling mode for the object.
	 */
	unsigned int tiling_mode;

	/** Current tiling stride for the object, if it's tiled. */
	uint32_t stride;
	unsigned int tiling_and_stride;
#define FENCE_MINIMUM_STRIDE 128 /* See i915_tiling_ok() */
#define TILING_MASK (FENCE_MINIMUM_STRIDE-1)
#define STRIDE_MASK (~TILING_MASK)

	unsigned int has_wc_mmap;
	/** Count of VMA actually bound by this object */
@@ -2359,6 +2357,24 @@ i915_gem_object_has_active_engine(const struct drm_i915_gem_object *obj,
	return obj->flags & BIT(engine + I915_BO_ACTIVE_SHIFT);
}

static inline unsigned int
i915_gem_object_get_tiling(struct drm_i915_gem_object *obj)
{
	return obj->tiling_and_stride & TILING_MASK;
}

static inline bool
i915_gem_object_is_tiled(struct drm_i915_gem_object *obj)
{
	return i915_gem_object_get_tiling(obj) != I915_TILING_NONE;
}

static inline unsigned int
i915_gem_object_get_stride(struct drm_i915_gem_object *obj)
{
	return obj->tiling_and_stride & STRIDE_MASK;
}

/*
 * Optimised SGL iterator for GEM objects
 */
@@ -3457,7 +3473,7 @@ static inline bool i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_objec
	struct drm_i915_private *dev_priv = to_i915(obj->base.dev);

	return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 &&
		obj->tiling_mode != I915_TILING_NONE;
		i915_gem_object_is_tiled(obj);
}

/* i915_debugfs.c */
+11 −9
Original line number Diff line number Diff line
@@ -1042,7 +1042,7 @@ i915_gem_gtt_pwrite_fast(struct drm_i915_private *i915,
	int ret;
	bool hit_slow_path = false;

	if (obj->tiling_mode != I915_TILING_NONE)
	if (i915_gem_object_is_tiled(obj))
		return -EFAULT;

	ret = i915_gem_object_ggtt_pin(obj, NULL, 0, 0,
@@ -1671,7 +1671,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)

	/* Use a partial view if the object is bigger than the aperture. */
	if (obj->base.size >= ggtt->mappable_end &&
	    obj->tiling_mode == I915_TILING_NONE) {
	    !i915_gem_object_is_tiled(obj)) {
		static const unsigned int chunk_size = 256; // 1 MiB

		memset(&view, 0, sizeof(view));
@@ -2189,7 +2189,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
	if (i915_gem_object_needs_bit17_swizzle(obj))
		i915_gem_object_do_bit_17_swizzle(obj);

	if (obj->tiling_mode != I915_TILING_NONE &&
	if (i915_gem_object_is_tiled(obj) &&
	    dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES)
		i915_gem_object_pin_pages(obj);

@@ -2938,10 +2938,12 @@ i915_vma_insert(struct i915_vma *vma, u64 size, u64 alignment, u64 flags)

	size = max(size, vma->size);
	if (flags & PIN_MAPPABLE)
		size = i915_gem_get_ggtt_size(dev_priv, size, obj->tiling_mode);
		size = i915_gem_get_ggtt_size(dev_priv, size,
					      i915_gem_object_get_tiling(obj));

	min_alignment =
		i915_gem_get_ggtt_alignment(dev_priv, size, obj->tiling_mode,
		i915_gem_get_ggtt_alignment(dev_priv, size,
					    i915_gem_object_get_tiling(obj),
					    flags & PIN_MAPPABLE);
	if (alignment == 0)
		alignment = min_alignment;
@@ -3637,10 +3639,10 @@ void __i915_vma_set_map_and_fenceable(struct i915_vma *vma)

	fence_size = i915_gem_get_ggtt_size(dev_priv,
					    obj->base.size,
					    obj->tiling_mode);
					    i915_gem_object_get_tiling(obj));
	fence_alignment = i915_gem_get_ggtt_alignment(dev_priv,
						      obj->base.size,
						      obj->tiling_mode,
						      i915_gem_object_get_tiling(obj),
						      true);

	fenceable = (vma->node.size == fence_size &&
@@ -3884,7 +3886,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
	}

	if (obj->pages &&
	    obj->tiling_mode != I915_TILING_NONE &&
	    i915_gem_object_is_tiled(obj) &&
	    dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES) {
		if (obj->madv == I915_MADV_WILLNEED)
			i915_gem_object_unpin_pages(obj);
@@ -4054,7 +4056,7 @@ void i915_gem_free_object(struct drm_gem_object *gem_obj)

	if (obj->pages && obj->madv == I915_MADV_WILLNEED &&
	    dev_priv->quirks & QUIRK_PIN_SWIZZLED_PAGES &&
	    obj->tiling_mode != I915_TILING_NONE)
	    i915_gem_object_is_tiled(obj))
		i915_gem_object_unpin_pages(obj);

	if (WARN_ON(obj->pages_pin_count))
+1 −1
Original line number Diff line number Diff line
@@ -803,7 +803,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *engine,
			entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE;
		need_fence =
			entry->flags & EXEC_OBJECT_NEEDS_FENCE &&
			obj->tiling_mode != I915_TILING_NONE;
			i915_gem_object_is_tiled(obj);
		need_mappable = need_fence || need_reloc_mappable(vma);

		if (entry->flags & EXEC_OBJECT_PINNED)
+24 −15
Original line number Diff line number Diff line
@@ -86,20 +86,22 @@ static void i965_write_fence_reg(struct drm_device *dev, int reg,

	if (obj) {
		u32 size = i915_gem_obj_ggtt_size(obj);
		unsigned int tiling = i915_gem_object_get_tiling(obj);
		unsigned int stride = i915_gem_object_get_stride(obj);
		uint64_t val;

		/* Adjust fence size to match tiled area */
		if (obj->tiling_mode != I915_TILING_NONE) {
			uint32_t row_size = obj->stride *
				(obj->tiling_mode == I915_TILING_Y ? 32 : 8);
		if (tiling != I915_TILING_NONE) {
			uint32_t row_size = stride *
				(tiling == I915_TILING_Y ? 32 : 8);
			size = (size / row_size) * row_size;
		}

		val = (uint64_t)((i915_gem_obj_ggtt_offset(obj) + size - 4096) &
				 0xfffff000) << 32;
		val |= i915_gem_obj_ggtt_offset(obj) & 0xfffff000;
		val |= (uint64_t)((obj->stride / 128) - 1) << fence_pitch_shift;
		if (obj->tiling_mode == I915_TILING_Y)
		val |= (uint64_t)((stride / 128) - 1) << fence_pitch_shift;
		if (tiling == I915_TILING_Y)
			val |= 1 << I965_FENCE_TILING_Y_SHIFT;
		val |= I965_FENCE_REG_VALID;

@@ -122,6 +124,8 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg,

	if (obj) {
		u32 size = i915_gem_obj_ggtt_size(obj);
		unsigned int tiling = i915_gem_object_get_tiling(obj);
		unsigned int stride = i915_gem_object_get_stride(obj);
		int pitch_val;
		int tile_width;

@@ -131,17 +135,17 @@ static void i915_write_fence_reg(struct drm_device *dev, int reg,
		     "object 0x%08llx [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n",
		     i915_gem_obj_ggtt_offset(obj), obj->map_and_fenceable, size);

		if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
		if (tiling == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
			tile_width = 128;
		else
			tile_width = 512;

		/* Note: pitch better be a power of two tile widths */
		pitch_val = obj->stride / tile_width;
		pitch_val = stride / tile_width;
		pitch_val = ffs(pitch_val) - 1;

		val = i915_gem_obj_ggtt_offset(obj);
		if (obj->tiling_mode == I915_TILING_Y)
		if (tiling == I915_TILING_Y)
			val |= 1 << I830_FENCE_TILING_Y_SHIFT;
		val |= I915_FENCE_SIZE_BITS(size);
		val |= pitch_val << I830_FENCE_PITCH_SHIFT;
@@ -161,6 +165,8 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg,

	if (obj) {
		u32 size = i915_gem_obj_ggtt_size(obj);
		unsigned int tiling = i915_gem_object_get_tiling(obj);
		unsigned int stride = i915_gem_object_get_stride(obj);
		uint32_t pitch_val;

		WARN((i915_gem_obj_ggtt_offset(obj) & ~I830_FENCE_START_MASK) ||
@@ -169,11 +175,11 @@ static void i830_write_fence_reg(struct drm_device *dev, int reg,
		     "object 0x%08llx not 512K or pot-size 0x%08x aligned\n",
		     i915_gem_obj_ggtt_offset(obj), size);

		pitch_val = obj->stride / 128;
		pitch_val = stride / 128;
		pitch_val = ffs(pitch_val) - 1;

		val = i915_gem_obj_ggtt_offset(obj);
		if (obj->tiling_mode == I915_TILING_Y)
		if (tiling == I915_TILING_Y)
			val |= 1 << I830_FENCE_TILING_Y_SHIFT;
		val |= I830_FENCE_SIZE_BITS(size);
		val |= pitch_val << I830_FENCE_PITCH_SHIFT;
@@ -201,9 +207,12 @@ static void i915_gem_write_fence(struct drm_device *dev, int reg,
	if (i915_gem_object_needs_mb(dev_priv->fence_regs[reg].obj))
		mb();

	WARN(obj && (!obj->stride || !obj->tiling_mode),
	WARN(obj &&
	     (!i915_gem_object_get_stride(obj) ||
	      !i915_gem_object_get_tiling(obj)),
	     "bogus fence setup with stride: 0x%x, tiling mode: %i\n",
	     obj->stride, obj->tiling_mode);
	     i915_gem_object_get_stride(obj),
	     i915_gem_object_get_tiling(obj));

	if (IS_GEN2(dev))
		i830_write_fence_reg(dev, reg, obj);
@@ -248,7 +257,7 @@ static void i915_gem_object_update_fence(struct drm_i915_gem_object *obj,

static inline void i915_gem_object_fence_lost(struct drm_i915_gem_object *obj)
{
	if (obj->tiling_mode)
	if (i915_gem_object_is_tiled(obj))
		i915_gem_release_mmap(obj);

	/* As we do not have an associated fence register, we will force
@@ -361,7 +370,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
{
	struct drm_device *dev = obj->base.dev;
	struct drm_i915_private *dev_priv = to_i915(dev);
	bool enable = obj->tiling_mode != I915_TILING_NONE;
	bool enable = i915_gem_object_is_tiled(obj);
	struct drm_i915_fence_reg *reg;
	int ret;

@@ -477,7 +486,7 @@ void i915_gem_restore_fences(struct drm_device *dev)
		 */
		if (reg->obj) {
			i915_gem_object_update_fence(reg->obj, reg,
						     reg->obj->tiling_mode);
						     i915_gem_object_get_tiling(reg->obj));
		} else {
			i915_gem_write_fence(dev, i, NULL);
		}
Loading