From ee9809c889cf5fbb1c60593ebb253878316d6092 Mon Sep 17 00:00:00 2001 From: Alexandre Marquet Date: Tue, 30 Apr 2024 00:28:25 +0930 Subject: [PATCH] pan/mdg: quirk to disable auto32 For some reason, flat shading on T604 does not work when using auto32 varyings type. This commit introduces a quirk for T60x, and some plumbing in pan_nir, allowing to explicitely use appropriate types, rather than always using .u32 for flat shading. Backport-to: 24.1 Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10632 Signed-off-by: Alexandre Marquet Reviewed-by: Eric R. Smith Acked-by: Erik Faye-Lund Part-of: --- src/panfrost/midgard/midgard_compile.c | 27 +++++++++++++++++++++--- src/panfrost/midgard/midgard_quirks.h | 8 +++++++ src/panfrost/util/pan_collect_varyings.c | 17 +++++++++++---- src/panfrost/util/pan_ir.h | 3 +++ 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index 31fd55bc7d3..d7504ae381c 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -1266,12 +1266,32 @@ emit_varying_read(compiler_context *ctx, unsigned dest, unsigned offset, ins.load_store.arg_reg = REGISTER_LDST_ZERO; ins.load_store.index_format = midgard_index_address_u32; - /* For flat shading, we always use .u32 and require 32-bit mode. For - * smooth shading, we use the appropriate floating-point type. + /* For flat shading, for GPUs supporting auto32, we always use .u32 and + * require 32-bit mode. For smooth shading, we use the appropriate + * floating-point type. * * This could be optimized, but it makes it easy to check correctness. */ - if (flat) { + if (ctx->quirks & MIDGARD_NO_AUTO32) { + switch (type) { + case nir_type_uint32: + case nir_type_bool32: + ins.op = midgard_op_ld_vary_32u; + break; + case nir_type_int32: + ins.op = midgard_op_ld_vary_32i; + break; + case nir_type_float32: + ins.op = midgard_op_ld_vary_32; + break; + case nir_type_float16: + ins.op = midgard_op_ld_vary_16; + break; + default: + unreachable("Attempted to load unknown type"); + break; + } + } else if (flat) { assert(nir_alu_type_get_type_size(type) == 32); ins.op = midgard_op_ld_vary_32u; } else { @@ -2891,6 +2911,7 @@ midgard_compile_shader_nir(nir_shader *nir, ctx->ssa_constants = _mesa_hash_table_u64_create(ctx); /* Collect varyings after lowering I/O */ + info->quirk_no_auto32 = (ctx->quirks & MIDGARD_NO_AUTO32); pan_nir_collect_varyings(nir, info); /* Optimisation passes */ diff --git a/src/panfrost/midgard/midgard_quirks.h b/src/panfrost/midgard/midgard_quirks.h index 3003dbdf7c2..fd7f797e04b 100644 --- a/src/panfrost/midgard/midgard_quirks.h +++ b/src/panfrost/midgard/midgard_quirks.h @@ -66,11 +66,19 @@ #define MIDGARD_NO_OOO (1 << 5) +/* Disable auto32 type (apparently broken on T60x). */ + +#define MIDGARD_NO_AUTO32 (1 << 6) + static inline unsigned midgard_get_quirks(unsigned gpu_id) { switch (gpu_id) { case 0x600: + return MIDGARD_OLD_BLEND | MIDGARD_BROKEN_BLEND_LOADS | + MIDGARD_BROKEN_LOD | MIDGARD_NO_UPPER_ALU | MIDGARD_NO_OOO | + MIDGARD_NO_AUTO32; + case 0x620: return MIDGARD_OLD_BLEND | MIDGARD_BROKEN_BLEND_LOADS | MIDGARD_BROKEN_LOD | MIDGARD_NO_UPPER_ALU | MIDGARD_NO_OOO; diff --git a/src/panfrost/util/pan_collect_varyings.c b/src/panfrost/util/pan_collect_varyings.c index 0134ecfb67b..c6588720589 100644 --- a/src/panfrost/util/pan_collect_varyings.c +++ b/src/panfrost/util/pan_collect_varyings.c @@ -67,10 +67,17 @@ struct slot_info { unsigned index; }; +struct walk_varyings_data { + struct pan_shader_info *info; + struct slot_info *slots; +}; + static bool walk_varyings(UNUSED nir_builder *b, nir_instr *instr, void *data) { - struct slot_info *slots = data; + struct walk_varyings_data *wv_data = data; + struct pan_shader_info *info = wv_data->info; + struct slot_info *slots = wv_data->slots; if (instr->type != nir_instr_type_intrinsic) return false; @@ -113,8 +120,9 @@ walk_varyings(UNUSED nir_builder *b, nir_instr *instr, void *data) * only to determine the type, and the GL linker uses the type from the * fragment shader instead. */ - bool flat = (intr->intrinsic != nir_intrinsic_load_interpolated_input); - nir_alu_type type = flat ? nir_type_uint : nir_type_float; + bool flat = intr->intrinsic != nir_intrinsic_load_interpolated_input; + 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 @@ -161,7 +169,8 @@ pan_nir_collect_varyings(nir_shader *s, struct pan_shader_info *info) return; struct slot_info slots[64] = {0}; - nir_shader_instructions_pass(s, walk_varyings, nir_metadata_all, slots); + struct walk_varyings_data wv_data = {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) ? info->varyings.output diff --git a/src/panfrost/util/pan_ir.h b/src/panfrost/util/pan_ir.h index 7b24fb6922e..a37a14f70b4 100644 --- a/src/panfrost/util/pan_ir.h +++ b/src/panfrost/util/pan_ir.h @@ -288,6 +288,9 @@ struct pan_shader_info { uint32_t ubo_mask; + /* Quirk for GPUs that does not support auto32 types. */ + bool quirk_no_auto32; + union { struct bifrost_shader_info bifrost; struct midgard_shader_info midgard;