On Thu, Mar 07, 2019 at 08:19:28AM +0000, Mikolaj Kucharski wrote:
> Hi Matthieu,
>
> On Tue, Feb 05, 2019 at 08:13:44AM +0100, Matthieu Herrb wrote:
> > On Mon, Feb 04, 2019 at 07:08:25PM +0000, Mikolaj Kucharski wrote:
> > > Hi,
> > >
> > > Sorry for missing subject line in my initial report. I tested git
> > > checkout of commit c37c7ee0748ba828ec5d2c7304cd2a17af2c8109 of
> > > xf86-video-intel driver from:
> > >
> > > https://gitlab.freedesktop.org/xorg/driver/xf86-video-intel.git
> > >
> > > and it seems to work for me on Huawei MateBook X and the crash reported
> > > below is gone.
> > >
> > > From what I can see, there are rare releases of xf86-video-intel driver,
> > > so would be possible to import to Xenocara git snapshot of the driver, if
> > > there is no recent code release?
> >
> > Last time I tried there were a number of regression on some older
> > hardware. If you can identify which commit is fixing the crash, I
> > would be happy to check if it can be back-ported.
>
> I spent some time git-bisect'ing the above mentioned repo and my tests
> show that commit e3edf2948467ad989590a347ffe687780192be16 is the very
> first commit which fixes the Xorg crash for me. I was bisecting between
It seems I'm off by one in terms of commits in the git repo history.
It's the next commit after above which makes the crash go away:
9fb399aee99ad98996f872477c133f08795ec54c
> 692c14d405bb352697b67f36a034d4963e272b66 (2.99.916) and master at the
> time 6afed33b2d673d88674f0c76efe500ae414e8e1b.
>
> There are number of commits between what I think is in base for Xenocara
> intel driver source code (692c14d405bb352697b67f36a034d4963e272b66) and
> working driver:
>
> $ git rev-list
> 692c14d405bb352697b67f36a034d4963e272b66..e3edf2948467ad989590a347ffe687780192be16
> | wc -l
> 15
Per above off by one, it's 16 commits.
> In that range of commits there are multiple commits which reference bug
> report https://bugs.freedesktop.org/show_bug.cgi?id=77074 so I don't
> think backport is going to be a single commit. I didn't look into cherry
> picking some of the commits from above range, but I want to try that.
> However, before going that route, is this really good direction?
So I've looked into it and I have following list of patches, which I've
applied to xenocara/driver/xf86-video-intel (names have the commit id):
0001_30932a7b9d25_sna__Avoid_u16_underflow_when_comput.patch
0002_e0f7e9fc2f0b_sna__Initialise_and_check_for_batch_.patch
0003_faf0bdd477b9_sna__Add_some_DBG_spam_for_BLT_boxes.patch
0008_9b25eeee85d3_sna__Do_apply_damage_twice_for_miSpa.patch
0012_797369449b87_sna__Do_not_mark_the_pixmap_as_clear.patch
0016_9fb399aee99a_sna_blt__Fix_computation_of_remainai.patch
I think above is the minimal set of changes against OpenBSD's Xenocara
source code to make the crash which I'm facing go away. At the end of
this email I have `cvs -q diff -uN` output.
To explicitly list commit IDs of above changes:
$ grep -he ^commit 00{01,02,03,08,12,16}_*.patch
commit 30932a7b9d255c2037bee19e01aa3edc37b07386
commit e0f7e9fc2f0b39b9e939ff48edea29950f125420
commit faf0bdd477b9ec73f943c3101a3ae30fd6d579ea
commit 9b25eeee85d32223841640c3a39901e4b63707ce
commit 797369449b87cbd578f9fb96f34b065e548755f6
commit 9fb399aee99ad98996f872477c133f08795ec54c
As some commits depend on each other, order of applying is important.
> Matthieu, you wrote that there were number of regressions on some older
> hardware. Is it easy to reproduce the problem? Do you have access to the
> affected hardware or do you know who has it and is willing to test it?
> I'm asking as I'm not sure is backporting multiple commits going to
> scale and what new issues may come up and what else needs to be
> addressed if there will be new problems.
>
> Anyway, I personally would prefer to focus efforts on updating the
> driver to latest commit (as of today it is
> 6afed33b2d673d88674f0c76efe500ae414e8e1b)
>
> Let me know, what do you think.
>
> > The state of the xf86-video-intel driver is sad. But everyone is
> > moving away from it to the modesettings driver. Hopefully the current
> > work on upgrading the kernel-side DRM code and the upcoming upgrade to
> > xserver 1,20.x will also improve the modesetting driver on OpenBSD, so
> > that less people will need to run the intel driver.
>
> I see. What time frame are you talking about here, when you say
> "upcoming upgrade to xserver 1,20.x"?
Index: src/sna/kgem.h
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-intel/src/sna/kgem.h,v
retrieving revision 1.4
diff -u -p -u -r1.4 kgem.h
--- src/sna/kgem.h 12 Apr 2015 19:42:06 -0000 1.4
+++ src/sna/kgem.h 7 Mar 2019 12:37:43 -0000
@@ -428,6 +428,13 @@ static inline void _kgem_set_mode(struct
kgem->mode = mode;
}
+static inline int kgem_batch_space(struct kgem *kgem)
+{
+ int rem = kgem->surface - kgem->nbatch;
+ assert(rem > 0);
+ return rem - KGEM_BATCH_RESERVED;
+}
+
static inline bool kgem_check_batch(struct kgem *kgem, int num_dwords)
{
assert(num_dwords > 0);
Index: src/sna/sna_accel.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-intel/src/sna/sna_accel.c,v
retrieving revision 1.8
diff -u -p -u -r1.8 sna_accel.c
--- src/sna/sna_accel.c 19 Nov 2017 20:16:12 -0000 1.8
+++ src/sna/sna_accel.c 7 Mar 2019 12:37:46 -0000
@@ -117,6 +117,10 @@
#define FontSetPrivate(font, idx, data) xfont2_font_set_private(font, idx,
data)
#endif
+#define IS_CLIPPED 0x2
+#define RECTILINEAR 0x4
+#define OVERWRITES 0x8
+
#if 0
static void __sna_fallback_flush(DrawablePtr d)
{
@@ -600,6 +604,7 @@ static bool sna_pixmap_free_cpu(struct s
if (priv->ptr == NULL)
return true;
+ DBG(("%s(pixmap=%ld)\n", __FUNCTION__,
priv->pixmap->drawable.serialNumber));
__sna_pixmap_free_cpu(sna, priv);
priv->cpu_bo = NULL;
@@ -3459,12 +3464,15 @@ done:
priv->cpu_damage == NULL &&
(box_covers_pixmap(pixmap, &r.extents) ||
box_inplace(pixmap, &r.extents))) {
- DBG(("%s: large operation on undamaged, promoting to
full GPU\n",
+ DBG(("%s: large operation on undamaged, discarding CPU
shadow\n",
__FUNCTION__));
assert(priv->gpu_bo);
assert(priv->gpu_bo->proxy == NULL);
- if (sna_pixmap_free_cpu(sna, priv, priv->cpu))
+ if (sna_pixmap_free_cpu(sna, priv, priv->cpu)) {
+ DBG(("%s: large operation on undamaged,
promoting to full GPU\n",
+ __FUNCTION__));
sna_damage_all(&priv->gpu_damage, pixmap);
+ }
}
if (DAMAGE_IS_ALL(priv->gpu_damage)) {
sna_pixmap_free_cpu(sna, priv, priv->cpu);
@@ -7990,7 +7998,7 @@ sna_fill_spans(DrawablePtr drawable, GCP
sna_fill_spans_blt(drawable,
bo, damage,
gc, color, n, pt, width, sorted,
- ®ion.extents, flags & 2);
+ ®ion.extents, flags & IS_CLIPPED);
} else {
/* Try converting these to a set of rectangles instead
*/
xRectangle *rect;
@@ -8013,12 +8021,12 @@ sna_fill_spans(DrawablePtr drawable, GCP
i = sna_poly_fill_rect_tiled_blt(drawable,
bo, damage,
gc, n, rect,
-
®ion.extents, flags & 2);
+
®ion.extents, flags & IS_CLIPPED);
} else {
i = sna_poly_fill_rect_stippled_blt(drawable,
bo, damage,
gc, n, rect,
-
®ion.extents, flags & 2);
+
®ion.extents, flags & IS_CLIPPED);
}
free (rect);
@@ -8881,7 +8889,7 @@ sna_poly_point(DrawablePtr drawable, GCP
if ((bo = sna_drawable_use_bo(drawable, PREFER_GPU,
®ion.extents, &damage)) &&
sna_poly_point_blt(drawable, bo, damage,
- gc, mode, n, pt, flags & 2))
+ gc, mode, n, pt, flags & IS_CLIPPED))
return;
}
@@ -9669,7 +9677,7 @@ sna_poly_line(DrawablePtr drawable, GCPt
gc->lineStyle, gc->lineStyle == LineSolid,
gc->lineWidth,
gc->planemask, PM_IS_SOLID(drawable, gc->planemask),
- data.flags & 4));
+ data.flags & RECTILINEAR));
if (!PM_IS_SOLID(drawable, gc->planemask))
goto fallback;
@@ -9697,7 +9705,7 @@ sna_poly_line(DrawablePtr drawable, GCPt
DBG(("%s: trying solid fill [%08x]\n",
__FUNCTION__, (unsigned)color));
- if (data.flags & 4) {
+ if (data.flags & RECTILINEAR) {
data.bo = sna_drawable_use_bo(drawable, PREFER_GPU,
&data.region.extents,
&data.damage);
@@ -9706,7 +9714,7 @@ sna_poly_line(DrawablePtr drawable, GCPt
data.bo, data.damage,
gc, color, mode, n, pt,
&data.region.extents,
- data.flags & 2))
+ data.flags & IS_CLIPPED))
return;
} else { /* !rectilinear */
if ((data.bo = sna_drawable_use_bo(drawable,
@@ -9717,11 +9725,11 @@ sna_poly_line(DrawablePtr drawable, GCPt
data.bo, data.damage,
gc, mode, n, pt,
&data.region.extents,
- data.flags & 2))
+ data.flags & IS_CLIPPED))
return;
}
- } else if (data.flags & 4) {
+ } else if (data.flags & RECTILINEAR) {
/* Try converting these to a set of rectangles instead */
data.bo = sna_drawable_use_bo(drawable, PREFER_GPU,
&data.region.extents,
&data.damage);
@@ -9779,13 +9787,13 @@ sna_poly_line(DrawablePtr drawable, GCPt
data.bo,
data.damage,
gc, n - 1,
rect + 1,
&data.region.extents,
- data.flags &
2);
+ data.flags &
IS_CLIPPED);
} else {
i = sna_poly_fill_rect_stippled_blt(drawable,
data.bo,
data.damage,
gc, n - 1,
rect + 1,
&data.region.extents,
- data.flags
& 2);
+ data.flags
& IS_CLIPPED);
}
free (rect);
@@ -9814,7 +9822,7 @@ spans_fallback:
data.op = &fill;
- if ((data.flags & 2) == 0) {
+ if ((data.flags & IS_CLIPPED) == 0) {
if (data.dx | data.dy)
sna_gc_ops__tmp.FillSpans =
sna_fill_spans__fill_offset;
else
@@ -9842,7 +9850,7 @@ spans_fallback:
} else {
data.op = &fill;
- if ((data.flags & 2) == 0) {
+ if ((data.flags & IS_CLIPPED) == 0) {
if (data.dx | data.dy)
sna_gc_ops__tmp.FillSpans =
sna_fill_spans__dash_offset;
else
@@ -9865,7 +9873,7 @@ spans_fallback:
DBG(("%s: miZeroLine (solid dash, clipped? %d
(complex? %d)), fg pass [%08x]\n",
__FUNCTION__,
- !!(data.flags & 2), data.flags & 2 &&
!region_is_singular(&data.region),
+ !!(data.flags & IS_CLIPPED), data.flags &
IS_CLIPPED && !region_is_singular(&data.region),
gc->fgPixel));
if (!sna_fill_init_blt(&fill,
@@ -9881,7 +9889,7 @@ spans_fallback:
DBG(("%s: miZeroLine (solid dash, clipped? %d
(complex? %d)), bg pass [%08x]\n",
__FUNCTION__,
- !!(data.flags & 2), data.flags & 2 &&
!region_is_singular(&data.region),
+ !!(data.flags & IS_CLIPPED), data.flags &
IS_CLIPPED && !region_is_singular(&data.region),
gc->bgPixel));
if (sna_fill_init_blt(&fill,
@@ -9951,7 +9959,7 @@ fallback:
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &data.region,
drawable_gc_flags(drawable, gc,
- !(data.flags & 4
&& n == 2))))
+ !(data.flags &
RECTILINEAR && n == 2))))
goto out;
if (sigtrap_get() == 0) {
@@ -10599,7 +10607,7 @@ sna_poly_segment(DrawablePtr drawable, G
gc->lineStyle, gc->lineStyle == LineSolid,
gc->lineWidth,
gc->planemask, PM_IS_SOLID(drawable, gc->planemask),
- data.flags & 4));
+ data.flags & RECTILINEAR));
if (!PM_IS_SOLID(drawable, gc->planemask))
goto fallback;
@@ -10609,7 +10617,7 @@ sna_poly_segment(DrawablePtr drawable, G
DBG(("%s: trying blt solid fill [%08x, flags=%x] paths\n",
__FUNCTION__, (unsigned)color, data.flags));
- if (data.flags & 4) {
+ if (data.flags & RECTILINEAR) {
if ((data.bo = sna_drawable_use_bo(drawable, PREFER_GPU,
&data.region.extents,
&data.damage)) &&
@@ -10617,7 +10625,7 @@ sna_poly_segment(DrawablePtr drawable, G
data.bo, data.damage,
gc, color, n, seg,
&data.region.extents,
- data.flags & 2))
+ data.flags & IS_CLIPPED))
return;
} else {
if ((data.bo = sna_drawable_use_bo(drawable,
@@ -10628,10 +10636,10 @@ sna_poly_segment(DrawablePtr drawable, G
data.bo, data.damage,
gc, n, seg,
&data.region.extents,
- data.flags & 2))
+ data.flags & IS_CLIPPED))
return;
}
- } else if (data.flags & 4) {
+ } else if (data.flags & RECTILINEAR) {
/* Try converting these to a set of rectangles instead */
xRectangle *rect;
int i;
@@ -10684,13 +10692,13 @@ sna_poly_segment(DrawablePtr drawable, G
data.bo, data.damage,
gc, n, rect,
&data.region.extents,
- data.flags & 2);
+ data.flags);
} else {
i = sna_poly_fill_rect_stippled_blt(drawable,
data.bo,
data.damage,
gc, n, rect,
&data.region.extents,
- data.flags & 2);
+ data.flags);
}
free (rect);
@@ -10741,7 +10749,7 @@ spans_fallback:
data.op = &fill;
- if ((data.flags & 2) == 0) {
+ if ((data.flags & IS_CLIPPED) == 0) {
if (data.dx | data.dy)
sna_gc_ops__tmp.FillSpans =
sna_fill_spans__fill_offset;
else
@@ -10799,7 +10807,7 @@ fallback:
goto out;
if (!sna_drawable_move_region_to_cpu(drawable, &data.region,
drawable_gc_flags(drawable, gc,
- !(data.flags & 4
&& n == 1))))
+ !(data.flags &
RECTILINEAR && n == 1))))
goto out;
if (sigtrap_get() == 0) {
@@ -11382,7 +11390,7 @@ sna_poly_rectangle(DrawablePtr drawable,
if (!PM_IS_SOLID(drawable, gc->planemask))
goto fallback;
- if (flags & 4 && gc->fillStyle == FillSolid && gc->lineStyle ==
LineSolid && gc->joinStyle == JoinMiter) {
+ if (flags & RECTILINEAR && gc->fillStyle == FillSolid && gc->lineStyle
== LineSolid && gc->joinStyle == JoinMiter) {
DBG(("%s: trying blt solid fill [%08lx] paths\n",
__FUNCTION__, gc->fgPixel));
if ((bo = sna_drawable_use_bo(drawable, PREFER_GPU,
@@ -11545,7 +11553,7 @@ sna_poly_arc(DrawablePtr drawable, GCPtr
FILL_POINTS |
FILL_SPANS))
goto fallback;
- if ((data.flags & 2) == 0) {
+ if ((data.flags & IS_CLIPPED) == 0) {
if (data.dx | data.dy)
sna_gc_ops__tmp.FillSpans =
sna_fill_spans__fill_offset;
else
@@ -11638,7 +11646,7 @@ sna_poly_fill_rect_blt(DrawablePtr drawa
GCPtr gc, uint32_t pixel,
int n, const xRectangle *rect,
const BoxRec *extents,
- bool clipped)
+ unsigned flags)
{
PixmapPtr pixmap = get_drawable_pixmap(drawable);
struct sna *sna = to_sna_from_pixmap(pixmap);
@@ -11650,7 +11658,7 @@ sna_poly_fill_rect_blt(DrawablePtr drawa
__FUNCTION__, pixmap->drawable.serialNumber, n,
rect->x, rect->y, rect->width, rect->height,
drawable->x, drawable->y,
- clipped));
+ flags&2));
if (n == 1 && region_is_singular(gc->pCompositeClip)) {
BoxRec r;
@@ -11665,38 +11673,37 @@ sna_poly_fill_rect_blt(DrawablePtr drawa
r.x1 += dx; r.y1 += dy;
r.x2 += dx; r.y2 += dy;
}
- DBG(("%s: using fill_one() fast path: (%d, %d), (%d,
%d). alu=%d, pixel=%08x\n",
- __FUNCTION__, r.x1, r.y1, r.x2, r.y2, gc->alu,
pixel));
+ DBG(("%s: using fill_one() fast path: (%d, %d), (%d,
%d). alu=%d, pixel=%08x, damage?=%d\n",
+ __FUNCTION__, r.x1, r.y1, r.x2, r.y2, gc->alu,
pixel, damage != NULL));
+ assert_pixmap_contains_box(pixmap, &r);
if (sna->render.fill_one(sna, pixmap, bo, pixel,
r.x1, r.y1, r.x2, r.y2,
gc->alu)) {
- if (damage) {
- assert_pixmap_contains_box(pixmap, &r);
- if (r.x2 - r.x1 ==
pixmap->drawable.width &&
- r.y2 - r.y1 ==
pixmap->drawable.height)
- sna_damage_all(damage, pixmap);
- else
- sna_damage_add_box(damage, &r);
- }
- assert_pixmap_damage(pixmap);
-
- if (alu_overwrites(gc->alu) &&
- r.x2 - r.x1 == pixmap->drawable.width &&
+ if (r.x2 - r.x1 == pixmap->drawable.width &&
r.y2 - r.y1 == pixmap->drawable.height) {
- struct sna_pixmap *priv =
sna_pixmap(pixmap);
- if (bo == priv->gpu_bo) {
- assert(priv->gpu_bo->proxy ==
NULL);
-
sna_damage_all(&priv->gpu_damage, pixmap);
-
sna_damage_destroy(&priv->cpu_damage);
- list_del(&priv->flush_list);
- priv->clear = true;
- priv->clear_color = gc->alu ==
GXcopyInverted ? ~pixel & ((1 << gc->depth) - 1) : pixel;
+ if (damage) {
+ sna_damage_all(damage, pixmap);
+ damage = NULL;
+ }
+ if (flags & OVERWRITES) {
+ struct sna_pixmap *priv =
sna_pixmap(pixmap);
+ if (bo == priv->gpu_bo) {
+ assert(damage == NULL
|| damage == &priv->gpu_damage);
+
assert(priv->gpu_bo->proxy == NULL);
+
sna_damage_destroy(&priv->cpu_damage);
+
list_del(&priv->flush_list);
+ priv->clear = true;
+ priv->clear_color =
gc->alu == GXcopyInverted ? ~pixel & ((1 << gc->depth) - 1) : pixel;
- DBG(("%s: pixmap=%ld, marking
clear [%08x]\n",
- __FUNCTION__,
pixmap->drawable.serialNumber, priv->clear_color));
+ DBG(("%s: pixmap=%ld,
marking clear [%08x]\n",
+ __FUNCTION__,
pixmap->drawable.serialNumber, priv->clear_color));
+ }
}
}
+ if (damage)
+ sna_damage_add_box(damage, &r);
+ assert_pixmap_damage(pixmap);
} else
success = false;
}
@@ -11710,7 +11717,7 @@ sna_poly_fill_rect_blt(DrawablePtr drawa
}
get_drawable_deltas(drawable, pixmap, &dx, &dy);
- if (!clipped) {
+ if ((flags & IS_CLIPPED) == 0) {
dx += drawable->x;
dy += drawable->y;
@@ -11918,7 +11925,7 @@ sna_poly_fill_polygon(DrawablePtr draw,
data.op = &fill;
- if ((data.flags & 2) == 0) {
+ if ((data.flags & IS_CLIPPED) == 0) {
if (data.dx | data.dy)
sna_gc_ops__tmp.FillSpans =
sna_fill_spans__fill_offset;
else
@@ -12174,7 +12181,7 @@ sna_poly_fill_rect_tiled_8x8_blt(Drawabl
sna->kgem.nbatch += 6;
}
} else do {
- int n_this_time;
+ int n_this_time, rem;
assert(sna->kgem.mode == KGEM_BLT);
b = sna->kgem.batch + sna->kgem.nbatch;
@@ -12217,8 +12224,9 @@ sna_poly_fill_rect_tiled_8x8_blt(Drawabl
}
n_this_time = n;
- if (3*n_this_time > sna->kgem.surface -
sna->kgem.nbatch - KGEM_BATCH_RESERVED)
- n_this_time = (sna->kgem.surface -
sna->kgem.nbatch - KGEM_BATCH_RESERVED) / 3;
+ rem = kgem_batch_space(&sna->kgem);
+ if (3*n_this_time > rem)
+ n_this_time = rem / 3;
assert(n_this_time);
n -= n_this_time;
@@ -13079,7 +13087,7 @@ sna_poly_fill_rect_stippled_8x8_blt(Draw
sna->kgem.nbatch += 9;
}
} else do {
- int n_this_time;
+ int n_this_time, rem;
assert(sna->kgem.mode == KGEM_BLT);
b = sna->kgem.batch + sna->kgem.nbatch;
@@ -13117,8 +13125,9 @@ sna_poly_fill_rect_stippled_8x8_blt(Draw
}
n_this_time = n;
- if (3*n_this_time > sna->kgem.surface -
sna->kgem.nbatch - KGEM_BATCH_RESERVED)
- n_this_time = (sna->kgem.surface -
sna->kgem.nbatch - KGEM_BATCH_RESERVED) / 3;
+ rem = kgem_batch_space(&sna->kgem);
+ if (3*n_this_time > rem)
+ n_this_time = rem / 3;
assert(n_this_time);
n -= n_this_time;
@@ -14756,11 +14765,14 @@ sna_poly_fill_rect(DrawablePtr draw, GCP
goto fallback;
}
+ if (alu_overwrites(gc->alu))
+ flags |= OVERWRITES;
+
/* Clear the cpu damage so that we refresh the GPU status of the
* pixmap upon a redraw after a period of inactivity.
*/
hint = PREFER_GPU;
- if (n == 1 && gc->fillStyle != FillStippled && alu_overwrites(gc->alu))
{
+ if (n == 1 && gc->fillStyle != FillStippled && flags & OVERWRITES) {
int16_t dx, dy;
region.data = NULL;
@@ -14770,7 +14782,7 @@ sna_poly_fill_rect(DrawablePtr draw, GCP
RegionTranslate(®ion, dx, dy);
}
- if ((flags & 2) == 0) {
+ if ((flags & IS_CLIPPED) == 0) {
hint |= IGNORE_DAMAGE;
if (region_subsumes_drawable(®ion,
&pixmap->drawable)) {
discard_cpu_damage(sna, priv);
@@ -14821,21 +14833,21 @@ sna_poly_fill_rect(DrawablePtr draw, GCP
if (sna_poly_fill_rect_blt(draw,
bo, damage,
gc, color, n, rect,
- ®ion.extents, flags & 2))
+ ®ion.extents, flags))
return;
} else if (gc->fillStyle == FillTiled) {
DBG(("%s: tiled fill, testing for blt\n", __FUNCTION__));
if (sna_poly_fill_rect_tiled_blt(draw, bo, damage,
gc, n, rect,
- ®ion.extents, flags & 2))
+ ®ion.extents, flags))
return;
} else {
DBG(("%s: stippled fill, testing for blt\n", __FUNCTION__));
if (sna_poly_fill_rect_stippled_blt(draw, bo, damage,
gc, n, rect,
- ®ion.extents, flags & 2))
+ ®ion.extents, flags))
return;
}
@@ -14889,19 +14901,22 @@ sna_poly_fill_rect__gpu(DrawablePtr draw
if (gc_is_solid(gc, &color)) {
(void)sna_poly_fill_rect_blt(draw,
- data->bo, data->damage,
+ data->bo, NULL,
gc, color, n, r,
- &data->region.extents, true);
+ &data->region.extents,
+ IS_CLIPPED);
} else if (gc->fillStyle == FillTiled) {
(void)sna_poly_fill_rect_tiled_blt(draw,
- data->bo, data->damage,
+ data->bo, NULL,
gc, n, r,
- &data->region.extents, true);
+ &data->region.extents,
+ IS_CLIPPED);
} else {
(void)sna_poly_fill_rect_stippled_blt(draw,
- data->bo, data->damage,
+ data->bo, NULL,
gc, n, r,
- &data->region.extents,
true);
+ &data->region.extents,
+ IS_CLIPPED);
}
}
@@ -14971,7 +14986,7 @@ sna_poly_fill_arc(DrawablePtr draw, GCPt
data.op = &fill;
- if ((data.flags & 2) == 0) {
+ if ((data.flags & IS_CLIPPED) == 0) {
if (data.dx | data.dy)
sna_gc_ops__tmp.FillSpans =
sna_fill_spans__fill_offset;
else
@@ -17048,7 +17063,7 @@ void sna_accel_flush(struct sna *sna)
assert(priv->flush);
if (sna_pixmap_move_to_gpu(priv->pixmap,
MOVE_READ | __MOVE_FORCE)) {
- if (priv->flush & 2) {
+ if (priv->flush & IS_CLIPPED) {
kgem_bo_unclean(&sna->kgem,
priv->gpu_bo);
sna_damage_all(&priv->gpu_damage,
priv->pixmap);
assert(priv->cpu_damage == NULL);
Index: src/sna/sna_blt.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-intel/src/sna/sna_blt.c,v
retrieving revision 1.3
diff -u -p -u -r1.3 sna_blt.c
--- src/sna/sna_blt.c 12 Apr 2015 19:42:06 -0000 1.3
+++ src/sna/sna_blt.c 7 Mar 2019 12:37:46 -0000
@@ -176,7 +176,8 @@ static bool sna_blt_fill_init(struct sna
{
uint32_t *b;
- if (!kgem_check_reloc(kgem, 1)) {
+ if (!kgem_check_batch(kgem, 24) ||
+ !kgem_check_reloc(kgem, 1)) {
_kgem_submit(kgem);
if (!kgem_check_bo_fenced(kgem, bo))
return false;
@@ -232,6 +233,7 @@ static bool sna_blt_fill_init(struct sna
sna->blt_state.fill_alu = alu;
}
+ assert(sna->kgem.mode == KGEM_BLT);
return true;
}
@@ -1102,13 +1104,16 @@ inline static void _sna_blt_fill_boxes(s
do {
uint32_t *b = kgem->batch + kgem->nbatch;
- int nbox_this_time;
+ int nbox_this_time, rem;
assert(sna->kgem.mode == KGEM_BLT);
nbox_this_time = nbox;
- if (3*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED) / 3;
- assert(nbox_this_time);
+ rem = kgem_batch_space(kgem);
+ if (3*nbox_this_time > rem)
+ nbox_this_time = rem / 3;
+ DBG(("%s: emitting %d boxes out of %d (batch space %d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
kgem->nbatch += 3 * nbox_this_time;
@@ -1198,13 +1203,16 @@ static void blt_composite_fill_boxes_no_
do {
uint32_t *b = kgem->batch + kgem->nbatch;
- int nbox_this_time;
+ int nbox_this_time, rem;
assert(sna->kgem.mode == KGEM_BLT);
nbox_this_time = nbox;
- if (3*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED) / 3;
- assert(nbox_this_time);
+ rem = kgem_batch_space(kgem);
+ if (3*nbox_this_time > rem)
+ nbox_this_time = rem / 3;
+ DBG(("%s: emitting %d boxes out of %d (batch space %d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
kgem->nbatch += 3 * nbox_this_time;
@@ -1310,13 +1318,16 @@ static void blt_composite_fill_boxes__th
do {
uint32_t *b = kgem->batch + kgem->nbatch;
- int nbox_this_time;
+ int nbox_this_time, rem;
assert(sna->kgem.mode == KGEM_BLT);
nbox_this_time = nbox;
- if (3*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED) / 3;
- assert(nbox_this_time);
+ rem = kgem_batch_space(kgem);
+ if (3*nbox_this_time > rem)
+ nbox_this_time = rem / 3;
+ DBG(("%s: emitting %d boxes out of %d (batch space %d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
kgem->nbatch += 3 * nbox_this_time;
@@ -1386,6 +1397,7 @@ static bool
begin_blt(struct sna *sna,
struct sna_composite_op *op)
{
+ assert(sna->kgem.mode == KGEM_BLT);
if (!kgem_check_bo_fenced(&sna->kgem, op->dst.bo)) {
kgem_submit(&sna->kgem);
if (!kgem_check_bo_fenced(&sna->kgem, op->dst.bo))
@@ -1603,14 +1615,17 @@ static void blt_composite_copy_boxes__th
if ((dst_dx | dst_dy) == 0) {
uint64_t hdr = (uint64_t)br13 << 32 | cmd;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (8*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch
- KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (8*nbox_this_time > rem)
+ nbox_this_time = rem / 8;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)/2;
- assert(nbox_this_time);
+ DBG(("%s: emitting %d boxes out of %d (batch space
%d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
assert(sna->kgem.mode == KGEM_BLT);
@@ -1656,14 +1671,17 @@ static void blt_composite_copy_boxes__th
} while (1);
} else {
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (8*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch
- KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (8*nbox_this_time > rem)
+ nbox_this_time = rem / 8;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)/2;
- assert(nbox_this_time);
+ DBG(("%s: emitting %d boxes out of %d (batch space
%d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
assert(sna->kgem.mode == KGEM_BLT);
@@ -1733,14 +1751,17 @@ static void blt_composite_copy_boxes__th
if ((dst_dx | dst_dy) == 0) {
uint64_t hdr = (uint64_t)br13 << 32 | cmd;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (10*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch
- KGEM_BATCH_RESERVED) / 10;
+ rem = kgem_batch_space(kgem);
+ if (10*nbox_this_time > rem)
+ nbox_this_time = rem / 10;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)/2;
- assert(nbox_this_time);
+ DBG(("%s: emitting %d boxes out of %d (batch space
%d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
assert(kgem->mode == KGEM_BLT);
@@ -1788,14 +1809,17 @@ static void blt_composite_copy_boxes__th
} while (1);
} else {
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (10*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch
- KGEM_BATCH_RESERVED) / 10;
+ rem = kgem_batch_space(kgem);
+ if (10*nbox_this_time > rem)
+ nbox_this_time = rem / 10;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)/2;
- assert(nbox_this_time);
+ DBG(("%s: emitting %d boxes out of %d (batch space
%d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
assert(kgem->mode == KGEM_BLT);
@@ -3124,12 +3148,13 @@ fastcall static void sna_blt_fill_op_poi
do {
uint32_t *b = kgem->batch + kgem->nbatch;
- int n_this_time;
+ int n_this_time, rem;
assert(sna->kgem.mode == KGEM_BLT);
n_this_time = n;
- if (2*n_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- n_this_time = (kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED) / 2;
+ rem = kgem_batch_space(kgem);
+ if (2*n_this_time > rem)
+ n_this_time = rem / 2;
assert(n_this_time);
n -= n_this_time;
@@ -3226,6 +3251,7 @@ bool sna_blt_fill(struct sna *sna, uint8
bo, bpp, alu, pixel))
return false;
+ assert(sna->kgem.mode == KGEM_BLT);
fill->blt = sna_blt_fill_op_blt;
fill->box = sna_blt_fill_op_box;
fill->boxes = sna_blt_fill_op_boxes;
@@ -3486,7 +3512,8 @@ bool sna_blt_fill_boxes(struct sna *sna,
{
uint32_t *b;
- if (!kgem_check_reloc(kgem, 1)) {
+ if (!kgem_check_batch(kgem, 24) ||
+ !kgem_check_reloc(kgem, 1)) {
_kgem_submit(kgem);
if (!kgem_check_bo_fenced(&sna->kgem, bo))
return false;
@@ -3543,12 +3570,15 @@ bool sna_blt_fill_boxes(struct sna *sna,
}
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (3*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED) / 3;
- assert(nbox_this_time);
+ rem = kgem_batch_space(kgem);
+ if (3*nbox_this_time > rem)
+ nbox_this_time = rem / 3;
+ DBG(("%s: emitting %d boxes out of %d (batch space %d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
assert(sna->kgem.mode == KGEM_BLT);
@@ -3622,6 +3652,7 @@ bool sna_blt_fill_boxes(struct sna *sna,
kgem->nbatch += 9;
}
assert(kgem->nbatch < kgem->surface);
+ assert(kgem_check_batch(kgem, 3));
}
} while (nbox);
@@ -3728,14 +3759,17 @@ bool sna_blt_copy_boxes(struct sna *sna,
if (kgem->gen >= 0100) {
uint64_t hdr = (uint64_t)br13 << 32 | cmd | 8;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (10*nbox_this_time > kgem->surface -
kgem->nbatch - KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface -
kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (10*nbox_this_time > rem)
+ nbox_this_time = rem / 10;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem)
- kgem->nreloc)/2;
- assert(nbox_this_time);
+ DBG(("%s: emitting %d boxes out of %d (batch
space %d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
assert(sna->kgem.mode == KGEM_BLT);
@@ -3784,14 +3818,17 @@ bool sna_blt_copy_boxes(struct sna *sna,
} else {
uint64_t hdr = (uint64_t)br13 << 32 | cmd | 6;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (8*nbox_this_time > kgem->surface -
kgem->nbatch - KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface -
kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (8*nbox_this_time > rem)
+ nbox_this_time = rem / 8;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem)
- kgem->nreloc)/2;
- assert(nbox_this_time);
+ DBG(("%s: emitting %d boxes out of %d (batch
space %d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
assert(sna->kgem.mode == KGEM_BLT);
@@ -3840,14 +3877,17 @@ bool sna_blt_copy_boxes(struct sna *sna,
if (kgem->gen >= 0100) {
cmd |= 8;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (10*nbox_this_time > kgem->surface -
kgem->nbatch - KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface -
kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (10*nbox_this_time > rem)
+ nbox_this_time = rem / 10;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem)
- kgem->nreloc)/2;
- assert(nbox_this_time);
+ DBG(("%s: emitting %d boxes out of %d (batch
space %d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
assert(sna->kgem.mode == KGEM_BLT);
@@ -3896,14 +3936,17 @@ bool sna_blt_copy_boxes(struct sna *sna,
} else {
cmd |= 6;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (8*nbox_this_time > kgem->surface -
kgem->nbatch - KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface -
kgem->nbatch - KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (8*nbox_this_time > rem)
+ nbox_this_time = rem / 8;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem)
- kgem->nreloc)/2;
- assert(nbox_this_time);
+ DBG(("%s: emitting %d boxes out of %d (batch
space %d)\n",
+ __FUNCTION__, nbox_this_time, nbox, rem));
+ assert(nbox_this_time > 0);
nbox -= nbox_this_time;
assert(sna->kgem.mode == KGEM_BLT);
Index: src/sna/sna_io.c
===================================================================
RCS file: /cvs/xenocara/driver/xf86-video-intel/src/sna/sna_io.c,v
retrieving revision 1.3
diff -u -p -u -r1.3 sna_io.c
--- src/sna/sna_io.c 12 Apr 2015 19:42:06 -0000 1.3
+++ src/sna/sna_io.c 7 Mar 2019 12:37:47 -0000
@@ -484,11 +484,12 @@ fallback:
if (sna->kgem.gen >= 0100) {
cmd |= 8;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = tmp_nbox;
- if (10*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch
- KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (10*nbox_this_time > rem)
+ nbox_this_time = rem / 8;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem) -
kgem->nreloc) / 2;
assert(nbox_this_time);
@@ -543,11 +544,11 @@ fallback:
} else {
cmd |= 6;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = tmp_nbox;
- if (8*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch
- KGEM_BATCH_RESERVED) / 8;
+ if (8*nbox_this_time > rem)
+ nbox_this_time = rem / 8;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem) -
kgem->nreloc) / 2;
assert(nbox_this_time);
@@ -1029,11 +1030,12 @@ tile:
if (kgem->gen >= 0100) {
cmd |= 8;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (10*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch
- KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (10*nbox_this_time > rem)
+ nbox_this_time = rem / 8;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem) -
kgem->nreloc) / 2;
assert(nbox_this_time);
@@ -1122,11 +1124,12 @@ tile:
} else {
cmd |= 6;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (8*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch
- KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (8*nbox_this_time > rem)
+ nbox_this_time = rem / 8;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem) -
kgem->nreloc) / 2;
assert(nbox_this_time);
@@ -1530,11 +1533,12 @@ tile:
if (sna->kgem.gen >= 0100) {
cmd |= 8;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (10*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch
- KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (10*nbox_this_time > rem)
+ nbox_this_time = rem / 8;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem) -
kgem->nreloc) / 2;
assert(nbox_this_time);
@@ -1627,11 +1631,12 @@ tile:
} else {
cmd |= 6;
do {
- int nbox_this_time;
+ int nbox_this_time, rem;
nbox_this_time = nbox;
- if (8*nbox_this_time > kgem->surface - kgem->nbatch -
KGEM_BATCH_RESERVED)
- nbox_this_time = (kgem->surface - kgem->nbatch
- KGEM_BATCH_RESERVED) / 8;
+ rem = kgem_batch_space(kgem);
+ if (8*nbox_this_time > rem)
+ nbox_this_time = rem / 8;
if (2*nbox_this_time > KGEM_RELOC_SIZE(kgem) -
kgem->nreloc)
nbox_this_time = (KGEM_RELOC_SIZE(kgem) -
kgem->nreloc) / 2;
assert(nbox_this_time);
--
Regards,
Mikolaj