st/xa: scissor to help tilers

Keep track of the maximal bounds of all the operations and set scissor
accordingly.  For tiling GPU's this can be a big win by reducing the
memory bandwidth spent moving pixels from system memory to tile buffer
and back.

You could imagine being more sophisticated and splitting up disjoint
operations.  But this simplistic approach is good enough for the common
cases.

Signed-off-by: Rob Clark <robclark@freedesktop.org>
Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
This commit is contained in:
Rob Clark 2014-04-08 16:48:50 -04:00 committed by Thomas Hellstrom
parent 3c52013273
commit a45ae814d1
4 changed files with 48 additions and 0 deletions

View File

@ -512,6 +512,8 @@ xa_composite_rect(struct xa_context *ctx,
const float *src_matrix = NULL; const float *src_matrix = NULL;
const float *mask_matrix = NULL; const float *mask_matrix = NULL;
xa_scissor_update(ctx, dstX, dstY, dstX + width, dstY + height);
if (comp->src->has_transform) if (comp->src->has_transform)
src_matrix = comp->src->transform; src_matrix = comp->src->transform;
if (comp->mask && comp->mask->has_transform) if (comp->mask && comp->mask->has_transform)

View File

@ -238,6 +238,8 @@ xa_copy(struct xa_context *ctx,
{ {
struct pipe_box src_box; struct pipe_box src_box;
xa_scissor_update(ctx, dx, dy, dx + width, dy + height);
if (ctx->simple_copy) { if (ctx->simple_copy) {
u_box_2d(sx, sy, width, height, &src_box); u_box_2d(sx, sy, width, height, &src_box);
ctx->pipe->resource_copy_region(ctx->pipe, 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_EXPORT void
xa_solid(struct xa_context *ctx, int x, int y, int width, int height) 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); renderer_solid(ctx, x, y, x + width, y + height, ctx->solid_color);
} }

View File

@ -38,6 +38,8 @@
#include "pipe/p_context.h" #include "pipe/p_context.h"
#include "pipe/p_state.h" #include "pipe/p_state.h"
#include "util/u_math.h"
#if defined(__GNUC__) && __GNUC__ >= 4 #if defined(__GNUC__) && __GNUC__ >= 4
#define XA_EXPORT __attribute__ ((visibility("default"))) #define XA_EXPORT __attribute__ ((visibility("default")))
#else #else
@ -105,6 +107,12 @@ struct xa_context {
struct xa_surface *dst; struct xa_surface *dst;
struct pipe_surface *srf; 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 simple_copy;
int has_solid_color; int has_solid_color;
@ -115,6 +123,27 @@ struct xa_context {
const struct xa_composite *comp; 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 { enum xa_vs_traits {
VS_COMPOSITE = 1 << 0, VS_COMPOSITE = 1 << 0,
VS_MASK = 1 << 1, VS_MASK = 1 << 1,

View File

@ -79,11 +79,22 @@ renderer_draw(struct xa_context *r)
if (!r->buffer_size) if (!r->buffer_size)
return; 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); cso_set_vertex_elements(r->cso, r->attrs_per_vertex, r->velems);
util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS, util_draw_user_vertex_buffer(r->cso, r->buffer, PIPE_PRIM_QUADS,
num_verts, /* verts */ num_verts, /* verts */
r->attrs_per_vertex); /* attribs/vert */ r->attrs_per_vertex); /* attribs/vert */
r->buffer_size = 0; r->buffer_size = 0;
xa_scissor_reset(r);
} }
static INLINE void static INLINE void
@ -111,6 +122,7 @@ renderer_init_state(struct xa_context *r)
raster.half_pixel_center = 1; raster.half_pixel_center = 1;
raster.bottom_edge_rule = 1; raster.bottom_edge_rule = 1;
raster.depth_clip = 1; raster.depth_clip = 1;
raster.scissor = 1;
cso_set_rasterizer(r->cso, &raster); cso_set_rasterizer(r->cso, &raster);
/* vertex elements state */ /* vertex elements state */
@ -333,6 +345,8 @@ renderer_bind_destination(struct xa_context *r,
struct pipe_framebuffer_state fb; struct pipe_framebuffer_state fb;
struct pipe_viewport_state viewport; struct pipe_viewport_state viewport;
xa_scissor_reset(r);
/* Framebuffer uses actual surface width/height /* Framebuffer uses actual surface width/height
*/ */
memset(&fb, 0, sizeof fb); memset(&fb, 0, sizeof fb);