diff --git a/src/amd/vulkan/radv_instance.c b/src/amd/vulkan/radv_instance.c
index 4279bc4af3d..f5f273aacc8 100644
--- a/src/amd/vulkan/radv_instance.c
+++ b/src/amd/vulkan/radv_instance.c
@@ -137,6 +137,7 @@ static const driOptionDescription radv_dri_options[] = {
DRI_CONF_OVERRIDE_VRAM_SIZE()
DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)
DRI_CONF_VK_WSI_FORCE_SWAPCHAIN_TO_CURRENT_EXTENT(false)
+ DRI_CONF_VK_X11_IGNORE_SUBOPTIMAL(false)
DRI_CONF_VK_REQUIRE_ETC2(false)
DRI_CONF_VK_REQUIRE_ASTC(false)
DRI_CONF_RADV_ZERO_VRAM(false)
diff --git a/src/freedreno/vulkan/tu_device.cc b/src/freedreno/vulkan/tu_device.cc
index 96af807661f..430cf3c1642 100644
--- a/src/freedreno/vulkan/tu_device.cc
+++ b/src/freedreno/vulkan/tu_device.cc
@@ -762,6 +762,7 @@ static const driOptionDescription tu_dri_options[] = {
DRI_CONF_SECTION_DEBUG
DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)
DRI_CONF_VK_WSI_FORCE_SWAPCHAIN_TO_CURRENT_EXTENT(false)
+ DRI_CONF_VK_X11_IGNORE_SUBOPTIMAL(false)
DRI_CONF_VK_DONT_CARE_AS_LOAD(false)
DRI_CONF_SECTION_END
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index 612caa5c553..5e1f22c052d 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -96,6 +96,7 @@ static const driOptionDescription anv_dri_options[] = {
DRI_CONF_ALWAYS_FLUSH_CACHE(false)
DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)
DRI_CONF_VK_WSI_FORCE_SWAPCHAIN_TO_CURRENT_EXTENT(false)
+ DRI_CONF_VK_X11_IGNORE_SUBOPTIMAL(false)
DRI_CONF_LIMIT_TRIG_INPUT_RANGE(false)
DRI_CONF_ANV_MESH_CONV_PRIM_ATTRS_TO_VERT_ATTRS(-2)
DRI_CONF_FORCE_VK_VENDOR(0)
diff --git a/src/intel/vulkan_hasvk/anv_device.c b/src/intel/vulkan_hasvk/anv_device.c
index 2819dd634b2..a7fb141b461 100644
--- a/src/intel/vulkan_hasvk/anv_device.c
+++ b/src/intel/vulkan_hasvk/anv_device.c
@@ -77,6 +77,7 @@ static const driOptionDescription anv_dri_options[] = {
DRI_CONF_ALWAYS_FLUSH_CACHE(false)
DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)
DRI_CONF_VK_WSI_FORCE_SWAPCHAIN_TO_CURRENT_EXTENT(false)
+ DRI_CONF_VK_X11_IGNORE_SUBOPTIMAL(false)
DRI_CONF_LIMIT_TRIG_INPUT_RANGE(false)
DRI_CONF_SECTION_END
diff --git a/src/nouveau/vulkan/nvk_instance.c b/src/nouveau/vulkan/nvk_instance.c
index 5340b1b6837..76e89a5ad58 100644
--- a/src/nouveau/vulkan/nvk_instance.c
+++ b/src/nouveau/vulkan/nvk_instance.c
@@ -71,6 +71,11 @@ static const driOptionDescription nvk_dri_options[] = {
DRI_CONF_VK_KHR_PRESENT_WAIT(false)
DRI_CONF_VK_XWAYLAND_WAIT_READY(true)
DRI_CONF_SECTION_END
+
+ DRI_CONF_SECTION_DEBUG
+ DRI_CONF_VK_WSI_FORCE_SWAPCHAIN_TO_CURRENT_EXTENT(false)
+ DRI_CONF_VK_X11_IGNORE_SUBOPTIMAL(false)
+ DRI_CONF_SECTION_END
};
static void
diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf
index 051b6ee4b52..7e7f33c07ef 100644
--- a/src/util/00-mesa-defaults.conf
+++ b/src/util/00-mesa-defaults.conf
@@ -597,24 +597,30 @@ TODO: document the other workarounds.
+
+
+
+
+
+
diff --git a/src/util/driconf.h b/src/util/driconf.h
index 32ccf87a5e1..04bf560f8bf 100644
--- a/src/util/driconf.h
+++ b/src/util/driconf.h
@@ -422,6 +422,10 @@
DRI_CONF_OPT_B(vk_x11_ensure_min_image_count, def, \
"Force the X11 WSI to create at least the number of image specified by the driver in VkSurfaceCapabilitiesKHR::minImageCount")
+#define DRI_CONF_VK_X11_IGNORE_SUBOPTIMAL(def) \
+ DRI_CONF_OPT_B(vk_x11_ignore_suboptimal, def, \
+ "Force the X11 WSI to never report VK_SUBOPTIMAL_KHR")
+
#define DRI_CONF_VK_KHR_PRESENT_WAIT(def) \
DRI_CONF_OPT_B(vk_khr_present_wait, def, \
"Expose VK_KHR_present_wait and id extensions despite them not being implemented for all supported surface types")
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index b6b803c52ef..8d136869040 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -160,6 +160,10 @@ struct wsi_device {
/* adds an extra minImageCount when running under xwayland */
bool extra_xwayland_image;
+
+ /* Never report VK_SUBOPTIMAL_KHR. Used to workaround
+ * games that cannot handle SUBOPTIMAL correctly. */
+ bool ignore_suboptimal;
} x11;
struct {
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 46733c932c8..0ac83108252 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -1241,9 +1241,12 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain,
if (config->pixmap_flags & PresentWindowDestroyed)
return VK_ERROR_SURFACE_LOST_KHR;
- if (config->width != chain->extent.width ||
- config->height != chain->extent.height)
- return VK_SUBOPTIMAL_KHR;
+ struct wsi_device *wsi_device = (struct wsi_device *)chain->base.wsi;
+ if (!wsi_device->x11.ignore_suboptimal) {
+ if (config->width != chain->extent.width ||
+ config->height != chain->extent.height)
+ return VK_SUBOPTIMAL_KHR;
+ }
break;
}
@@ -1280,6 +1283,11 @@ x11_handle_dri3_present_event(struct x11_swapchain *chain,
}
VkResult result = VK_SUCCESS;
+
+ struct wsi_device *wsi_device = (struct wsi_device *)chain->base.wsi;
+ if (wsi_device->x11.ignore_suboptimal)
+ return result;
+
switch (complete->mode) {
case XCB_PRESENT_COMPLETE_MODE_COPY:
if (chain->copy_is_suboptimal)
@@ -1824,9 +1832,12 @@ x11_acquire_next_image(struct wsi_swapchain *anv_chain,
xcb_get_geometry_reply_t *geom = xcb_get_geometry_reply(chain->conn, geom_cookie, &err);
VkResult result = VK_SUCCESS;
if (geom) {
- if (chain->extent.width != geom->width ||
- chain->extent.height != geom->height)
- result = VK_SUBOPTIMAL_KHR;
+ struct wsi_device *wsi_device = (struct wsi_device *)chain->base.wsi;
+ if (!wsi_device->x11.ignore_suboptimal) {
+ if (chain->extent.width != geom->width ||
+ chain->extent.height != geom->height)
+ result = VK_SUBOPTIMAL_KHR;
+ }
} else {
result = VK_ERROR_SURFACE_LOST_KHR;
}
@@ -2823,8 +2834,10 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
* happen by flip, only by copy. So this is a suboptimal copy, because if the client would change
* the chain extents X may be able to flip
*/
- if (chain->extent.width != cur_width || chain->extent.height != cur_height)
- chain->status = VK_SUBOPTIMAL_KHR;
+ if (!wsi_device->x11.ignore_suboptimal) {
+ if (chain->extent.width != cur_width || chain->extent.height != cur_height)
+ chain->status = VK_SUBOPTIMAL_KHR;
+ }
/* On a new swapchain this helper variable is set to false. Once we present it will have an
* impact once we ever do at least one flip and go back to copying afterwards. It is presumed
@@ -3020,6 +3033,11 @@ wsi_x11_init_wsi(struct wsi_device *wsi_device,
wsi_device->x11.xwaylandWaitReady =
driQueryOptionb(dri_options, "vk_xwayland_wait_ready");
}
+
+ if (driCheckOption(dri_options, "vk_x11_ignore_suboptimal", DRI_BOOL)) {
+ wsi_device->x11.ignore_suboptimal =
+ driQueryOptionb(dri_options, "vk_x11_ignore_suboptimal");
+ }
}
wsi->base.get_support = x11_surface_get_support;