From 749c544b84123627b9f7026bf9c02d10a7139465 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 13 Jun 2019 14:56:02 +0200 Subject: [PATCH] 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 Reviewed-by: Alyssa Rosenzweig --- .../panfrost/midgard/midgard_compile.c | 6 +-- src/gallium/drivers/panfrost/pan_assemble.c | 7 +-- src/gallium/drivers/panfrost/pan_context.c | 44 ++++++++++++++++--- src/gallium/drivers/panfrost/pan_context.h | 2 +- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/src/gallium/drivers/panfrost/midgard/midgard_compile.c b/src/gallium/drivers/panfrost/midgard/midgard_compile.c index 6761b276814..1374c1ee647 100644 --- a/src/gallium/drivers/panfrost/midgard/midgard_compile.c +++ b/src/gallium/drivers/panfrost/midgard/midgard_compile.c @@ -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); } } diff --git a/src/gallium/drivers/panfrost/pan_assemble.c b/src/gallium/drivers/panfrost/pan_assemble.c index a6ba5fa6790..de8a53ce05d 100644 --- a/src/gallium/drivers/panfrost/pan_assemble.c +++ b/src/gallium/drivers/panfrost/pan_assemble.c @@ -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; } diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c index 53c2fe3cee7..d178a0f1db2 100644 --- a/src/gallium/drivers/panfrost/pan_context.c +++ b/src/gallium/drivers/panfrost/pan_context.c @@ -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 = diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h index 6f3bca939e5..3eac8d6b5a2 100644 --- a/src/gallium/drivers/panfrost/pan_context.h +++ b/src/gallium/drivers/panfrost/pan_context.h @@ -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]; -- 2.30.2