Skip to content

Commit

Permalink
renderervulkan: only consider modifiers support all the image properties
Browse files Browse the repository at this point in the history
If you have a modifier with image compression that is only support for
some image formats like :
   - B8G8R8A8_UNORM : compression supported
   - B8G8R8A8_SRB   : compression not supported

Then the render will not use compression but the modifier indicates it
is present, so the compositor will try to make use of the side
compressed data and this will lead to corruptions.

This fixes issues on Intel HW of Gfx9/Gfx11 generations.
  • Loading branch information
llandwerlin-intel committed Dec 14, 2023
1 parent 3e14ef9 commit cbbe4c8
Showing 1 changed file with 65 additions and 0 deletions.
65 changes: 65 additions & 0 deletions src/rendervulkan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2449,6 +2449,49 @@ int CVulkanTexture::memoryFence()
return fence;
}

static bool is_image_format_modifier_supported(VkFormat format, uint32_t drmFormat, uint64_t modifier)
{
VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
.format = format,
.type = VK_IMAGE_TYPE_2D,
.tiling = VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,
.usage = VK_IMAGE_USAGE_SAMPLED_BIT,
};

std::array<VkFormat, 2> formats = {
DRMFormatToVulkan(drmFormat, false),
DRMFormatToVulkan(drmFormat, true),
};

VkImageFormatListCreateInfo formatList = {
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
.viewFormatCount = (uint32_t)formats.size(),
.pViewFormats = formats.data(),
};

if ( formats[0] != formats[1] )
{
formatList.pNext = std::exchange(imageFormatInfo.pNext,
&formatList);
imageFormatInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
}

VkPhysicalDeviceImageDrmFormatModifierInfoEXT modifierInfo = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT,
.pNext = nullptr,
.drmFormatModifier = modifier,
};

modifierInfo.pNext = std::exchange(imageFormatInfo.pNext, &modifierInfo);

VkImageFormatProperties2 imageFormatProps = {
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
};

VkResult res = g_device.vk.GetPhysicalDeviceImageFormatProperties2( g_device.physDev(), &imageFormatInfo, &imageFormatProps );
return res == VK_SUCCESS;
}

bool vulkan_init_format(VkFormat format, uint32_t drmFormat)
{
Expand All @@ -2461,6 +2504,25 @@ bool vulkan_init_format(VkFormat format, uint32_t drmFormat)
.usage = VK_IMAGE_USAGE_SAMPLED_BIT,
};

std::array<VkFormat, 2> formats = {
DRMFormatToVulkan(drmFormat, false),
DRMFormatToVulkan(drmFormat, true),
};

VkImageFormatListCreateInfo formatList = {
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO,
.viewFormatCount = (uint32_t)formats.size(),
.pViewFormats = formats.data(),
};

if ( formats[0] != formats[1] )
{
formatList.pNext = std::exchange(imageFormatInfo.pNext,
&formatList);
imageFormatInfo.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
}


VkImageFormatProperties2 imageFormatProps = {
.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
};
Expand Down Expand Up @@ -2518,6 +2580,9 @@ bool vulkan_init_format(VkFormat format, uint32_t drmFormat)

uint64_t modifier = modifierProps[j].drmFormatModifier;

if ( !is_image_format_modifier_supported( format, drmFormat, modifier ) )
continue;

if ( ( modifierProps[j].drmFormatModifierTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT ) == 0 )
{
continue;
Expand Down

0 comments on commit cbbe4c8

Please sign in to comment.