diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-08 02:27:28 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-01-08 14:34:01 +0000 |
commit | 3f7ea44bf19a03ee81b683885c9c2416092254a3 (patch) | |
tree | 59d5c0eccce828f0a38e05190d5c35def161469f | |
parent | 803ac5c6b992cb5448c67b11345b87a5d2b9c60d (diff) |
sna/gen[67]: Hook into the clear operation for glyph masks
Allow SandyBridge to specialise its clear routine to reduce the number
of ring switches. It may be interesting to specialise the clear routines
even further and use the special render clear commands...
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/sna/gen6_render.c | 98 | ||||
-rw-r--r-- | src/sna/gen7_render.c | 98 | ||||
-rw-r--r-- | src/sna/sna_glyphs.c | 6 | ||||
-rw-r--r-- | src/sna/sna_render.c | 13 | ||||
-rw-r--r-- | src/sna/sna_render.h | 1 |
5 files changed, 211 insertions, 5 deletions
diff --git a/src/sna/gen6_render.c b/src/sna/gen6_render.c index 86bf4600..e95cdd66 100644 --- a/src/sna/gen6_render.c +++ b/src/sna/gen6_render.c @@ -55,6 +55,7 @@ #define NO_COPY_BOXES 0 #define NO_FILL 0 #define NO_FILL_BOXES 0 +#define NO_CLEAR 0 #define GEN6_MAX_SIZE 8192 @@ -3552,6 +3553,102 @@ gen6_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, return TRUE; } +static Bool +gen6_render_clear_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) +{ + BoxRec box; + + box.x1 = 0; + box.y1 = 0; + box.x2 = dst->drawable.width; + box.y2 = dst->drawable.height; + + return sna_blt_fill_boxes(sna, GXclear, + bo, dst->drawable.bitsPerPixel, + 0, &box, 1); +} + +static Bool +gen6_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) +{ + struct sna_composite_op tmp; + +#if NO_CLEAR + return gen6_render_clear_try_blt(sna, dst, bo); +#endif + + DBG(("%s: %dx%d\n", + __FUNCTION__, + dst->drawable.width, + dst->drawable.height)); + + /* Prefer to use the BLT if already engaged */ + if (sna->kgem.ring == KGEM_BLT && + gen6_render_clear_try_blt(sna, dst, bo)) + return TRUE; + + /* Must use the BLT if we can't RENDER... */ + if (too_large(dst->drawable.width, dst->drawable.height)) + return gen6_render_clear_try_blt(sna, dst, bo); + + tmp.op = PictOpClear; + + tmp.dst.pixmap = dst; + tmp.dst.width = dst->drawable.width; + tmp.dst.height = dst->drawable.height; + tmp.dst.format = sna_format_for_depth(dst->drawable.depth); + tmp.dst.bo = bo; + tmp.dst.x = tmp.dst.y = 0; + + tmp.src.bo = sna_render_get_solid(sna, 0); + tmp.src.filter = SAMPLER_FILTER_NEAREST; + tmp.src.repeat = SAMPLER_EXTEND_REPEAT; + + tmp.mask.bo = NULL; + tmp.mask.filter = SAMPLER_FILTER_NEAREST; + tmp.mask.repeat = SAMPLER_EXTEND_NONE; + + tmp.is_affine = TRUE; + tmp.floats_per_vertex = 3; + tmp.floats_per_rect = 9; + tmp.has_component_alpha = 0; + tmp.need_magic_ca_pass = FALSE; + + tmp.u.gen6.wm_kernel = GEN6_WM_KERNEL_NOMASK; + tmp.u.gen6.nr_surfaces = 2; + tmp.u.gen6.nr_inputs = 1; + tmp.u.gen6.ve_id = 1; + + if (!kgem_check_bo(&sna->kgem, bo, NULL)) + _kgem_submit(&sna->kgem); + + gen6_emit_fill_state(sna, &tmp); + gen6_align_vertex(sna, &tmp); + + if (!gen6_get_rectangles(sna, &tmp, 1)) { + gen6_emit_fill_state(sna, &tmp); + gen6_get_rectangles(sna, &tmp, 1); + } + + OUT_VERTEX(dst->drawable.width, dst->drawable.height); + OUT_VERTEX_F(1); + OUT_VERTEX_F(1); + + OUT_VERTEX(0, dst->drawable.height); + OUT_VERTEX_F(0); + OUT_VERTEX_F(1); + + OUT_VERTEX(0, 0); + OUT_VERTEX_F(0); + OUT_VERTEX_F(0); + + gen6_vertex_flush(sna); + kgem_bo_destroy(&sna->kgem, tmp.src.bo); + _kgem_set_mode(&sna->kgem, KGEM_RENDER); + + return TRUE; +} + static void gen6_render_flush(struct sna *sna) { gen6_vertex_finish(sna, TRUE); @@ -3658,6 +3755,7 @@ Bool gen6_render_init(struct sna *sna) sna->render.fill_boxes = gen6_render_fill_boxes; sna->render.fill = gen6_render_fill; sna->render.fill_one = gen6_render_fill_one; + sna->render.clear = gen6_render_clear; sna->render.flush = gen6_render_flush; sna->render.reset = gen6_render_reset; diff --git a/src/sna/gen7_render.c b/src/sna/gen7_render.c index dd93ae99..9d17c879 100644 --- a/src/sna/gen7_render.c +++ b/src/sna/gen7_render.c @@ -55,6 +55,7 @@ #define NO_COPY_BOXES 0 #define NO_FILL 0 #define NO_FILL_BOXES 0 +#define NO_CLEAR 0 #define GEN7_MAX_SIZE 16384 @@ -3608,6 +3609,102 @@ gen7_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, return TRUE; } +static Bool +gen7_render_clear_try_blt(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) +{ + BoxRec box; + + box.x1 = 0; + box.y1 = 0; + box.x2 = dst->drawable.width; + box.y2 = dst->drawable.height; + + return sna_blt_fill_boxes(sna, GXclear, + bo, dst->drawable.bitsPerPixel, + 0, &box, 1); +} + +static Bool +gen7_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) +{ + struct sna_composite_op tmp; + +#if NO_CLEAR + return gen7_render_clear_try_blt(sna, dst, bo); +#endif + + DBG(("%s: %dx%d\n", + __FUNCTION__, + dst->drawable.width, + dst->drawable.height)); + + /* Prefer to use the BLT if already engaged */ + if (sna->kgem.ring == KGEM_BLT && + gen7_render_clear_try_blt(sna, dst, bo)) + return TRUE; + + /* Must use the BLT if we can't RENDER... */ + if (too_large(dst->drawable.width, dst->drawable.height)) + return gen7_render_clear_try_blt(sna, dst, bo); + + tmp.op = PictOpClear; + + tmp.dst.pixmap = dst; + tmp.dst.width = dst->drawable.width; + tmp.dst.height = dst->drawable.height; + tmp.dst.format = sna_format_for_depth(dst->drawable.depth); + tmp.dst.bo = bo; + tmp.dst.x = tmp.dst.y = 0; + + tmp.src.bo = sna_render_get_solid(sna, 0); + tmp.src.filter = SAMPLER_FILTER_NEAREST; + tmp.src.repeat = SAMPLER_EXTEND_REPEAT; + + tmp.mask.bo = NULL; + tmp.mask.filter = SAMPLER_FILTER_NEAREST; + tmp.mask.repeat = SAMPLER_EXTEND_NONE; + + tmp.is_affine = TRUE; + tmp.floats_per_vertex = 3; + tmp.floats_per_rect = 9; + tmp.has_component_alpha = 0; + tmp.need_magic_ca_pass = FALSE; + + tmp.u.gen7.wm_kernel = GEN6_WM_KERNEL_NOMASK; + tmp.u.gen7.nr_surfaces = 2; + tmp.u.gen7.nr_inputs = 1; + tmp.u.gen7.ve_id = 1; + + if (!kgem_check_bo(&sna->kgem, bo, NULL)) + _kgem_submit(&sna->kgem); + + gen7_emit_fill_state(sna, &tmp); + gen7_align_vertex(sna, &tmp); + + if (!gen7_get_rectangles(sna, &tmp, 1)) { + gen7_emit_fill_state(sna, &tmp); + gen7_get_rectangles(sna, &tmp, 1); + } + + OUT_VERTEX(dst->drawable.width, dst->drawable.height); + OUT_VERTEX_F(1); + OUT_VERTEX_F(1); + + OUT_VERTEX(0, dst->drawable.height); + OUT_VERTEX_F(0); + OUT_VERTEX_F(1); + + OUT_VERTEX(0, 0); + OUT_VERTEX_F(0); + OUT_VERTEX_F(0); + + gen7_vertex_flush(sna); + kgem_bo_destroy(&sna->kgem, tmp.src.bo); + _kgem_set_mode(&sna->kgem, KGEM_RENDER); + + return TRUE; +} + static void gen7_render_flush(struct sna *sna) { gen7_vertex_finish(sna, TRUE); @@ -3711,6 +3808,7 @@ Bool gen7_render_init(struct sna *sna) sna->render.fill_boxes = gen7_render_fill_boxes; sna->render.fill = gen7_render_fill; sna->render.fill_one = gen7_render_fill_one; + sna->render.clear = gen7_render_clear; sna->render.flush = gen7_render_flush; sna->render.reset = gen7_render_reset; diff --git a/src/sna/sna_glyphs.c b/src/sna/sna_glyphs.c index 209b199b..f64d2f91 100644 --- a/src/sna/sna_glyphs.c +++ b/src/sna/sna_glyphs.c @@ -654,11 +654,7 @@ static bool clear_pixmap(struct sna *sna, PixmapPtr pixmap) { struct sna_pixmap *priv = sna_pixmap(pixmap); - return sna->render.fill_one(sna, pixmap, priv->gpu_bo, 0, - 0, 0, - pixmap->drawable.width, - pixmap->drawable.height, - GXclear); + return sna->render.clear(sna, pixmap, priv->gpu_bo); } static Bool diff --git a/src/sna/sna_render.c b/src/sna/sna_render.c index 96c43666..c4d8a58c 100644 --- a/src/sna/sna_render.c +++ b/src/sna/sna_render.c @@ -197,6 +197,18 @@ no_render_fill_one(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo, color, &box, 1); } +static Bool +no_render_clear(struct sna *sna, PixmapPtr dst, struct kgem_bo *bo) +{ + DBG(("%s: pixmap=%ld %dx%d\n", __FUNCTION__, + dst->drawable.serialNumber, + dst->drawable.width, + dst->drawable.height)); + return sna->render.fill_one(sna, dst, bo, 0, + 0, 0, dst->drawable.width, dst->drawable.height, + GXclear); +} + static void no_render_reset(struct sna *sna) { (void)sna; @@ -235,6 +247,7 @@ void no_render_init(struct sna *sna) render->fill_boxes = no_render_fill_boxes; render->fill = no_render_fill; render->fill_one = no_render_fill_one; + render->clear = no_render_clear; render->reset = no_render_reset; render->flush = no_render_flush; diff --git a/src/sna/sna_render.h b/src/sna/sna_render.h index 5cd0d7cb..2229c18b 100644 --- a/src/sna/sna_render.h +++ b/src/sna/sna_render.h @@ -219,6 +219,7 @@ struct sna_render { uint32_t color, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint8_t alu); + Bool (*clear)(struct sna *sna, PixmapPtr dst, struct kgem_bo *dst_bo); Bool (*copy_boxes)(struct sna *sna, uint8_t alu, PixmapPtr src, struct kgem_bo *src_bo, int16_t src_dx, int16_t src_dy, |