draw: fix vsplit code when the (post-bias) index value is -1

vsplit_add_cache uses the post-bias index for hashing, but the
vsplit_add_cache_uint/ushort/ubyte ones used the pre-bias index, therefore
the code for handling the special case (because -1 matches the initialization
value of the cache) wasn't actually working.
Commit 78a997f728 actually simplified the
cache logic somewhat, but it looks like this particular problem carried over
(and duplicated to the ushort/ubyte cases, since before only uint needed it).
This could lead to the vsplit cache doing the wrong thing, in particular
later fetch_info might indicate there are 0 values to fetch. This only really
affected edge cases which were bogus to begin with, but it could lead to a
crash with the jit vertex shader, since it cannot handle this case correctly
(the count loop is always executed at least once and we would not allocate
any memory for the shader outputs), so add another assert to catch it there.

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
Roland Scheidegger 2018-01-16 03:01:56 +01:00
parent 0ad73031ec
commit 1f462eaf39
2 changed files with 4 additions and 3 deletions

View File

@ -368,6 +368,7 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle,
unsigned start_or_maxelt, vid_base;
const unsigned *elts;
assert(fetch_info->count > 0);
llvm_vert_info.count = fetch_info->count;
llvm_vert_info.vertex_size = fpme->vertex_size;
llvm_vert_info.stride = fpme->vertex_size;

View File

@ -133,7 +133,7 @@ vsplit_add_cache_ubyte(struct vsplit_frontend *vsplit, const ubyte *elts,
VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias);
/* unlike the uint case this can only happen with elt_bias */
if (elt_bias && elt_idx == DRAW_MAX_FETCH_IDX && !vsplit->cache.has_max_fetch) {
unsigned hash = fetch % MAP_SIZE;
unsigned hash = elt_idx % MAP_SIZE;
vsplit->cache.fetches[hash] = 0;
vsplit->cache.has_max_fetch = TRUE;
}
@ -148,7 +148,7 @@ vsplit_add_cache_ushort(struct vsplit_frontend *vsplit, const ushort *elts,
VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias);
/* unlike the uint case this can only happen with elt_bias */
if (elt_bias && elt_idx == DRAW_MAX_FETCH_IDX && !vsplit->cache.has_max_fetch) {
unsigned hash = fetch % MAP_SIZE;
unsigned hash = elt_idx % MAP_SIZE;
vsplit->cache.fetches[hash] = 0;
vsplit->cache.has_max_fetch = TRUE;
}
@ -168,7 +168,7 @@ vsplit_add_cache_uint(struct vsplit_frontend *vsplit, const uint *elts,
VSPLIT_CREATE_IDX(elts, start, fetch, elt_bias);
/* Take care for DRAW_MAX_FETCH_IDX (since cache is initialized to -1). */
if (elt_idx == DRAW_MAX_FETCH_IDX && !vsplit->cache.has_max_fetch) {
unsigned hash = fetch % MAP_SIZE;
unsigned hash = elt_idx % MAP_SIZE;
/* force update - any value will do except DRAW_MAX_FETCH_IDX */
vsplit->cache.fetches[hash] = 0;
vsplit->cache.has_max_fetch = TRUE;