mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-18 01:50:40 +01:00
radeonsi: handle MultiDrawIndirect in si_get_draw_start_count
Also handle the GL_ARB_indirect_parameters case where the count itself
is in a buffer.
Use transfers rather than mapping the buffers directly. This anticipates
the possibility that the buffers are sparse (once ARB_sparse_buffer is
implemented), in which case they cannot be mapped directly.
Fixes GL45-CTS.gtf43.GL3Tests.multi_draw_indirect.multi_draw_indirect_type
on <= CIK.
v2:
- unmap the indirect buffer correctly
- handle the corner case where we have indirect draws, but all of them
have count 0.
Cc: mesa-stable@lists.freedesktop.org
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Acked-by: Edward O'Callaghan <funfunctor@folklore1984.net>
(cherry picked from commit 6a1d9684f4)
This commit is contained in:
parent
c47f1d6350
commit
7cb353520d
1 changed files with 53 additions and 7 deletions
|
|
@ -906,13 +906,59 @@ static void si_get_draw_start_count(struct si_context *sctx,
|
|||
unsigned *start, unsigned *count)
|
||||
{
|
||||
if (info->indirect) {
|
||||
struct r600_resource *indirect =
|
||||
(struct r600_resource*)info->indirect;
|
||||
int *data = r600_buffer_map_sync_with_rings(&sctx->b,
|
||||
indirect, PIPE_TRANSFER_READ);
|
||||
data += info->indirect_offset/sizeof(int);
|
||||
*start = data[2];
|
||||
*count = data[0];
|
||||
unsigned indirect_count;
|
||||
struct pipe_transfer *transfer;
|
||||
unsigned begin, end;
|
||||
unsigned map_size;
|
||||
unsigned *data;
|
||||
|
||||
if (info->indirect_params) {
|
||||
data = pipe_buffer_map_range(&sctx->b.b,
|
||||
info->indirect_params,
|
||||
info->indirect_params_offset,
|
||||
sizeof(unsigned),
|
||||
PIPE_TRANSFER_READ, &transfer);
|
||||
|
||||
indirect_count = *data;
|
||||
|
||||
pipe_buffer_unmap(&sctx->b.b, transfer);
|
||||
} else {
|
||||
indirect_count = info->indirect_count;
|
||||
}
|
||||
|
||||
if (!indirect_count) {
|
||||
*start = *count = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
map_size = (indirect_count - 1) * info->indirect_stride + 3 * sizeof(unsigned);
|
||||
data = pipe_buffer_map_range(&sctx->b.b, info->indirect,
|
||||
info->indirect_offset, map_size,
|
||||
PIPE_TRANSFER_READ, &transfer);
|
||||
|
||||
begin = UINT_MAX;
|
||||
end = 0;
|
||||
|
||||
for (unsigned i = 0; i < indirect_count; ++i) {
|
||||
unsigned count = data[0];
|
||||
unsigned start = data[2];
|
||||
|
||||
if (count > 0) {
|
||||
begin = MIN2(begin, start);
|
||||
end = MAX2(end, start + count);
|
||||
}
|
||||
|
||||
data += info->indirect_stride / sizeof(unsigned);
|
||||
}
|
||||
|
||||
pipe_buffer_unmap(&sctx->b.b, transfer);
|
||||
|
||||
if (begin < end) {
|
||||
*start = begin;
|
||||
*count = end - begin;
|
||||
} else {
|
||||
*start = *count = 0;
|
||||
}
|
||||
} else {
|
||||
*start = info->start;
|
||||
*count = info->count;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue