diff --git a/src/gallium/state_trackers/xa/xa_composite.c b/src/gallium/state_trackers/xa/xa_composite.c index b65f6eb09aa..7ae35a160e5 100644 --- a/src/gallium/state_trackers/xa/xa_composite.c +++ b/src/gallium/state_trackers/xa/xa_composite.c @@ -512,6 +512,8 @@ xa_composite_rect(struct xa_context *ctx, const float *src_matrix = NULL; const float *mask_matrix = NULL; + xa_scissor_update(ctx, dstX, dstY, dstX + width, dstY + height); + if (comp->src->has_transform) src_matrix = comp->src->transform; if (comp->mask && comp->mask->has_transform) diff --git a/src/gallium/state_trackers/xa/xa_context.c b/src/gallium/state_trackers/xa/xa_context.c index ee326762e42..867999a911b 100644 --- a/src/gallium/state_trackers/xa/xa_context.c +++ b/src/gallium/state_trackers/xa/xa_context.c @@ -238,6 +238,8 @@ xa_copy(struct xa_context *ctx, { struct pipe_box src_box; + xa_scissor_update(ctx, dx, dy, dx + width, dy + height); + if (ctx->simple_copy) { u_box_2d(sx, sy, width, height, &src_box); ctx->pipe->resource_copy_region(ctx->pipe, @@ -324,6 +326,7 @@ xa_solid_prepare(struct xa_context *ctx, struct xa_surface *dst, XA_EXPORT void xa_solid(struct xa_context *ctx, int x, int y, int width, int height) { + xa_scissor_update(ctx, x, y, x + width, y + height); renderer_solid(ctx, x, y, x + width, y + height, ctx->solid_color); } diff --git a/src/gallium/state_trackers/xa/xa_priv.h b/src/gallium/state_trackers/xa/xa_priv.h index 8b96bf56417..b67337995a8 100644 --- a/src/gallium/state_trackers/xa/xa_priv.h +++ b/src/gallium/state_trackers/xa/xa_priv.h @@ -38,6 +38,8 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" +#include "util/u_math.h" + #if defined(__GNUC__) && __GNUC__ >= 4 #define XA_EXPORT __attribute__ ((visibility("default"))) #else @@ -105,6 +107,12 @@ struct xa_context { struct xa_surface *dst; struct pipe_surface *srf; + /* destination scissor state.. we scissor out untouched parts + * of the dst for the benefit of tilers: + */ + struct pipe_scissor_state scissor; + int scissor_valid; + int simple_copy; int has_solid_color; @@ -115,6 +123,27 @@ struct xa_context { const struct xa_composite *comp; }; +static INLINE void +xa_scissor_reset(struct xa_context *ctx) +{ + ctx->scissor.maxx = 0; + ctx->scissor.maxy = 0; + ctx->scissor.minx = ~0; + ctx->scissor.miny = ~0; + ctx->scissor_valid = FALSE; +} + +static INLINE void +xa_scissor_update(struct xa_context *ctx, unsigned minx, unsigned miny, + unsigned maxx, unsigned maxy) +{ + ctx->scissor.maxx = MAX2(ctx->scissor.maxx, maxx); + ctx->scissor.maxy = MAX2(ctx->scissor.maxy, maxy); + ctx->scissor.minx = MIN2(ctx->scissor.minx, minx); + ctx->scissor.miny = MIN2(ctx->scissor.miny, miny); + ctx->scissor_valid = TRUE; +} + enum xa_vs_traits { VS_COMPOSITE = 1 << 0, VS_MASK = 1 << 1, diff --git a/src/gallium/state_trackers/xa/xa_renderer.c b/src/gallium/state_trackers/xa/xa_renderer.c index 33ae133dacb..121d8ed3b9b 100644 --- a/src/gallium/state_trackers/xa/xa_renderer.c +++ b/src/gallium/state_trackers/xa/xa_renderer.c @@ -79,11 +79,22 @@ renderer_draw(struct xa_context *r) if (!r->buffer_size) return; + if (!r->scissor_valid) { + r->scissor.minx = 0; + r->scissor.miny = 0; + r->scissor.maxx = r->dst->tex->width0; + r->scissor.maxy = r->dst->tex->height0; + } + + r->pipe->set_scissor_states(r->pipe, 0, 1, &r->scissor); + cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems); util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS, num_verts, /* verts */ r->attrs_per_vertex); /* attribs/vert */ r->buffer_size = 0; + + xa_scissor_reset(r); } static INLINE void @@ -111,6 +122,7 @@ renderer_init_state(struct xa_context *r) raster.half_pixel_center = 1; raster.bottom_edge_rule = 1; raster.depth_clip = 1; + raster.scissor = 1; cso_set_rasterizer(r->cso, &raster); /* vertex elements state */ @@ -333,6 +345,8 @@ renderer_bind_destination(struct xa_context *r, struct pipe_framebuffer_state fb; struct pipe_viewport_state viewport; + xa_scissor_reset(r); + /* Framebuffer uses actual surface width/height */ memset(&fb, 0, sizeof fb);