mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-08 12:50:12 +01:00
tnl: Try not to botch index buffer munging when start > 0.
Commit4c751ad67a(vbo/dlist: use a shared index buffer) caused multiple draws to use the same index buffer, and began setting the primitive's `start` field to the offset needed to access the right portion of the index buffer. Unfortunately, t_rebase_prims completely botches handling this case. Say for example we had start = 40, min_index = 6, max_index = 11. The actual indexes in the buffer are ib[40..45]. t_rebase_prims, however, would allocate an index buffer containing only 6 elements, and populate them with <ib[0..5] - min_index>. For one, this reads the wrong source data, leading to garbage index values. For another, it stores the new index buffer in the wrong spot, so drawing will try and read elements [40..45] of an array of length 6, and crash. This patch makes t_rebase_prims allocate a larger index buffer, with the blank space at the beginning, and try to copy the correct section of index buffer data over. This only works if `start` is the same for all primitives, however, so if we detect different ones, we recurse to rebase and call draw() separately for each different start value. Fixes:4c751ad67a("vbo/dlist: use a shared index buffer") Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4082 Acked-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8522>
This commit is contained in:
parent
14ae5069da
commit
bd6120f562
1 changed files with 23 additions and 5 deletions
|
|
@ -59,11 +59,12 @@
|
|||
|
||||
#define REBASE(TYPE) \
|
||||
static void *rebase_##TYPE(const void *ptr, \
|
||||
unsigned start, \
|
||||
unsigned count, \
|
||||
TYPE min_index) \
|
||||
{ \
|
||||
const TYPE *in = (TYPE *)ptr; \
|
||||
TYPE *tmp_indices = malloc(count * sizeof(TYPE)); \
|
||||
TYPE *tmp_indices = malloc((start + count) * sizeof(TYPE)); \
|
||||
\
|
||||
if (tmp_indices == NULL) { \
|
||||
_mesa_error_no_memory(__func__); \
|
||||
|
|
@ -71,7 +72,7 @@ static void *rebase_##TYPE(const void *ptr, \
|
|||
} \
|
||||
\
|
||||
for (unsigned i = 0; i < count; i++) \
|
||||
tmp_indices[i] = in[i] - min_index; \
|
||||
tmp_indices[start + i] = in[start + i] - min_index; \
|
||||
\
|
||||
return (void *)tmp_indices; \
|
||||
}
|
||||
|
|
@ -145,6 +146,23 @@ void t_rebase_prims(struct gl_context *ctx,
|
|||
|
||||
prim = tmp_prims;
|
||||
} else if (ib) {
|
||||
unsigned start = prim[0].start;
|
||||
for (i = 1; i < nr_prims; i++) {
|
||||
if (prim[i].start != start) {
|
||||
if (0) {
|
||||
printf("%s recursing due to mismatched start "
|
||||
"(prim[0].start = %u vs. prim[%u].start = %u)\n",
|
||||
__func__, start, i, prim[i].start);
|
||||
}
|
||||
|
||||
t_rebase_prims(ctx, arrays, &prim[0], i, ib, min_index,
|
||||
max_index, num_instances, base_instance, draw);
|
||||
t_rebase_prims(ctx, arrays, &prim[i], nr_prims - i, ib, min_index,
|
||||
max_index, num_instances, base_instance, draw);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Unfortunately need to adjust each index individually.
|
||||
*/
|
||||
bool map_ib = false;
|
||||
|
|
@ -166,13 +184,13 @@ void t_rebase_prims(struct gl_context *ctx,
|
|||
*/
|
||||
switch (ib->index_size_shift) {
|
||||
case 2:
|
||||
tmp_indices = rebase_GLuint( ptr, ib->count, min_index );
|
||||
tmp_indices = rebase_GLuint(ptr, start, ib->count, min_index);
|
||||
break;
|
||||
case 1:
|
||||
tmp_indices = rebase_GLushort( ptr, ib->count, min_index );
|
||||
tmp_indices = rebase_GLushort(ptr, start, ib->count, min_index);
|
||||
break;
|
||||
case 0:
|
||||
tmp_indices = rebase_GLubyte( ptr, ib->count, min_index );
|
||||
tmp_indices = rebase_GLubyte(ptr, start, ib->count, min_index);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue