panfrost: move handling for bifrost mediump lowering to pan_collect_varyings

For Bifrost and newer, we always write mediump varyings from a 32-bit
source in the VS. This is needed because the FS does not unconditionally
lower mediump to 16-bit.

Previously we worked around this in panvk by replacing 16-bit formats
with 32-bit in emit_varying_descs, but once we support
storageInputOutput16, we will need to preserve 16-bit formats for
explicit 16-bit varyings.

Signed-off-by: Benjamin Lee <benjamin.lee@collabora.com>
Reviewed-by: Lars-Ivar Hesselberg Simonsen <lars-ivar.simonsen@arm.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33078>
This commit is contained in:
Benjamin Lee 2025-01-28 16:25:55 -08:00 committed by Marge Bot
parent 26ba20be51
commit 02dc105a36
5 changed files with 30 additions and 37 deletions

View file

@ -5856,7 +5856,7 @@ bifrost_compile_shader_nir(nir_shader *nir,
info->tls_size = nir->scratch_size;
info->vs.idvs = bi_should_idvs(nir, inputs);
pan_nir_collect_varyings(nir, info);
pan_nir_collect_varyings(nir, info, PAN_MEDIUMP_VARY_32BIT);
if (info->vs.idvs) {
bi_compile_variant(nir, inputs, binary, info, BI_IDVS_POSITION);

View file

@ -2984,7 +2984,7 @@ midgard_compile_shader_nir(nir_shader *nir,
/* Collect varyings after lowering I/O */
info->quirk_no_auto32 = (ctx->quirks & MIDGARD_NO_AUTO32);
pan_nir_collect_varyings(nir, info);
pan_nir_collect_varyings(nir, info, PAN_MEDIUMP_VARY_SMOOTH_16BIT);
/* Optimisation passes */
optimise_nir(nir, ctx->quirks, inputs->is_blend);

View file

@ -69,6 +69,7 @@ struct slot_info {
};
struct walk_varyings_data {
enum pan_mediump_vary mediump;
struct pan_shader_info *info;
struct slot_info *slots;
};
@ -128,19 +129,20 @@ walk_varyings(UNUSED nir_builder *b, nir_instr *instr, void *data)
bool auto32 = !info->quirk_no_auto32;
nir_alu_type type = (flat && auto32) ? nir_type_uint : nir_type_float;
/* Demote interpolated float varyings to fp16 where possible. We do not
* demote flat varyings, including integer varyings, due to various
* issues with the Midgard hardware behaviour and TGSI shaders, as well
* as having no demonstrable benefit in practice.
*/
if (type == nir_type_float && sem.medium_precision)
size = 16;
else {
/* We never emit 16-bit user varyings except for lowered mediump floats */
if (sem.location >= VARYING_SLOT_VAR0)
assert(size == 32);
if (sem.medium_precision) {
/* Demote interpolated float varyings to fp16 where possible. We do not
* demote flat varyings, including integer varyings, due to various
* issues with the Midgard hardware behaviour and TGSI shaders, as well
* as having no demonstrable benefit in practice.
*/
if (wv_data->mediump == PAN_MEDIUMP_VARY_SMOOTH_16BIT)
size = type == nir_type_float ? 16 : 32;
if (wv_data->mediump == PAN_MEDIUMP_VARY_32BIT)
size = 32;
}
assert(size == 32 || size == 16);
type |= size;
/* Count currently contains the number of components accessed by this
@ -206,14 +208,15 @@ pan_nir_collect_noperspective_varyings_fs(nir_shader *s)
}
void
pan_nir_collect_varyings(nir_shader *s, struct pan_shader_info *info)
pan_nir_collect_varyings(nir_shader *s, struct pan_shader_info *info,
enum pan_mediump_vary mediump)
{
if (s->info.stage != MESA_SHADER_VERTEX &&
s->info.stage != MESA_SHADER_FRAGMENT)
return;
struct slot_info slots[64] = {0};
struct walk_varyings_data wv_data = {info, slots};
struct walk_varyings_data wv_data = {mediump, info, slots};
nir_shader_instructions_pass(s, walk_varyings, nir_metadata_all, &wv_data);
struct pan_shader_varying *varyings = (s->info.stage == MESA_SHADER_VERTEX)

View file

@ -393,6 +393,15 @@ void pan_print_alu_type(nir_alu_type t, FILE *fp);
#define PAN_WRITEOUT_S 4
#define PAN_WRITEOUT_2 8
/* Specify the mediump lowering behavior for pan_nir_collect_varyings */
enum pan_mediump_vary {
/* Always assign a 32-bit format to mediump varyings */
PAN_MEDIUMP_VARY_32BIT,
/* Assign a 16-bit format to varyings with smooth interpolation, and a
* 32-bit format to varyings with flat interpolation */
PAN_MEDIUMP_VARY_SMOOTH_16BIT,
};
bool pan_nir_lower_zs_store(nir_shader *nir);
bool pan_nir_lower_store_component(nir_shader *shader);
@ -413,7 +422,8 @@ bool pan_lower_xfb(nir_shader *nir);
bool pan_lower_image_index(nir_shader *shader, unsigned vs_img_attrib_offset);
uint32_t pan_nir_collect_noperspective_varyings_fs(nir_shader *s);
void pan_nir_collect_varyings(nir_shader *s, struct pan_shader_info *info);
void pan_nir_collect_varyings(nir_shader *s, struct pan_shader_info *info,
enum pan_mediump_vary mediump);
/*
* Helper returning the subgroup size. Generally, this is equal to the number of

View file

@ -197,31 +197,11 @@ emit_varying_descs(const struct panvk_cmd_buffer *cmdbuf,
if (var->location < VARYING_SLOT_VAR0)
continue;
/* We currently always write out F32 in the vertex shaders, so the format
* needs to reflect this. */
enum pipe_format f = var->format;
switch (f) {
case PIPE_FORMAT_R16_FLOAT:
f = PIPE_FORMAT_R32_FLOAT;
break;
case PIPE_FORMAT_R16G16_FLOAT:
f = PIPE_FORMAT_R32G32_FLOAT;
break;
case PIPE_FORMAT_R16G16B16_FLOAT:
f = PIPE_FORMAT_R32G32B32_FLOAT;
break;
case PIPE_FORMAT_R16G16B16A16_FLOAT:
f = PIPE_FORMAT_R32G32B32A32_FLOAT;
break;
default:
break;
}
uint32_t loc = var->location - VARYING_SLOT_VAR0;
pan_pack(&descs[i], ATTRIBUTE, cfg) {
cfg.attribute_type = MALI_ATTRIBUTE_TYPE_VERTEX_PACKET;
cfg.offset_enable = false;
cfg.format = GENX(panfrost_format_from_pipe_format)(f)->hw;
cfg.format = GENX(panfrost_format_from_pipe_format)(var->format)->hw;
cfg.table = 61;
cfg.frequency = MALI_ATTRIBUTE_FREQUENCY_VERTEX;
cfg.offset = 1024 + (loc * 16);