iris: Add support for damage region
Newer compositor sends the damaged region of the screen, with this we can reduce the rendering area discarding vertices outside of damaged area. Reviewed-by: Rohan Garg <rohan.garg@intel.com> Signed-off-by: José Roberto de Souza <jose.souza@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30048>
This commit is contained in:

committed by
Marge Bot

parent
57c5962413
commit
1fc82ee558
@@ -1014,6 +1014,8 @@ struct iris_context {
|
||||
struct pipe_stencil_ref stencil_ref;
|
||||
struct pipe_framebuffer_state framebuffer;
|
||||
struct pipe_clip_state clip_planes;
|
||||
/* width and height treated like x2 and y2 */
|
||||
struct pipe_box render_area;
|
||||
|
||||
float default_outer_level[4];
|
||||
float default_inner_level[2];
|
||||
|
@@ -167,6 +167,10 @@ struct iris_resource {
|
||||
* The screen the resource was originally created with, stored for refcounting.
|
||||
*/
|
||||
struct pipe_screen *orig_screen;
|
||||
|
||||
/* width and height treated like x2 and y2 */
|
||||
struct pipe_box damage;
|
||||
bool use_damage;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -753,6 +753,40 @@ iris_screen_get_fd(struct pipe_screen *pscreen)
|
||||
return screen->winsys_fd;
|
||||
}
|
||||
|
||||
static void
|
||||
iris_set_damage_region(struct pipe_screen *pscreen, struct pipe_resource *pres,
|
||||
unsigned int nrects, const struct pipe_box *rects)
|
||||
{
|
||||
struct iris_resource *res = (struct iris_resource *)pres;
|
||||
|
||||
res->use_damage = nrects > 0;
|
||||
if (!res->use_damage)
|
||||
return;
|
||||
|
||||
res->damage.x = INT32_MAX;
|
||||
res->damage.y = INT32_MAX;
|
||||
res->damage.width = 0;
|
||||
res->damage.height = 0;
|
||||
|
||||
for (unsigned i = 0; i < nrects; i++) {
|
||||
res->damage.x = MIN2(res->damage.x, rects[i].x);
|
||||
res->damage.y = MIN2(res->damage.y, rects[i].y);
|
||||
res->damage.width = MAX2(res->damage.width, rects[i].width + rects[i].x);
|
||||
res->damage.height = MAX2(res->damage.height, rects[i].height + rects[i].y);
|
||||
|
||||
if (unlikely(res->damage.x == 0 &&
|
||||
res->damage.y == 0 &&
|
||||
res->damage.width == res->base.b.width0 &&
|
||||
res->damage.height == res->base.b.height0))
|
||||
break;
|
||||
}
|
||||
|
||||
res->damage.x = MAX2(res->damage.x, 0);
|
||||
res->damage.y = MAX2(res->damage.y, 0);
|
||||
res->damage.width = MIN2(res->damage.width, res->base.b.width0);
|
||||
res->damage.height = MIN2(res->damage.height, res->base.b.height0);
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
iris_screen_create(int fd, const struct pipe_screen_config *config)
|
||||
{
|
||||
@@ -881,6 +915,7 @@ iris_screen_create(int fd, const struct pipe_screen_config *config)
|
||||
pscreen->query_memory_info = iris_query_memory_info;
|
||||
pscreen->get_driver_query_group_info = iris_get_monitor_group_info;
|
||||
pscreen->get_driver_query_info = iris_get_monitor_info;
|
||||
pscreen->set_damage_region = iris_set_damage_region;
|
||||
iris_init_screen_program_functions(pscreen);
|
||||
|
||||
genX_call(screen->devinfo, init_screen_state, screen);
|
||||
|
@@ -3765,6 +3765,8 @@ iris_set_framebuffer_state(struct pipe_context *ctx,
|
||||
struct pipe_framebuffer_state *cso = &ice->state.framebuffer;
|
||||
struct iris_resource *zres;
|
||||
struct iris_resource *stencil_res;
|
||||
struct iris_resource *new_res = NULL;
|
||||
struct pipe_box new_render_area;
|
||||
|
||||
unsigned samples = util_framebuffer_get_num_samples(state);
|
||||
unsigned layers = util_framebuffer_get_num_layers(state);
|
||||
@@ -3795,8 +3797,21 @@ iris_set_framebuffer_state(struct pipe_context *ctx,
|
||||
ice->state.dirty |= IRIS_DIRTY_CLIP;
|
||||
}
|
||||
|
||||
if (cso->width != state->width || cso->height != state->height) {
|
||||
if (state->nr_cbufs > 0 && state->cbufs[0])
|
||||
new_res = (struct iris_resource *)state->cbufs[0]->texture;
|
||||
|
||||
if (new_res && new_res->use_damage) {
|
||||
new_render_area = new_res->damage;
|
||||
} else {
|
||||
new_render_area.x = 0;
|
||||
new_render_area.y = 0;
|
||||
new_render_area.width = state->width;
|
||||
new_render_area.height = state->height;
|
||||
}
|
||||
|
||||
if (memcmp(&ice->state.render_area, &new_render_area, sizeof(new_render_area))) {
|
||||
ice->state.dirty |= IRIS_DIRTY_SF_CL_VIEWPORT;
|
||||
ice->state.render_area = new_render_area;
|
||||
}
|
||||
|
||||
if (cso->zsbuf || state->zsbuf) {
|
||||
@@ -6928,6 +6943,7 @@ iris_upload_dirty_render_state(struct iris_context *ice,
|
||||
|
||||
if (dirty & IRIS_DIRTY_SF_CL_VIEWPORT) {
|
||||
struct pipe_framebuffer_state *cso_fb = &ice->state.framebuffer;
|
||||
int32_t x_min, y_min, x_max, y_max;
|
||||
uint32_t sf_cl_vp_address;
|
||||
uint32_t *vp_map =
|
||||
stream_state(batch, ice->state.dynamic_uploader,
|
||||
@@ -6935,6 +6951,11 @@ iris_upload_dirty_render_state(struct iris_context *ice,
|
||||
4 * ice->state.num_viewports *
|
||||
GENX(SF_CLIP_VIEWPORT_length), 64, &sf_cl_vp_address);
|
||||
|
||||
x_min = ice->state.render_area.x;
|
||||
y_min = ice->state.render_area.y;
|
||||
x_max = ice->state.render_area.width;
|
||||
y_max = ice->state.render_area.height;
|
||||
|
||||
for (unsigned i = 0; i < ice->state.num_viewports; i++) {
|
||||
const struct pipe_viewport_state *state = &ice->state.viewports[i];
|
||||
float gb_xmin, gb_xmax, gb_ymin, gb_ymax;
|
||||
@@ -6944,7 +6965,7 @@ iris_upload_dirty_render_state(struct iris_context *ice,
|
||||
float vp_ymin = viewport_extent(state, 1, -1.0f);
|
||||
float vp_ymax = viewport_extent(state, 1, 1.0f);
|
||||
|
||||
intel_calculate_guardband_size(0, cso_fb->width, 0, cso_fb->height,
|
||||
intel_calculate_guardband_size(x_min, x_max, y_min, y_max,
|
||||
state->scale[0], state->scale[1],
|
||||
state->translate[0], state->translate[1],
|
||||
&gb_xmin, &gb_xmax, &gb_ymin, &gb_ymax);
|
||||
|
Reference in New Issue
Block a user