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: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6766>
This commit is contained in:
Iago Toral Quiroga 2020-01-16 07:46:11 +01:00 committed by Marge Bot
parent 4825a76a22
commit c75846e674
3 changed files with 86 additions and 7 deletions

View 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

View 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;

View 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,