aboutsummaryrefslogtreecommitdiffstats
path: root/src/gallium/state_trackers/xa
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2014-04-08 16:48:50 -0400
committerThomas Hellstrom <[email protected]>2014-04-17 09:42:06 +0200
commita45ae814d1985bb9e72ba8f5cb73e070d22bd5b6 (patch)
tree907c37bb2a453670e5aeab335a543a82c0df2a59 /src/gallium/state_trackers/xa
parent3c520132737623d53e5c8dec6d3496ab8dffda1f (diff)
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 <[email protected]> Reviewed-by: Thomas Hellstrom <[email protected]>
Diffstat (limited to 'src/gallium/state_trackers/xa')
-rw-r--r--src/gallium/state_trackers/xa/xa_composite.c2
-rw-r--r--src/gallium/state_trackers/xa/xa_context.c3
-rw-r--r--src/gallium/state_trackers/xa/xa_priv.h29
-rw-r--r--src/gallium/state_trackers/xa/xa_renderer.c14
4 files changed, 48 insertions, 0 deletions
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);