(*num_resources)++;
}
+static bool
+bind_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds, unsigned num_wds, VkWriteDescriptorSet *wds,
+ unsigned num_resources, struct zink_descriptor_resource *resources,
+ uint32_t *dynamic_offsets, unsigned dynamic_offset_idx, bool is_compute, bool cache_hit)
+{
+ bool need_flush = false;
+ struct zink_program *pg = zds->pg;
+ struct zink_batch *batch = is_compute ? &ctx->compute_batch : zink_curr_batch(ctx);
+ struct zink_screen *screen = zink_screen(ctx->base.screen);
+ assert(zds->desc_set);
+ unsigned check_flush_id = is_compute ? 0 : ZINK_COMPUTE_BATCH_ID;
+ for (int i = 0; i < num_resources; ++i) {
+ assert(num_resources <= zink_program_num_bindings_typed(pg, zds->type, is_compute));
+ assert(num_resources <= zds->num_resources);
+
+ struct zink_resource *res = resources[i].res;
+ if (res) {
+ need_flush |= zink_batch_reference_resource_rw(batch, res, resources[i].write) == check_flush_id;
+ }
+ }
+ if (!cache_hit && num_wds)
+ vkUpdateDescriptorSets(screen->dev, num_wds, wds, 0, NULL);
+
+ vkCmdBindDescriptorSets(batch->cmdbuf, is_compute ? VK_PIPELINE_BIND_POINT_COMPUTE : VK_PIPELINE_BIND_POINT_GRAPHICS,
+ pg->layout, zds->type, 1, &zds->desc_set, zds->type == ZINK_DESCRIPTOR_TYPE_UBO ? dynamic_offset_idx : 0, dynamic_offsets);
+ return need_flush;
+}
+
+static bool
+update_ubo_descriptors(struct zink_context *ctx, struct zink_descriptor_set *zds, struct zink_transition *transitions, int *num_transitions,
+ struct set *transition_hash, bool is_compute, bool cache_hit)
+{
+ struct zink_program *pg = zds->pg;
+ struct zink_screen *screen = zink_screen(ctx->base.screen);
+ unsigned num_descriptors = pg->num_descriptors[zds->type];
+ unsigned num_bindings = zink_program_num_bindings_typed(pg, zds->type, is_compute);
+ VkWriteDescriptorSet wds[num_descriptors];
+ struct zink_descriptor_resource resources[num_bindings];
+ VkDescriptorBufferInfo buffer_infos[num_bindings];
+ unsigned num_wds = 0;
+ unsigned num_buffer_info = 0;
+ unsigned num_resources = 0;
+ struct zink_shader **stages;
+ struct {
+ uint32_t binding;
+ uint32_t offset;
+ } dynamic_buffers[PIPE_MAX_CONSTANT_BUFFERS];
+ uint32_t dynamic_offsets[PIPE_MAX_CONSTANT_BUFFERS];
+ unsigned dynamic_offset_idx = 0;
+
+ unsigned num_stages = is_compute ? 1 : ZINK_SHADER_COUNT;
+ if (is_compute)
+ stages = &ctx->curr_compute->shader;
+ else
+ stages = &ctx->gfx_stages[0];
+
+ for (int i = 0; i < num_stages; i++) {
+ struct zink_shader *shader = stages[i];
+ if (!shader)
+ continue;
+ enum pipe_shader_type stage = pipe_shader_type_from_mesa(shader->nir->info.stage);
+
+ for (int j = 0; j < shader->num_bindings[zds->type]; j++) {
+ int index = shader->bindings[zds->type][j].index;
+ assert(shader->bindings[zds->type][j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
+ shader->bindings[zds->type][j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC);
+ assert(ctx->ubos[stage][index].buffer_size <= screen->info.props.limits.maxUniformBufferRange);
+ struct zink_resource *res = zink_resource(ctx->ubos[stage][index].buffer);
+ assert(!res || ctx->ubos[stage][index].buffer_size > 0);
+ assert(!res || ctx->ubos[stage][index].buffer);
+ assert(num_resources < num_bindings);
+ desc_set_res_add(zds, res, num_resources, cache_hit);
+ read_descriptor_resource(&resources[num_resources], res, &num_resources);
+ assert(num_buffer_info < num_bindings);
+ buffer_infos[num_buffer_info].buffer = res ? res->buffer :
+ (screen->info.rb2_feats.nullDescriptor ?
+ VK_NULL_HANDLE :
+ zink_resource(ctx->dummy_vertex_buffer)->buffer);
+ if (shader->bindings[zds->type][j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
+ buffer_infos[num_buffer_info].offset = 0;
+ /* we're storing this to qsort later */
+ dynamic_buffers[dynamic_offset_idx].binding = shader->bindings[zds->type][j].binding;
+ dynamic_buffers[dynamic_offset_idx++].offset = res ? ctx->ubos[stage][index].buffer_offset : 0;
+ } else
+ buffer_infos[num_buffer_info].offset = res ? ctx->ubos[stage][index].buffer_offset : 0;
+ buffer_infos[num_buffer_info].range = res ? ctx->ubos[stage][index].buffer_size : VK_WHOLE_SIZE;
+ if (res)
+ add_transition(res, 0, VK_ACCESS_UNIFORM_READ_BIT, stage, &transitions[*num_transitions], num_transitions, transition_hash);
+ wds[num_wds].pBufferInfo = buffer_infos + num_buffer_info;
+ ++num_buffer_info;
+
+ wds[num_wds].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
+ wds[num_wds].pNext = NULL;
+ wds[num_wds].dstBinding = shader->bindings[zds->type][j].binding;
+ wds[num_wds].dstArrayElement = 0;
+ wds[num_wds].descriptorCount = shader->bindings[zds->type][j].size;
+ wds[num_wds].descriptorType = shader->bindings[zds->type][j].type;
+ wds[num_wds].dstSet = zds->desc_set;
+ ++num_wds;
+ }
+ }
+
+ /* Values are taken from pDynamicOffsets in an order such that all entries for set N come before set N+1;
+ * within a set, entries are ordered by the binding numbers in the descriptor set layouts
+ * - vkCmdBindDescriptorSets spec
+ *
+ * because of this, we have to sort all the dynamic offsets by their associated binding to ensure they
+ * match what the driver expects
+ */
+ if (dynamic_offset_idx > 1)
+ qsort(dynamic_buffers, dynamic_offset_idx, sizeof(uint32_t) * 2, cmp_dynamic_offset_binding);
+ for (int i = 0; i < dynamic_offset_idx; i++)
+ dynamic_offsets[i] = dynamic_buffers[i].offset;
+
+ return bind_descriptors(ctx, zds, num_wds, wds, num_resources, resources, dynamic_offsets, dynamic_offset_idx, is_compute, cache_hit);
+}
+
static void
update_descriptors(struct zink_context *ctx, struct zink_screen *screen, bool is_compute)
{
unsigned num_surface_refs = 0;
unsigned num_resources[ZINK_DESCRIPTOR_TYPES] = {0};
struct zink_shader **stages;
- struct {
- uint32_t binding;
- uint32_t offset;
- } dynamic_buffers[PIPE_MAX_CONSTANT_BUFFERS];
- uint32_t dynamic_offsets[PIPE_MAX_CONSTANT_BUFFERS];
- unsigned dynamic_offset_idx = 0;
unsigned num_stages = is_compute ? 1 : ZINK_SHADER_COUNT;
if (is_compute)
int num_transitions = 0;
struct set *ht = _mesa_set_create(NULL, transition_hash, transition_equals);
- for (int h = 0; h < ZINK_DESCRIPTOR_TYPES; h++) {
+
+ bool need_flush = false;
+ if (zds[ZINK_DESCRIPTOR_TYPE_UBO])
+ need_flush |= update_ubo_descriptors(ctx, zds[ZINK_DESCRIPTOR_TYPE_UBO], transitions, &num_transitions, ht, is_compute, cache_hit[ZINK_DESCRIPTOR_TYPE_UBO]);
+ assert(num_transitions <= num_bindings);
+ for (int h = 1; h < ZINK_DESCRIPTOR_TYPES; h++) {
for (int i = 0; i < num_stages; i++) {
struct zink_shader *shader = stages[i];
if (!shader)
for (int j = 0; j < shader->num_bindings[h]; j++) {
int index = shader->bindings[h][j].index;
- if (shader->bindings[h][j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
- shader->bindings[h][j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
- assert(ctx->ubos[stage][index].buffer_size <= screen->info.props.limits.maxUniformBufferRange);
- struct zink_resource *res = zink_resource(ctx->ubos[stage][index].buffer);
- assert(!res || ctx->ubos[stage][index].buffer_size > 0);
- assert(!res || ctx->ubos[stage][index].buffer);
- assert(num_resources[h] < num_bindings);
- desc_set_res_add(zds[h], res, num_resources[h], cache_hit[h]);
- read_descriptor_resource(&resources[h][num_resources[h]], res, &num_resources[h]);
- assert(num_buffer_info[h] < num_bindings);
- buffer_infos[h][num_buffer_info[h]].buffer = res ? res->buffer :
- (screen->info.rb2_feats.nullDescriptor ?
- VK_NULL_HANDLE :
- zink_resource(ctx->dummy_vertex_buffer)->buffer);
- if (shader->bindings[h][j].type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC) {
- buffer_infos[h][num_buffer_info[h]].offset = 0;
- /* we're storing this to qsort later */
- dynamic_buffers[dynamic_offset_idx].binding = shader->bindings[h][j].binding;
- dynamic_buffers[dynamic_offset_idx++].offset = res ? ctx->ubos[stage][index].buffer_offset : 0;
- } else
- buffer_infos[h][num_buffer_info[h]].offset = res ? ctx->ubos[stage][index].buffer_offset : 0;
- buffer_infos[h][num_buffer_info[h]].range = res ? ctx->ubos[stage][index].buffer_size : VK_WHOLE_SIZE;
- if (res)
- add_transition(res, 0, VK_ACCESS_UNIFORM_READ_BIT, stage, &transitions[num_transitions], &num_transitions, ht);
- wds[h][num_wds[h]].pBufferInfo = buffer_infos[h] + num_buffer_info[h];
- ++num_buffer_info[h];
- } else if (shader->bindings[h][j].type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) {
+ if (shader->bindings[h][j].type == VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) {
struct zink_resource *res = zink_resource(ctx->ssbos[stage][index].buffer);
desc_set_res_add(zds[h], res, num_resources[h], cache_hit[h]);
if (res) {
}
_mesa_set_destroy(ht, NULL);
- /* Values are taken from pDynamicOffsets in an order such that all entries for set N come before set N+1;
- * within a set, entries are ordered by the binding numbers in the descriptor set layouts
- * - vkCmdBindDescriptorSets spec
- *
- * because of this, we have to sort all the dynamic offsets by their associated binding to ensure they
- * match what the driver expects
- */
- if (dynamic_offset_idx > 1)
- qsort(dynamic_buffers, dynamic_offset_idx, sizeof(uint32_t) * 2, cmp_dynamic_offset_binding);
- for (int i = 0; i < dynamic_offset_idx; i++)
- dynamic_offsets[i] = dynamic_buffers[i].offset;
-
unsigned check_flush_id = is_compute ? 0 : ZINK_COMPUTE_BATCH_ID;
- bool need_flush = false;
- for (int h = 0; h < ZINK_DESCRIPTOR_TYPES; h++) {
+ for (int h = 1; h < ZINK_DESCRIPTOR_TYPES; h++) {
if (!zds[h])
continue;
assert(zds[h]->desc_set);
if (is_compute)
vkCmdBindDescriptorSets(batch->cmdbuf, VK_PIPELINE_BIND_POINT_COMPUTE,
- ctx->curr_compute->base.layout, h, 1, &zds[h]->desc_set, h == ZINK_DESCRIPTOR_TYPE_UBO ? dynamic_offset_idx : 0, dynamic_offsets);
+ ctx->curr_compute->base.layout, h, 1, &zds[h]->desc_set, 0, NULL);
else
vkCmdBindDescriptorSets(batch->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS,
- ctx->curr_program->base.layout, h, 1, &zds[h]->desc_set, h == ZINK_DESCRIPTOR_TYPE_UBO ? dynamic_offset_idx : 0, dynamic_offsets);
+ ctx->curr_program->base.layout, h, 1, &zds[h]->desc_set, 0, NULL);
for (int i = 0; i < num_stages; i++) {
struct zink_shader *shader = stages[i];