summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQiang Yu <[email protected]>2019-06-30 21:44:12 +0800
committerQiang Yu <[email protected]>2019-09-23 09:48:15 +0800
commitafbaed906d7ba89467b177e768c36f29d6053ad0 (patch)
tree2a7bfd5aa0f1cb3f34bf08f350feb4c3c4e487db
parent8278b236b05b2d2f04439e6bc12766315a95869b (diff)
lima: implement EGL_KHR_partial_update
This extension set a damage region for each buffer swap which can be used to reduce buffer reload cost by only feed damage region's tile buffer address for PP. Reviewed-and-Tested-by: Vasily Khoruzhick <[email protected]> Signed-off-by: Qiang Yu <[email protected]>
-rw-r--r--src/gallium/drivers/lima/lima_context.h7
-rw-r--r--src/gallium/drivers/lima/lima_draw.c43
-rw-r--r--src/gallium/drivers/lima/lima_resource.c50
-rw-r--r--src/gallium/drivers/lima/lima_resource.h7
-rw-r--r--src/gallium/drivers/lima/lima_state.c44
5 files changed, 86 insertions, 65 deletions
diff --git a/src/gallium/drivers/lima/lima_context.h b/src/gallium/drivers/lima/lima_context.h
index 286f8dc86c2..3d8bf6c2b3f 100644
--- a/src/gallium/drivers/lima/lima_context.h
+++ b/src/gallium/drivers/lima/lima_context.h
@@ -159,12 +159,6 @@ struct lima_ctx_plb_pp_stream {
uint32_t offset[4];
};
-struct lima_damage_state {
- struct pipe_scissor_state *region;
- unsigned num_region;
- bool aligned;
-};
-
struct lima_pp_stream_state {
struct lima_bo *bo;
uint32_t bo_offset;
@@ -213,7 +207,6 @@ struct lima_context {
struct pipe_stencil_ref stencil_ref;
struct lima_context_constant_buffer const_buffer[PIPE_SHADER_TYPES];
struct lima_texture_stateobj tex_stateobj;
- struct lima_damage_state damage;
struct lima_pp_stream_state pp_stream;
unsigned min_index;
diff --git a/src/gallium/drivers/lima/lima_draw.c b/src/gallium/drivers/lima/lima_draw.c
index ab7f1b134c2..6bd738c55ed 100644
--- a/src/gallium/drivers/lima/lima_draw.c
+++ b/src/gallium/drivers/lima/lima_draw.c
@@ -210,23 +210,36 @@ lima_ctx_dirty(struct lima_context *ctx)
return ctx->plbu_cmd_array.size;
}
+static inline struct lima_damage_region *
+lima_ctx_get_damage(struct lima_context *ctx)
+{
+ if (!ctx->framebuffer.base.nr_cbufs)
+ return NULL;
+
+ struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]);
+ struct lima_resource *res = lima_resource(surf->base.texture);
+ return &res->damage;
+}
+
static bool
lima_fb_need_reload(struct lima_context *ctx)
{
/* Depth buffer is always discarded */
if (!ctx->framebuffer.base.nr_cbufs)
return false;
- if (ctx->damage.region) {
- /* for EGL_KHR_partial_update we just want to reload the
- * region not aligned to tile boundary */
- if (!ctx->damage.aligned)
- return true;
+
+ struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]);
+ struct lima_resource *res = lima_resource(surf->base.texture);
+ if (res->damage.region) {
+ /* for EGL_KHR_partial_update, when EGL_EXT_buffer_age is enabled,
+ * we need to reload damage region, otherwise just want to reload
+ * the region not aligned to tile boundary */
+ //if (!res->damage.aligned)
+ // return true;
+ return true;
}
- else {
- struct lima_surface *surf = lima_surface(ctx->framebuffer.base.cbufs[0]);
- if (surf->reload)
+ else if (surf->reload)
return true;
- }
return false;
}
@@ -510,9 +523,9 @@ lima_get_pp_stream_size(int num_pp, int tiled_w, int tiled_h, uint32_t *off)
}
static bool
-inside_damage_region(int x, int y, struct lima_damage_state *ds)
+inside_damage_region(int x, int y, struct lima_damage_region *ds)
{
- if (!ds->region)
+ if (!ds || !ds->region)
return true;
for (int i = 0; i < ds->num_region; i++) {
@@ -531,6 +544,7 @@ lima_update_pp_stream(struct lima_context *ctx, int off_x, int off_y,
{
struct lima_pp_stream_state *ps = &ctx->pp_stream;
struct lima_context_framebuffer *fb = &ctx->framebuffer;
+ struct lima_damage_region *damage = lima_ctx_get_damage(ctx);
struct lima_screen *screen = lima_screen(ctx->base.screen);
int i, num_pp = screen->num_pp;
@@ -556,7 +570,7 @@ lima_update_pp_stream(struct lima_context *ctx, int off_x, int off_y,
x += off_x;
y += off_y;
- if (!inside_damage_region(x, y, &ctx->damage))
+ if (!inside_damage_region(x, y, damage))
continue;
int pp = index % num_pp;
@@ -586,7 +600,7 @@ lima_update_pp_stream(struct lima_context *ctx, int off_x, int off_y,
static void
lima_update_damage_pp_stream(struct lima_context *ctx)
{
- struct lima_damage_state *ds = &ctx->damage;
+ struct lima_damage_region *ds = lima_ctx_get_damage(ctx);
struct pipe_scissor_state max = ds->region[0];
/* find a max region to cover all the damage region */
@@ -671,7 +685,8 @@ lima_update_submit_bo(struct lima_context *ctx)
ctx->plb_gp_size, false, "gp plb stream at va %x\n",
ctx->plb_gp_stream->va + ctx->plb_index * ctx->plb_gp_size);
- if (ctx->damage.region)
+ struct lima_damage_region *damage = lima_ctx_get_damage(ctx);
+ if (damage && damage->region)
lima_update_damage_pp_stream(ctx);
else if (ctx->plb_pp_stream)
lima_update_full_pp_stream(ctx);
diff --git a/src/gallium/drivers/lima/lima_resource.c b/src/gallium/drivers/lima/lima_resource.c
index 741fda1f222..b2e33f4d3ff 100644
--- a/src/gallium/drivers/lima/lima_resource.c
+++ b/src/gallium/drivers/lima/lima_resource.c
@@ -264,6 +264,9 @@ lima_resource_destroy(struct pipe_screen *pscreen, struct pipe_resource *pres)
if (res->scanout)
renderonly_scanout_destroy(res->scanout, screen->ro);
+ if (res->damage.region)
+ FREE(res->damage.region);
+
FREE(res);
}
@@ -343,6 +346,52 @@ lima_resource_get_handle(struct pipe_screen *pscreen,
return true;
}
+static void
+lima_resource_set_damage_region(struct pipe_screen *pscreen,
+ struct pipe_resource *pres,
+ unsigned int nrects,
+ const struct pipe_box *rects)
+{
+ struct lima_resource *res = lima_resource(pres);
+ struct lima_damage_region *damage = &res->damage;
+ int i;
+
+ if (damage->region) {
+ FREE(damage->region);
+ damage->region = NULL;
+ damage->num_region = 0;
+ }
+
+ if (!nrects)
+ return;
+
+ damage->region = CALLOC(nrects, sizeof(*damage->region));
+ if (!damage->region)
+ return;
+
+ for (i = 0; i < nrects; i++) {
+ struct pipe_scissor_state *r = damage->region + i;
+ int y = pres->height0 - (rects[i].y + rects[i].height);
+ /* region in tile unit */
+ r->minx = rects[i].x >> 4;
+ r->miny = y >> 4;
+ r->maxx = (rects[i].x + rects[i].width + 0xf) >> 4;
+ r->maxy = (y + rects[i].height + 0xf) >> 4;
+ }
+
+ /* is region aligned to tiles? */
+ damage->aligned = true;
+ for (i = 0; i < nrects; i++) {
+ if (rects[i].x & 0xf || rects[i].y & 0xf ||
+ rects[i].width & 0xf || rects[i].height & 0xf) {
+ damage->aligned = false;
+ break;
+ }
+ }
+
+ damage->num_region = nrects;
+}
+
void
lima_resource_screen_init(struct lima_screen *screen)
{
@@ -351,6 +400,7 @@ lima_resource_screen_init(struct lima_screen *screen)
screen->base.resource_from_handle = lima_resource_from_handle;
screen->base.resource_destroy = lima_resource_destroy;
screen->base.resource_get_handle = lima_resource_get_handle;
+ screen->base.set_damage_region = lima_resource_set_damage_region;
}
static struct pipe_surface *
diff --git a/src/gallium/drivers/lima/lima_resource.h b/src/gallium/drivers/lima/lima_resource.h
index ba88b0696fe..7e7a9628a86 100644
--- a/src/gallium/drivers/lima/lima_resource.h
+++ b/src/gallium/drivers/lima/lima_resource.h
@@ -38,9 +38,16 @@ struct lima_resource_level {
uint32_t offset;
};
+struct lima_damage_region {
+ struct pipe_scissor_state *region;
+ unsigned num_region;
+ bool aligned;
+};
+
struct lima_resource {
struct pipe_resource base;
+ struct lima_damage_region damage;
struct renderonly_scanout *scanout;
struct lima_bo *bo;
bool tiled;
diff --git a/src/gallium/drivers/lima/lima_state.c b/src/gallium/drivers/lima/lima_state.c
index fb3b36a4b2b..286529e9db0 100644
--- a/src/gallium/drivers/lima/lima_state.c
+++ b/src/gallium/drivers/lima/lima_state.c
@@ -414,50 +414,6 @@ lima_set_sampler_views(struct pipe_context *pctx,
ctx->dirty |= LIMA_CONTEXT_DIRTY_TEXTURES;
}
-UNUSED static bool
-lima_set_damage_region(struct pipe_context *pctx, unsigned num_rects, int *rects)
-{
- struct lima_context *ctx = lima_context(pctx);
- struct lima_damage_state *damage = &ctx->damage;
- int i;
-
- if (damage->region)
- ralloc_free(damage->region);
-
- if (!num_rects) {
- damage->region = NULL;
- damage->num_region = 0;
- return true;
- }
-
- damage->region = ralloc_size(ctx, sizeof(*damage->region) * num_rects);
- if (!damage->region) {
- damage->num_region = 0;
- return false;
- }
-
- for (i = 0; i < num_rects; i++) {
- struct pipe_scissor_state *r = damage->region + i;
- /* region in tile unit */
- r->minx = rects[i * 4] >> 4;
- r->miny = rects[i * 4 + 1] >> 4;
- r->maxx = (rects[i * 4] + rects[i * 4 + 2] + 0xf) >> 4;
- r->maxy = (rects[i * 4 + 1] + rects[i * 4 + 3] + 0xf) >> 4;
- }
-
- /* is region aligned to tiles? */
- damage->aligned = true;
- for (i = 0; i < num_rects * 4; i++) {
- if (rects[i] & 0xf) {
- damage->aligned = false;
- break;
- }
- }
-
- damage->num_region = num_rects;
- return true;
-}
-
static void
lima_set_sample_mask(struct pipe_context *pctx,
unsigned sample_mask)