Mesa (main): zink: use tc rebind info for buffer replacements
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Wed Sep 1 02:34:23 UTC 2021
Module: Mesa
Branch: main
Commit: 2aaca02bbf85857e06f97c84a1d67821dba04069
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=2aaca02bbf85857e06f97c84a1d67821dba04069
Author: Mike Blumenkrantz <michael.blumenkrantz at gmail.com>
Date: Fri Jul 9 11:12:08 2021 -0400
zink: use tc rebind info for buffer replacements
this makes the most common type of replacement more efficient
Reviewed-by: Dave Airlie <airlied at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12575>
---
src/gallium/drivers/zink/zink_context.c | 94 +++++++++++++++++++++------------
1 file changed, 59 insertions(+), 35 deletions(-)
diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c
index 8f860035540..5e74a63ff55 100644
--- a/src/gallium/drivers/zink/zink_context.c
+++ b/src/gallium/drivers/zink/zink_context.c
@@ -3220,13 +3220,12 @@ rebind_ibo(struct zink_context *ctx, enum pipe_shader_type shader, unsigned slot
}
static unsigned
-rebind_buffer(struct zink_context *ctx, struct zink_resource *res)
+rebind_buffer(struct zink_context *ctx, struct zink_resource *res, const uint32_t rebind_mask, const unsigned expected_num_rebinds)
{
- const unsigned total_rebinds = res->bind_count[0] + res->bind_count[1];
- unsigned num_rebinds = 0, num_image_rebinds_remaining[2] = {res->image_bind_count[0], res->image_bind_count[1]};
+ unsigned num_rebinds = 0;
bool has_write = false;
- if (res->so_bind_count && ctx->num_so_targets) {
+ if ((rebind_mask & BITFIELD_BIT(TC_BINDING_STREAMOUT_BUFFER)) || (!rebind_mask && res->so_bind_count && ctx->num_so_targets)) {
for (unsigned i = 0; i < ctx->num_so_targets; i++) {
if (ctx->so_targets[i]) {
struct zink_resource *so = zink_resource(ctx->so_targets[i]->buffer);
@@ -3237,61 +3236,84 @@ rebind_buffer(struct zink_context *ctx, struct zink_resource *res)
}
}
}
+ if (num_rebinds && expected_num_rebinds == num_rebinds)
+ goto end;
- if (res->vbo_bind_mask) {
+ if ((rebind_mask & BITFIELD_BIT(TC_BINDING_VERTEX_BUFFER)) || (!rebind_mask && res->vbo_bind_mask)) {
u_foreach_bit(slot, res->vbo_bind_mask) {
if (ctx->vertex_buffers[slot].buffer.resource != &res->base.b) //wrong context
- return 0;
+ goto end;
set_vertex_buffer_clamped(ctx, slot);
num_rebinds++;
}
ctx->vertex_buffers_dirty = true;
}
- if (res->ubo_bind_count[0] + res->ubo_bind_count[1] > 0) {
- for (unsigned shader = res->ubo_bind_count[0] ? 0 : PIPE_SHADER_COMPUTE;
- num_rebinds < total_rebinds && shader < PIPE_SHADER_TYPES; shader++) {
- u_foreach_bit(slot, res->ubo_bind_mask[shader]) {
- if (&res->base.b != ctx->ubos[shader][slot].buffer) //wrong context
- return 0;
-
- rebind_ubo(ctx, shader, slot);
- num_rebinds++;
- }
+ if (num_rebinds && expected_num_rebinds == num_rebinds)
+ goto end;
+
+ const uint32_t ubo_mask = rebind_mask ?
+ rebind_mask & BITFIELD_RANGE(TC_BINDING_UBO_VS, PIPE_SHADER_TYPES) :
+ ((res->ubo_bind_count[0] ? BITFIELD_RANGE(TC_BINDING_UBO_VS, (PIPE_SHADER_TYPES - 1)) : 0) |
+ (res->ubo_bind_count[1] ? BITFIELD_BIT(TC_BINDING_UBO_CS) : 0));
+ u_foreach_bit(shader, ubo_mask >> TC_BINDING_UBO_VS) {
+ u_foreach_bit(slot, res->ubo_bind_mask[shader]) {
+ if (&res->base.b != ctx->ubos[shader][slot].buffer) //wrong context
+ goto end;
+ rebind_ubo(ctx, shader, slot);
+ num_rebinds++;
}
}
- for (unsigned shader = 0; num_rebinds < total_rebinds && shader < PIPE_SHADER_TYPES; shader++) {
+ if (num_rebinds && expected_num_rebinds == num_rebinds)
+ goto end;
+
+ const unsigned ssbo_mask = rebind_mask ?
+ rebind_mask & BITFIELD_RANGE(TC_BINDING_SSBO_VS, PIPE_SHADER_TYPES) :
+ BITFIELD_RANGE(TC_BINDING_SSBO_VS, PIPE_SHADER_TYPES);
+ u_foreach_bit(shader, ssbo_mask >> TC_BINDING_SSBO_VS) {
u_foreach_bit(slot, res->ssbo_bind_mask[shader]) {
struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][slot];
if (&res->base.b != ssbo->buffer) //wrong context
- return 0;
-
+ goto end;
rebind_ssbo(ctx, shader, slot);
has_write |= (ctx->writable_ssbos[shader] & BITFIELD64_BIT(slot)) != 0;
num_rebinds++;
}
+ }
+ if (num_rebinds && expected_num_rebinds == num_rebinds)
+ goto end;
+ const unsigned sampler_mask = rebind_mask ?
+ rebind_mask & BITFIELD_RANGE(TC_BINDING_SAMPLERVIEW_VS, PIPE_SHADER_TYPES) :
+ BITFIELD_RANGE(TC_BINDING_SAMPLERVIEW_VS, PIPE_SHADER_TYPES);
+ u_foreach_bit(shader, sampler_mask >> TC_BINDING_SAMPLERVIEW_VS) {
u_foreach_bit(slot, res->sampler_binds[shader]) {
struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[shader][slot]);
if (&res->base.b != sampler_view->base.texture) //wrong context
- return 0;
-
+ goto end;
rebind_tbo(ctx, shader, slot);
num_rebinds++;
}
- if (unlikely(num_image_rebinds_remaining[shader == PIPE_SHADER_COMPUTE])) {
- for (unsigned slot = 0; num_image_rebinds_remaining[shader == PIPE_SHADER_COMPUTE] &&
- slot < ctx->di.num_images[shader]; slot++) {
- struct zink_resource *cres = zink_get_resource_for_descriptor(ctx, ZINK_DESCRIPTOR_TYPE_IMAGE, shader, slot);
- if (res != cres)
- continue;
+ }
+ if (num_rebinds && expected_num_rebinds == num_rebinds)
+ goto end;
+
+ const unsigned image_mask = rebind_mask ?
+ rebind_mask & BITFIELD_RANGE(TC_BINDING_IMAGE_VS, PIPE_SHADER_TYPES) :
+ BITFIELD_RANGE(TC_BINDING_IMAGE_VS, PIPE_SHADER_TYPES);
+ unsigned num_image_rebinds_remaining = rebind_mask ? expected_num_rebinds - num_rebinds : res->image_bind_count[0] + res->image_bind_count[1];
+ u_foreach_bit(shader, image_mask >> TC_BINDING_IMAGE_VS) {
+ for (unsigned slot = 0; num_image_rebinds_remaining && slot < ctx->di.num_images[shader]; slot++) {
+ struct zink_resource *cres = zink_get_resource_for_descriptor(ctx, ZINK_DESCRIPTOR_TYPE_IMAGE, shader, slot);
+ if (res != cres)
+ continue;
- rebind_ibo(ctx, shader, slot);
- const struct zink_image_view *image_view = &ctx->image_views[shader][slot];
- has_write |= (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE) != 0;
- num_image_rebinds_remaining[shader == PIPE_SHADER_COMPUTE]--;
- num_rebinds++;
- }
+ rebind_ibo(ctx, shader, slot);
+ const struct zink_image_view *image_view = &ctx->image_views[shader][slot];
+ has_write |= (image_view->base.access & PIPE_IMAGE_ACCESS_WRITE) != 0;
+ num_image_rebinds_remaining--;
+ num_rebinds++;
}
}
+end:
zink_batch_resource_usage_set(&ctx->batch, res, has_write);
return num_rebinds;
}
@@ -3353,7 +3375,7 @@ zink_resource_rebind(struct zink_context *ctx, struct zink_resource *res)
if (!res->bind_count[0] && !res->bind_count[1])
return true;
if (res->base.b.target == PIPE_BUFFER)
- return rebind_buffer(ctx, res) == res->bind_count[0] + res->bind_count[1];
+ return rebind_buffer(ctx, res, 0, 0) == res->bind_count[0] + res->bind_count[1];
rebind_image(ctx, res);
return false;
}
@@ -3410,7 +3432,9 @@ zink_context_replace_buffer_storage(struct pipe_context *pctx, struct pipe_resou
d->access = s->access;
d->access_stage = s->access_stage;
d->unordered_barrier = s->unordered_barrier;
- if (!zink_resource_rebind(ctx, d))
+ /* force counter buffer reset */
+ d->bind_history &= ~ZINK_RESOURCE_USAGE_STREAMOUT;
+ if (num_rebinds && rebind_buffer(ctx, d, rebind_mask, num_rebinds) != num_rebinds)
ctx->buffer_rebind_counter = p_atomic_inc_return(&zink_screen(ctx->base.screen)->buffer_rebind_counter);
}
More information about the mesa-commit
mailing list