From 59937f62a6ba30fedc5bfd0d399388c77370449c Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Thu, 23 May 2024 20:01:03 +0200 Subject: [PATCH] ir3/a7xx: Fix FS consts corruption when other FS has zero constlen Having zero consts in one FS may corrupt consts in follow up FSs, on such GPUs blob never has zero consts in FS. The mechanism of corruption is unknown. Fixes geometry flickering in a number of games, including: Baldur's Gate 3 Assasin's Creed Rogue Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/common/freedreno_dev_info.h | 6 ++++++ src/freedreno/common/freedreno_devices.py | 4 ++++ src/freedreno/ir3/ir3_compiler.c | 1 + src/freedreno/ir3/ir3_compiler.h | 2 ++ src/freedreno/ir3/ir3_compiler_nir.c | 5 +++++ 5 files changed, 18 insertions(+) diff --git a/src/freedreno/common/freedreno_dev_info.h b/src/freedreno/common/freedreno_dev_info.h index e2170df697c..1ccb98338e4 100644 --- a/src/freedreno/common/freedreno_dev_info.h +++ b/src/freedreno/common/freedreno_dev_info.h @@ -254,6 +254,12 @@ struct fd_dev_info { * parallel with "forcebin". It is exacerbated by using "syncdraw". */ bool no_gs_hw_binning_quirk; + + /* Having zero consts in one FS may corrupt consts in follow up FSs, + * on such GPUs blob never has zero consts in FS. The mechanism of + * corruption is unknown. + */ + bool fs_must_have_non_zero_constlen_quirk; } a7xx; }; diff --git a/src/freedreno/common/freedreno_devices.py b/src/freedreno/common/freedreno_devices.py index 7d2ec1a38a2..ae177e8a70d 100644 --- a/src/freedreno/common/freedreno_devices.py +++ b/src/freedreno/common/freedreno_devices.py @@ -799,10 +799,12 @@ a7xx_base = A6XXProps( a7xx_725 = A7XXProps( cmdbuf_start_a725_quirk = True, supports_ibo_ubwc = True, + fs_must_have_non_zero_constlen_quirk = True, ) a7xx_730 = A7XXProps( supports_ibo_ubwc = True, + fs_must_have_non_zero_constlen_quirk = True, ) a7xx_740 = A7XXProps( @@ -810,6 +812,7 @@ a7xx_740 = A7XXProps( has_event_write_sample_count = True, ubwc_unorm_snorm_int_compatible = True, supports_ibo_ubwc = True, + fs_must_have_non_zero_constlen_quirk = True, ) a7xx_740_a32 = A7XXProps( @@ -818,6 +821,7 @@ a7xx_740_a32 = A7XXProps( has_event_write_sample_count = True, ubwc_unorm_snorm_int_compatible = True, supports_ibo_ubwc = True, + fs_must_have_non_zero_constlen_quirk = True, ) a7xx_750 = A7XXProps( diff --git a/src/freedreno/ir3/ir3_compiler.c b/src/freedreno/ir3/ir3_compiler.c index cd98feede54..2f36294c1b8 100644 --- a/src/freedreno/ir3/ir3_compiler.c +++ b/src/freedreno/ir3/ir3_compiler.c @@ -224,6 +224,7 @@ ir3_compiler_create(struct fd_device *dev, const struct fd_dev_id *dev_id, compiler->has_branch_and_or = true; compiler->has_predication = true; compiler->has_scalar_alu = dev_info->a6xx.has_scalar_alu; + compiler->fs_must_have_non_zero_constlen_quirk = dev_info->a7xx.fs_must_have_non_zero_constlen_quirk; } else { compiler->max_const_pipeline = 512; compiler->max_const_geom = 512; diff --git a/src/freedreno/ir3/ir3_compiler.h b/src/freedreno/ir3/ir3_compiler.h index 77d36767deb..ac8885656d1 100644 --- a/src/freedreno/ir3/ir3_compiler.h +++ b/src/freedreno/ir3/ir3_compiler.h @@ -276,6 +276,8 @@ struct ir3_compiler { * register. */ bool has_scalar_alu; + + bool fs_must_have_non_zero_constlen_quirk; }; void ir3_compiler_destroy(struct ir3_compiler *compiler); diff --git a/src/freedreno/ir3/ir3_compiler_nir.c b/src/freedreno/ir3/ir3_compiler_nir.c index a23b4c37d61..8fed9d9116b 100644 --- a/src/freedreno/ir3/ir3_compiler_nir.c +++ b/src/freedreno/ir3/ir3_compiler_nir.c @@ -5479,6 +5479,11 @@ ir3_compile_shader_nir(struct ir3_compiler *compiler, ctx->so->per_samp = ctx->s->info.fs.uses_sample_shading; + if (ctx->so->type == MESA_SHADER_FRAGMENT && + compiler->fs_must_have_non_zero_constlen_quirk) { + so->constlen = MAX2(so->constlen, 4); + } + out: if (ret) { if (so->ir)