panfrost: Fix general purpose varying handling

When both the fragment and vertex shaders point to the same varying
location they expect to share the same varying slot.
Make sure vertex and fragment varyings pointing to the same loc have
->src_offset set to the same value.

[Alyssa: In addition a patch implement txs, this fixes GALLIUM_HUD on
Panfrost]

Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
This commit is contained in:
Boris Brezillon 2019-06-13 14:56:02 +02:00 committed by Alyssa Rosenzweig
parent 7566a9a58a
commit 749c544b84
4 changed files with 44 additions and 15 deletions

View file

@ -2414,9 +2414,9 @@ midgard_compile_shader_nir(nir_shader *nir, midgard_program *program, bool is_bl
unsigned loc = var->data.driver_location;
unsigned sz = glsl_type_size(var->type, FALSE);
for (int c = loc; c < (loc + sz); ++c) {
program->varyings[c] = var->data.location;
max_varying = MAX2(max_varying, c);
for (int c = 0; c < sz; ++c) {
program->varyings[loc + c] = var->data.location + c;
max_varying = MAX2(max_varying, loc + c);
}
}

View file

@ -105,8 +105,6 @@ panfrost_shader_compile(struct panfrost_context *ctx, struct mali_shader_meta *m
unsigned default_vec4_swizzle = panfrost_get_default_swizzle(4);
/* Iterate the varyings and emit the corresponding descriptor */
unsigned general_purpose_count = 0;
for (unsigned i = 0; i < program.varying_count; ++i) {
unsigned location = program.varyings[i];
@ -136,12 +134,9 @@ panfrost_shader_compile(struct panfrost_context *ctx, struct mali_shader_meta *m
state->reads_point_coord = true;
} else {
v.index = 0;
v.src_offset = 16 * (general_purpose_count++);
}
state->varyings[i] = v;
state->varyings_loc[i] = location;
}
/* Set the stride for the general purpose fp32 vec4 varyings */
state->general_varying_stride = (4 * 4) * general_purpose_count;
}

View file

@ -697,6 +697,7 @@ panfrost_emit_varying_descriptor(
struct panfrost_shader_state *vs = &ctx->vs->variants[ctx->vs->active_variant];
struct panfrost_shader_state *fs = &ctx->fs->variants[ctx->fs->active_variant];
unsigned int num_gen_varyings = 0;
/* Allocate the varying descriptor */
@ -706,6 +707,42 @@ panfrost_emit_varying_descriptor(
struct panfrost_transfer trans = panfrost_allocate_transient(ctx,
vs_size + fs_size);
/*
* Assign ->src_offset now that we know about all the general purpose
* varyings that will be used by the fragment and vertex shaders.
*/
for (unsigned i = 0; i < vs->tripipe->varying_count; i++) {
/*
* General purpose varyings have ->index set to 0, skip other
* entries.
*/
if (vs->varyings[i].index)
continue;
vs->varyings[i].src_offset = 16 * (num_gen_varyings++);
}
for (unsigned i = 0; i < fs->tripipe->varying_count; i++) {
unsigned j;
if (fs->varyings[i].index)
continue;
/*
* Re-use the VS general purpose varying pos if it exists,
* create a new one otherwise.
*/
for (j = 0; j < vs->tripipe->varying_count; j++) {
if (fs->varyings_loc[i] == vs->varyings_loc[j])
break;
}
if (j < vs->tripipe->varying_count)
fs->varyings[i].src_offset = vs->varyings[j].src_offset;
else
fs->varyings[i].src_offset = 16 * (num_gen_varyings++);
}
memcpy(trans.cpu, vs->varyings, vs_size);
memcpy(trans.cpu + vs_size, fs->varyings, fs_size);
@ -716,11 +753,8 @@ panfrost_emit_varying_descriptor(
union mali_attr varyings[PIPE_MAX_ATTRIBS];
unsigned idx = 0;
/* General varyings -- use the VS's, since those are more likely to be
* accurate on desktop */
panfrost_emit_varyings(ctx, &varyings[idx++],
vs->general_varying_stride, invocation_count);
panfrost_emit_varyings(ctx, &varyings[idx++], num_gen_varyings * 16,
invocation_count);
/* fp32 vec4 gl_Position */
ctx->payload_tiler.postfix.position_varying =

View file

@ -267,8 +267,8 @@ struct panfrost_shader_state {
bool writes_point_size;
bool reads_point_coord;
unsigned general_varying_stride;
struct mali_attr_meta varyings[PIPE_MAX_ATTRIBS];
gl_varying_slot varyings_loc[PIPE_MAX_ATTRIBS];
unsigned sysval_count;
unsigned sysval[MAX_SYSVAL_COUNT];