NetBSD-Bugs archive

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

Re: port-amd64/57143: Screen rotation causes loss of acceleration on i915



The following reply was made to PR port-amd64/57143; it has been noted by GNATS.

From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
To: mayuresh%acm.org@localhost
Cc: gnats-bugs%NetBSD.org@localhost
Subject: Re: port-amd64/57143: Screen rotation causes loss of acceleration on i915
Date: Sun, 9 Jul 2023 22:28:04 +0000

 This is a multi-part message in MIME format.
 --=_iH22Mq8cEGadrlwrn55fhppMX7+AHtfW
 
 Can you please try with the attached patch on top of a current kernel
 and see if it still reproduces?
 
 --=_iH22Mq8cEGadrlwrn55fhppMX7+AHtfW
 Content-Type: text/plain; charset="ISO-8859-1"; name="i915rotateremap"
 Content-Transfer-Encoding: quoted-printable
 Content-Disposition: attachment; filename="i915rotateremap.patch"
 
 From cdc07f918cec0d2bed86f0ac8d2c1848e9f9dceb Mon Sep 17 00:00:00 2001
 From: Taylor R Campbell <riastradh%NetBSD.org@localhost>
 Date: Sun, 9 Jul 2023 22:00:18 +0000
 Subject: [PATCH] WIP: i915: Implement rotate and remap views.
 
 ---
  .../bsd/drm2/dist/drm/i915/gt/intel_ggtt.c    | 186 ++++++++++++------
  1 file changed, 126 insertions(+), 60 deletions(-)
 
 diff --git a/sys/external/bsd/drm2/dist/drm/i915/gt/intel_ggtt.c b/sys/exte=
 rnal/bsd/drm2/dist/drm/i915/gt/intel_ggtt.c
 index 4da9f00317c4..044d632a80cb 100644
 --- a/sys/external/bsd/drm2/dist/drm/i915/gt/intel_ggtt.c
 +++ b/sys/external/bsd/drm2/dist/drm/i915/gt/intel_ggtt.c
 @@ -1433,7 +1433,30 @@ void i915_gem_restore_gtt_mappings(struct drm_i915_p=
 rivate *i915)
  		setup_private_pat(ggtt->vm.gt->uncore);
  }
 =20
 -#ifndef __NetBSD__
 +#ifdef __NetBSD__
 +static int
 +ensure_view_dmamap(struct drm_i915_gem_object *obj, struct sg_table *st)
 +{
 +	int ret;
 +
 +	/* XXX KASSERT?  */
 +	if (obj->mm.pages->sgl->sg_dmamap =3D=3D NULL)
 +		return 0;
 +
 +	/* XXX errno NetBSD->Linux */
 +	ret =3D -bus_dmamap_create(obj->base.dev->dmat,
 +	    (bus_size_t)st->nents << PAGE_SHIFT,
 +	    st->nents, PAGE_SIZE, 0, BUS_DMA_NOWAIT,
 +	    &st->sgl->sg_dmamap);
 +	if (ret) {
 +		st->sgl->sg_dmamap =3D NULL;
 +		return ret;
 +	}
 +
 +	st->sgl->sg_dmat =3D obj->base.dev->dmat;
 +	return 0;
 +}
 +#endif
 =20
  static struct scatterlist *
  rotate_pages(struct drm_i915_gem_object *obj, unsigned int offset,
 @@ -1447,18 +1470,43 @@ rotate_pages(struct drm_i915_gem_object *obj, unsig=
 ned int offset,
  	for (column =3D 0; column < width; column++) {
  		src_idx =3D stride * (height - 1) + column + offset;
  		for (row =3D 0; row < height; row++) {
 +#ifdef __NetBSD__
 +			/*
 +			 * XXX Do we need to handle >1-page segments
 +			 * here?
 +			 */
 +			CTASSERT(PAGE_SIZE =3D=3D I915_GTT_PAGE_SIZE);
 +			KASSERTMSG(src_idx <=3D obj->mm.pages->sgl->sg_npgs,
 +			    "src_idx=3D%u npgs=3D%u",
 +			    src_idx, obj->mm.pages->sgl->sg_npgs);
 +			sg->sg_pgs[st->nents] =3D
 +			    obj->mm.pages->sgl->sg_pgs[src_idx / PAGE_SIZE];
 +			if (obj->mm.pages->sgl->sg_dmamap) {
 +				bus_dmamap_t m =3D obj->mm.pages->sgl->sg_dmamap;
 +
 +				KASSERTMSG(src_idx <=3D m->dm_nsegs,
 +				    "src_idx=3D%u dm_nsegs=3D%d",
 +				    src_idx, m->dm_nsegs);
 +				sg->sg_dmamap->dm_segs[st->nents].ds_addr =3D
 +				    m->dm_segs[src_idx / PAGE_SIZE].ds_addr;
 +				sg->sg_dmamap->dm_segs[st->nents].ds_len =3D
 +				    PAGE_SIZE;
 +			}
 +#endif
  			st->nents++;
  			/*
  			 * We don't need the pages, but need to initialize
  			 * the entries so the sg list can be happily traversed.
  			 * The only thing we need are DMA addresses.
  			 */
 +#ifndef __NetBSD__
  			sg_set_page(sg, NULL, I915_GTT_PAGE_SIZE, 0);
  			sg_dma_address(sg) =3D
  				i915_gem_object_get_dma_address(obj, src_idx);
  			sg_dma_len(sg) =3D I915_GTT_PAGE_SIZE;
  			sg =3D sg_next(sg);
  			src_idx -=3D stride;
 +#endif
  		}
  	}
 =20
 @@ -1484,6 +1532,14 @@ intel_rotate_pages(struct intel_rotation_info *rot_i=
 nfo,
  	if (ret)
  		goto err_sg_alloc;
 =20
 +#ifdef __NetBSD__
 +	ret =3D ensure_view_dmamap(obj, st);
 +	if (ret) {
 +		sg_free_table(st);
 +		goto err_sg_alloc;
 +	}
 +#endif
 +
  	st->nents =3D 0;
  	sg =3D st->sgl;
 =20
 @@ -1493,6 +1549,10 @@ intel_rotate_pages(struct intel_rotation_info *rot_i=
 nfo,
  				  rot_info->plane[i].stride, st, sg);
  	}
 =20
 +#ifdef __NetBSD__
 +	KASSERTMSG(st->nents =3D=3D size, "nents=3D%u size=3D%u", st->nents, size=
 );
 +#endif
 +
  	return st;
 =20
  err_sg_alloc:
 @@ -1513,6 +1573,7 @@ remap_pages(struct drm_i915_gem_object *obj, unsigned=
  int offset,
  {
  	unsigned int row;
 =20
 +	/* height pages */
  	for (row =3D 0; row < height; row++) {
  		unsigned int left =3D width * I915_GTT_PAGE_SIZE;
 =20
 @@ -1530,12 +1591,38 @@ remap_pages(struct drm_i915_gem_object *obj, unsign=
 ed int offset,
 =20
  			length =3D min(left, length);
 =20
 +#ifdef __NetBSD__
 +			/*
 +			 * XXX Do we need to handle >1-page segments
 +			 * here?
 +			 */
 +			KASSERTMSG(length <=3D PAGE_SIZE, "length=3D%u", length);
 +			KASSERTMSG(offset <=3D obj->mm.pages->sgl->sg_npgs,
 +			    "offset=3D%u npgs=3D%u",
 +			    offset, obj->mm.pages->sgl->sg_npgs);
 +			sg->sg_pgs[st->nents] =3D
 +			    obj->mm.pages->sgl->sg_pgs[offset / PAGE_SIZE];
 +			if (obj->mm.pages->sgl->sg_dmamap) {
 +				bus_dmamap_t m =3D obj->mm.pages->sgl->sg_dmamap;
 +
 +				KASSERTMSG(offset <=3D m->dm_nsegs,
 +				    "offset=3D%u dm_nsegs=3D%d",
 +				    offset, m->dm_nsegs);
 +				sg->sg_dmamap->dm_segs[st->nents].ds_addr =3D
 +				    addr;
 +				sg->sg_dmamap->dm_segs[st->nents].ds_len =3D
 +				    length;
 +			}
 +#endif
 +
  			st->nents++;
 =20
 +#ifndef __NetBSD__
  			sg_set_page(sg, NULL, length, 0);
  			sg_dma_address(sg) =3D addr;
  			sg_dma_len(sg) =3D length;
  			sg =3D sg_next(sg);
 +#endif
 =20
  			offset +=3D length / I915_GTT_PAGE_SIZE;
  			left -=3D length;
 @@ -1566,6 +1653,14 @@ intel_remap_pages(struct intel_remapped_info *rem_in=
 fo,
  	if (ret)
  		goto err_sg_alloc;
 =20
 +#ifdef __NetBSD__
 +	ret =3D ensure_view_dmamap(obj, st);
 +	if (ret) {
 +		sg_free_table(st);
 +		goto err_sg_alloc;
 +	}
 +#endif
 +
  	st->nents =3D 0;
  	sg =3D st->sgl;
 =20
 @@ -1575,6 +1670,10 @@ intel_remap_pages(struct intel_remapped_info *rem_in=
 fo,
  				 rem_info->plane[i].stride, st, sg);
  	}
 =20
 +#ifdef __NetBSD__
 +	KASSERTMSG(st->nents =3D=3D size, "nents=3D%u size=3D%u", st->nents, size=
 );
 +#endif
 +
  	i915_sg_trim(st);
 =20
  	return st;
 @@ -1589,15 +1688,36 @@ err_st_alloc:
  	return ERR_PTR(ret);
  }
 =20
 -#endif	/* __NetBSD__ */
 -
  static noinline struct sg_table *
  intel_partial_pages(const struct i915_ggtt_view *view,
  		    struct drm_i915_gem_object *obj)
  {
 +	struct sg_table *st;
 +	struct scatterlist *sg, *iter;
 +	unsigned int count =3D view->partial.size;
 +	unsigned int offset;
 +	int ret;
 +
 +	st =3D kmalloc(sizeof(*st), GFP_KERNEL);
 +	if (!st) {
 +		ret =3D -ENOMEM;
 +		goto err_st_alloc;
 +	}
 +
 +	ret =3D sg_alloc_table(st, count, GFP_KERNEL);
 +	if (ret)
 +		goto err_sg_alloc;
 +
  #ifdef __NetBSD__
 -	struct sg_table *st =3D NULL;
 -	int ret =3D -ENOMEM;
 +	__USE(sg);
 +	__USE(iter);
 +	__USE(offset);
 +
 +	ret =3D ensure_view_dmamap(obj, st);
 +	if (ret) {
 +		sg_free_table(st);
 +		goto err_sg_alloc;
 +	}
 =20
  	KASSERTMSG(view->partial.offset <=3D obj->base.size >> PAGE_SHIFT,
  	    "obj=3D%p size=3D0x%zx; view offset=3D0x%zx size=3D0x%zx",
 @@ -1615,29 +1735,6 @@ intel_partial_pages(const struct i915_ggtt_view *vie=
 w,
  	KASSERTMSG(view->partial.size <=3D INT_MAX, "view size=3D0x%zx",
  	    (size_t)view->partial.size);
 =20
 -	st =3D kmalloc(sizeof(*st), GFP_KERNEL);
 -	if (st =3D=3D NULL)
 -		goto fail;
 -	ret =3D sg_alloc_table(st, view->partial.size, GFP_KERNEL);
 -	if (ret) {
 -		kfree(st);
 -		st =3D NULL;
 -		goto fail;
 -	}
 -
 -	/* XXX errno NetBSD->Linux */
 -	if (obj->mm.pages->sgl->sg_dmamap) { /* XXX KASSERT?  */
 -		ret =3D -bus_dmamap_create(obj->base.dev->dmat,
 -		    (bus_size_t)view->partial.size << PAGE_SHIFT,
 -		    view->partial.size, PAGE_SIZE, 0, BUS_DMA_NOWAIT,
 -		    &st->sgl->sg_dmamap);
 -		if (ret) {
 -			st->sgl->sg_dmamap =3D NULL;
 -			goto fail;
 -		}
 -		st->sgl->sg_dmat =3D obj->base.dev->dmat;
 -	}
 -
  	/*
  	 * Copy over the pages.  The view's offset and size are in
  	 * units of pages already.
 @@ -1690,31 +1787,8 @@ intel_partial_pages(const struct i915_ggtt_view *vie=
 w,
  		}
  	}
 =20
 -	/* Success!  */
  	return st;
 -
 -fail:	if (st) {
 -		sg_free_table(st);
 -		kfree(st);
 -	}
 -	return ERR_PTR(ret);
  #else
 -	struct sg_table *st;
 -	struct scatterlist *sg, *iter;
 -	unsigned int count =3D view->partial.size;
 -	unsigned int offset;
 -	int ret;
 -
 -	st =3D kmalloc(sizeof(*st), GFP_KERNEL);
 -	if (!st) {
 -		ret =3D -ENOMEM;
 -		goto err_st_alloc;
 -	}
 -
 -	ret =3D sg_alloc_table(st, count, GFP_KERNEL);
 -	if (ret)
 -		goto err_sg_alloc;
 -
  	iter =3D i915_gem_object_get_sg(obj, view->partial.offset, &offset);
  	GEM_BUG_ON(!iter);
 =20
 @@ -1743,12 +1817,12 @@ fail:	if (st) {
  		iter =3D __sg_next(iter);
  		offset =3D 0;
  	} while (1);
 +#endif
 =20
  err_sg_alloc:
  	kfree(st);
  err_st_alloc:
  	return ERR_PTR(ret);
 -#endif	/* __NetBSD__ */
  }
 =20
  static int
 @@ -1773,21 +1847,13 @@ i915_get_ggtt_vma_pages(struct i915_vma *vma)
  		return 0;
 =20
  	case I915_GGTT_VIEW_ROTATED:
 -#ifdef __NetBSD__
 -		vma->pages =3D ERR_PTR(-ENODEV);
 -#else
  		vma->pages =3D
  			intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
 -#endif
  		break;
 =20
  	case I915_GGTT_VIEW_REMAPPED:
 -#ifdef __NetBSD__
 -		vma->pages =3D ERR_PTR(-ENODEV);
 -#else
  		vma->pages =3D
  			intel_remap_pages(&vma->ggtt_view.remapped, vma->obj);
 -#endif
  		break;
 =20
  	case I915_GGTT_VIEW_PARTIAL:
 
 --=_iH22Mq8cEGadrlwrn55fhppMX7+AHtfW--
 


Home | Main Index | Thread Index | Old Index