diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 99a5c3bf7a3..08d70ce26f4 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -2471,6 +2471,44 @@ zink_make_image_handle_resident(struct pipe_context *pctx, uint64_t handle, unsi ctx->di.bindless_dirty[1] = true; } +static void +zink_set_global_binding(struct pipe_context *pctx, + unsigned first, unsigned count, + struct pipe_resource **resources, + uint32_t **handles) +{ + struct zink_context *ctx = zink_context(pctx); + + size_t size = ctx->di.global_bindings.capacity; + if (!util_dynarray_resize(&ctx->di.global_bindings, struct pipe_resource*, first + count + 8)) + unreachable("zink: out of memory somehow"); + if (size != ctx->di.global_bindings.capacity) { + uint8_t *data = ctx->di.global_bindings.data; + memset(data + size, 0, ctx->di.global_bindings.capacity - size); + } + + struct pipe_resource **globals = ctx->di.global_bindings.data; + for (unsigned i = 0; i < count; i++) { + if (resources && resources[i]) { + struct zink_resource *res = zink_resource(resources[i]); + + util_range_add(&res->base.b, &res->valid_buffer_range, 0, res->base.b.width0); + pipe_resource_reference(&globals[first + i], resources[i]); + + uint64_t addr = 0; + memcpy(&addr, handles[i], sizeof(addr)); + addr += zink_resource_get_address(zink_screen(pctx->screen), res); + memcpy(handles[i], &addr, sizeof(addr)); + zink_resource_usage_set(res, ctx->batch.state, true); + res->obj->unordered_read = res->obj->unordered_write = false; + zink_screen(ctx->base.screen)->buffer_barrier(ctx, res, VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); + } else if (globals[i]) { + zink_batch_reference_resource(&ctx->batch, zink_resource(globals[first + i])); + pipe_resource_reference(&globals[first + i], NULL); + } + } +} + static void zink_set_stencil_ref(struct pipe_context *pctx, const struct pipe_stencil_ref ref) @@ -3203,6 +3241,16 @@ zink_update_descriptor_refs(struct zink_context *ctx, bool compute) } } } + + unsigned global_count = util_dynarray_num_elements(&ctx->di.global_bindings, struct zink_resource*); + struct zink_resource **globals = ctx->di.global_bindings.data; + for (unsigned i = 0; i < global_count; i++) { + struct zink_resource *res = globals[i]; + if (!res) + continue; + zink_batch_resource_usage_set(batch, res, true, true); + res->obj->unordered_read = res->obj->unordered_write = false; + } } static void @@ -5208,6 +5256,8 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->base.set_stream_output_targets = zink_set_stream_output_targets; ctx->base.flush_resource = zink_flush_resource; + if (screen->info.have_KHR_buffer_device_address) + ctx->base.set_global_binding = zink_set_global_binding; ctx->base.emit_string_marker = zink_emit_string_marker; diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index 7a2c79ccf0b..455be335c1c 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -1937,6 +1937,7 @@ struct zink_context { uint8_t num_ubos[MESA_SHADER_STAGES]; uint8_t num_ssbos[MESA_SHADER_STAGES]; + struct util_dynarray global_bindings; VkDescriptorImageInfo textures[MESA_SHADER_STAGES][PIPE_MAX_SAMPLERS]; uint32_t emulate_nonseamless[MESA_SHADER_STAGES];