glsl: Fix subscripted arrays with no XFB packing

We need to duplicate the subscripted members even if they happen to be
aligned, since the other elements may be passed into the consumer
shader. Fixes on Panfrost:

dEQP-GLES3.functional.transform_feedback.array_element.interleaved.lines.highp_float

Note: the test did pass on main previously due to an elaborate set of
driver hacks. I don't believe the old behaviour was correct regardless.

Only Panfrost is affected by this change and the next, as every other
driver sets PIPE_CAP_PACKED_STREAM_OUTPUT.

Acked-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10778>
This commit is contained in:
Alyssa Rosenzweig
2020-08-27 08:21:40 -04:00
committed by Marge Bot
parent 7efa5f3c80
commit 538ab8c571
2 changed files with 5 additions and 7 deletions

View File

@@ -2925,17 +2925,15 @@ assign_varying_locations(struct gl_context *ctx,
/* There are two situations where a new output varying is needed:
*
* - If varying packing is disabled for xfb and the current declaration
* is not aligned within the top level varying (e.g. vec3_arr[1]).
* is subscripting an array, whether the subscript is aligned or not.
* to preserve the rest of the array for the consumer.
*
* - If a builtin variable needs to be copied to a new variable
* before its content is modified by another lowering pass (e.g.
* \c gl_Position is transformed by \c nir_lower_viewport_transform).
*/
const unsigned dmul =
matched_candidate->type->without_array()->is_64bit() ? 2 : 1;
const bool lowered =
(disable_xfb_packing &&
!tfeedback_decls[i].is_aligned(dmul, matched_candidate->struct_offset_floats)) ||
(disable_xfb_packing && tfeedback_decls[i].subscripted()) ||
(matched_candidate->toplevel_var->data.explicit_location &&
matched_candidate->toplevel_var->data.location < VARYING_SLOT_VAR0 &&
(!consumer || consumer->Stage == MESA_SHADER_FRAGMENT) &&

View File

@@ -130,9 +130,9 @@ public:
return !this->next_buffer_separator && !this->skip_components;
}
bool is_aligned(unsigned dmul, unsigned offset) const
bool subscripted() const
{
return (dmul * (this->array_subscript + offset)) % 4 == 0;
return this->is_subscripted;
}
const char *name() const