[PATCH] drm/i915: swizzling support for snb/ivb

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Feb 04, 2012 at 09:59:57PM +0100, Eric Anholt wrote:
> On Thu,  2 Feb 2012 09:58:12 +0100, Daniel Vetter <daniel.vetter at ffwll.ch> wrote:
> > We have to do this manually. Somebody had a Great Idea.
> > 
> > I've measured speed-ups just a few percent above the noise level
> > (below 5% for the best case), but no slowdows. Chris Wilson measured
> > quite a bit more (10-20% above the usual snb variance) on a more
> > recent and better tuned version of sna, but also recorded a few
> > slow-downs on benchmarks know for uglier amounts of snb-induced
> > variance.
> 
> 
> > diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
> > index 51a2b0c..86fffd2 100644
> > --- a/drivers/gpu/drm/i915/i915_gem.c
> > +++ b/drivers/gpu/drm/i915/i915_gem.c
> > @@ -3681,12 +3681,31 @@ i915_gem_idle(struct drm_device *dev)
> >  	return 0;
> >  }
> >  
> > +void i915_gem_init_swizzling(struct drm_device *dev)
> > +{
> > +	drm_i915_private_t *dev_priv = dev->dev_private;
> > +
> > +	if (INTEL_INFO(dev)->gen < 6 ||
> > +	    dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_NONE)
> > +		return;
> > +
> > +	I915_WRITE(DISP_ARB_CTL, I915_READ(DISP_ARB_CTL) |
> > +				 DISP_TILE_SURFACE_SWIZZLING);
> > +
> > +	I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_SWZCTL);
> > +	if (IS_GEN6(dev))
> > +		I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_SNB));
> > +	else
> > +		I915_WRITE(ARB_MODE, ARB_MODE_ENABLE(ARB_MODE_SWIZZLE_IVB));
> > +}
> 
> > diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
> > index 861223b..1a93066 100644
> > --- a/drivers/gpu/drm/i915/i915_gem_tiling.c
> > +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
> > @@ -93,8 +93,23 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
> >  	uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
> >  
> >  	if (INTEL_INFO(dev)->gen >= 6) {
> > -		swizzle_x = I915_BIT_6_SWIZZLE_NONE;
> > -		swizzle_y = I915_BIT_6_SWIZZLE_NONE;
> > +		uint32_t dimm_c0, dimm_c1;
> > +		dimm_c0 = I915_READ(MAD_DIMM_C0);
> > +		dimm_c1 = I915_READ(MAD_DIMM_C1);
> > +		dimm_c0 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
> > +		dimm_c1 &= MAD_DIMM_A_SIZE_MASK | MAD_DIMM_B_SIZE_MASK;
> > +		/* Enable swizzling when the channels are populated with
> > +		 * identically sized dimms. We don't need to check the 3rd
> > +		 * channel because no cpu with gpu attached ships in that
> > +		 * configuration. Also, swizzling only makes sense for 2
> > +		 * channels anyway. */
> > +		if (dimm_c0 == dimm_c1) {
> > +			swizzle_x = I915_BIT_6_SWIZZLE_9_10;
> > +			swizzle_y = I915_BIT_6_SWIZZLE_9;
> > +		} else {
> > +			swizzle_x = I915_BIT_6_SWIZZLE_NONE;
> > +			swizzle_y = I915_BIT_6_SWIZZLE_NONE;
> > +		}
> 
> It looks to me like you're making the HW always swizzle bit 6 according
> to 9 or 9/10 in i915_gem_init_swizzling, but you're not performing the
> software side of swizzling in the !dual channel case.  My guess would be
> that when you take your other DIMM the swizzling for pread/pwrite/swap
> goes wrong, and that the answer would be to just not look at dimm sizes.

Hm, I'm a bit confused here ... So let me explain how swizzling on gen6+
works with this patch:

In the reset/bootup state the gpu doesn't do any additional swizzling for
tiled surfaces. You have to explicitly frob the 3 registers for gt, cpu
gtt window and scanout. I presume the gpu is pretty oblivious to what the
memory controller does and swizzling could also be enabled on
single-channel or L-shaped layouts (iirc I haven't tried that though).

Now the patch just detects whether we have symmetrically populated
channels and sets the swizzle stuff accordingly. i915_gem_init_swizzling
gets called at init, gpu reset and resume time and the programms the hw
bits accordingly to the swizzling we want. So
i915_gem_detect_bit_6_swizzle is a bit a mistdenomer on gen6+, but I've
thought it fits in better this way with the existing code-flow.

It's been quite a while since I've stitched this together but iirc I've
tested all the different possibilities by yanking dimms (safe for the 2
dimms per channel case, my laptop doesn't have enough slots for that). And
we have a set of testcase in i-g-t that should test pread/pwrite and
swapping, so I'm positive that we should catch any issues with this
easily.

> Other than that, looks reasonable to me.  Might make it clear what's
> going on in the commit message -- "swizzling support for snb/ivb" made
> me think you were fixing up the software side of bit 6 swizzling, when
> it looks like you're actually enabling bit 6 swizzling for the first
> time.

Yeah, I'll improve the commit message to be a bit less terse and explain
what's actually going on.

Thanks, Daniel
-- 
Daniel Vetter
Mail: daniel at ffwll.ch
Mobile: +41 (0)79 365 57 48


[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux