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;
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;
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;
}
}
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++) {
{
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;
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;
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 */
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);
if (res->scanout)
renderonly_scanout_destroy(res->scanout, screen->ro);
+ if (res->damage.region)
+ FREE(res->damage.region);
+
FREE(res);
}
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)
{
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 *
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;
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)