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