diff --git a/src/intel/vulkan/anv_instance.c b/src/intel/vulkan/anv_instance.c
index f42165d8a98..406449d0f8b 100644
--- a/src/intel/vulkan/anv_instance.c
+++ b/src/intel/vulkan/anv_instance.c
@@ -15,6 +15,7 @@ static const driOptionDescription anv_dri_options[] = {
DRI_CONF_VK_KHR_PRESENT_WAIT(false)
DRI_CONF_VK_XWAYLAND_WAIT_READY(false)
DRI_CONF_ANV_ASSUME_FULL_SUBGROUPS(0)
+ DRI_CONF_ANV_ASSUME_FULL_SUBGROUPS_WITH_BARRIER(false)
DRI_CONF_ANV_DISABLE_FCV(false)
DRI_CONF_ANV_DISABLE_XE2_CCS(false)
DRI_CONF_ANV_EXTERNAL_MEMORY_IMPLICIT_SYNC(true)
@@ -136,6 +137,8 @@ anv_init_dri_options(struct anv_instance *instance)
instance->assume_full_subgroups =
driQueryOptioni(&instance->dri_options, "anv_assume_full_subgroups");
+ instance->assume_full_subgroups_with_barrier =
+ driQueryOptionb(&instance->dri_options, "anv_assume_full_subgroups_with_barrier");
instance->limit_trig_input_range =
driQueryOptionb(&instance->dri_options, "limit_trig_input_range");
instance->sample_mask_out_opengl_behaviour =
diff --git a/src/intel/vulkan/anv_pipeline.c b/src/intel/vulkan/anv_pipeline.c
index d744986cafe..1ceaac02fd5 100644
--- a/src/intel/vulkan/anv_pipeline.c
+++ b/src/intel/vulkan/anv_pipeline.c
@@ -740,6 +740,9 @@ anv_pipeline_hash_compute(struct anv_compute_pipeline *pipeline,
const uint8_t afs = device->physical->instance->assume_full_subgroups;
_mesa_sha1_update(&ctx, &afs, sizeof(afs));
+ const bool afswb = device->physical->instance->assume_full_subgroups_with_barrier;
+ _mesa_sha1_update(&ctx, &afswb, sizeof(afswb));
+
_mesa_sha1_update(&ctx, stage->shader_sha1,
sizeof(stage->shader_sha1));
_mesa_sha1_update(&ctx, &stage->key.cs, sizeof(stage->key.cs));
@@ -919,6 +922,15 @@ anv_fixup_subgroup_size(struct anv_device *device, struct shader_info *info)
local_size % BRW_SUBGROUP_SIZE == 0)
info->subgroup_size = SUBGROUP_SIZE_FULL_SUBGROUPS;
+ if (device->physical->instance->assume_full_subgroups_with_barrier &&
+ info->stage == MESA_SHADER_COMPUTE &&
+ device->info->verx10 <= 125 &&
+ info->uses_control_barrier &&
+ info->subgroup_size == SUBGROUP_SIZE_VARYING &&
+ local_size &&
+ local_size % BRW_SUBGROUP_SIZE == 0)
+ info->subgroup_size = SUBGROUP_SIZE_FULL_SUBGROUPS;
+
/* If the client requests that we dispatch full subgroups but doesn't
* allow us to pick a subgroup size, we have to smash it to the API
* value of 32. Performance will likely be terrible in this case but
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index f5c9ae53fa7..6363fe366ec 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1279,6 +1279,7 @@ struct anv_instance {
* Workarounds for game bugs.
*/
uint8_t assume_full_subgroups;
+ bool assume_full_subgroups_with_barrier;
bool limit_trig_input_range;
bool sample_mask_out_opengl_behaviour;
bool force_filter_addr_rounding;
diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf
index 105b2f99e4d..ab117ef735a 100644
--- a/src/util/00-mesa-defaults.conf
+++ b/src/util/00-mesa-defaults.conf
@@ -1156,6 +1156,9 @@ TODO: document the other workarounds.
+
+
+
diff --git a/src/util/driconf.h b/src/util/driconf.h
index 8d8ab4fa2a0..043e666c0b8 100644
--- a/src/util/driconf.h
+++ b/src/util/driconf.h
@@ -743,6 +743,10 @@
DRI_CONF_OPT_I(anv_assume_full_subgroups, def, 0, 32, \
"Allow assuming full subgroups requirement even when it's not specified explicitly and set the given size")
+#define DRI_CONF_ANV_ASSUME_FULL_SUBGROUPS_WITH_BARRIER(def) \
+ DRI_CONF_OPT_B(anv_assume_full_subgroups_with_barrier, def, \
+ "Assume full subgroups requirement for compute shaders that use control barriers")
+
#define DRI_CONF_ANV_SAMPLE_MASK_OUT_OPENGL_BEHAVIOUR(def) \
DRI_CONF_OPT_B(anv_sample_mask_out_opengl_behaviour, def, \
"Ignore sample mask out when having single sampled target")