radv: add a dynamic vertex format cache.

With dynamic vertex bindings the vertex format lookups are a lot
more frequent (vs being baked in the pipeline). Add a simple lookup
cache using a dynamic array to keep track of the hw values, and
avoid repeated translation.

This also reduces the memset to just the bitfields since all
the others will be overwritten.

Seen in perf traces gputest gimark with zink on radv.

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15846>
This commit is contained in:
Dave Airlie
2022-04-11 15:37:01 +10:00
committed by Marge Bot
parent af1ecbeb0a
commit 105279e989
2 changed files with 53 additions and 21 deletions
+42 -21
View File
@@ -401,6 +401,8 @@ radv_destroy_cmd_buffer(struct radv_cmd_buffer *cmd_buffer)
{
list_del(&cmd_buffer->pool_link);
util_dynarray_fini(&cmd_buffer->cached_vertex_formats);
list_for_each_entry_safe(struct radv_cmd_buffer_upload, up, &cmd_buffer->upload.list, list)
{
cmd_buffer->device->ws->buffer_destroy(cmd_buffer->device->ws, up->upload_bo);
@@ -469,6 +471,8 @@ radv_create_cmd_buffer(struct radv_device *device, struct radv_cmd_pool *pool,
vk_object_base_init(&device->vk, &cmd_buffer->meta_push_descriptors.base,
VK_OBJECT_TYPE_DESCRIPTOR_SET);
util_dynarray_init(&cmd_buffer->cached_vertex_formats, NULL);
for (unsigned i = 0; i < MAX_BIND_POINTS; i++)
vk_object_base_init(&device->vk, &cmd_buffer->descriptors[i].push_set.set.base,
VK_OBJECT_TYPE_DESCRIPTOR_SET);
@@ -5738,10 +5742,6 @@ radv_CmdSetVertexInputEXT(VkCommandBuffer commandBuffer, uint32_t vertexBindingD
const VkVertexInputAttributeDescription2EXT *attrib = &pVertexAttributeDescriptions[i];
const VkVertexInputBindingDescription2EXT *binding = bindings[attrib->binding];
unsigned loc = attrib->location;
const struct util_format_description *format_desc = vk_format_description(attrib->format);
unsigned nfmt, dfmt;
bool post_shuffle;
enum radv_vs_input_alpha_adjust alpha_adjust;
state->attribute_mask |= 1u << loc;
state->bindings[loc] = attrib->binding;
@@ -5757,37 +5757,58 @@ radv_CmdSetVertexInputEXT(VkCommandBuffer commandBuffer, uint32_t vertexBindingD
cmd_buffer->vertex_bindings[attrib->binding].stride = binding->stride;
state->offsets[loc] = attrib->offset;
radv_translate_vertex_format(cmd_buffer->device->physical_device, attrib->format, format_desc,
&dfmt, &nfmt, &post_shuffle, &alpha_adjust);
struct dynamic_vertex_format_cache *found = NULL;
util_dynarray_foreach(&cmd_buffer->cached_vertex_formats,
struct dynamic_vertex_format_cache,
vf) {
if (vf->format == attrib->format) {
found = vf;
break;
}
}
if (!found) {
unsigned nfmt, dfmt;
bool post_shuffle;
enum radv_vs_input_alpha_adjust alpha_adjust;
const struct util_format_description *format_desc = vk_format_description(attrib->format);
state->formats[loc] = dfmt | (nfmt << 4);
const uint8_t format_align_req_minus_1 = format_desc->channel[0].size >= 32 ? 3 :
(format_desc->block.bits / 8u - 1);
state->format_align_req_minus_1[loc] = format_align_req_minus_1;
state->format_sizes[loc] = format_desc->block.bits / 8u;
found = util_dynarray_grow(&cmd_buffer->cached_vertex_formats,
struct dynamic_vertex_format_cache, 1);
radv_translate_vertex_format(cmd_buffer->device->physical_device, attrib->format, format_desc,
&dfmt, &nfmt, &post_shuffle, &alpha_adjust);
found->format = attrib->format;
found->hw_fmt = dfmt | (nfmt << 4);
const uint8_t format_align_req_minus_1 = format_desc->channel[0].size >= 32 ? 3 :
(format_desc->block.bits / 8u - 1);
found->fmt_align_req_minus_1 = format_align_req_minus_1;
found->fmt_size = format_desc->block.bits / 8u;
found->post_shuffle = post_shuffle;
found->alpha_adjust_lo = alpha_adjust & 0x1;
found->alpha_adjust_hi = (alpha_adjust >> 1) & 0x1;
}
state->formats[loc] = found->hw_fmt;
state->format_align_req_minus_1[loc] = found->fmt_align_req_minus_1;
state->format_sizes[loc] = found->fmt_size;
state->alpha_adjust_lo |= found->alpha_adjust_lo << loc;
state->alpha_adjust_hi |= found->alpha_adjust_hi << loc;
if (found->post_shuffle)
state->post_shuffle |= 1u << loc;
if (chip == GFX6 || chip >= GFX10) {
const struct radv_vertex_binding *vb = cmd_buffer->vertex_bindings;
unsigned bit = 1u << loc;
if (binding->stride & format_align_req_minus_1) {
if (binding->stride & found->fmt_align_req_minus_1) {
state->misaligned_mask |= bit;
if (cmd_buffer->state.vbo_bound_mask & bit)
cmd_buffer->state.vbo_misaligned_mask |= bit;
} else {
state->possibly_misaligned_mask |= bit;
if (cmd_buffer->state.vbo_bound_mask & bit &&
((vb[attrib->binding].offset + state->offsets[loc]) & format_align_req_minus_1))
((vb[attrib->binding].offset + state->offsets[loc]) & found->fmt_align_req_minus_1))
cmd_buffer->state.vbo_misaligned_mask |= bit;
}
}
if (alpha_adjust) {
state->alpha_adjust_lo |= (alpha_adjust & 0x1) << loc;
state->alpha_adjust_hi |= (alpha_adjust >> 1) << loc;
}
if (post_shuffle)
state->post_shuffle |= 1u << loc;
}
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_VERTEX_BUFFER |
+11
View File
@@ -1566,6 +1566,16 @@ enum radv_cmd_buffer_status {
RADV_CMD_BUFFER_STATUS_PENDING,
};
struct dynamic_vertex_format_cache {
VkFormat format;
uint8_t hw_fmt;
uint8_t fmt_align_req_minus_1;
uint8_t fmt_size;
bool post_shuffle;
bool alpha_adjust_lo;
bool alpha_adjust_hi;
};
struct radv_cmd_buffer {
struct vk_command_buffer vk;
@@ -1574,6 +1584,7 @@ struct radv_cmd_buffer {
struct radv_cmd_pool *pool;
struct list_head pool_link;
struct util_dynarray cached_vertex_formats;
VkCommandBufferUsageFlags usage_flags;
enum radv_cmd_buffer_status status;
struct radeon_cmdbuf *cs;