Use inodes to compare DMA-BUFs

The file descriptions are only equal to each other if the producer
has dup'ed the same FD.
This commit is contained in:
Simon Ser 2021-07-05 19:32:26 +02:00
parent eb5972ccf6
commit 84dd1e6542

View file

@ -1,12 +1,11 @@
// Initialize Vulkan and composite stuff with a compute queue // Initialize Vulkan and composite stuff with a compute queue
#include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <sys/stat.h>
#include <array> #include <array>
#include <sys/syscall.h>
#include "rendervulkan.hpp" #include "rendervulkan.hpp"
#include "main.hpp" #include "main.hpp"
#include "steamcompmgr.hpp" #include "steamcompmgr.hpp"
@ -223,18 +222,27 @@ int32_t findMemoryType( VkMemoryPropertyFlags properties, uint32_t requiredTypeB
return -1; return -1;
} }
// Copied from <linux/kcmp.h> static bool allDMABUFsEqual( wlr_dmabuf_attributes *pDMA )
#define KCMP_FILE 0
static bool allFileDescriptorsEqual( wlr_dmabuf_attributes *pDMA )
{ {
pid_t pid = getpid(); if ( pDMA->n_planes == 1 )
return true;
struct stat first_stat;
if ( fstat( pDMA->fd[0], &first_stat ) != 0 )
{
perror( "fstat failed" );
return false;
}
for ( int i = 1; i < pDMA->n_planes; ++i ) for ( int i = 1; i < pDMA->n_planes; ++i )
{ {
// kcmp returns -1 for failures, 0 for equal, >0 for different struct stat plane_stat;
if ( pDMA->fd[0] != pDMA->fd[i] && if ( fstat( pDMA->fd[i], &plane_stat ) != 0 )
syscall( SYS_kcmp, pid, pid, KCMP_FILE, pDMA->fd[0], pDMA->fd[i] ) > 0 ) {
perror( "fstat failed" );
return false;
}
if ( plane_stat.st_ino != first_stat.st_ino )
return false; return false;
} }
@ -474,7 +482,7 @@ bool CVulkanTexture::BInit( uint32_t width, uint32_t height, VkFormat format, cr
{ {
// TODO: multi-planar DISTINCT DMA-BUFs support (see vkBindImageMemory2 // TODO: multi-planar DISTINCT DMA-BUFs support (see vkBindImageMemory2
// and VkBindImagePlaneMemoryInfo) // and VkBindImagePlaneMemoryInfo)
assert( pDMA->n_planes == 1 || allFileDescriptorsEqual( pDMA ) ); assert( allDMABUFsEqual( pDMA ) );
// Importing memory from a FD transfers ownership of the FD // Importing memory from a FD transfers ownership of the FD
int fd = dup( pDMA->fd[0] ); int fd = dup( pDMA->fd[0] );