zink: always do full-fb clears in renderpass begin when possible
previously if any of the pending clears required an explicit clear then we'd clear them explicitly, but with this patch we're shifting the first pending clear into the renderpass begin if possible and then applying the remaining clears on top of that in order to reduce gpu operations Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9206>
This commit is contained in:
parent
5fe329e307
commit
5ac0c2c5c9
|
@ -267,7 +267,7 @@ zink_clear_framebuffer(struct zink_context *ctx, unsigned clear_buffers)
|
|||
if (num_clears != zink_fb_clear_count(fb_clear))
|
||||
goto out;
|
||||
/* compare all the clears to determine if we can batch these buffers together */
|
||||
for (int j = 0; j < num_clears; j++) {
|
||||
for (int j = !zink_fb_clear_first_needs_explicit(fb_clear); j < num_clears; j++) {
|
||||
struct zink_framebuffer_clear_data *a = zink_fb_clear_element(color_clear, j);
|
||||
struct zink_framebuffer_clear_data *b = zink_fb_clear_element(fb_clear, j);
|
||||
/* scissors don't match, fire this one off */
|
||||
|
@ -292,7 +292,7 @@ zink_clear_framebuffer(struct zink_context *ctx, unsigned clear_buffers)
|
|||
if (num_clears != zink_fb_clear_count(fb_clear))
|
||||
goto out;
|
||||
/* compare all the clears to determine if we can batch these buffers together */
|
||||
for (int j = 0; j < zink_fb_clear_count(color_clear); j++) {
|
||||
for (int j = !zink_fb_clear_first_needs_explicit(fb_clear); j < zink_fb_clear_count(color_clear); j++) {
|
||||
struct zink_framebuffer_clear_data *a = zink_fb_clear_element(color_clear, j);
|
||||
struct zink_framebuffer_clear_data *b = zink_fb_clear_element(fb_clear, j);
|
||||
/* scissors don't match, fire this one off */
|
||||
|
@ -307,7 +307,7 @@ zink_clear_framebuffer(struct zink_context *ctx, unsigned clear_buffers)
|
|||
out:
|
||||
if (to_clear) {
|
||||
if (num_clears) {
|
||||
for (int j = 0; j < num_clears; j++) {
|
||||
for (int j = !zink_fb_clear_first_needs_explicit(color_clear); j < num_clears; j++) {
|
||||
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(color_clear, j);
|
||||
struct zink_framebuffer_clear_data *zsclear = NULL;
|
||||
if (zs_clear)
|
||||
|
@ -319,7 +319,7 @@ out:
|
|||
zsclear ? zsclear->zs.stencil : 0);
|
||||
}
|
||||
} else {
|
||||
for (int j = 0; j < zink_fb_clear_count(zs_clear); j++) {
|
||||
for (int j = !zink_fb_clear_first_needs_explicit(zs_clear); j < zink_fb_clear_count(zs_clear); j++) {
|
||||
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(zs_clear, j);
|
||||
zink_clear(&ctx->base, to_clear,
|
||||
clear->has_scissor ? &clear->scissor : NULL,
|
||||
|
@ -408,8 +408,15 @@ zink_fb_clear_needs_explicit(struct zink_framebuffer_clear *fb_clear)
|
|||
{
|
||||
if (zink_fb_clear_count(fb_clear) != 1)
|
||||
return true;
|
||||
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
|
||||
return clear->has_scissor || clear->conditional;
|
||||
return zink_fb_clear_element_needs_explicit(zink_fb_clear_element(fb_clear, 0));
|
||||
}
|
||||
|
||||
bool
|
||||
zink_fb_clear_first_needs_explicit(struct zink_framebuffer_clear *fb_clear)
|
||||
{
|
||||
if (!zink_fb_clear_count(fb_clear))
|
||||
return false;
|
||||
return zink_fb_clear_element_needs_explicit(zink_fb_clear_element(fb_clear, 0));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -70,6 +70,9 @@ zink_clear_texture(struct pipe_context *ctx,
|
|||
bool
|
||||
zink_fb_clear_needs_explicit(struct zink_framebuffer_clear *fb_clear);
|
||||
|
||||
bool
|
||||
zink_fb_clear_first_needs_explicit(struct zink_framebuffer_clear *fb_clear);
|
||||
|
||||
void
|
||||
zink_clear_framebuffer(struct zink_context *ctx, unsigned clear_buffers);
|
||||
|
||||
|
@ -92,6 +95,12 @@ zink_fb_clear_reset(struct zink_framebuffer_clear *fb_clear)
|
|||
fb_clear->enabled = false;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
zink_fb_clear_element_needs_explicit(struct zink_framebuffer_clear_data *clear)
|
||||
{
|
||||
return clear->has_scissor || clear->conditional;
|
||||
}
|
||||
|
||||
void
|
||||
zink_clear_apply_conditionals(struct zink_context *ctx);
|
||||
|
||||
|
|
|
@ -740,7 +740,7 @@ get_render_pass(struct zink_context *ctx)
|
|||
state.rts[i].format = zink_get_format(screen, surf->format);
|
||||
state.rts[i].samples = surf->texture->nr_samples > 0 ? surf->texture->nr_samples :
|
||||
VK_SAMPLE_COUNT_1_BIT;
|
||||
state.rts[i].clear_color = ctx->fb_clears[i].enabled && !zink_fb_clear_needs_explicit(&ctx->fb_clears[i]);
|
||||
state.rts[i].clear_color = ctx->fb_clears[i].enabled && !zink_fb_clear_first_needs_explicit(&ctx->fb_clears[i]);
|
||||
clears |= !!state.rts[i].clear_color ? BITFIELD_BIT(i) : 0;
|
||||
} else {
|
||||
state.rts[i].format = VK_FORMAT_R8_UINT;
|
||||
|
@ -756,10 +756,10 @@ get_render_pass(struct zink_context *ctx)
|
|||
state.rts[fb->nr_cbufs].format = zsbuf->format;
|
||||
state.rts[fb->nr_cbufs].samples = zsbuf->base.nr_samples > 0 ? zsbuf->base.nr_samples : VK_SAMPLE_COUNT_1_BIT;
|
||||
state.rts[fb->nr_cbufs].clear_color = fb_clear->enabled &&
|
||||
!zink_fb_clear_needs_explicit(fb_clear) &&
|
||||
!zink_fb_clear_first_needs_explicit(fb_clear) &&
|
||||
(zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_DEPTH);
|
||||
state.rts[fb->nr_cbufs].clear_stencil = fb_clear->enabled &&
|
||||
!zink_fb_clear_needs_explicit(fb_clear) &&
|
||||
!zink_fb_clear_first_needs_explicit(fb_clear) &&
|
||||
(zink_fb_clear_element(fb_clear, 0)->zs.bits & PIPE_CLEAR_STENCIL);
|
||||
clears |= state.rts[fb->nr_cbufs].clear_color || state.rts[fb->nr_cbufs].clear_stencil ? BITFIELD_BIT(fb->nr_cbufs) : 0;;
|
||||
state.num_rts++;
|
||||
|
@ -869,12 +869,14 @@ zink_begin_render_pass(struct zink_context *ctx, struct zink_batch *batch)
|
|||
if (!fb_state->cbufs[i] || !ctx->fb_clears[i].enabled)
|
||||
continue;
|
||||
/* these need actual clear calls inside the rp */
|
||||
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(&ctx->fb_clears[i], 0);
|
||||
if (zink_fb_clear_needs_explicit(&ctx->fb_clears[i])) {
|
||||
clear_buffers |= (PIPE_CLEAR_COLOR0 << i);
|
||||
if (zink_fb_clear_count(&ctx->fb_clears[i]) < 2 ||
|
||||
zink_fb_clear_element_needs_explicit(clear))
|
||||
continue;
|
||||
}
|
||||
/* we now know there's only one clear */
|
||||
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(&ctx->fb_clears[i], 0);
|
||||
/* we now know there's one clear that can be done here */
|
||||
if (clear->color.srgb) {
|
||||
clears[i].color.float32[0] = util_format_srgb_to_linear_float(clear->color.color.f[0]);
|
||||
clears[i].color.float32[1] = util_format_srgb_to_linear_float(clear->color.color.f[1]);
|
||||
|
@ -891,17 +893,18 @@ zink_begin_render_pass(struct zink_context *ctx, struct zink_batch *batch)
|
|||
}
|
||||
if (fb_state->zsbuf && ctx->fb_clears[PIPE_MAX_COLOR_BUFS].enabled) {
|
||||
struct zink_framebuffer_clear *fb_clear = &ctx->fb_clears[PIPE_MAX_COLOR_BUFS];
|
||||
if (zink_fb_clear_needs_explicit(fb_clear)) {
|
||||
for (int j = 0; j < zink_fb_clear_count(fb_clear); j++)
|
||||
clear_buffers |= zink_fb_clear_element(fb_clear, j)->zs.bits;
|
||||
} else {
|
||||
struct zink_framebuffer_clear_data *clear = zink_fb_clear_element(fb_clear, 0);
|
||||
if (!zink_fb_clear_element_needs_explicit(clear)) {
|
||||
clears[fb_state->nr_cbufs].depthStencil.depth = clear->zs.depth;
|
||||
clears[fb_state->nr_cbufs].depthStencil.stencil = clear->zs.stencil;
|
||||
rpbi.clearValueCount = fb_state->nr_cbufs + 1;
|
||||
clear_validate |= BITFIELD_BIT(fb_state->nr_cbufs);
|
||||
assert(ctx->framebuffer->rp->state.clears);
|
||||
}
|
||||
if (zink_fb_clear_needs_explicit(fb_clear)) {
|
||||
for (int j = !zink_fb_clear_element_needs_explicit(clear); j < zink_fb_clear_count(fb_clear); j++)
|
||||
clear_buffers |= zink_fb_clear_element(fb_clear, j)->zs.bits;
|
||||
}
|
||||
}
|
||||
assert(clear_validate == ctx->framebuffer->rp->state.clears);
|
||||
rpbi.pClearValues = &clears[0];
|
||||
|
|
Loading…
Reference in New Issue