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:
committed by
Marge Bot
parent
6c54344f5b
commit
b6c862bed7
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user