From 2d263ff7e662bdedf685d4dbcf7cd1bfbf241395 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 24 Jun 2015 10:19:26 +0100 Subject: [PATCH] sna/gen4: Fix larger than 3D pipeline fills If we need to handle a FillRectangles request that is larger than the 3D pipeline can handle, we need to split that operation up into smaller chunks. This is achieved by redirecting the rendering through a view of the surface (offset so that coordinates are within range), or else we have to fallback to creating temporary surfaces. If we fail to do so, we should hit an assertion that the render target fits within the 3D pipeline inside gen4_emit_drawing_rectangle() Reported-by: Zdenek Kabelac Signed-off-by: Chris Wilson --- src/sna/gen4_render.c | 19 ++++++++++++++++++- src/sna/gen5_render.c | 14 ++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/sna/gen4_render.c b/src/sna/gen4_render.c index 89cf07aa..05006766 100644 --- a/src/sna/gen4_render.c +++ b/src/sna/gen4_render.c @@ -2740,6 +2740,20 @@ gen4_render_fill_boxes(struct sna *sna, tmp.dst.format = format; tmp.dst.bo = dst_bo; + sna_render_composite_redirect_init(&tmp); + if (too_large(dst->width, dst->height)) { + BoxRec extents; + + boxes_extents(box, n, &extents); + if (!sna_render_composite_redirect(sna, &tmp, + extents.x1, extents.y1, + extents.x2 - extents.x1, + extents.y2 - extents.y1, + n > 1)) + return sna_tiling_fill_boxes(sna, op, format, color, + dst, dst_bo, box, n); + } + gen4_channel_init_solid(sna, &tmp.src, pixel); tmp.is_affine = true; @@ -2750,8 +2764,10 @@ gen4_render_fill_boxes(struct sna *sna, if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { kgem_submit(&sna->kgem); - if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) + if (!kgem_check_bo(&sna->kgem, dst_bo, NULL)) { + kgem_bo_destroy(&sna->kgem, tmp.src.bo); return false; + } } gen4_align_vertex(sna, &tmp); @@ -2767,6 +2783,7 @@ gen4_render_fill_boxes(struct sna *sna, gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); + sna_render_composite_redirect_done(sna, &tmp); return true; } diff --git a/src/sna/gen5_render.c b/src/sna/gen5_render.c index 0f9f6736..099efb24 100644 --- a/src/sna/gen5_render.c +++ b/src/sna/gen5_render.c @@ -2734,6 +2734,19 @@ gen5_render_fill_boxes(struct sna *sna, tmp.dst.format = format; tmp.dst.bo = dst_bo; + if (too_large(dst->width, dst->height)) { + BoxRec extents; + + boxes_extents(box, n, &extents); + if (!sna_render_composite_redirect(sna, &tmp, + extents.x1, extents.y1, + extents.x2 - extents.x1, + extents.y2 - extents.y1, + n > 1)) + return sna_tiling_fill_boxes(sna, op, format, color, + dst, dst_bo, box, n); + } + tmp.src.bo = sna_render_get_solid(sna, pixel); tmp.src.filter = SAMPLER_FILTER_NEAREST; tmp.src.repeat = SAMPLER_EXTEND_REPEAT; @@ -2780,6 +2793,7 @@ gen5_render_fill_boxes(struct sna *sna, gen4_vertex_flush(sna); kgem_bo_destroy(&sna->kgem, tmp.src.bo); + sna_render_composite_redirect_done(sna, &tmp); return true; }