Module: Mesa Branch: main Commit: 59cc9c8df15c3624ecd712613e59393f7e1dbfe8 URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=59cc9c8df15c3624ecd712613e59393f7e1dbfe8
Author: Mike Blumenkrantz <[email protected]> Date: Tue May 11 11:08:03 2021 -0400 zink: optimize buffer rebinds this leverages all the slot masks to more optimally run through all the rebinds, also enabling some code consolidation Reviewed-by: Dave Airlie <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11747> --- src/gallium/drivers/zink/zink_context.c | 172 ++++++++++++-------------------- 1 file changed, 63 insertions(+), 109 deletions(-) diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 4110cd7adb2..c728a2816e9 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -3127,127 +3127,81 @@ zink_rebind_framebuffer(struct zink_context *ctx, struct zink_resource *res) zink_batch_no_rp(ctx); } -static bool -check_and_rebind_buffer(struct zink_context *ctx, struct zink_resource *res, unsigned shader, enum zink_descriptor_type type, unsigned i) -{ - bool is_write = false; - bool is_read = true; - struct zink_resource *cres = zink_get_resource_for_descriptor(ctx, type, shader, i); - if (res != cres) - return false; - - switch (type) { - case ZINK_DESCRIPTOR_TYPE_UBO: - update_descriptor_state_ubo(ctx, shader, i); - break; - case ZINK_DESCRIPTOR_TYPE_SSBO: { - struct pipe_shader_buffer *ssbo = &ctx->ssbos[shader][i]; - is_write = ctx->writable_ssbos[shader] & BITFIELD64_BIT(i); - util_range_add(&res->base.b, &res->valid_buffer_range, ssbo->buffer_offset, - ssbo->buffer_offset + ssbo->buffer_size); - update_descriptor_state_ssbo(ctx, shader, i); - break; - } - case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: { - struct zink_sampler_view *sampler_view = zink_sampler_view(ctx->sampler_views[shader][i]); - if (zink_batch_usage_exists(sampler_view->buffer_view->batch_uses)) - zink_batch_reference_bufferview(&ctx->batch, sampler_view->buffer_view); - zink_buffer_view_reference(zink_screen(ctx->base.screen), &sampler_view->buffer_view, NULL); - sampler_view->buffer_view = get_buffer_view(ctx, res, sampler_view->base.format, - sampler_view->base.u.buf.offset, sampler_view->base.u.buf.size); - update_descriptor_state_sampler(ctx, shader, i); - break; - } - case ZINK_DESCRIPTOR_TYPE_IMAGE: { - struct zink_image_view *image_view = &ctx->image_views[shader][i]; - zink_descriptor_set_refs_clear(&image_view->buffer_view->desc_set_refs, image_view->buffer_view); - if (zink_batch_usage_exists(image_view->buffer_view->batch_uses)) - zink_batch_reference_bufferview(&ctx->batch, image_view->buffer_view); - zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL); - if (!zink_resource_object_init_storage(ctx, res)) { - debug_printf("couldn't create storage image!"); - return false; - } - is_write = image_view->base.access & PIPE_IMAGE_ACCESS_WRITE; - is_read = image_view->base.access & PIPE_IMAGE_ACCESS_READ; - image_view->buffer_view = get_buffer_view(ctx, res, image_view->base.format, - image_view->base.u.buf.offset, image_view->base.u.buf.size); - assert(image_view->buffer_view); - util_range_add(&res->base.b, &res->valid_buffer_range, image_view->base.u.buf.offset, - image_view->base.u.buf.offset + image_view->base.u.buf.size); - update_descriptor_state_image(ctx, shader, i); - break; - } - default: - break; - } - - zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, type, i, 1); - zink_batch_resource_usage_set(&ctx->batch, res, is_write); - return true; -} - static void rebind_buffer(struct zink_context *ctx, struct zink_resource *res) { - unsigned num_rebinds = 0; + 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]}; + bool has_write = false; - for (unsigned shader = 0; shader < PIPE_SHADER_TYPES; shader++) { - if (!(res->bind_stages & (1 << shader))) - continue; - for (enum zink_descriptor_type type = 0; type < ZINK_DESCRIPTOR_TYPES; type++) { - if (!(res->bind_history & BITFIELD64_BIT(type))) - continue; + if (res->vbo_bind_count) { + ctx->vertex_buffers_dirty = true; + num_rebinds += res->vbo_bind_count; + } + for (unsigned shader = 0; 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; - uint32_t usage = zink_program_get_descriptor_usage(ctx, shader, type); - u_foreach_bit(i, usage) { - if (check_and_rebind_buffer(ctx, res, shader, type, i)) - num_rebinds++; - } + update_descriptor_state_ubo(ctx, shader, slot); + zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_UBO, slot, 1); + num_rebinds++; } - } - unsigned total_binds = res->bind_count[0] + res->bind_count[1] - res->vbo_bind_count; - /* we've missed some rebinds, so we have to go back for them */ - if (total_binds != num_rebinds) { - for (unsigned shader = 0; shader < PIPE_SHADER_TYPES; shader++) { - if (!(res->bind_stages & (1 << shader))) - continue; - for (enum zink_descriptor_type type = 0; type < ZINK_DESCRIPTOR_TYPES; type++) { - if (!(res->bind_history & BITFIELD64_BIT(type))) + 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; + + has_write |= ctx->writable_ssbos[shader] & BITFIELD64_BIT(slot); + util_range_add(&res->base.b, &res->valid_buffer_range, ssbo->buffer_offset, + ssbo->buffer_offset + ssbo->buffer_size); + update_descriptor_state_ssbo(ctx, shader, slot); + zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SSBO, slot, 1); + num_rebinds++; + } + 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; + + if (zink_batch_usage_exists(sampler_view->buffer_view->batch_uses)) + zink_batch_reference_bufferview(&ctx->batch, sampler_view->buffer_view); + zink_buffer_view_reference(zink_screen(ctx->base.screen), &sampler_view->buffer_view, NULL); + sampler_view->buffer_view = get_buffer_view(ctx, res, sampler_view->base.format, + sampler_view->base.u.buf.offset, sampler_view->base.u.buf.size); + update_descriptor_state_sampler(ctx, shader, slot); + zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW, slot, 1); + 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; - unsigned num_descriptors = 0; - switch (type) { - case ZINK_DESCRIPTOR_TYPE_UBO: - num_descriptors = ctx->di.num_ubos[shader]; - break; - case ZINK_DESCRIPTOR_TYPE_SAMPLER_VIEW: - num_descriptors = ctx->di.num_sampler_views[shader]; - break; - case ZINK_DESCRIPTOR_TYPE_SSBO: - num_descriptors = ctx->di.num_ssbos[shader]; - break; - case ZINK_DESCRIPTOR_TYPE_IMAGE: - num_descriptors = ctx->di.num_images[shader]; - break; - default: - unreachable("ack"); - } - for (unsigned i = 0; i < num_descriptors; i++) { - if (check_and_rebind_buffer(ctx, res, shader, type, i)) - num_rebinds++; - if (total_binds == num_rebinds) - goto out; + struct zink_image_view *image_view = &ctx->image_views[shader][slot]; + zink_descriptor_set_refs_clear(&image_view->buffer_view->desc_set_refs, image_view->buffer_view); + if (zink_batch_usage_exists(image_view->buffer_view->batch_uses)) + zink_batch_reference_bufferview(&ctx->batch, image_view->buffer_view); + zink_buffer_view_reference(zink_screen(ctx->base.screen), &image_view->buffer_view, NULL); + if (!zink_resource_object_init_storage(ctx, res)) { + debug_printf("couldn't create storage image!"); + continue; } + has_write |= image_view->base.access & PIPE_IMAGE_ACCESS_WRITE; + image_view->buffer_view = get_buffer_view(ctx, res, image_view->base.format, + image_view->base.u.buf.offset, image_view->base.u.buf.size); + assert(image_view->buffer_view); + util_range_add(&res->base.b, &res->valid_buffer_range, image_view->base.u.buf.offset, + image_view->base.u.buf.offset + image_view->base.u.buf.size); + update_descriptor_state_image(ctx, shader, slot); + zink_screen(ctx->base.screen)->context_invalidate_descriptor_state(ctx, shader, ZINK_DESCRIPTOR_TYPE_IMAGE, slot, 1); + num_image_rebinds_remaining[shader == PIPE_SHADER_COMPUTE]--; } } } -out: - assert(total_binds == num_rebinds); - if (!res->vbo_bind_count) - return; - zink_batch_resource_usage_set(&ctx->batch, res, false); - ctx->vertex_buffers_dirty = true; + zink_batch_resource_usage_set(&ctx->batch, res, has_write); } static inline struct zink_screen ** _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
