glsl: test both inputs when sorting varyings for xfb

In the sort functions used to sort varyings in gl_nir_link_varyings,
we were only checking the first input for whether or not it is xfb.
Check both inputs, and also provide a definite order for the xfb vs.
non-xfb varyings (the xfb come last, as the initial sort established).

This fixes a problem encountered on panfrost, where qsort could
mix xfb and non-xfb varyings which started out separate.

Note that the sort is still not stable. We probably should make it
stable, but that is a more extensive change that's handled in a later
commit.

Cc: mesa-stable
Signed-off-by: Eric R. Smith <eric.smith@collabora.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29178>
This commit is contained in:
Eric R. Smith
2024-05-09 19:45:03 -03:00
committed by Marge Bot
parent 485d56ed81
commit 5102a922e7

View File

@@ -2424,9 +2424,17 @@ static int
varying_matches_xfb_comparator(const void *x_generic, const void *y_generic)
{
const struct match *x = (const struct match *) x_generic;
if (x->producer_var != NULL && x->producer_var->data.is_xfb_only)
return varying_matches_match_comparator(x_generic, y_generic);
const struct match *y = (const struct match *) y_generic;
/* if both varying are used by transform feedback, sort them */
if (x->producer_var != NULL && x->producer_var->data.is_xfb_only) {
if (y->producer_var != NULL && y->producer_var->data.is_xfb_only)
return 0;
/* if x is varying and y is not, put y first */
return +1;
} else if (y->producer_var != NULL && y->producer_var->data.is_xfb_only) {
/* if y is varying and x is not, leave x first */
return -1;
}
/* FIXME: When the comparator returns 0 it means the elements being
* compared are equivalent. However the qsort documentation says:
@@ -2449,8 +2457,11 @@ static int
varying_matches_not_xfb_comparator(const void *x_generic, const void *y_generic)
{
const struct match *x = (const struct match *) x_generic;
const struct match *y = (const struct match *) y_generic;
if (x->producer_var != NULL && !x->producer_var->data.is_xfb)
if ( (x->producer_var != NULL && !x->producer_var->data.is_xfb)
&& (y->producer_var != NULL && !y->producer_var->data.is_xfb) )
/* if both are non-xfb, then sort them */
return varying_matches_match_comparator(x_generic, y_generic);
/* FIXME: When the comparator returns 0 it means the elements being