diff --git a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
index 4509751a1c6..4fd080494f1 100644
--- a/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
+++ b/src/gallium/auxiliary/pipe-loader/driinfo_gallium.h
@@ -38,6 +38,7 @@ DRI_CONF_SECTION_DEBUG
DRI_CONF_GLX_EXTENSION_OVERRIDE()
DRI_CONF_INDIRECT_GL_EXTENSION_OVERRIDE()
DRI_CONF_DISABLE_PROTECTED_CONTENT_CHECK(false)
+ DRI_CONF_IGNORE_MAP_UNSYNCHRONIZED(false)
DRI_CONF_SECTION_END
DRI_CONF_SECTION_MISCELLANEOUS
diff --git a/src/gallium/frontends/dri/dri_screen.c b/src/gallium/frontends/dri/dri_screen.c
index c117f593d1a..d3938117a41 100644
--- a/src/gallium/frontends/dri/dri_screen.c
+++ b/src/gallium/frontends/dri/dri_screen.c
@@ -99,6 +99,8 @@ dri_fill_st_options(struct dri_screen *screen)
driQueryOptionb(optionCache, "allow_draw_out_of_order");
options->allow_incorrect_primitive_id =
driQueryOptionb(optionCache, "allow_incorrect_primitive_id");
+ options->ignore_map_unsynchronized =
+ driQueryOptionb(optionCache, "ignore_map_unsynchronized");
options->force_gl_names_reuse =
driQueryOptionb(optionCache, "force_gl_names_reuse");
diff --git a/src/gallium/include/frontend/api.h b/src/gallium/include/frontend/api.h
index 70afed3499a..3d05123455f 100644
--- a/src/gallium/include/frontend/api.h
+++ b/src/gallium/include/frontend/api.h
@@ -242,6 +242,7 @@ struct st_config_options
bool allow_glsl_cross_stage_interpolation_mismatch;
bool allow_draw_out_of_order;
bool allow_incorrect_primitive_id;
+ bool ignore_map_unsynchronized;
bool force_integer_tex_nearest;
bool force_gl_names_reuse;
char *force_gl_vendor;
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index 7756a5cfa82..2fd5aeef152 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -539,10 +539,20 @@ st_bufferobj_map_range(struct gl_context *ctx,
assert(offset < obj->Size);
assert(offset + length <= obj->Size);
- const enum pipe_map_flags transfer_flags =
+ enum pipe_map_flags transfer_flags =
st_access_flags_to_transfer_flags(access,
offset == 0 && length == obj->Size);
+ /* Sometimes games do silly things like MapBufferRange(UNSYNC|DISCARD_RANGE)
+ * In this case, the the UNSYNC is a bit redundant, but the games rely
+ * on the driver rebinding/replacing the backing storage rather than
+ * going down the UNSYNC path (ie. honoring DISCARD_x first before UNSYNC).
+ */
+ if (unlikely(st_context(ctx)->options.ignore_map_unsynchronized)) {
+ if (transfer_flags & (PIPE_MAP_DISCARD_RANGE | PIPE_MAP_DISCARD_WHOLE_RESOURCE))
+ transfer_flags &= ~PIPE_MAP_UNSYNCHRONIZED;
+ }
+
obj->Mappings[index].Pointer = pipe_buffer_map_range(pipe,
st_obj->buffer,
offset, length,
diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf
index a559c59ed97..ec8b225dec8 100644
--- a/src/util/00-mesa-defaults.conf
+++ b/src/util/00-mesa-defaults.conf
@@ -22,7 +22,7 @@ Application bugs worked around in this file:
built-ins (specifically gl_VertexID), which causes the vertex shaders to fail
to compile.
-* Applications that are not suitable for adapative sync are blacklisted here.
+* Applications that are not suitable for adapative sync are denylisted here.
TODO: document the other workarounds.
@@ -296,6 +296,13 @@ TODO: document the other workarounds.
+
+
+
+
+
diff --git a/src/util/driconf.h b/src/util/driconf.h
index f210ed39355..422fec52df2 100644
--- a/src/util/driconf.h
+++ b/src/util/driconf.h
@@ -233,6 +233,10 @@
DRI_CONF_OPT_B(disable_protected_content_check, def, \
"Don't reject image import if protected_content attribute doesn't match")
+#define DRI_CONF_IGNORE_MAP_UNSYNCHRONIZED(def) \
+ DRI_CONF_OPT_B(ignore_map_unsynchronized, def, \
+ "Ignore GL_MAP_UNSYNCHRONIZED_BIT, workaround for games that use it incorrectly")
+
/**
* \brief Image quality-related options
*/