nvk: Rework descriptor set bindings

This switches from struct-of-array to array-of-struct and also addes a
new nvk_descriptor_set_type enum to make it more clear exactly what, if
anything, is bound at any give time.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30580>
This commit is contained in:
Faith Ekstrand
2024-08-08 13:09:21 -05:00
committed by Marge Bot
parent 6c54344f5b
commit b6c862bed7
3 changed files with 73 additions and 36 deletions
+36 -24
View File
@@ -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
+14 -2
View File
@@ -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;
+23 -10
View File
@@ -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);