From 3d38c9597ff3b687026fa4c664f8b4aa20b97f53 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 15 Feb 2024 14:35:12 -0500 Subject: [PATCH] zink: hook up KHR_partial_update this just requires clamping the renderArea to the passed damage rect, which is composed by merging all the passed rects into a single large region Part-of: --- src/gallium/drivers/zink/zink_context.c | 2 ++ src/gallium/drivers/zink/zink_render_pass.c | 8 ++++++++ src/gallium/drivers/zink/zink_screen.c | 18 ++++++++++++++++++ src/gallium/drivers/zink/zink_types.h | 3 +++ 4 files changed, 31 insertions(+) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 97289d788da..52f511e1705 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -2923,6 +2923,8 @@ begin_rendering(struct zink_context *ctx) assert(ctx->dynamic_fb.info.renderArea.extent.height <= res->base.b.height0); assert(ctx->fb_state.width <= res->base.b.width0); assert(ctx->fb_state.height <= res->base.b.height0); + if (res->use_damage) + ctx->dynamic_fb.info.renderArea = res->damage; } if (ctx->fb_state.zsbuf && zsbuf_used) { struct zink_surface *surf = zink_csurface(ctx->fb_state.zsbuf); diff --git a/src/gallium/drivers/zink/zink_render_pass.c b/src/gallium/drivers/zink/zink_render_pass.c index 0dfd93d05a8..d2b907ba78b 100644 --- a/src/gallium/drivers/zink/zink_render_pass.c +++ b/src/gallium/drivers/zink/zink_render_pass.c @@ -662,6 +662,14 @@ begin_render_pass(struct zink_context *ctx) rpbi.renderArea.extent.width = fb_state->width; rpbi.renderArea.extent.height = fb_state->height; + if (ctx->fb_state.cbufs[0]) { + struct zink_resource *res = zink_resource(ctx->fb_state.cbufs[0]->texture); + if (zink_is_swapchain(res)) { + if (res->use_damage) + rpbi.renderArea = res->damage; + } + } + VkClearValue clears[PIPE_MAX_COLOR_BUFS + 1] = {0}; unsigned clear_buffers = 0; uint32_t clear_validate = 0; diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index 80fbc74048b..11e54a0054a 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -1533,6 +1533,22 @@ zink_is_format_supported(struct pipe_screen *pscreen, return true; } +static void +zink_set_damage_region(struct pipe_screen *pscreen, struct pipe_resource *pres, unsigned int nrects, const struct pipe_box *rects) +{ + struct zink_resource *res = zink_resource(pres); + + for (unsigned i = 0; i < nrects; i++) { + int y = pres->height0 - rects[i].y - rects[i].height; + res->damage.extent.width = MAX2(res->damage.extent.width, rects[i].x + rects[i].width); + res->damage.extent.height = MAX2(res->damage.extent.height, y + rects[i].height); + res->damage.offset.x = MIN2(res->damage.offset.x, rects[i].x); + res->damage.offset.y = MIN2(res->damage.offset.y, y); + } + + res->use_damage = nrects > 0; +} + static void zink_destroy_screen(struct pipe_screen *pscreen) { @@ -1825,6 +1841,7 @@ zink_flush_frontbuffer(struct pipe_screen *pscreen, util_queue_fence_wait(&bs->flush_completed); } } + res->use_damage = false; /* always verify that this was acquired */ assert(zink_kopper_acquired(res->obj->dt, res->obj->dt_idx)); @@ -3457,6 +3474,7 @@ zink_internal_create_screen(const struct pipe_screen_config *config, int64_t dev screen->base.get_sparse_texture_virtual_page_size = zink_get_sparse_texture_virtual_page_size; screen->base.get_driver_query_group_info = zink_get_driver_query_group_info; screen->base.get_driver_query_info = zink_get_driver_query_info; + screen->base.set_damage_region = zink_set_damage_region; if (screen->info.have_EXT_sample_locations) { VkMultisamplePropertiesEXT prop; diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index edc705584a1..bc668b60d8e 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1360,6 +1360,9 @@ struct zink_resource { }; }; + VkRect2D damage; + bool use_damage; + bool copies_warned; bool swapchain; bool dmabuf;