diff --git a/src/nouveau/vulkan/nvk_cmd_buffer.c b/src/nouveau/vulkan/nvk_cmd_buffer.c index 424ead2204f..62de9a550f0 100644 --- a/src/nouveau/vulkan/nvk_cmd_buffer.c +++ b/src/nouveau/vulkan/nvk_cmd_buffer.c @@ -31,8 +31,8 @@ nvk_descriptor_state_fini(struct nvk_cmd_buffer *cmd, struct nvk_cmd_pool *pool = nvk_cmd_buffer_pool(cmd); for (unsigned i = 0; i < NVK_MAX_SETS; i++) { - vk_free(&pool->vk.alloc, desc->push[i]); - desc->push[i] = NULL; + vk_free(&pool->vk.alloc, desc->sets[i].push); + desc->sets[i].push = NULL; } } @@ -688,12 +688,19 @@ nvk_bind_descriptor_sets(struct nvk_cmd_buffer *cmd, unsigned s = i + info->firstSet; VK_FROM_HANDLE(nvk_descriptor_set, set, info->pDescriptorSets[i]); - if (desc->sets[s] != set) { - struct nvk_buffer_address set_addr = - set != NULL ? nvk_descriptor_set_addr(set) - : NVK_BUFFER_ADDRESS_NULL; + if (desc->sets[s].type != NVK_DESCRIPTOR_SET_TYPE_SET || + desc->sets[s].set != set) { + struct nvk_buffer_address set_addr; + if (set != NULL) { + desc->sets[s].type = NVK_DESCRIPTOR_SET_TYPE_SET; + desc->sets[s].set = set; + set_addr = nvk_descriptor_set_addr(set); + } else { + desc->sets[s].type = NVK_DESCRIPTOR_SET_TYPE_NONE; + desc->sets[s].set = NULL; + set_addr = NVK_BUFFER_ADDRESS_NULL; + } nvk_descriptor_state_set_root(cmd, desc, sets[s], set_addr); - desc->sets[s] = set; } set_dynamic_buffer_start[s] = dyn_buffer_end; @@ -798,21 +805,22 @@ nvk_cmd_push_descriptors(struct nvk_cmd_buffer *cmd, uint32_t set) { assert(set < NVK_MAX_SETS); - if (unlikely(desc->push[set] == NULL)) { - desc->push[set] = vk_zalloc(&cmd->vk.pool->alloc, - sizeof(*desc->push[set]), 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (unlikely(desc->push[set] == NULL)) { + if (unlikely(desc->sets[set].push == NULL)) { + desc->sets[set].push = vk_zalloc(&cmd->vk.pool->alloc, + sizeof(*desc->sets[set].push), 8, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (unlikely(desc->sets[set].push == NULL)) { vk_command_buffer_set_error(&cmd->vk, VK_ERROR_OUT_OF_HOST_MEMORY); return NULL; } } /* Pushing descriptors replaces whatever sets are bound */ - desc->sets[set] = NULL; + desc->sets[set].type = NVK_DESCRIPTOR_SET_TYPE_PUSH; + desc->sets[set].set = NULL; desc->push_dirty |= BITFIELD_BIT(set); - return desc->push[set]; + return desc->sets[set].push; } static void @@ -866,12 +874,10 @@ nvk_cmd_buffer_flush_push_descriptors(struct nvk_cmd_buffer *cmd, VkResult result; u_foreach_bit(set_idx, desc->push_dirty) { - /* We only have an active push descriptor set if sets[set_idx] == NULL. - */ - if (desc->sets[set_idx] != NULL) + if (desc->sets[set_idx].type != NVK_DESCRIPTOR_SET_TYPE_PUSH) continue; - struct nvk_push_descriptor_set *push_set = desc->push[set_idx]; + struct nvk_push_descriptor_set *push_set = desc->sets[set_idx].push; uint64_t push_set_addr; result = nvk_cmd_buffer_upload_data(cmd, push_set->data, sizeof(push_set->data), @@ -932,10 +938,10 @@ nvk_cmd_buffer_get_cbuf_addr(struct nvk_cmd_buffer *cmd, } case NVK_CBUF_TYPE_UBO_DESC: { - if (desc->sets[cbuf->desc_set] != NULL) + if (desc->sets[cbuf->desc_set].type != NVK_DESCRIPTOR_SET_TYPE_PUSH) return false; - struct nvk_push_descriptor_set *push = desc->push[cbuf->desc_set]; + struct nvk_push_descriptor_set *push = desc->sets[cbuf->desc_set].push; if (push == NULL) return false; @@ -957,12 +963,18 @@ nvk_cmd_buffer_get_cbuf_descriptor_addr(struct nvk_cmd_buffer *cmd, const struct nvk_cbuf *cbuf) { assert(cbuf->type == NVK_CBUF_TYPE_UBO_DESC); + switch (desc->sets[cbuf->desc_set].type) { + case NVK_DESCRIPTOR_SET_TYPE_SET: { + struct nvk_buffer_address set_addr; + nvk_descriptor_state_get_root(desc, sets[cbuf->desc_set], &set_addr); - struct nvk_buffer_address set_addr; - nvk_descriptor_state_get_root(desc, sets[cbuf->desc_set], &set_addr); + assert(cbuf->desc_offset < set_addr.size); + return set_addr.base_addr + cbuf->desc_offset; + } - assert(cbuf->desc_offset < set_addr.size); - return set_addr.base_addr + cbuf->desc_offset; + default: + unreachable("Unknown descriptor set type"); + } } void diff --git a/src/nouveau/vulkan/nvk_cmd_buffer.h b/src/nouveau/vulkan/nvk_cmd_buffer.h index f500b3cff7c..9b6f5085f1d 100644 --- a/src/nouveau/vulkan/nvk_cmd_buffer.h +++ b/src/nouveau/vulkan/nvk_cmd_buffer.h @@ -69,14 +69,25 @@ struct nvk_root_descriptor_table { #define nvk_root_descriptor_offset(member)\ offsetof(struct nvk_root_descriptor_table, member) +enum ENUM_PACKED nvk_descriptor_set_type { + NVK_DESCRIPTOR_SET_TYPE_NONE, + NVK_DESCRIPTOR_SET_TYPE_SET, + NVK_DESCRIPTOR_SET_TYPE_PUSH, +}; + +struct nvk_descriptor_set_binding { + enum nvk_descriptor_set_type type; + struct nvk_descriptor_set *set; + struct nvk_push_descriptor_set *push; +}; + struct nvk_descriptor_state { alignas(16) char root[sizeof(struct nvk_root_descriptor_table)]; void (*flush_root)(struct nvk_cmd_buffer *cmd, struct nvk_descriptor_state *desc, size_t offset, size_t size); - struct nvk_descriptor_set *sets[NVK_MAX_SETS]; - struct nvk_push_descriptor_set *push[NVK_MAX_SETS]; + struct nvk_descriptor_set_binding sets[NVK_MAX_SETS]; uint32_t push_dirty; }; @@ -185,6 +196,7 @@ struct nvk_cmd_buffer { struct vk_command_buffer vk; struct { + uint64_t descriptor_buffers[NVK_MAX_SETS]; struct nvk_graphics_state gfx; struct nvk_compute_state cs; } state; diff --git a/src/nouveau/vulkan/nvk_cmd_meta.c b/src/nouveau/vulkan/nvk_cmd_meta.c index 68c9e2d7f25..1f018d3ba8a 100644 --- a/src/nouveau/vulkan/nvk_cmd_meta.c +++ b/src/nouveau/vulkan/nvk_cmd_meta.c @@ -63,8 +63,7 @@ struct nvk_meta_save { struct vk_dynamic_graphics_state dynamic; struct nvk_shader *shaders[MESA_SHADER_MESH + 1]; struct nvk_addr_range vb0; - struct nvk_descriptor_set *desc0; - bool has_push_desc0; + struct nvk_descriptor_set_binding desc0; struct nvk_push_descriptor_set push_desc0; uint8_t set_dynamic_buffer_start[NVK_MAX_SETS]; uint8_t push[NVK_MAX_PUSH_SIZE]; @@ -86,9 +85,8 @@ nvk_meta_begin(struct nvk_cmd_buffer *cmd, save->vb0 = cmd->state.gfx.vb0; save->desc0 = desc->sets[0]; - save->has_push_desc0 = desc->push[0]; - if (save->has_push_desc0) - save->push_desc0 = *desc->push[0]; + if (desc->sets[0].push != NULL) + save->push_desc0 = *desc->sets[0].push; nvk_descriptor_state_get_root_array(desc, set_dynamic_buffer_start, 0, NVK_MAX_SETS, @@ -138,13 +136,28 @@ nvk_meta_end(struct nvk_cmd_buffer *cmd, { struct nvk_descriptor_state *desc = &cmd->state.gfx.descriptors; - if (save->desc0) { - desc->sets[0] = save->desc0; - struct nvk_buffer_address addr = nvk_descriptor_set_addr(save->desc0); + switch (save->desc0.type) { + case NVK_DESCRIPTOR_SET_TYPE_NONE: + desc->sets[0].type = NVK_DESCRIPTOR_SET_TYPE_NONE; + break; + + case NVK_DESCRIPTOR_SET_TYPE_SET: { + desc->sets[0].type = NVK_DESCRIPTOR_SET_TYPE_SET; + desc->sets[0].set = save->desc0.set; + struct nvk_buffer_address addr = nvk_descriptor_set_addr(save->desc0.set); nvk_descriptor_state_set_root(cmd, desc, sets[0], addr); - } else if (save->has_push_desc0) { - *desc->push[0] = save->push_desc0; + break; + } + + case NVK_DESCRIPTOR_SET_TYPE_PUSH: + desc->sets[0].type = NVK_DESCRIPTOR_SET_TYPE_PUSH; + desc->sets[0].set = NULL; + *desc->sets[0].push = save->push_desc0; desc->push_dirty |= BITFIELD_BIT(0); + break; + + default: + unreachable("Unknown descriptor set type"); } nvk_cmd_dirty_cbufs_for_descriptors(cmd, ~0, 0, 1, 0, 0);