mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-03 07:10:15 +01:00
panfrost: Don't duplicate attribute buffers
If the (vbi, divisor) tuple matches, we can save an attribute buffer descriptor. We do the linking at CSO create time. This should be a bit more cache friendly. Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11123>
This commit is contained in:
parent
61b83fba27
commit
f14dbc02fb
3 changed files with 57 additions and 13 deletions
|
|
@ -1623,9 +1623,15 @@ panfrost_emit_vertex_data(struct panfrost_batch *batch,
|
|||
* Also, we allocate more memory than what's needed here if either instancing
|
||||
* is enabled or images are present, this can be improved. */
|
||||
unsigned bufs_per_attrib = (instanced || nr_images > 0) ? 2 : 1;
|
||||
unsigned nr_bufs = (vs->info.attribute_count * bufs_per_attrib) +
|
||||
unsigned nr_bufs = ((so->nr_bufs + nr_images) * bufs_per_attrib) +
|
||||
(pan_is_bifrost(dev) ? 1 : 0);
|
||||
|
||||
/* Midgard needs vertexid/instanceid handled specially */
|
||||
bool special_vbufs = dev->arch < 6 && vs->info.attribute_count >= PAN_VERTEX_ID;
|
||||
|
||||
if (special_vbufs)
|
||||
nr_bufs += 2;
|
||||
|
||||
if (!nr_bufs) {
|
||||
*buffers = 0;
|
||||
return 0;
|
||||
|
|
@ -1648,14 +1654,9 @@ panfrost_emit_vertex_data(struct panfrost_batch *batch,
|
|||
unsigned attrib_to_buffer[PIPE_MAX_ATTRIBS] = { 0 };
|
||||
unsigned k = 0;
|
||||
|
||||
for (unsigned i = 0; i < so->num_elements; ++i) {
|
||||
/* We map buffers 1:1 with the attributes, which
|
||||
* means duplicating some vertex buffers (who cares? aside from
|
||||
* maybe some caching implications but I somehow doubt that
|
||||
* matters) */
|
||||
|
||||
struct pipe_vertex_element *elem = &so->pipe[i];
|
||||
unsigned vbi = elem->vertex_buffer_index;
|
||||
for (unsigned i = 0; i < so->nr_bufs; ++i) {
|
||||
unsigned vbi = so->buffers[i].vbi;
|
||||
unsigned divisor = so->buffers[i].divisor;
|
||||
attrib_to_buffer[i] = k;
|
||||
|
||||
if (!(ctx->vb_mask & (1 << vbi)))
|
||||
|
|
@ -1685,7 +1686,6 @@ panfrost_emit_vertex_data(struct panfrost_batch *batch,
|
|||
|
||||
/* When there is a divisor, the hardware-level divisor is
|
||||
* the product of the instance divisor and the padded count */
|
||||
unsigned divisor = elem->instance_divisor;
|
||||
unsigned stride = buf->stride;
|
||||
|
||||
if (ctx->indirect_draw) {
|
||||
|
|
@ -1766,8 +1766,7 @@ panfrost_emit_vertex_data(struct panfrost_batch *batch,
|
|||
}
|
||||
|
||||
/* Add special gl_VertexID/gl_InstanceID buffers */
|
||||
|
||||
if (unlikely(vs->info.attribute_count >= PAN_VERTEX_ID)) {
|
||||
if (unlikely(special_vbufs)) {
|
||||
panfrost_vertex_id(ctx->padded_count, &bufs[k], ctx->instance_count > 1);
|
||||
|
||||
pan_pack(out + PAN_VERTEX_ID, ATTRIBUTE, cfg) {
|
||||
|
|
@ -1821,7 +1820,7 @@ panfrost_emit_vertex_data(struct panfrost_batch *batch,
|
|||
src_offset -= buf->stride * ctx->offset_start;
|
||||
|
||||
pan_pack(out + i, ATTRIBUTE, cfg) {
|
||||
cfg.buffer_index = attrib_to_buffer[i];
|
||||
cfg.buffer_index = attrib_to_buffer[so->element_buffer[i]];
|
||||
cfg.format = so->formats[i];
|
||||
cfg.offset = src_offset;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -897,6 +897,31 @@ panfrost_set_shader_images(
|
|||
}
|
||||
}
|
||||
|
||||
/* Assigns a vertex buffer for a given (index, divisor) tuple */
|
||||
|
||||
static unsigned
|
||||
pan_assign_vertex_buffer(struct pan_vertex_buffer *buffers,
|
||||
unsigned *nr_bufs,
|
||||
unsigned vbi,
|
||||
unsigned divisor)
|
||||
{
|
||||
/* Look up the buffer */
|
||||
for (unsigned i = 0; i < (*nr_bufs); ++i) {
|
||||
if (buffers[i].vbi == vbi && buffers[i].divisor == divisor)
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Else, create a new buffer */
|
||||
unsigned idx = (*nr_bufs)++;
|
||||
|
||||
buffers[idx] = (struct pan_vertex_buffer) {
|
||||
.vbi = vbi,
|
||||
.divisor = divisor
|
||||
};
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
static void *
|
||||
panfrost_create_vertex_elements_state(
|
||||
struct pipe_context *pctx,
|
||||
|
|
@ -909,6 +934,15 @@ panfrost_create_vertex_elements_state(
|
|||
so->num_elements = num_elements;
|
||||
memcpy(so->pipe, elements, sizeof(*elements) * num_elements);
|
||||
|
||||
/* Assign attribute buffers corresponding to the vertex buffers, keyed
|
||||
* for a particular divisor since that's how instancing works on Mali */
|
||||
for (unsigned i = 0; i < num_elements; ++i) {
|
||||
so->element_buffer[i] = pan_assign_vertex_buffer(
|
||||
so->buffers, &so->nr_bufs,
|
||||
elements[i].vertex_buffer_index,
|
||||
elements[i].instance_divisor);
|
||||
}
|
||||
|
||||
for (int i = 0; i < num_elements; ++i) {
|
||||
enum pipe_format fmt = elements[i].src_format;
|
||||
const struct util_format_description *desc = util_format_description(fmt);
|
||||
|
|
|
|||
|
|
@ -306,9 +306,20 @@ struct panfrost_shader_variants {
|
|||
unsigned active_variant;
|
||||
};
|
||||
|
||||
struct pan_vertex_buffer {
|
||||
unsigned vbi;
|
||||
unsigned divisor;
|
||||
};
|
||||
|
||||
struct panfrost_vertex_state {
|
||||
unsigned num_elements;
|
||||
|
||||
/* buffers corresponds to attribute buffer, element_buffers corresponds
|
||||
* to an index in buffers for each vertex element */
|
||||
struct pan_vertex_buffer buffers[PIPE_MAX_ATTRIBS];
|
||||
unsigned element_buffer[PIPE_MAX_ATTRIBS];
|
||||
unsigned nr_bufs;
|
||||
|
||||
struct pipe_vertex_element pipe[PIPE_MAX_ATTRIBS];
|
||||
unsigned formats[PIPE_MAX_ATTRIBS];
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue