vulkan/wsi: Add a driconf option to force WSI to advertise BGRA8_UNORM first
authorJason Ekstrand <jason@jlekstrand.net>
Fri, 10 Jan 2020 19:16:25 +0000 (13:16 -0600)
committerMarge Bot <eric+marge@anholt.net>
Tue, 14 Jan 2020 19:27:13 +0000 (19:27 +0000)
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@intel.com>
Reviewed-by: Samuel Pitoiset <samuel.pitoiset@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
src/intel/vulkan/anv_device.c
src/util/00-mesa-defaults.conf
src/util/xmlpool/t_options.h
src/vulkan/wsi/wsi_common.c
src/vulkan/wsi/wsi_common.h
src/vulkan/wsi/wsi_common_display.c
src/vulkan/wsi/wsi_common_wayland.c
src/vulkan/wsi/wsi_common_x11.c

index a1dffe90b8a0dc2d0a30627155f82a7aefaef336..b4e840c76efd5f7008a9282026e57c937859d2c9 100644 (file)
@@ -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)
index cd7298ab3c57db07092700daab7ebaed4386e9f1..239048fba0162579c2ffb8b05ae461c561b651fb 100644 (file)
@@ -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;
 
index e5f333942b71a320edddbc906800c6de94e55614..8702a317d798756aad116b04d79eab66fecd8dc8 100644 (file)
@@ -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: -->
index fe186c1fa796a87a0ca9e823a33511bd7cb1d097..1d8ea07ebdd22419e03570224614ac7b3d3a42ba 100644 (file)
@@ -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)")) \
index e45810d9c5d3aea1221b82715830c6789cf852a5..1fb2bf7df3eca9b8e06c1a14193f558c097ea2fb 100644 (file)
@@ -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;
index 704c1abd809fda906f90f384851c2273145f9085..3e3f79b1a4a92cee4fe595c60963a401ccce52b4 100644 (file)
@@ -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. */
index 66e191906fcbd2a24a89275bd07edbad8eaaeb0c..04c77162df423ffea5f585e59e0e21e4bdb6ee34 100644 (file)
@@ -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;
       }
    }
index 438c2f50da39e57fe5d88fa554954252b824bf0f..dcea92a858a02b5bdeaced883f6acaaab032a72b 100644 (file)
@@ -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)) {
index 491bd8a3702e4e892745f7a0accd29968237afb7..95106af5b6edb68c1a4111e46f122f3ed3faf64c 100644 (file)
@@ -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;
       }
    }