From 962b162766126e3d8c5599aca8dcac1d83df0f47 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Tue, 26 Jan 2021 10:37:32 -0500 Subject: [PATCH] zink: update scissor only when necessary Reviewed-by: Dave Airlie Part-of: --- src/gallium/drivers/zink/zink_context.c | 7 +++++ src/gallium/drivers/zink/zink_context.h | 1 + src/gallium/drivers/zink/zink_draw.c | 41 +++++++++++++------------ src/gallium/drivers/zink/zink_state.c | 3 ++ 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index abad104d17b..af1a1e468d1 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -892,6 +892,7 @@ zink_set_scissor_states(struct pipe_context *pctx, for (unsigned i = 0; i < num_scissors; i++) ctx->vp_state.scissor_states[start_slot + i] = states[i]; + ctx->scissor_changed = true; } static void @@ -1710,6 +1711,7 @@ flush_batch(struct zink_context *ctx, bool sync) ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true; ctx->vertex_buffers_dirty = true; ctx->vp_state_changed = true; + ctx->scissor_changed = true; } } @@ -1787,7 +1789,12 @@ zink_set_framebuffer_state(struct pipe_context *pctx, ctx->rp_changed |= ctx->fb_state.nr_cbufs != state->nr_cbufs; ctx->rp_changed |= !!ctx->fb_state.zsbuf != !!state->zsbuf; + unsigned w = ctx->fb_state.width; + unsigned h = ctx->fb_state.height; + util_copy_framebuffer_state(&ctx->fb_state, state); + if (ctx->fb_state.width != w || ctx->fb_state.height != h) + ctx->scissor_changed = true; rebind_fb_state(ctx, NULL, true); /* get_framebuffer adds a ref if the fb is reused or created; * always do get_framebuffer first to avoid deleting the same fb diff --git a/src/gallium/drivers/zink/zink_context.h b/src/gallium/drivers/zink/zink_context.h index 0aa484882dc..f097c66b5f1 100644 --- a/src/gallium/drivers/zink/zink_context.h +++ b/src/gallium/drivers/zink/zink_context.h @@ -204,6 +204,7 @@ struct zink_context { struct zink_viewport_state vp_state; bool vp_state_changed; + bool scissor_changed; float line_width; float blend_constants[4]; diff --git a/src/gallium/drivers/zink/zink_draw.c b/src/gallium/drivers/zink/zink_draw.c index f9f1523021e..d237a3a755e 100644 --- a/src/gallium/drivers/zink/zink_draw.c +++ b/src/gallium/drivers/zink/zink_draw.c @@ -562,28 +562,31 @@ zink_draw_vbo(struct pipe_context *pctx, else vkCmdSetViewport(batch->state->cmdbuf, 0, ctx->vp_state.num_viewports, viewports); } - VkRect2D scissors[PIPE_MAX_VIEWPORTS]; - if (ctx->rast_state->base.scissor) { - for (unsigned i = 0; i < ctx->vp_state.num_viewports; i++) { - scissors[i].offset.x = ctx->vp_state.scissor_states[i].minx; - scissors[i].offset.y = ctx->vp_state.scissor_states[i].miny; - scissors[i].extent.width = ctx->vp_state.scissor_states[i].maxx - ctx->vp_state.scissor_states[i].minx; - scissors[i].extent.height = ctx->vp_state.scissor_states[i].maxy - ctx->vp_state.scissor_states[i].miny; - } - } else { - for (unsigned i = 0; i < ctx->vp_state.num_viewports; i++) { - scissors[i].offset.x = 0; - scissors[i].offset.y = 0; - scissors[i].extent.width = ctx->fb_state.width; - scissors[i].extent.height = ctx->fb_state.height; + if (ctx->scissor_changed || ctx->vp_state_changed || pipeline_changed) { + VkRect2D scissors[PIPE_MAX_VIEWPORTS]; + if (ctx->rast_state->base.scissor) { + for (unsigned i = 0; i < ctx->vp_state.num_viewports; i++) { + scissors[i].offset.x = ctx->vp_state.scissor_states[i].minx; + scissors[i].offset.y = ctx->vp_state.scissor_states[i].miny; + scissors[i].extent.width = ctx->vp_state.scissor_states[i].maxx - ctx->vp_state.scissor_states[i].minx; + scissors[i].extent.height = ctx->vp_state.scissor_states[i].maxy - ctx->vp_state.scissor_states[i].miny; + } + } else { + for (unsigned i = 0; i < ctx->vp_state.num_viewports; i++) { + scissors[i].offset.x = 0; + scissors[i].offset.y = 0; + scissors[i].extent.width = ctx->fb_state.width; + scissors[i].extent.height = ctx->fb_state.height; + } } + if (screen->info.have_EXT_extended_dynamic_state) + screen->vk_CmdSetScissorWithCountEXT(batch->state->cmdbuf, ctx->vp_state.num_viewports, scissors); + else + vkCmdSetScissor(batch->state->cmdbuf, 0, ctx->vp_state.num_viewports, scissors); } - if (screen->info.have_EXT_extended_dynamic_state) - screen->vk_CmdSetScissorWithCountEXT(batch->state->cmdbuf, ctx->vp_state.num_viewports, scissors); - else - vkCmdSetScissor(batch->state->cmdbuf, 0, ctx->vp_state.num_viewports, scissors); - ctx->vp_state_changed = false; + ctx->scissor_changed = false; + if (line_width_needed(reduced_prim, rast_state->hw_state.polygon_mode)) { if (screen->info.feats.features.wideLines || ctx->line_width == 1.0f) vkCmdSetLineWidth(batch->state->cmdbuf, ctx->line_width); diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c index b006d67c39e..084f244f022 100644 --- a/src/gallium/drivers/zink/zink_state.c +++ b/src/gallium/drivers/zink/zink_state.c @@ -474,6 +474,7 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso) struct zink_screen *screen = zink_screen(pctx->screen); bool clip_halfz = ctx->rast_state ? ctx->rast_state->base.clip_halfz : false; bool point_quad_rasterization = ctx->rast_state ? ctx->rast_state->base.point_quad_rasterization : false; + bool scissor = ctx->rast_state ? ctx->rast_state->base.scissor : false; ctx->rast_state = cso; if (ctx->rast_state) { @@ -503,6 +504,8 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso) } if (ctx->rast_state->base.point_quad_rasterization != point_quad_rasterization) ctx->dirty_shader_stages |= BITFIELD_BIT(PIPE_SHADER_FRAGMENT); + if (ctx->rast_state->base.scissor != scissor) + ctx->scissor_changed = true; } }