nvk: Use helper macros for accessing root descriptors

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29591>
This commit is contained in:
Faith Ekstrand 2024-05-20 11:00:10 -05:00 committed by Marge Bot
parent 2423b0b295
commit b2d85ca36f
6 changed files with 116 additions and 50 deletions

View File

@ -651,6 +651,16 @@ nvk_bind_descriptor_sets(struct nvk_cmd_buffer *cmd,
struct nvk_device *dev = nvk_cmd_buffer_device(cmd);
struct nvk_physical_device *pdev = nvk_device_physical(dev);
union nvk_buffer_descriptor dynamic_buffers[NVK_MAX_DYNAMIC_BUFFERS];
uint8_t set_dynamic_buffer_start[NVK_MAX_SETS];
/* Read off the current dynamic buffer start array so we can use it to
* determine where we should start binding dynamic buffers.
*/
nvk_descriptor_state_get_root_array(desc, set_dynamic_buffer_start,
0, NVK_MAX_SETS,
set_dynamic_buffer_start);
/* Fro the Vulkan 1.3.275 spec:
*
* "When binding a descriptor set (see Descriptor Set Binding) to
@ -668,8 +678,7 @@ nvk_bind_descriptor_sets(struct nvk_cmd_buffer *cmd,
* range and it's only our responsibility to adjust all
* set_dynamic_buffer_start[p] for p > s as needed.
*/
const uint8_t dyn_buffer_start =
desc->root.set_dynamic_buffer_start[info->firstSet];
const uint8_t dyn_buffer_start = set_dynamic_buffer_start[info->firstSet];
uint8_t dyn_buffer_end = dyn_buffer_start;
uint32_t next_dyn_offset = 0;
@ -678,15 +687,14 @@ nvk_bind_descriptor_sets(struct nvk_cmd_buffer *cmd,
VK_FROM_HANDLE(nvk_descriptor_set, set, info->pDescriptorSets[i]);
if (desc->sets[s] != set) {
if (set != NULL) {
desc->root.sets[s] = nvk_descriptor_set_addr(set);
} else {
desc->root.sets[s] = NVK_BUFFER_ADDRESS_NULL;
}
struct nvk_buffer_address set_addr =
set != NULL ? nvk_descriptor_set_addr(set)
: NVK_BUFFER_ADDRESS_NULL;
nvk_descriptor_state_set_root(cmd, desc, sets[s], set_addr);
desc->sets[s] = set;
}
desc->root.set_dynamic_buffer_start[s] = dyn_buffer_end;
set_dynamic_buffer_start[s] = dyn_buffer_end;
if (pipeline_layout->set_layouts[s] != NULL) {
const struct nvk_descriptor_set_layout *set_layout =
@ -703,7 +711,7 @@ nvk_bind_descriptor_sets(struct nvk_cmd_buffer *cmd,
} else {
db.addr.base_addr += offset;
}
desc->root.dynamic_buffers[dyn_buffer_end + j] = db;
dynamic_buffers[dyn_buffer_end + j] = db;
}
next_dyn_offset += set->layout->dynamic_buffer_count;
}
@ -716,9 +724,25 @@ nvk_bind_descriptor_sets(struct nvk_cmd_buffer *cmd,
assert(dyn_buffer_end <= NVK_MAX_DYNAMIC_BUFFERS);
assert(next_dyn_offset <= info->dynamicOffsetCount);
nvk_descriptor_state_set_root_array(cmd, desc, dynamic_buffers,
dyn_buffer_start, dyn_buffer_end,
&dynamic_buffers[dyn_buffer_start]);
/* We need to set everything above first_set because later calls to
* nvk_bind_descriptor_sets() depend on it for knowing where to start and
* they may not be called on the next consecutive set.
*/
for (uint32_t s = info->firstSet + info->descriptorSetCount;
s < NVK_MAX_SETS; s++)
desc->root.set_dynamic_buffer_start[s] = dyn_buffer_end;
set_dynamic_buffer_start[s] = dyn_buffer_end;
/* We need to at least sync everything from first_set to NVK_MAX_SETS.
* However, we only save anything if firstSet >= 4 so we may as well sync
* everything just to be safe.
*/
nvk_descriptor_state_set_root_array(cmd, desc, set_dynamic_buffer_start,
0, NVK_MAX_SETS,
set_dynamic_buffer_start);
nvk_cmd_dirty_cbufs_for_descriptors(cmd, info->stageFlags, info->firstSet,
info->firstSet + info->descriptorSetCount,
@ -747,7 +771,9 @@ nvk_push_constants(UNUSED struct nvk_cmd_buffer *cmd,
struct nvk_descriptor_state *desc,
const VkPushConstantsInfoKHR *info)
{
memcpy(desc->root.push + info->offset, info->pValues, info->size);
nvk_descriptor_state_set_root_array(cmd, desc, push,
info->offset, info->size,
(char *)info->pValues);
}
@ -854,10 +880,11 @@ nvk_cmd_buffer_flush_push_descriptors(struct nvk_cmd_buffer *cmd,
return;
}
desc->root.sets[set_idx] = (struct nvk_buffer_address) {
struct nvk_buffer_address set_addr = {
.base_addr = push_set_addr,
.size = sizeof(push_set->data),
};
nvk_descriptor_state_set_root(cmd, desc, sets[set_idx], set_addr);
}
}
@ -888,14 +915,17 @@ nvk_cmd_buffer_get_cbuf_addr(struct nvk_cmd_buffer *cmd,
return true;
case NVK_CBUF_TYPE_DESC_SET:
*addr_out = desc->root.sets[cbuf->desc_set];
nvk_descriptor_state_get_root(desc, sets[cbuf->desc_set], addr_out);
return true;
case NVK_CBUF_TYPE_DYNAMIC_UBO: {
const uint32_t dyn_start =
desc->root.set_dynamic_buffer_start[cbuf->desc_set];
*addr_out = nvk_ubo_descriptor_addr(pdev,
desc->root.dynamic_buffers[dyn_start + cbuf->dynamic_idx]);
uint8_t dyn_idx;
nvk_descriptor_state_get_root(
desc, set_dynamic_buffer_start[cbuf->desc_set], &dyn_idx);
dyn_idx += cbuf->dynamic_idx;
union nvk_buffer_descriptor ubo_desc;
nvk_descriptor_state_get_root(desc, dynamic_buffers[dyn_idx], &ubo_desc);
*addr_out = nvk_ubo_descriptor_addr(pdev, ubo_desc);
return true;
}
@ -926,8 +956,11 @@ nvk_cmd_buffer_get_cbuf_descriptor_addr(struct nvk_cmd_buffer *cmd,
{
assert(cbuf->type == NVK_CBUF_TYPE_UBO_DESC);
assert(cbuf->desc_offset < desc->root.sets[cbuf->desc_set].size);
return desc->root.sets[cbuf->desc_set].base_addr + cbuf->desc_offset;
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;
}
void

View File

@ -22,6 +22,7 @@
struct nvk_buffer;
struct nvk_cbuf;
struct nvk_cmd_bo;
struct nvk_cmd_buffer;
struct nvk_cmd_pool;
struct nvk_image_view;
struct nvk_push_descriptor_set;
@ -75,12 +76,46 @@ struct nvk_root_descriptor_table {
offsetof(struct nvk_root_descriptor_table, member)
struct nvk_descriptor_state {
struct nvk_root_descriptor_table root;
alignas(16) char root[sizeof(struct nvk_root_descriptor_table)];
struct nvk_descriptor_set *sets[NVK_MAX_SETS];
struct nvk_push_descriptor_set *push[NVK_MAX_SETS];
uint32_t push_dirty;
};
#define nvk_descriptor_state_get_root(desc, member, dst) do { \
const struct nvk_root_descriptor_table *root = \
(const struct nvk_root_descriptor_table *)(desc)->root; \
*dst = root->member; \
} while (0)
#define nvk_descriptor_state_get_root_array(desc, member, \
start, count, dst) do { \
const struct nvk_root_descriptor_table *root = \
(const struct nvk_root_descriptor_table *)(desc)->root; \
unsigned _start = start; \
assert(_start + count <= ARRAY_SIZE(root->member)); \
for (unsigned i = 0; i < count; i++) \
(dst)[i] = root->member[i + _start]; \
} while (0)
#define nvk_descriptor_state_set_root(cmd, desc, member, src) do { \
struct nvk_descriptor_state *_desc = (desc); \
struct nvk_root_descriptor_table *root = \
(struct nvk_root_descriptor_table *)_desc->root; \
root->member = (src); \
} while (0)
#define nvk_descriptor_state_set_root_array(cmd, desc, member, \
start, count, src) do { \
struct nvk_descriptor_state *_desc = (desc); \
struct nvk_root_descriptor_table *root = \
(struct nvk_root_descriptor_table *)_desc->root; \
unsigned _start = start; \
assert(_start + count <= ARRAY_SIZE(root->member)); \
for (unsigned i = 0; i < count; i++) \
root->member[i + _start] = (src)[i]; \
} while (0)
struct nvk_attachment {
VkFormat vk_format;
struct nvk_image_view *iview;

View File

@ -116,12 +116,10 @@ nvk_flush_compute_state(struct nvk_cmd_buffer *cmd,
nvk_cmd_buffer_flush_push_descriptors(cmd, desc);
desc->root.cs.base_group[0] = base_workgroup[0];
desc->root.cs.base_group[1] = base_workgroup[1];
desc->root.cs.base_group[2] = base_workgroup[2];
desc->root.cs.group_count[0] = global_size[0];
desc->root.cs.group_count[1] = global_size[1];
desc->root.cs.group_count[2] = global_size[2];
nvk_descriptor_state_set_root_array(cmd, desc, cs.base_group,
0, 3, base_workgroup);
nvk_descriptor_state_set_root_array(cmd, desc, cs.group_count,
0, 3, global_size);
/* pre Pascal the constant buffer sizes need to be 0x100 aligned. As we
* simply allocated a buffer and upload data to it, make sure its size is

View File

@ -1804,7 +1804,6 @@ vk_to_nvk_sample_location(VkSampleLocationEXT loc)
static void
nvk_flush_ms_state(struct nvk_cmd_buffer *cmd)
{
struct nvk_descriptor_state *desc = &cmd->state.gfx.descriptors;
const struct nvk_rendering_state *render = &cmd->state.gfx.render;
const struct vk_dynamic_graphics_state *dyn =
&cmd->vk.dynamic_graphics_state;
@ -1865,10 +1864,13 @@ nvk_flush_ms_state(struct nvk_cmd_buffer *cmd)
sl = vk_standard_sample_locations_state(samples);
}
for (uint32_t i = 0; i < sl->per_pixel; i++) {
desc->root.draw.sample_locations[i] =
vk_to_nvk_sample_location(sl->locations[i]);
}
struct nvk_sample_location push_sl[NVK_MAX_SAMPLES];
for (uint32_t i = 0; i < sl->per_pixel; i++)
push_sl[i] = vk_to_nvk_sample_location(sl->locations[i]);
nvk_descriptor_state_set_root_array(cmd, &cmd->state.gfx.descriptors,
draw.sample_locations,
0, NVK_MAX_SAMPLES, push_sl);
if (nvk_cmd_buffer_3d_cls(cmd) >= MAXWELL_B) {
struct nvk_sample_location loc[16];

View File

@ -66,7 +66,7 @@ struct nvk_meta_save {
bool has_push_desc0;
struct nvk_push_descriptor_set push_desc0;
uint8_t set_dynamic_buffer_start[NVK_MAX_SETS];
uint8_t push[128];
uint8_t push[NVK_MAX_PUSH_SIZE];
};
static void
@ -89,14 +89,11 @@ nvk_meta_begin(struct nvk_cmd_buffer *cmd,
if (save->has_push_desc0)
save->push_desc0 = *desc->push[0];
STATIC_ASSERT(sizeof(save->set_dynamic_buffer_start) ==
sizeof(desc->root.set_dynamic_buffer_start));
memcpy(save->set_dynamic_buffer_start,
desc->root.set_dynamic_buffer_start,
sizeof(save->set_dynamic_buffer_start));
STATIC_ASSERT(sizeof(save->push) == sizeof(desc->root.push));
memcpy(save->push, desc->root.push, sizeof(save->push));
nvk_descriptor_state_get_root_array(desc, set_dynamic_buffer_start,
0, NVK_MAX_SETS,
save->set_dynamic_buffer_start);
nvk_descriptor_state_get_root_array(desc, push, 0, NVK_MAX_PUSH_SIZE,
save->push);
struct nv_push *p = nvk_cmd_buffer_push(cmd, 2);
P_IMMD(p, NV9097, SET_STATISTICS_COUNTER, {
@ -142,7 +139,8 @@ nvk_meta_end(struct nvk_cmd_buffer *cmd,
if (save->desc0) {
desc->sets[0] = save->desc0;
desc->root.sets[0] = nvk_descriptor_set_addr(save->desc0);
struct nvk_buffer_address addr = nvk_descriptor_set_addr(save->desc0);
nvk_descriptor_state_set_root(cmd, desc, sets[0], addr);
} else if (save->has_push_desc0) {
*desc->push[0] = save->push_desc0;
desc->push_dirty |= BITFIELD_BIT(0);
@ -152,11 +150,9 @@ nvk_meta_end(struct nvk_cmd_buffer *cmd,
/* Restore set_dynaic_buffer_start because meta binding set 0 can disturb
* all dynamic buffers starts for all sets.
*/
STATIC_ASSERT(sizeof(save->set_dynamic_buffer_start) ==
sizeof(desc->root.set_dynamic_buffer_start));
memcpy(desc->root.set_dynamic_buffer_start,
save->set_dynamic_buffer_start,
sizeof(save->set_dynamic_buffer_start));
nvk_descriptor_state_set_root_array(cmd, desc, set_dynamic_buffer_start,
0, NVK_MAX_SETS,
save->set_dynamic_buffer_start);
/* Restore the dynamic state */
assert(save->dynamic.vi == &cmd->state.gfx._dynamic_vi);
@ -177,7 +173,8 @@ nvk_meta_end(struct nvk_cmd_buffer *cmd,
nvk_cmd_bind_vertex_buffer(cmd, 0, save->vb0);
memcpy(desc->root.push, save->push, sizeof(save->push));
nvk_descriptor_state_set_root_array(cmd, desc, push, 0, sizeof(save->push),
save->push);
struct nv_push *p = nvk_cmd_buffer_push(cmd, 2);
P_IMMD(p, NV9097, SET_STATISTICS_COUNTER, {

View File

@ -931,7 +931,6 @@ nvk_meta_copy_query_pool_results(struct nvk_cmd_buffer *cmd,
VkQueryResultFlags flags)
{
struct nvk_device *dev = nvk_cmd_buffer_device(cmd);
struct nvk_descriptor_state *desc = &cmd->state.cs.descriptors;
VkResult result;
const struct nvk_copy_query_push push = {
@ -968,7 +967,8 @@ nvk_meta_copy_query_pool_results(struct nvk_cmd_buffer *cmd,
/* Save pipeline and push constants */
struct nvk_shader *shader_save = cmd->state.cs.shader;
uint8_t push_save[NVK_MAX_PUSH_SIZE];
memcpy(push_save, desc->root.push, NVK_MAX_PUSH_SIZE);
nvk_descriptor_state_get_root_array(&cmd->state.cs.descriptors, push,
0, NVK_MAX_PUSH_SIZE, push_save);
dev->vk.dispatch_table.CmdBindPipeline(nvk_cmd_buffer_to_handle(cmd),
VK_PIPELINE_BIND_POINT_COMPUTE,
@ -983,7 +983,8 @@ nvk_meta_copy_query_pool_results(struct nvk_cmd_buffer *cmd,
/* Restore pipeline and push constants */
if (shader_save)
nvk_cmd_bind_compute_shader(cmd, shader_save);
memcpy(desc->root.push, push_save, NVK_MAX_PUSH_SIZE);
nvk_descriptor_state_set_root_array(cmd, &cmd->state.cs.descriptors, push,
0, NVK_MAX_PUSH_SIZE, push_save);
}
VKAPI_ATTR void VKAPI_CALL