diff --git a/src/panfrost/compiler/bifrost_compile.c b/src/panfrost/compiler/bifrost_compile.c index 4bf803f7d20..96d4353734b 100644 --- a/src/panfrost/compiler/bifrost_compile.c +++ b/src/panfrost/compiler/bifrost_compile.c @@ -556,6 +556,7 @@ bi_emit_load_vary(bi_builder *b, nir_intrinsic_instr *instr) enum bi_sample sample = BI_SAMPLE_CENTER; enum bi_update update = BI_UPDATE_STORE; enum bi_register_format regfmt = BI_REGISTER_FORMAT_AUTO; + enum bi_source_format source_format; bool smooth = instr->intrinsic == nir_intrinsic_load_interpolated_input; bi_index src0 = bi_null(); @@ -575,9 +576,11 @@ bi_emit_load_vary(bi_builder *b, nir_intrinsic_instr *instr) assert(sz == 16 || sz == 32); regfmt = (sz == 16) ? BI_REGISTER_FORMAT_F16 : BI_REGISTER_FORMAT_F32; + source_format = BI_SOURCE_FORMAT_F32; } else { assert(sz == 32); regfmt = BI_REGISTER_FORMAT_U32; + source_format = BI_SOURCE_FORMAT_FLAT32; /* Valhall can't have bi_null() here, although the source is * logically unused for flat varyings @@ -601,9 +604,6 @@ bi_emit_load_vary(bi_builder *b, nir_intrinsic_instr *instr) b->shader->malloc_idvs && b->shader->inputs->valhall.use_ld_var_buf; if (use_ld_var_buf) { - enum bi_source_format source_format = - smooth ? BI_SOURCE_FORMAT_F32 : BI_SOURCE_FORMAT_FLAT32; - if (immediate) { /* Immediate index given in bytes. */ bi_ld_var_buf_imm_to(b, sz, dest, src0, regfmt, sample, source_format, diff --git a/src/panfrost/util/pan_collect_varyings.c b/src/panfrost/util/pan_collect_varyings.c index 03b43bfd79f..ea6c74f534f 100644 --- a/src/panfrost/util/pan_collect_varyings.c +++ b/src/panfrost/util/pan_collect_varyings.c @@ -48,6 +48,7 @@ varying_format(nir_alu_type t, unsigned ncomps) VARYING_FORMAT(float, 32, FLOAT, 32), VARYING_FORMAT(uint, 32, UINT, 32), VARYING_FORMAT(float, 16, FLOAT, 16), + VARYING_FORMAT(uint, 16, UINT, 16), }; #undef VARYING_FORMAT @@ -84,6 +85,7 @@ walk_varyings(UNUSED nir_builder *b, nir_instr *instr, void *data) nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr); unsigned count; + unsigned size; /* Only consider intrinsics that access varyings */ switch (intr->intrinsic) { @@ -92,6 +94,7 @@ walk_varyings(UNUSED nir_builder *b, nir_instr *instr, void *data) return false; count = nir_src_num_components(intr->src[0]); + size = nir_alu_type_get_type_size(nir_intrinsic_src_type(intr)); break; case nir_intrinsic_load_input: @@ -100,6 +103,7 @@ walk_varyings(UNUSED nir_builder *b, nir_instr *instr, void *data) return false; count = intr->def.num_components; + size = intr->def.bit_size; break; default: @@ -130,9 +134,14 @@ walk_varyings(UNUSED nir_builder *b, nir_instr *instr, void *data) * as having no demonstrable benefit in practice. */ if (type == nir_type_float && sem.medium_precision) - type |= 16; - else - type |= 32; + size = 16; + else { + /* We never emit 16-bit user varyings except for lowered mediump floats */ + if (sem.location >= VARYING_SLOT_VAR0) + assert(size == 32); + } + + type |= size; /* Count currently contains the number of components accessed by this * intrinsics. However, we may be accessing a fractional location,