Add support for multi-planar DMA-BUF Vulkan export

This commit is contained in:
Simon Ser 2021-04-01 19:06:08 +02:00
parent a900bef8b8
commit 4f24653d77

View file

@ -118,6 +118,7 @@ std::vector< VulkanSamplerCacheEntry_t > g_vecVulkanSamplerCache;
VulkanTexture_t g_emptyTex; VulkanTexture_t g_emptyTex;
static std::map< VkFormat, std::map< uint64_t, VkDrmFormatModifierPropertiesEXT > > DRMModifierProps = {};
static struct wlr_drm_format_set sampledDRMFormats = {}; static struct wlr_drm_format_set sampledDRMFormats = {};
#define MAX_DEVICE_COUNT 8 #define MAX_DEVICE_COUNT 8
@ -515,12 +516,22 @@ bool CVulkanTexture::BInit( uint32_t width, uint32_t height, VkFormat format, cr
assert( pDMA == nullptr ); assert( pDMA == nullptr );
struct wlr_dmabuf_attributes dmabuf = {}; struct wlr_dmabuf_attributes dmabuf = {};
dmabuf.n_planes = 1; // TODO: query from VkDrmFormatModifierPropertiesEXT::drmFormatModifierPlaneCount
dmabuf.width = width; dmabuf.width = width;
dmabuf.height = height; dmabuf.height = height;
dmabuf.format = VulkanFormatToDRM( format ); dmabuf.format = VulkanFormatToDRM( format );
assert( dmabuf.format != DRM_FORMAT_INVALID ); assert( dmabuf.format != DRM_FORMAT_INVALID );
// TODO: disjoint planes support
const VkMemoryGetFdInfoKHR memory_get_fd_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
.pNext = NULL,
.memory = m_vkImageMemory,
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
};
res = dyn_vkGetMemoryFdKHR(device, &memory_get_fd_info, &dmabuf.fd[0]);
if ( res != VK_SUCCESS )
return false;
if ( tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT ) if ( tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT )
{ {
assert( dyn_vkGetImageDrmFormatModifierPropertiesEXT != nullptr ); assert( dyn_vkGetImageDrmFormatModifierPropertiesEXT != nullptr );
@ -531,9 +542,23 @@ bool CVulkanTexture::BInit( uint32_t width, uint32_t height, VkFormat format, cr
return false; return false;
dmabuf.modifier = imgModifierProps.drmFormatModifier; dmabuf.modifier = imgModifierProps.drmFormatModifier;
// TODO: support multi-planar DMA-BUFs assert( DRMModifierProps.count( format ) > 0);
assert( DRMModifierProps[ format ].count( dmabuf.modifier ) > 0);
dmabuf.n_planes = DRMModifierProps[ format ][ dmabuf.modifier ].drmFormatModifierPlaneCount;
const VkImageAspectFlagBits planeAspects[] = {
VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT,
VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT,
VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT,
VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT,
};
assert( dmabuf.n_planes <= 4 );
for ( int i = 0; i < dmabuf.n_planes; i++ )
{
VkImageSubresource subresource = { VkImageSubresource subresource = {
.aspectMask = VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT, .aspectMask = planeAspects[i],
.mipLevel = 0, .mipLevel = 0,
.arrayLayer = 0, .arrayLayer = 0,
}; };
@ -542,25 +567,24 @@ bool CVulkanTexture::BInit( uint32_t width, uint32_t height, VkFormat format, cr
dmabuf.offset[0] = subresourceLayout.offset; dmabuf.offset[0] = subresourceLayout.offset;
dmabuf.stride[0] = subresourceLayout.rowPitch; dmabuf.stride[0] = subresourceLayout.rowPitch;
} }
// Copy the first FD to all other planes
for ( int i = 1; i < dmabuf.n_planes; i++ )
{
dmabuf.fd[i] = dup( dmabuf.fd[0] );
if ( dmabuf.fd[i] < 0 )
return false;
}
}
else else
{ {
dmabuf.n_planes = 1;
dmabuf.modifier = DRM_FORMAT_MOD_INVALID; dmabuf.modifier = DRM_FORMAT_MOD_INVALID;
dmabuf.offset[0] = 0;
dmabuf.stride[0] = m_unRowPitch; dmabuf.stride[0] = m_unRowPitch;
} }
const VkMemoryGetFdInfoKHR memory_get_fd_info = {
.sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
.pNext = NULL,
.memory = m_vkImageMemory,
.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
};
res = dyn_vkGetMemoryFdKHR(device, &memory_get_fd_info, &dmabuf.fd[0]);
if ( res != VK_SUCCESS )
return false;
m_FBID = drm_fbid_from_dmabuf( &g_DRM, nullptr, &dmabuf ); m_FBID = drm_fbid_from_dmabuf( &g_DRM, nullptr, &dmabuf );
if ( m_FBID == 0 ) if ( m_FBID == 0 )
return false; return false;
@ -710,8 +734,12 @@ void init_formats()
modifierPropList.pDrmFormatModifierProperties = modifierProps.data(); modifierPropList.pDrmFormatModifierProperties = modifierProps.data();
vkGetPhysicalDeviceFormatProperties2( physicalDevice, format, &formatProps ); vkGetPhysicalDeviceFormatProperties2( physicalDevice, format, &formatProps );
std::map< uint64_t, VkDrmFormatModifierPropertiesEXT > map = {};
for ( size_t j = 0; j < modifierProps.size(); j++ ) for ( size_t j = 0; j < modifierProps.size(); j++ )
{ {
map[ modifierProps[j].drmFormatModifier ] = modifierProps[j];
if ( ( modifierProps[j].drmFormatModifierTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT ) == 0 ) if ( ( modifierProps[j].drmFormatModifierTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT ) == 0 )
{ {
continue; continue;
@ -722,6 +750,8 @@ void init_formats()
} }
wlr_drm_format_set_add( &sampledDRMFormats, drmFormat, modifierProps[j].drmFormatModifier ); wlr_drm_format_set_add( &sampledDRMFormats, drmFormat, modifierProps[j].drmFormatModifier );
} }
DRMModifierProps[ format ] = map;
} }
} }