Mesa (master): vulkan/wsi: Add a driconf option to force WSI to advertise BGRA8_UNORM first

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Jan 14 19:40:14 UTC 2020


Module: Mesa
Branch: master
Commit: 7c16a1ae4e629ccbae3979ec9be105e6b44e0acf
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=7c16a1ae4e629ccbae3979ec9be105e6b44e0acf

Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Fri Jan 10 13:16:25 2020 -0600

vulkan/wsi: Add a driconf option to force WSI to advertise BGRA8_UNORM first

The Aztec Ruins benchmark just grabs the first format in the list and
SRGB causes it to render washed out.  With this workaround, it renders
the same as OpenGL.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin at intel.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset at gmail.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3350>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3350>

---

 src/amd/vulkan/radv_device.c        |  4 ++++
 src/intel/vulkan/anv_device.c       |  1 +
 src/util/00-mesa-defaults.conf      |  1 +
 src/util/xmlpool/t_options.h        |  5 +++++
 src/vulkan/wsi/wsi_common.c         |  5 +++++
 src/vulkan/wsi/wsi_common.h         |  1 +
 src/vulkan/wsi/wsi_common_display.c | 31 +++++++++++++++++++++++++++----
 src/vulkan/wsi/wsi_common_wayland.c | 15 +++++++++++++++
 src/vulkan/wsi/wsi_common_x11.c     | 30 ++++++++++++++++++++++++++----
 9 files changed, 85 insertions(+), 8 deletions(-)

diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index a1dffe90b8a..b4e840c76ef 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -661,6 +661,10 @@ DRI_CONF_BEGIN
 		DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)
 		DRI_CONF_VK_X11_STRICT_IMAGE_COUNT("false")
 	DRI_CONF_SECTION_END
+
+	DRI_CONF_SECTION_DEBUG
+		DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST("false")
+	DRI_CONF_SECTION_END
 DRI_CONF_END;
 
 static void  radv_init_dri_options(struct radv_instance *instance)
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index cd7298ab3c5..239048fba01 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -57,6 +57,7 @@ DRI_CONF_BEGIN
 
    DRI_CONF_SECTION_DEBUG
       DRI_CONF_ALWAYS_FLUSH_CACHE("false")
+      DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST("false")
    DRI_CONF_SECTION_END
 DRI_CONF_END;
 
diff --git a/src/util/00-mesa-defaults.conf b/src/util/00-mesa-defaults.conf
index e5f333942b7..8702a317d79 100644
--- a/src/util/00-mesa-defaults.conf
+++ b/src/util/00-mesa-defaults.conf
@@ -503,6 +503,7 @@ TODO: document the other workarounds.
 
         <application name="gfxbench" executable="testfw_app">
             <option name="vk_x11_override_min_image_count" value="2" />
+            <option name="vk_wsi_force_bgra8_unorm_first" value="true" />
         </application>
 
         <!-- Gallium Nine workarounds: -->
diff --git a/src/util/xmlpool/t_options.h b/src/util/xmlpool/t_options.h
index fe186c1fa79..1d8ea07ebdd 100644
--- a/src/util/xmlpool/t_options.h
+++ b/src/util/xmlpool/t_options.h
@@ -225,6 +225,11 @@ DRI_CONF_OPT_BEGIN_B(adaptive_sync,def) \
         DRI_CONF_DESC(en,gettext("Adapt the monitor sync to the application performance (when possible)")) \
 DRI_CONF_OPT_END
 
+#define DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(def) \
+DRI_CONF_OPT_BEGIN_B(vk_wsi_force_bgra8_unorm_first, def) \
+        DRI_CONF_DESC(en,gettext("Force vkGetPhysicalDeviceSurfaceFormatsKHR to return VK_FORMAT_B8G8R8A8_UNORM as the first format")) \
+DRI_CONF_OPT_END
+
 #define DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(def) \
 DRI_CONF_OPT_BEGIN_V(vk_x11_override_min_image_count, int, def, "0:999") \
         DRI_CONF_DESC(en,gettext("Override the VkSurfaceCapabilitiesKHR::minImageCount (0 = no override)")) \
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
index e45810d9c5d..1fb2bf7df3e 100644
--- a/src/vulkan/wsi/wsi_common.c
+++ b/src/vulkan/wsi/wsi_common.c
@@ -135,6 +135,11 @@ wsi_device_init(struct wsi_device *wsi,
       if (driCheckOption(dri_options, "adaptive_sync", DRI_BOOL))
          wsi->enable_adaptive_sync = driQueryOptionb(dri_options,
                                                      "adaptive_sync");
+
+      if (driCheckOption(dri_options, "vk_wsi_force_bgra8_unorm_first",  DRI_BOOL)) {
+         wsi->force_bgra8_unorm_first =
+            driQueryOptionb(dri_options, "vk_wsi_force_bgra8_unorm_first");
+      }
    }
 
    return VK_SUCCESS;
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
index 704c1abd809..3e3f79b1a4a 100644
--- a/src/vulkan/wsi/wsi_common.h
+++ b/src/vulkan/wsi/wsi_common.h
@@ -112,6 +112,7 @@ struct wsi_device {
    bool supports_modifiers;
    uint32_t maxImageDimension2D;
    VkPresentModeKHR override_present_mode;
+   bool force_bgra8_unorm_first;
 
    /* Whether to enable adaptive sync for a swapchain if implemented and
     * available. Not all window systems might support this. */
diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
index 66e191906fc..04c77162df4 100644
--- a/src/vulkan/wsi/wsi_common_display.c
+++ b/src/vulkan/wsi/wsi_common_display.c
@@ -896,6 +896,23 @@ static const struct {
    { .format = VK_FORMAT_B8G8R8A8_UNORM, .drm_format = DRM_FORMAT_XRGB8888 },
 };
 
+static void
+get_sorted_vk_formats(struct wsi_device *wsi_device, VkFormat *sorted_formats)
+{
+   for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++)
+      sorted_formats[i] = available_surface_formats[i].format;
+
+   if (wsi_device->force_bgra8_unorm_first) {
+      for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
+         if (sorted_formats[i] == VK_FORMAT_B8G8R8A8_UNORM) {
+            sorted_formats[i] = sorted_formats[0];
+            sorted_formats[0] = VK_FORMAT_B8G8R8A8_UNORM;
+            break;
+         }
+      }
+   }
+}
+
 static VkResult
 wsi_display_surface_get_formats(VkIcdSurfaceBase *icd_surface,
                                 struct wsi_device *wsi_device,
@@ -904,9 +921,12 @@ wsi_display_surface_get_formats(VkIcdSurfaceBase *icd_surface,
 {
    VK_OUTARRAY_MAKE(out, surface_formats, surface_format_count);
 
-   for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
+   VkFormat sorted_formats[ARRAY_SIZE(available_surface_formats)];
+   get_sorted_vk_formats(wsi_device, sorted_formats);
+
+   for (unsigned i = 0; i < ARRAY_SIZE(sorted_formats); i++) {
       vk_outarray_append(&out, f) {
-         f->format = available_surface_formats[i].format;
+         f->format = sorted_formats[i];
          f->colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
       }
    }
@@ -923,10 +943,13 @@ wsi_display_surface_get_formats2(VkIcdSurfaceBase *surface,
 {
    VK_OUTARRAY_MAKE(out, surface_formats, surface_format_count);
 
-   for (unsigned i = 0; i < ARRAY_SIZE(available_surface_formats); i++) {
+   VkFormat sorted_formats[ARRAY_SIZE(available_surface_formats)];
+   get_sorted_vk_formats(wsi_device, sorted_formats);
+
+   for (unsigned i = 0; i < ARRAY_SIZE(sorted_formats); i++) {
       vk_outarray_append(&out, f) {
          assert(f->sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR);
-         f->surfaceFormat.format = available_surface_formats[i].format;
+         f->surfaceFormat.format = sorted_formats[i];
          f->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
       }
    }
diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
index 438c2f50da3..dcea92a858a 100644
--- a/src/vulkan/wsi/wsi_common_wayland.c
+++ b/src/vulkan/wsi/wsi_common_wayland.c
@@ -421,6 +421,21 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
    if (display->drm.wl_drm || display->dmabuf.wl_dmabuf)
       wl_display_roundtrip_queue(display->wl_display, display->queue);
 
+   if (wsi_wl->wsi->force_bgra8_unorm_first) {
+      /* Find BGRA8_UNORM in the list and swap it to the first position if we
+       * can find it.  Some apps get confused if SRGB is first in the list.
+       */
+      VkFormat *first_fmt = u_vector_head(display->formats);
+      VkFormat *iter_fmt;
+      u_vector_foreach(iter_fmt, display->formats) {
+         if (*iter_fmt == VK_FORMAT_B8G8R8A8_UNORM) {
+            *iter_fmt = *first_fmt;
+            *first_fmt = VK_FORMAT_B8G8R8A8_UNORM;
+            break;
+         }
+      }
+   }
+
    /* We need prime support for wl_drm */
    if (display->drm.wl_drm &&
        (display->drm.capabilities & WL_DRM_CAPABILITY_PRIME)) {
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
index 491bd8a3702..95106af5b6e 100644
--- a/src/vulkan/wsi/wsi_common_x11.c
+++ b/src/vulkan/wsi/wsi_common_x11.c
@@ -569,6 +569,22 @@ x11_surface_get_capabilities2(VkIcdSurfaceBase *icd_surface,
    return result;
 }
 
+static void
+get_sorted_vk_formats(struct wsi_device *wsi_device, VkFormat *sorted_formats)
+{
+   memcpy(sorted_formats, formats, sizeof(formats));
+
+   if (wsi_device->force_bgra8_unorm_first) {
+      for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
+         if (sorted_formats[i] == VK_FORMAT_B8G8R8A8_UNORM) {
+            sorted_formats[i] = sorted_formats[0];
+            sorted_formats[0] = VK_FORMAT_B8G8R8A8_UNORM;
+            break;
+         }
+      }
+   }
+}
+
 static VkResult
 x11_surface_get_formats(VkIcdSurfaceBase *surface,
                         struct wsi_device *wsi_device,
@@ -577,9 +593,12 @@ x11_surface_get_formats(VkIcdSurfaceBase *surface,
 {
    VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount);
 
-   for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
+   VkFormat sorted_formats[ARRAY_SIZE(formats)];
+   get_sorted_vk_formats(wsi_device, sorted_formats);
+
+   for (unsigned i = 0; i < ARRAY_SIZE(sorted_formats); i++) {
       vk_outarray_append(&out, f) {
-         f->format = formats[i];
+         f->format = sorted_formats[i];
          f->colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
       }
    }
@@ -596,10 +615,13 @@ x11_surface_get_formats2(VkIcdSurfaceBase *surface,
 {
    VK_OUTARRAY_MAKE(out, pSurfaceFormats, pSurfaceFormatCount);
 
-   for (unsigned i = 0; i < ARRAY_SIZE(formats); i++) {
+   VkFormat sorted_formats[ARRAY_SIZE(formats)];
+   get_sorted_vk_formats(wsi_device, sorted_formats);
+
+   for (unsigned i = 0; i < ARRAY_SIZE(sorted_formats); i++) {
       vk_outarray_append(&out, f) {
          assert(f->sType == VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR);
-         f->surfaceFormat.format = formats[i];
+         f->surfaceFormat.format = sorted_formats[i];
          f->surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
       }
    }



More information about the mesa-commit mailing list