asahi: extract agx_calculate_vbo_clamp

honeykrisp will use.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29607>
This commit is contained in:
Alyssa Rosenzweig 2024-06-06 17:01:49 -04:00 committed by Marge Bot
parent ad85c043e7
commit 30c8d55a71
2 changed files with 45 additions and 39 deletions

View file

@ -193,3 +193,40 @@ agx_set_null_pbe(struct agx_pbe_packed *pbe, uint64_t sink)
cfg.buffer = sink;
}
}
/*
* Determine the maximum vertex/divided instance index. For robustness,
* the index will be clamped to this before reading (if soft fault is
* disabled).
*
* Index i accesses up to (exclusive) offset:
*
* src_offset + (i * stride) + elsize_B
*
* so we require
*
* src_offset + (i * stride) + elsize_B <= size
*
* <==>
*
* i <= floor((size - src_offset - elsize_B) / stride)
*/
static inline uint32_t
agx_calculate_vbo_clamp(uint64_t vbuf, uint64_t sink, enum pipe_format format,
uint32_t size_B, uint32_t stride_B, uint32_t offset_B,
uint64_t *vbuf_out)
{
unsigned elsize_B = util_format_get_blocksize(format);
unsigned subtracted_B = offset_B + elsize_B;
/* If at least one index is valid, determine the max. Otherwise, direct reads
* to zero.
*/
if (size_B >= subtracted_B) {
*vbuf_out = vbuf + offset_B;
return (size_B - subtracted_B) / stride_B;
} else {
*vbuf_out = sink;
return 0;
}
}

View file

@ -48,47 +48,16 @@ agx_upload_vbos(struct agx_batch *batch)
}
}
uint32_t zeroes[4] = {0};
uint64_t sink = agx_pool_upload_aligned(&batch->pool, &zeroes, 16, 16);
for (unsigned i = 0; i < PIPE_MAX_ATTRIBS; ++i) {
unsigned buffer_size = buf_sizes[attribs->buffers[i]];
unsigned buf = attribs->buffers[i];
/* Determine the maximum vertex/divided instance index. For robustness,
* the index will be clamped to this before reading (if soft fault is
* disabled).
*
* Index i accesses up to (exclusive) offset:
*
* src_offset + (i * stride) + elsize_B
*
* so we require
*
* src_offset + (i * stride) + elsize_B <= size
*
* <==>
*
* i <= floor((size - src_offset - elsize_B) / stride)
*/
unsigned elsize_B = util_format_get_blocksize(attribs->key[i].format);
unsigned subtracted = attribs->src_offsets[i] + elsize_B;
if (buffer_size >= subtracted) {
/* At least one index is valid, determine the max. If this is zero,
* only 1 index is valid.
*/
unsigned max_index =
(buffer_size - subtracted) / attribs->key[i].stride;
batch->uniforms.attrib_base[i] =
buffers[attribs->buffers[i]] + attribs->src_offsets[i];
batch->uniforms.attrib_clamp[i] = max_index;
} else {
/* No indices are valid. Direct reads to a single zero. */
uint32_t zeroes[4] = {0};
uint64_t sink = agx_pool_upload_aligned(&batch->pool, &zeroes, 16, 16);
batch->uniforms.attrib_base[i] = sink;
batch->uniforms.attrib_clamp[i] = 0;
}
batch->uniforms.attrib_clamp[i] = agx_calculate_vbo_clamp(
buffers[buf], sink, attribs->key[i].format, buf_sizes[buf],
attribs->key[i].stride, attribs->src_offsets[i],
&batch->uniforms.attrib_base[i]);
}
}