xf86-video-intel: 5 commits - src/sna/kgem.c src/sna/kgem.h src/sna/sna_accel.c test/basic-stippledrect.c test/basic-tiledrect.c test/.gitignore test/Makefile.am test/test_display.c test/test.h test/test_render.c
Chris Wilson
ickle at kemper.freedesktop.org
Mon Dec 2 09:15:12 PST 2013
src/sna/kgem.c | 6 -
src/sna/kgem.h | 1
src/sna/sna_accel.c | 130 ++++++++++++-------------
test/.gitignore | 2
test/Makefile.am | 2
test/basic-stippledrect.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++
test/basic-tiledrect.c | 236 +++++++++++++++++++++++++++++++++++++++++++++
test/test.h | 4
test/test_display.c | 16 +--
test/test_render.c | 2
10 files changed, 558 insertions(+), 80 deletions(-)
New commits:
commit 9a8478dae681212bd7a86640f90e6d47c9393b1a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Dec 2 15:48:50 2013 +0000
sna: Fix stipple offset for drawing into child windows
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index 94d983b..9260ac8 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -12086,9 +12086,17 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
get_drawable_deltas(drawable, pixmap, &dx, &dy);
{
- unsigned px = (0 - gc->patOrg.x - dx) & 7;
- unsigned py = (0 - gc->patOrg.y - dy) & 7;
+ int px, py;
+
+ px = (0 - gc->patOrg.x - drawable->x - dx) % 8;
+ if (px < 0)
+ px += 8;
+
+ py = (0 - gc->patOrg.y - drawable->y - dy) % 8;
+ if (py < 0)
+ py += 8;
DBG(("%s: pat offset (%d, %d)\n", __FUNCTION__ ,px, py));
+
br00 = XY_SCANLINE_BLT | px << 12 | py << 8 | 3 << 20;
br13 = bo->pitch;
if (sna->kgem.gen >= 040 && bo->tiling) {
@@ -12133,7 +12141,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
assert(sna->kgem.mode == KGEM_BLT);
b = sna->kgem.batch + sna->kgem.nbatch;
if (sna->kgem.gen >= 0100) {
- b[0] = XY_MONO_PAT | (br00 & (BLT_DST_TILED | 0x7<<12 | 0x7<<8)) | 3<<20 | 8;
+ b[0] = XY_MONO_PAT | (br00 & 0x7f00) | 3<<20 | 8;
b[1] = br13;
b[2] = (r->y + dy) << 16 | (r->x + dx);
b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx);
@@ -12149,7 +12157,7 @@ sna_poly_fill_rect_stippled_8x8_blt(DrawablePtr drawable,
b[9] = pat[1];
sna->kgem.nbatch += 10;
} else {
- b[0] = XY_MONO_PAT | (br00 & (BLT_DST_TILED | 0x7<<12 | 0x7<<8)) | 3<<20 | 7;
+ b[0] = XY_MONO_PAT | (br00 & 0x7f00) | 3<<20 | 7;
b[1] = br13;
b[2] = (r->y + dy) << 16 | (r->x + dx);
b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx);
commit 32b942d0ff4f1d389ac643bfe6b18029d266dc13
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Dec 2 10:43:51 2013 +0000
tests: Exercise stippled fills
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/test/.gitignore b/test/.gitignore
index 7a36837..979d896 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -4,6 +4,7 @@ basic-fillrect
basic-putimage
basic-lines
basic-stress
+basic-stippledrect
basic-tiledrect
render-fill
render-trapezoid
diff --git a/test/Makefile.am b/test/Makefile.am
index 033afd3..df022e2 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,6 +1,7 @@
stress_TESTS = \
basic-fillrect \
basic-tiledrect \
+ basic-stippledrect \
basic-rectangle \
basic-string \
basic-copyarea \
diff --git a/test/basic-stippledrect.c b/test/basic-stippledrect.c
new file mode 100644
index 0000000..8a89efd
--- /dev/null
+++ b/test/basic-stippledrect.c
@@ -0,0 +1,239 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "test.h"
+
+static unsigned char bitmap4x4[] = {
+ 0x03, 0x06, 0x0c, 0x09
+};
+
+static unsigned char bitmap8x8[3][8] = {
+ { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 },
+ { 0x00, 0xfe, 0x92, 0x92, 0xfe, 0x92, 0x92, 0xfe },
+ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa },
+};
+
+static void fill_rect(struct test_target *t, uint8_t alu,
+ XRectangle *clip, int nclip,
+ uint8_t stipple, uint8_t opaque, int tx, int ty,
+ int x, int y, int w, int h,
+ uint32_t fg, uint32_t bg)
+{
+ Display *dpy = t->dpy->dpy;
+ XGCValues val;
+ GC gc;
+
+ val.function = alu;
+ val.foreground = fg;
+ val.background = bg;
+ val.fill_style = opaque ? FillOpaqueStippled : FillStippled;
+ val.ts_x_origin = tx;
+ val.ts_y_origin = ty;
+ if (stipple == 0) {
+ val.stipple = XCreateBitmapFromData(dpy, t->draw, (char *)bitmap4x4, 4, 4);
+ } else {
+ char *b = (char *)bitmap8x8[stipple-1];
+ val.stipple = XCreateBitmapFromData(dpy, t->draw, b, 8, 8);
+ }
+
+ gc = XCreateGC(dpy, t->draw, GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCStipple | GCForeground | GCBackground | GCFunction, &val);
+ if (nclip)
+ XSetClipRectangles(dpy, gc, 0, 0, clip, nclip, Unsorted);
+ XFillRectangle(dpy, t->draw, gc, x, y, w, h);
+ XFreeGC(dpy, gc);
+ XFreePixmap(dpy, val.stipple);
+}
+
+static void clear(struct test_target *tt)
+{
+ XRenderColor render_color = {0};
+ XRenderFillRectangle(tt->dpy->dpy, PictOpClear, tt->picture, &render_color,
+ 0, 0, tt->width, tt->height);
+}
+
+static void unclipped_tests(struct test *t, int reps, int sets, enum target target)
+{
+ struct test_target real, ref;
+ int r, s;
+
+ printf("Testing unclipped stippled fills (%s): ", test_target_name(target));
+ fflush(stdout);
+
+ test_target_create_render(&t->real, target, &real);
+ clear(&real);
+
+ test_target_create_render(&t->ref, target, &ref);
+ clear(&ref);
+
+ for (s = 0; s < sets; s++) {
+ for (r = 0; r < reps; r++) {
+ int x = rand() % real.width;
+ int y = rand() % real.height;
+ int w = rand() % (real.width - x);
+ int h = rand() % (real.height - y);
+ int tx = rand() % (2*real.width) - real.width;
+ int ty = rand() % (2*real.height) - real.height;
+ uint8_t stipple = rand() % 4;
+ uint8_t opaque = rand() % 1;
+ uint8_t alu = rand() % (GXset + 1);
+ uint32_t fg = rand();
+ uint32_t bg = rand();
+
+ fill_rect(&real, alu, NULL, 0,
+ stipple, opaque, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ fill_rect(&ref, alu, NULL, 0,
+ stipple, opaque, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ }
+
+ test_compare(t,
+ real.draw, real.format,
+ ref.draw, ref.format,
+ 0, 0, real.width, real.height,
+ "");
+ }
+
+ printf("passed [%d iterations x %d]\n", reps, sets);
+
+ test_target_destroy_render(&t->real, &real);
+ test_target_destroy_render(&t->ref, &ref);
+}
+
+static void simple_clip_tests(struct test *t, int reps, int sets, enum target target)
+{
+ struct test_target real, ref;
+ int r, s;
+
+ printf("Testing simple clipped stippled fills (%s): ", test_target_name(target));
+ fflush(stdout);
+
+ test_target_create_render(&t->real, target, &real);
+ clear(&real);
+
+ test_target_create_render(&t->ref, target, &ref);
+ clear(&ref);
+
+ for (s = 0; s < sets; s++) {
+ for (r = 0; r < reps; r++) {
+ int x = rand() % (2*real.width) - real.width;
+ int y = rand() % (2*real.height) - real.height;
+ int w = rand() % (2*real.width);
+ int h = rand() % (2*real.height);
+ int tx = rand() % (2*real.width) - real.width;
+ int ty = rand() % (2*real.height) - real.height;
+ uint8_t stipple = rand() % 4;
+ uint8_t opaque = rand() % 1;
+ uint8_t alu = rand() % (GXset + 1);
+ uint32_t fg = rand();
+ uint32_t bg = rand();
+
+ fill_rect(&real, alu, NULL, 0,
+ stipple, opaque, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ fill_rect(&ref, alu, NULL, 0,
+ stipple, opaque, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ }
+
+ test_compare(t,
+ real.draw, real.format,
+ ref.draw, ref.format,
+ 0, 0, real.width, real.height,
+ "");
+ }
+
+ printf("passed [%d iterations x %d]\n", reps, sets);
+
+ test_target_destroy_render(&t->real, &real);
+ test_target_destroy_render(&t->ref, &ref);
+}
+
+static void complex_clip_tests(struct test *t, int reps, int sets, enum target target)
+{
+ struct test_target real, ref;
+ XRectangle *clip;
+ int nclip, r, s;
+
+ printf("Testing complex clipped stippled fills (%s): ", test_target_name(target));
+ fflush(stdout);
+
+ test_target_create_render(&t->real, target, &real);
+ clear(&real);
+
+ test_target_create_render(&t->ref, target, &ref);
+ clear(&ref);
+
+ for (s = 0; s < sets; s++) {
+ nclip = (rand() % 16) + 2;
+ clip = malloc(sizeof(XRectangle)*nclip);
+ for (r = 0; r < nclip; r++) {
+ clip[r].x = rand() % real.width;
+ clip[r].y = rand() % real.height;
+ clip[r].width = rand() % (real.width - clip[r].x);
+ clip[r].height = rand() % (real.height - clip[r].y);
+ }
+
+ for (r = 0; r < reps; r++) {
+ int x = rand() % (2*real.width) - real.width;
+ int y = rand() % (2*real.height) - real.height;
+ int w = rand() % (2*real.width);
+ int h = rand() % (2*real.height);
+ int tx = rand() % (2*real.width) - real.width;
+ int ty = rand() % (2*real.height) - real.height;
+ uint8_t stipple = rand() % 4;
+ uint8_t opaque = rand() % 1;
+ uint8_t alu = rand() % (GXset + 1);
+ uint32_t fg = rand();
+ uint32_t bg = rand();
+
+ fill_rect(&real, alu, clip, nclip,
+ stipple, opaque, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ fill_rect(&ref, alu, clip, nclip,
+ stipple, opaque, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ }
+
+ test_compare(t,
+ real.draw, real.format,
+ ref.draw, ref.format,
+ 0, 0, real.width, real.height,
+ "");
+
+ free(clip);
+ }
+
+ printf("passed [%d iterations x %d]\n", reps, sets);
+
+ test_target_destroy_render(&t->real, &real);
+ test_target_destroy_render(&t->ref, &ref);
+}
+
+int main(int argc, char **argv)
+{
+ struct test test;
+ int i;
+
+ test_init(&test, argc, argv);
+
+ for (i = 0; i <= DEFAULT_ITERATIONS; i++) {
+ int reps = REPS(i), sets = SETS(i);
+ enum target t;
+
+ for (t = TARGET_FIRST; t <= TARGET_LAST; t++) {
+ unclipped_tests(&test, reps, sets, t);
+ simple_clip_tests(&test, reps, sets, t);
+ complex_clip_tests(&test, reps, sets, t);
+ }
+ }
+
+ return 0;
+}
commit 463ab7f4faf46f6530423b6b10f2cd1bb6d0aa83
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Dec 2 11:08:05 2013 +0000
sna: Fix tile origin for pattern blits
References: https://bugs.freedesktop.org/show_bug.cgi?id=71260
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_accel.c b/src/sna/sna_accel.c
index e1487ee..94d983b 100644
--- a/src/sna/sna_accel.c
+++ b/src/sna/sna_accel.c
@@ -11310,7 +11310,7 @@ sna_pixmap_get_source_bo(PixmapPtr pixmap)
if (priv->cpu_damage && priv->cpu_bo)
return kgem_bo_reference(priv->cpu_bo);
- if (!sna_pixmap_force_to_gpu(pixmap, MOVE_READ))
+ if (!sna_pixmap_force_to_gpu(pixmap, MOVE_READ | MOVE_ASYNC_HINT))
return NULL;
return kgem_bo_reference(priv->gpu_bo);
@@ -11343,20 +11343,40 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
if (NO_TILE_8x8)
return false;
- DBG(("%s x %d [(%d, %d)x(%d, %d)...], clipped=%x\n",
- __FUNCTION__, n, r->x, r->y, r->width, r->height, clipped));
+ DBG(("%s x %d [(%d, %d)x(%d, %d)...], clipped=%x, origin=(%d, %d)\n",
+ __FUNCTION__, n, r->x, r->y, r->width, r->height, clipped, origin->x, origin->y));
+
+ DBG(("%s: tile_bo tiling=%d, pitch=%d\n", __FUNCTION__, tile_bo->tiling, tile_bo->pitch));
+ if (tile_bo->tiling)
+ return false;
+
+ assert(tile_bo->pitch == 8 * drawable->bitsPerPixel >> 3);
kgem_set_mode(&sna->kgem, KGEM_BLT, bo);
if (!kgem_check_batch(&sna->kgem, 10+2*3) ||
!kgem_check_reloc(&sna->kgem, 2) ||
- !kgem_check_bo_fenced(&sna->kgem, bo)) {
+ !kgem_check_many_bo_fenced(&sna->kgem, bo, tile_bo, NULL)) {
kgem_submit(&sna->kgem);
- if (!kgem_check_bo_fenced(&sna->kgem, bo))
+ if (!kgem_check_many_bo_fenced(&sna->kgem, bo, tile_bo, NULL))
return false;
_kgem_set_mode(&sna->kgem, KGEM_BLT);
}
+ get_drawable_deltas(drawable, pixmap, &dx, &dy);
+ assert(extents->x1 + dx >= 0);
+ assert(extents->y1 + dy >= 0);
+ assert(extents->x2 + dx <= pixmap->drawable.width);
+ assert(extents->y2 + dy <= pixmap->drawable.height);
+
br00 = XY_SCANLINE_BLT;
+ tx = (-drawable->x - dx - origin->x) % 8;
+ if (tx < 0)
+ tx += 8;
+ ty = (-drawable->y - dy - origin->y) % 8;
+ if (ty < 0)
+ ty += 8;
+ br00 |= tx << 12 | ty << 8;
+
br13 = bo->pitch;
if (sna->kgem.gen >= 040 && bo->tiling) {
br00 |= BLT_DST_TILED;
@@ -11365,24 +11385,14 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
br13 |= blt_depth(drawable->depth) << 24;
br13 |= fill_ROP[gc->alu] << 16;
- get_drawable_deltas(drawable, pixmap, &dx, &dy);
- assert(extents->x1 + dx >= 0);
- assert(extents->y1 + dy >= 0);
- assert(extents->x2 + dx <= pixmap->drawable.width);
- assert(extents->y2 + dy <= pixmap->drawable.height);
-
if (!clipped) {
dx += drawable->x;
dy += drawable->y;
sna_damage_add_rectangles(damage, r, n, dx, dy);
if (n == 1) {
- tx = (r->x - origin->x) % 8;
- if (tx < 0)
- tx = 8 - tx;
- ty = (r->y - origin->y) % 8;
- if (ty < 0)
- ty = 8 - ty;
+ DBG(("%s: rect=(%d, %d)x(%d, %d) + (%d, %d), tile=(%d, %d)\n",
+ __FUNCTION__, r->x, r->y, r->width, r->height, dx, dy, tx, ty));
assert(r->x + dx >= 0);
assert(r->y + dy >= 0);
@@ -11392,7 +11402,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
assert(sna->kgem.mode == KGEM_BLT);
b = sna->kgem.batch + sna->kgem.nbatch;
if (sna->kgem.gen >= 0100) {
- b[0] = XY_PAT_BLT | tx << 12 | ty << 8 | 3 << 20 | (br00 & BLT_DST_TILED) | 6;
+ b[0] = XY_PAT_BLT | 3 << 20 | (br00 & 0x7f00) | 6;
b[1] = br13;
b[2] = (r->y + dy) << 16 | (r->x + dx);
b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx);
@@ -11409,7 +11419,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
0);
sna->kgem.nbatch += 8;
} else {
- b[0] = XY_PAT_BLT | tx << 12 | ty << 8 | 3 << 20 | (br00 & BLT_DST_TILED) | 4;
+ b[0] = XY_PAT_BLT | 3 << 20 | (br00 & 0x7f00) | 4;
b[1] = br13;
b[2] = (r->y + dy) << 16 | (r->x + dx);
b[3] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx);
@@ -11482,14 +11492,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
assert(r->x + dx + r->width <= pixmap->drawable.width);
assert(r->y + dy + r->height <= pixmap->drawable.height);
- tx = (r->x - origin->x) % 8;
- if (tx < 0)
- tx = 8 - tx;
- ty = (r->y - origin->y) % 8;
- if (ty < 0)
- ty = 8 - ty;
-
- b[0] = br00 | tx << 12 | ty << 8;
+ b[0] = br00;
b[1] = (r->y + dy) << 16 | (r->x + dx);
b[2] = (r->y + r->height + dy) << 16 | (r->x + r->width + dx);
b += 3; r++;
@@ -11554,6 +11557,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
if (clip.data == NULL) {
const BoxRec *c = &clip.extents;
+ DBG(("%s: simple clip, %d boxes\n", __FUNCTION__, n));
while (n--) {
BoxRec box;
@@ -11617,17 +11621,12 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
assert(box.x2 + dx <= pixmap->drawable.width);
assert(box.y2 + dy <= pixmap->drawable.height);
- ty = (box.y1 - drawable->y - origin->y) % 8;
- if (ty < 0)
- ty = 8 - ty;
-
- tx = (box.x1 - drawable->x - origin->x) % 8;
- if (tx < 0)
- tx = 8 - tx;
+ DBG(("%s: box=(%d, %d),(%d, %d) + (%d, %d), tile=(%d, %d)\n",
+ __FUNCTION__, box.x1, box.y1, box.x2, box.y2, dx, dy, tx, ty));
assert(sna->kgem.mode == KGEM_BLT);
b = sna->kgem.batch + sna->kgem.nbatch;
- b[0] = br00 | tx << 12 | ty << 8;
+ b[0] = br00;
b[1] = (box.y1 + dy) << 16 | (box.x1 + dx);
b[2] = (box.y2 + dy) << 16 | (box.x2 + dx);
sna->kgem.nbatch += 3;
@@ -11638,6 +11637,7 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
const BoxRec * const clip_end = clip_start + clip.data->numRects;
const BoxRec *c;
+ DBG(("%s: complex clip (%ld cliprects), %d boxes\n", __FUNCTION__, (long)clip.data->numRects, n));
do {
BoxRec box;
@@ -11711,17 +11711,9 @@ sna_poly_fill_rect_tiled_8x8_blt(DrawablePtr drawable,
assert(bb.x2 + dx <= pixmap->drawable.width);
assert(bb.y2 + dy <= pixmap->drawable.height);
- ty = (bb.y1 - drawable->y - origin->y) % 8;
- if (ty < 0)
- ty = 8 - ty;
-
- tx = (bb.x1 - drawable->x - origin->x) % 8;
- if (tx < 0)
- tx = 8 - tx;
-
assert(sna->kgem.mode == KGEM_BLT);
b = sna->kgem.batch + sna->kgem.nbatch;
- b[0] = br00 | tx << 12 | ty << 8;
+ b[0] = br00;
b[1] = (bb.y1 + dy) << 16 | (bb.x1 + dx);
b[2] = (bb.y2 + dy) << 16 | (bb.x2 + dx);
sna->kgem.nbatch += 3;
@@ -11773,6 +11765,7 @@ sna_poly_fill_rect_tiled_nxm_blt(DrawablePtr drawable,
assert(tile->drawable.height && tile->drawable.height <= 8);
assert(tile->drawable.width && tile->drawable.width <= 8);
assert(has_coherent_ptr(sna, sna_pixmap(tile), MOVE_READ));
+ upload->pitch = 8*tile->drawable.bitsPerPixel >> 3; /* for sanity checks */
cpp = tile->drawable.bitsPerPixel/8;
for (h = 0; h < tile->drawable.height; h++) {
@@ -11848,23 +11841,24 @@ sna_poly_fill_rect_tiled_blt(DrawablePtr drawable,
ret = sna_poly_fill_rect_tiled_8x8_blt(drawable, bo, damage,
tile_bo, gc, n, rect,
extents, clipped);
- kgem_bo_destroy(&sna->kgem, tile_bo);
-
- return ret;
- }
-
- if ((tile->drawable.width | tile->drawable.height) <= 0xc &&
- is_power_of_two(tile->drawable.width) &&
- is_power_of_two(tile->drawable.height))
- return sna_poly_fill_rect_tiled_nxm_blt(drawable, bo, damage,
- gc, n, rect,
- extents, clipped);
+ if (ret) {
+ kgem_bo_destroy(&sna->kgem, tile_bo);
+ return true;
+ }
+ } else {
+ if ((tile->drawable.width | tile->drawable.height) <= 0xc &&
+ is_power_of_two(tile->drawable.width) &&
+ is_power_of_two(tile->drawable.height))
+ return sna_poly_fill_rect_tiled_nxm_blt(drawable, bo, damage,
+ gc, n, rect,
+ extents, clipped);
- tile_bo = sna_pixmap_get_source_bo(tile);
- if (tile_bo == NULL) {
- DBG(("%s: unable to move tile go GPU, fallback\n",
- __FUNCTION__));
- return false;
+ tile_bo = sna_pixmap_get_source_bo(tile);
+ if (tile_bo == NULL) {
+ DBG(("%s: unable to move tile go GPU, fallback\n",
+ __FUNCTION__));
+ return false;
+ }
}
if (!sna_copy_init_blt(©, sna, tile, tile_bo, pixmap, bo, alu)) {
commit 6889ba38ab2bb050dec3057dbc584619dbe6d2e2
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Dec 2 14:20:51 2013 +0000
sna: Drop forced alignment to 64 on pre-gen4 devices
Some linear GPU bo that we create must be naturally aligned, and the
extra alignment imposed for pure paranoia is counter productive.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/kgem.c b/src/sna/kgem.c
index 35b76d9..4305c76 100644
--- a/src/sna/kgem.c
+++ b/src/sna/kgem.c
@@ -1258,10 +1258,6 @@ void kgem_init(struct kgem *kgem, int fd, struct pci_device *dev, unsigned gen)
DBG(("%s: maximum batch size? %d\n", __FUNCTION__,
kgem->batch_size));
- kgem->min_alignment = 4;
- if (gen < 040)
- kgem->min_alignment = 64;
-
kgem->half_cpu_cache_pages = cpu_cache_size() >> 13;
DBG(("%s: last-level cache size: %d bytes, threshold in pages: %d\n",
__FUNCTION__, cpu_cache_size(), kgem->half_cpu_cache_pages));
@@ -1424,7 +1420,7 @@ inline static uint32_t kgem_pitch_alignment(struct kgem *kgem, unsigned flags)
return 256;
if (flags & CREATE_SCANOUT)
return 64;
- return kgem->min_alignment;
+ return 4;
}
void kgem_get_tile_size(struct kgem *kgem, int tiling, int pitch,
diff --git a/src/sna/kgem.h b/src/sna/kgem.h
index d847f3f..14d7d68 100644
--- a/src/sna/kgem.h
+++ b/src/sna/kgem.h
@@ -158,7 +158,6 @@ struct kgem {
uint16_t nreloc__self;
uint16_t nfence;
uint16_t batch_size;
- uint16_t min_alignment;
uint32_t flush:1;
uint32_t need_expire:1;
commit 49af22ee5533b1afbf30f50fcfd7245f1c8d98bc
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Dec 2 10:43:51 2013 +0000
tests: Exercise tiled fills
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/test/.gitignore b/test/.gitignore
index 05bb936..7a36837 100644
--- a/test/.gitignore
+++ b/test/.gitignore
@@ -4,6 +4,7 @@ basic-fillrect
basic-putimage
basic-lines
basic-stress
+basic-tiledrect
render-fill
render-trapezoid
render-trapezoid-image
diff --git a/test/Makefile.am b/test/Makefile.am
index 5c2a3e1..033afd3 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -1,5 +1,6 @@
stress_TESTS = \
basic-fillrect \
+ basic-tiledrect \
basic-rectangle \
basic-string \
basic-copyarea \
diff --git a/test/basic-tiledrect.c b/test/basic-tiledrect.c
new file mode 100644
index 0000000..1596c4c
--- /dev/null
+++ b/test/basic-tiledrect.c
@@ -0,0 +1,236 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "test.h"
+
+static unsigned char bitmap4x4[] = {
+ 0x03, 0x06, 0x0c, 0x09
+};
+
+static unsigned char bitmap8x8[3][8] = {
+ { 0xcc, 0x66, 0x33, 0x99, 0xcc, 0x66, 0x33, 0x99 },
+ { 0x00, 0xfe, 0x92, 0x92, 0xfe, 0x92, 0x92, 0xfe },
+ { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa },
+};
+
+static void fill_rect(struct test_target *t, uint8_t alu,
+ XRectangle *clip, int nclip,
+ uint8_t tile, int tx, int ty,
+ int x, int y, int w, int h,
+ uint32_t fg, uint32_t bg)
+{
+ Display *dpy = t->dpy->dpy;
+ XGCValues val;
+ GC gc;
+
+ val.function = alu;
+ val.fill_style = FillTiled;
+ val.ts_x_origin = tx;
+ val.ts_y_origin = ty;
+ if (tile == 0) {
+ val.tile = XCreatePixmapFromBitmapData(dpy, t->draw, (char *)bitmap4x4, 4, 4,
+ fg, bg, t->depth);
+ } else {
+ char *b = (char *)bitmap8x8[tile-1];
+ val.tile = XCreatePixmapFromBitmapData(dpy, t->draw, b, 8, 8,
+ fg, bg, t->depth);
+ }
+
+ gc = XCreateGC(dpy, t->draw, GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin | GCTile | GCFunction, &val);
+ if (nclip)
+ XSetClipRectangles(dpy, gc, 0, 0, clip, nclip, Unsorted);
+ XFillRectangle(dpy, t->draw, gc, x, y, w, h);
+ XFreeGC(dpy, gc);
+ XFreePixmap(dpy, val.tile);
+}
+
+static void clear(struct test_target *tt)
+{
+ XRenderColor render_color = {0};
+ XRenderFillRectangle(tt->dpy->dpy, PictOpClear, tt->picture, &render_color,
+ 0, 0, tt->width, tt->height);
+}
+
+static void unclipped_tests(struct test *t, int reps, int sets, enum target target)
+{
+ struct test_target real, ref;
+ int r, s;
+
+ printf("Testing unclipped tiled fills (%s): ", test_target_name(target));
+ fflush(stdout);
+
+ test_target_create_render(&t->real, target, &real);
+ clear(&real);
+
+ test_target_create_render(&t->ref, target, &ref);
+ clear(&ref);
+
+ for (s = 0; s < sets; s++) {
+ for (r = 0; r < reps; r++) {
+ int x = rand() % real.width;
+ int y = rand() % real.height;
+ int w = rand() % (real.width - x);
+ int h = rand() % (real.height - y);
+ int tx = rand() % (2*real.width) - real.width;
+ int ty = rand() % (2*real.height) - real.height;
+ uint8_t tile = rand() % 4;
+ uint8_t alu = rand() % (GXset + 1);
+ uint32_t fg = rand();
+ uint32_t bg = rand();
+
+ fill_rect(&real, alu, NULL, 0,
+ tile, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ fill_rect(&ref, alu, NULL, 0,
+ tile, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ }
+
+ test_compare(t,
+ real.draw, real.format,
+ ref.draw, ref.format,
+ 0, 0, real.width, real.height,
+ "");
+ }
+
+ printf("passed [%d iterations x %d]\n", reps, sets);
+
+ test_target_destroy_render(&t->real, &real);
+ test_target_destroy_render(&t->ref, &ref);
+}
+
+static void simple_clip_tests(struct test *t, int reps, int sets, enum target target)
+{
+ struct test_target real, ref;
+ int r, s;
+
+ printf("Testing simple clipped tiled fills (%s): ", test_target_name(target));
+ fflush(stdout);
+
+ test_target_create_render(&t->real, target, &real);
+ clear(&real);
+
+ test_target_create_render(&t->ref, target, &ref);
+ clear(&ref);
+
+ for (s = 0; s < sets; s++) {
+ for (r = 0; r < reps; r++) {
+ int x = rand() % (2*real.width) - real.width;
+ int y = rand() % (2*real.height) - real.height;
+ int w = rand() % (2*real.width);
+ int h = rand() % (2*real.height);
+ int tx = rand() % (2*real.width) - real.width;
+ int ty = rand() % (2*real.height) - real.height;
+ uint8_t tile = rand() % 4;
+ uint8_t alu = rand() % (GXset + 1);
+ uint32_t fg = rand();
+ uint32_t bg = rand();
+
+ fill_rect(&real, alu, NULL, 0,
+ tile, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ fill_rect(&ref, alu, NULL, 0,
+ tile, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ }
+
+ test_compare(t,
+ real.draw, real.format,
+ ref.draw, ref.format,
+ 0, 0, real.width, real.height,
+ "");
+ }
+
+ printf("passed [%d iterations x %d]\n", reps, sets);
+
+ test_target_destroy_render(&t->real, &real);
+ test_target_destroy_render(&t->ref, &ref);
+}
+
+static void complex_clip_tests(struct test *t, int reps, int sets, enum target target)
+{
+ struct test_target real, ref;
+ XRectangle *clip;
+ int nclip, r, s;
+
+ printf("Testing complex clipped tiled fills (%s): ", test_target_name(target));
+ fflush(stdout);
+
+ test_target_create_render(&t->real, target, &real);
+ clear(&real);
+
+ test_target_create_render(&t->ref, target, &ref);
+ clear(&ref);
+
+ for (s = 0; s < sets; s++) {
+ nclip = (rand() % 16) + 2;
+ clip = malloc(sizeof(XRectangle)*nclip);
+ for (r = 0; r < nclip; r++) {
+ clip[r].x = rand() % real.width;
+ clip[r].y = rand() % real.height;
+ clip[r].width = rand() % (real.width - clip[r].x);
+ clip[r].height = rand() % (real.height - clip[r].y);
+ }
+
+ for (r = 0; r < reps; r++) {
+ int x = rand() % (2*real.width) - real.width;
+ int y = rand() % (2*real.height) - real.height;
+ int w = rand() % (2*real.width);
+ int h = rand() % (2*real.height);
+ int tx = rand() % (2*real.width) - real.width;
+ int ty = rand() % (2*real.height) - real.height;
+ uint8_t tile = rand() % 4;
+ uint8_t alu = rand() % (GXset + 1);
+ uint32_t fg = rand();
+ uint32_t bg = rand();
+
+ fill_rect(&real, alu, clip, nclip,
+ tile, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ fill_rect(&ref, alu, clip, nclip,
+ tile, tx, ty,
+ x, y, w, h,
+ fg, bg);
+ }
+
+ test_compare(t,
+ real.draw, real.format,
+ ref.draw, ref.format,
+ 0, 0, real.width, real.height,
+ "");
+
+ free(clip);
+ }
+
+ printf("passed [%d iterations x %d]\n", reps, sets);
+
+ test_target_destroy_render(&t->real, &real);
+ test_target_destroy_render(&t->ref, &ref);
+}
+
+int main(int argc, char **argv)
+{
+ struct test test;
+ int i;
+
+ test_init(&test, argc, argv);
+
+ for (i = 0; i <= DEFAULT_ITERATIONS; i++) {
+ int reps = REPS(i), sets = SETS(i);
+ enum target t;
+
+ for (t = TARGET_FIRST; t <= TARGET_LAST; t++) {
+ unclipped_tests(&test, reps, sets, t);
+ simple_clip_tests(&test, reps, sets, t);
+ complex_clip_tests(&test, reps, sets, t);
+ }
+ }
+
+ return 0;
+}
diff --git a/test/test.h b/test/test.h
index 3cd9457..568e000 100644
--- a/test/test.h
+++ b/test/test.h
@@ -31,7 +31,7 @@ struct test {
Window root;
XShmSegmentInfo shm;
int max_shm_size;
- int width, height;
+ int width, height, depth;
XRenderPictFormat *format;
} real, ref;
};
@@ -82,7 +82,7 @@ struct test_target {
GC gc;
XRenderPictFormat *format;
Picture picture;
- int width, height;
+ int width, height, depth;
enum target target;
};
diff --git a/test/test_display.c b/test/test_display.c
index b5e7e06..36cfe69 100644
--- a/test/test_display.c
+++ b/test/test_display.c
@@ -16,12 +16,12 @@ static Window get_root(struct test_display *t)
* can guarantee we do not get clipped by children.
*/
attr.override_redirect = 1;
- w= XCreateWindow(t->dpy, DefaultRootWindow(t->dpy),
- 0, 0, t->width, t->height, 0,
- DefaultDepth(t->dpy, DefaultScreen(t->dpy)),
- InputOutput,
- DefaultVisual(t->dpy, DefaultScreen(t->dpy)),
- CWOverrideRedirect, &attr);
+ w = XCreateWindow(t->dpy, DefaultRootWindow(t->dpy),
+ 0, 0, t->width, t->height, 0,
+ DefaultDepth(t->dpy, DefaultScreen(t->dpy)),
+ InputOutput,
+ DefaultVisual(t->dpy, DefaultScreen(t->dpy)),
+ CWOverrideRedirect, &attr);
XMapWindow(t->dpy, w);
return w;
@@ -125,6 +125,7 @@ static void default_setup(struct test_display *dpy)
XRenderFindVisualFormat(dpy->dpy,
DefaultVisual(dpy->dpy,
DefaultScreen(dpy->dpy)));
+ dpy->depth = DefaultDepth(dpy->dpy, DefaultScreen(dpy->dpy));
}
static void test_get_displays(int argc, char **argv,
@@ -136,8 +137,7 @@ static void test_get_displays(int argc, char **argv,
shm_setup(real);
real->root = get_root(real);
- ref->dpy = ref_display(real->width, real->height,
- DefaultDepth(real->dpy, DefaultScreen(real->dpy)));
+ ref->dpy = ref_display(real->width, real->height, real->depth);
default_setup(ref);
shm_setup(ref);
ref->root = get_root(ref);
diff --git a/test/test_render.c b/test/test_render.c
index 67889ac..926e930 100644
--- a/test/test_render.c
+++ b/test/test_render.c
@@ -31,6 +31,7 @@ void test_target_create_render(struct test_display *dpy,
tt->format = dpy->format;
tt->width = dpy->width;
tt->height = dpy->height;
+ tt->depth = dpy->depth;
switch (target) {
case ROOT:
@@ -56,6 +57,7 @@ void test_target_create_render(struct test_display *dpy,
tt->draw = XCreatePixmap(dpy->dpy, tt->draw,
dpy->width, dpy->height,
tt->format->depth);
+ tt->depth = 32;
break;
}
More information about the xorg-commit
mailing list