v3dv: implement DRM modifier setup for WSI
authorIago Toral Quiroga <itoral@igalia.com>
Thu, 16 Jan 2020 06:46:11 +0000 (07:46 +0100)
committerMarge Bot <eric+marge@anholt.net>
Tue, 13 Oct 2020 21:21:26 +0000 (21:21 +0000)
This is only really relevant when running on real hardware, since
when we run on the simulator we don't care about the format of the
swapchain images.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>

src/broadcom/vulkan/v3dv_extensions.py
src/broadcom/vulkan/v3dv_formats.c
src/broadcom/vulkan/v3dv_image.c

index 3a51951..e1fded3 100644 (file)
@@ -65,6 +65,7 @@ EXTENSIONS = [
     Extension('VK_KHR_get_physical_device_properties2',   1, True),
     Extension('VK_EXT_debug_report',                      9, True),
     Extension('VK_EXT_external_memory_dma_buf',           1, True),
+    Extension('VK_EXT_image_drm_format_modifier',         1, False),
 ]
 
 # Sort the extension list the way we expect: KHR, then EXT, then vendors
index 740318e..93fcc5d 100644 (file)
@@ -26,7 +26,9 @@
 #include "vk_format_info.h"
 
 #include "broadcom/cle/v3dx_pack.h"
+#include "drm-uapi/drm_fourcc.h"
 #include "util/format/u_format.h"
+#include "vulkan/wsi/wsi_common.h"
 
 #define SWIZ(x,y,z,w) {   \
    PIPE_SWIZZLE_##x,      \
@@ -291,7 +293,28 @@ v3dv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice,
                                           &pFormatProperties->formatProperties);
 
    vk_foreach_struct(ext, pFormatProperties->pNext) {
-      switch (ext->sType) {
+      switch ((unsigned)ext->sType) {
+      case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT: {
+         struct VkDrmFormatModifierPropertiesListEXT *list = (void *)ext;
+         VK_OUTARRAY_MAKE(out, list->pDrmFormatModifierProperties,
+                          &list->drmFormatModifierCount);
+         /* Only expose LINEAR for winsys formats.
+          * FIXME: is this correct?
+          */
+         if (format == VK_FORMAT_B8G8R8A8_SRGB ||
+             format == VK_FORMAT_B8G8R8A8_UNORM) {
+            vk_outarray_append(&out, mod_props) {
+               mod_props->drmFormatModifier = DRM_FORMAT_MOD_LINEAR;
+               mod_props->drmFormatModifierPlaneCount = 1;
+            }
+         } else {
+            vk_outarray_append(&out, mod_props) {
+               mod_props->drmFormatModifier = DRM_FORMAT_MOD_BROADCOM_UIF;
+               mod_props->drmFormatModifierPlaneCount = 1;
+            }
+         }
+         break;
+      }
       default:
          v3dv_debug_ignored_stype(ext->sType);
          break;
index aed7657..80516c6 100644 (file)
@@ -27,6 +27,8 @@
 #include "util/format/u_format.h"
 #include "util/u_math.h"
 #include "vk_format_info.h"
+#include "vk_util.h"
+#include "vulkan/wsi/wsi_common.h"
 
 /* These are tunable parameters in the HW design, but all the V3D
  * implementations agree.
@@ -273,6 +275,47 @@ v3dv_CreateImage(VkDevice _device,
    v3dv_assert(pCreateInfo->extent.height > 0);
    v3dv_assert(pCreateInfo->extent.depth > 0);
 
+   /* When using the simulator the WSI common code will see that our
+    * driver wsi device doesn't match the display device and because of that
+    * it will not attempt to present directly from the swapchain images,
+    * instead it will use the prime blit path (use_prime_blit flag in
+    * struct wsi_swapchain), where it copies the contents of the swapchain
+    * images to a linear buffer with appropriate row stride for presentation.
+    * As a result, on that path, swapchain images do not have any special
+    * requirements and are not created with the pNext structs below.
+    */
+   uint64_t modifier = DRM_FORMAT_MOD_INVALID;
+   if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
+      const VkImageDrmFormatModifierListCreateInfoEXT *mod_info =
+         vk_find_struct_const(pCreateInfo->pNext,
+                              IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
+      assert(mod_info);
+      for (uint32_t i = 0; i < mod_info->drmFormatModifierCount; i++) {
+         switch (mod_info->pDrmFormatModifiers[i]) {
+         case DRM_FORMAT_MOD_LINEAR:
+            if (modifier == DRM_FORMAT_MOD_INVALID)
+               modifier = DRM_FORMAT_MOD_LINEAR;
+            break;
+         case DRM_FORMAT_MOD_BROADCOM_UIF:
+            modifier = DRM_FORMAT_MOD_BROADCOM_UIF;
+            break;
+         }
+      }
+   } else {
+      const struct wsi_image_create_info *wsi_info =
+         vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
+      if (wsi_info)
+         modifier = DRM_FORMAT_MOD_LINEAR;
+      else
+         modifier = DRM_FORMAT_MOD_BROADCOM_UIF;
+   }
+
+   /* 1D and 1D_ARRAY textures are always raster-order */
+   if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D)
+      modifier = DRM_FORMAT_MOD_LINEAR;
+
+   assert(modifier != DRM_FORMAT_MOD_INVALID);
+
    const struct v3dv_format *format = v3dv_get_format(pCreateInfo->format);
    v3dv_assert(format != NULL && format->supported);
 
@@ -293,12 +336,8 @@ v3dv_CreateImage(VkDevice _device,
    image->create_flags = pCreateInfo->flags;
    image->tiling = pCreateInfo->tiling;
 
-   image->drm_format_mod = DRM_FORMAT_MOD_INVALID;
-   image->tiled = true;
-
-   /* 1D and 1D_ARRAY textures are always raster-order */
-   if (image->type == VK_IMAGE_TYPE_1D)
-      image->tiled = false;
+   image->drm_format_mod = modifier;
+   image->tiled = image->drm_format_mod != DRM_FORMAT_MOD_LINEAR;
 
    image->cpp = vk_format_get_blocksize(image->vk_format);
 
@@ -326,6 +365,22 @@ v3dv_GetImageSubresourceLayout(VkDevice device,
    layout->size = slice->size;
 }
 
+VkResult
+v3dv_GetImageDrmFormatModifierPropertiesEXT(
+   VkDevice device,
+   VkImage _image,
+   VkImageDrmFormatModifierPropertiesEXT *pProperties)
+{
+   V3DV_FROM_HANDLE(v3dv_image, image, _image);
+
+   assert(pProperties->sType =
+          VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT);
+
+   pProperties->drmFormatModifier = image->drm_format_mod;
+
+   return VK_SUCCESS;
+}
+
 void
 v3dv_DestroyImage(VkDevice _device,
                   VkImage _image,