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 **