From c75846e674e87ef545a9303e572388b29313ac3d Mon Sep 17 00:00:00 2001 From: Iago Toral Quiroga Date: Thu, 16 Jan 2020 07:46:11 +0100 Subject: [PATCH] v3dv: implement DRM modifier setup for WSI 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: --- src/broadcom/vulkan/v3dv_extensions.py | 1 + src/broadcom/vulkan/v3dv_formats.c | 25 +++++++++- src/broadcom/vulkan/v3dv_image.c | 67 +++++++++++++++++++++++--- 3 files changed, 86 insertions(+), 7 deletions(-) diff --git a/src/broadcom/vulkan/v3dv_extensions.py b/src/broadcom/vulkan/v3dv_extensions.py index 3a519512938..e1fded37b48 100644 --- a/src/broadcom/vulkan/v3dv_extensions.py +++ b/src/broadcom/vulkan/v3dv_extensions.py @@ -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 diff --git a/src/broadcom/vulkan/v3dv_formats.c b/src/broadcom/vulkan/v3dv_formats.c index 740318e98c2..93fcc5d7dcf 100644 --- a/src/broadcom/vulkan/v3dv_formats.c +++ b/src/broadcom/vulkan/v3dv_formats.c @@ -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; diff --git a/src/broadcom/vulkan/v3dv_image.c b/src/broadcom/vulkan/v3dv_image.c index aed7657fcc8..80516c62a59 100644 --- a/src/broadcom/vulkan/v3dv_image.c +++ b/src/broadcom/vulkan/v3dv_image.c @@ -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,