Mesa (staging/20.1): radv,vulkan: add a new x11 wsi drirc workaround for DOOM Eternal

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Jul 3 23:55:14 UTC 2020


Module: Mesa
Branch: staging/20.1
Commit: be2619862c1cfa725ed216794e5c0e5b7e7ae89e
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=be2619862c1cfa725ed216794e5c0e5b7e7ae89e

Author: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Date:   Wed Jul  1 08:06:09 2020 +0200

radv,vulkan: add a new x11 wsi drirc workaround for DOOM Eternal

DOOM Eternal happily creates a swapchain with 2 images for IMMEDIATE.
This fixes a 10% performance issue with RADV.

Cc: 20.1 <mesa-stable at lists.freedesktop.org>
Signed-off-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Reviewed-by: Bas Nieuwenhuizen <bas at basnieuwenhuizen.nl>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5704>
(cherry picked from commit ab9ecb607b88dd4610815ac254205656918e408e)

---

 .pick_status.json               |  2 +-
 src/amd/vulkan/radv_device.c    |  1 +
 src/util/00-mesa-defaults.conf  |  6 +++++
 src/util/xmlpool/t_options.h    |  5 ++++
 src/vulkan/wsi/wsi_common.h     |  5 ++++
 src/vulkan/wsi/wsi_common_x11.c | 57 +++++++++++++++++++++++++----------------
 6 files changed, 53 insertions(+), 23 deletions(-)

diff --git a/.pick_status.json b/.pick_status.json
index b810d845a24..337ff50237c 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -4,7 +4,7 @@
         "description": "radv,vulkan: add a new x11 wsi drirc workaround for DOOM Eternal",
         "nominated": true,
         "nomination_type": 0,
-        "resolution": 0,
+        "resolution": 1,
         "master_sha": null,
         "because_sha": null
     },
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index e43b1ccf36b..6dd6540848d 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -576,6 +576,7 @@ DRI_CONF_BEGIN
 		DRI_CONF_ADAPTIVE_SYNC("true")
 		DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)
 		DRI_CONF_VK_X11_STRICT_IMAGE_COUNT("false")
+		DRI_CONF_VK_X11_ENSURE_MIN_IMAGE_COUNT("false")
 		DRI_CONF_RADV_NO_DYNAMIC_BOUNDS("false")
 	DRI_CONF_SECTION_END
 
diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf
index 4a9e64be220..e02d4dc9d35 100644
--- a/src/util/00-mesa-defaults.conf
+++ b/src/util/00-mesa-defaults.conf
@@ -579,6 +579,12 @@ TODO: document the other workarounds.
         <application name="DOOM" executable="DOOMx64vk.exe">
             <option name="vk_x11_strict_image_count" value="true" />
         </application>
+
+        <!-- DOOM Doom Eternal happily creates a swapchain with 2 images for
+             IMMEDIATE. This fixes a 10% performance issue with RADV. -->
+        <application name="DOOMEternal" executable="DOOMEternalx64vk.exe">
+            <option name="vk_x11_ensure_min_image_count" value="true" />
+        </application>
     </device>
     <!-- vmwgfx doesn't like full buffer swaps and can't sync to vertical retraces.-->
     <device driver="vmwgfx">
diff --git a/src/util/xmlpool/t_options.h b/src/util/xmlpool/t_options.h
index 3a5eab044af..b86aefa77ef 100644
--- a/src/util/xmlpool/t_options.h
+++ b/src/util/xmlpool/t_options.h
@@ -245,6 +245,11 @@ DRI_CONF_OPT_BEGIN_B(vk_x11_strict_image_count, def) \
         DRI_CONF_DESC(en,gettext("Force the X11 WSI to create exactly the number of image specified by the application in VkSwapchainCreateInfoKHR::minImageCount")) \
 DRI_CONF_OPT_END
 
+#define DRI_CONF_VK_X11_ENSURE_MIN_IMAGE_COUNT(def) \
+DRI_CONF_OPT_BEGIN_B(vk_x11_ensure_min_image_count, def) \
+        DRI_CONF_DESC(en,gettext("Force the X11 WSI to create at least the number of image specified by the driver in VkSurfaceCapabilitiesKHR::minImageCount")) \
+DRI_CONF_OPT_END
+
 #define DRI_CONF_MESA_GLTHREAD(def) \
 DRI_CONF_OPT_BEGIN_B(mesa_glthread, def) \
         DRI_CONF_DESC(en,gettext("Enable offloading GL driver work to a separate thread")) \
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index 99ccdf84cde..cbf7e1be14e 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -109,6 +109,11 @@ struct wsi_device {
        * provided VkSwapchainCreateInfoKH::RminImageCount.
        */
       bool strict_imageCount;
+
+      /* Ensures to create at least the number of image specified by the
+       * driver in VkSurfaceCapabilitiesKHR::minImageCount.
+       */
+      bool ensure_minImageCount;
    } x11;
 
    /* Signals the semaphore such that any wait on the semaphore will wait on
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 95106af5b6e..00f9192777b 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -450,6 +450,33 @@ x11_surface_get_support(VkIcdSurfaceBase *icd_surface,
    return VK_SUCCESS;
 }
 
+static uint32_t
+x11_get_min_image_count(struct wsi_device *wsi_device)
+{
+   if (wsi_device->x11.override_minImageCount)
+      return wsi_device->x11.override_minImageCount;
+
+   /* For IMMEDIATE and FIFO, most games work in a pipelined manner where the
+    * can produce frames at a rate of 1/MAX(CPU duration, GPU duration), but
+    * the render latency is CPU duration + GPU duration.
+    *
+    * This means that with scanout from pageflipping we need 3 frames to run
+    * full speed:
+    * 1) CPU rendering work
+    * 2) GPU rendering work
+    * 3) scanout
+    *
+    * Once we have a nonblocking acquire that returns a semaphore we can merge
+    * 1 and 3. Hence the ideal implementation needs only 2 images, but games
+    * cannot tellwe currently do not have an ideal implementation and that
+    * hence they need to allocate 3 images. So let us do it for them.
+    *
+    * This is a tradeoff as it uses more memory than needed for non-fullscreen
+    * and non-performance intensive applications.
+    */
+   return 3;
+}
+
 static VkResult
 x11_surface_get_capabilities(VkIcdSurfaceBase *icd_surface,
                              struct wsi_device *wsi_device,
@@ -502,31 +529,10 @@ x11_surface_get_capabilities(VkIcdSurfaceBase *icd_surface,
                                       VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
    }
 
-   /* For IMMEDIATE and FIFO, most games work in a pipelined manner where the
-    * can produce frames at a rate of 1/MAX(CPU duration, GPU duration), but
-    * the render latency is CPU duration + GPU duration.
-    *
-    * This means that with scanout from pageflipping we need 3 frames to run
-    * full speed:
-    * 1) CPU rendering work
-    * 2) GPU rendering work
-    * 3) scanout
-    *
-    * Once we have a nonblocking acquire that returns a semaphore we can merge
-    * 1 and 3. Hence the ideal implementation needs only 2 images, but games
-    * cannot tellwe currently do not have an ideal implementation and that
-    * hence they need to allocate 3 images. So let us do it for them.
-    *
-    * This is a tradeoff as it uses more memory than needed for non-fullscreen
-    * and non-performance intensive applications.
-    */
-   caps->minImageCount = 3;
+   caps->minImageCount = x11_get_min_image_count(wsi_device);
    /* There is no real maximum */
    caps->maxImageCount = 0;
 
-   if (wsi_device->x11.override_minImageCount)
-      caps->minImageCount = wsi_device->x11.override_minImageCount;
-
    caps->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
    caps->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
    caps->maxImageArrayLayers = 1;
@@ -1439,6 +1445,8 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
       num_images = pCreateInfo->minImageCount;
    else if (present_mode == VK_PRESENT_MODE_MAILBOX_KHR)
       num_images = MAX2(num_images, 5);
+   else if (wsi_device->x11.ensure_minImageCount)
+      num_images = MAX2(num_images, x11_get_min_image_count(wsi_device));
 
    xcb_connection_t *conn = x11_surface_get_connection(icd_surface);
    struct wsi_x11_connection *wsi_conn =
@@ -1658,6 +1666,11 @@ wsi_x11_init_wsi(struct wsi_device *wsi_device,
          wsi_device->x11.strict_imageCount =
             driQueryOptionb(dri_options, "vk_x11_strict_image_count");
       }
+      if (driCheckOption(dri_options, "vk_x11_ensure_min_image_count", DRI_BOOL)) {
+         wsi_device->x11.ensure_minImageCount =
+            driQueryOptionb(dri_options, "vk_x11_ensure_min_image_count");
+      }
+
    }
 
    wsi->base.get_support = x11_surface_get_support;



More information about the mesa-commit mailing list