Switch commit waiting over to polling the DMA-BUF fd.

Remove the implicit sync Vulkan fence hack, it took us 0.2ms of GPU time
to prepare the 1x1 copy to wait on.
This commit is contained in:
Pierre-Loup A. Griffais 2020-08-30 13:26:46 -07:00
parent 165946fad9
commit 6dd7f60540
3 changed files with 32 additions and 48 deletions

View file

@ -346,6 +346,14 @@ bool CVulkanTexture::BInit( uint32_t width, uint32_t height, VkFormat format, cr
importMemoryInfo.pNext = allocInfo.pNext;
allocInfo.pNext = &importMemoryInfo;
// Take another copy to poll for implicit sync completion
m_FD = dup( pDMA->fd[0] );
if ( m_FD < 0 )
{
perror( "dup failed" );
return false;
}
}
if (vkAllocateMemory(device, &allocInfo, nullptr, &m_vkImageMemory) != VK_SUCCESS) {
@ -452,6 +460,12 @@ bool CVulkanTexture::BInit( uint32_t width, uint32_t height, VkFormat format, cr
CVulkanTexture::~CVulkanTexture( void )
{
if ( m_FD >= 0 )
{
close( m_FD );
m_FD = -1;
}
if ( m_pMappedData != nullptr )
{
vkUnmapMemory( device, g_output.pScreenshotImage->m_vkImageMemory );
@ -742,7 +756,7 @@ int init_device()
bufferCreateInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
bufferCreateInfo.pNext = nullptr;
bufferCreateInfo.size = 512 * 512 * 4;
bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
bufferCreateInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
result = vkCreateBuffer( device, &bufferCreateInfo, nullptr, &uploadBuffer );
@ -1263,7 +1277,6 @@ VulkanTexture_t vulkan_create_texture_from_dmabuf( struct wlr_dmabuf_attributes
CVulkanTexture::createFlags texCreateFlags;
texCreateFlags.bTextureable = true;
texCreateFlags.bTransferSrc = true;
if ( pTex->BInit( pDMA->width, pDMA->height, DRMFormatToVulkan( pDMA->format ), texCreateFlags, pDMA ) == false )
{
@ -1764,52 +1777,17 @@ uint32_t vulkan_texture_get_fbid( VulkanTexture_t vulkanTex )
return ret;
}
uint32_t vulkan_get_texture_fence( VulkanTexture_t vulkanTex )
int vulkan_get_texture_fence( VulkanTexture_t vulkanTex )
{
// Queue a trivial rendering operation referencing the texture, then wait for it
// This lets us simulate a "fence" for implicit-sync surfaces maybe
CVulkanTexture *pTex = g_mapVulkanTextures[ vulkanTex ];
if ( pTex == nullptr )
{
assert( 0 );
return -1;
}
VkCommandBuffer commandBuffer;
VkFence fence;
uint32_t handle = get_command_buffer( commandBuffer, &fence );
VkBufferImageCopy region = {};
region.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.layerCount = 1
};
region.imageExtent = {
.width = 1,
.height = 1,
.depth = 1
};
vkCmdCopyImageToBuffer( commandBuffer, pTex->m_vkImage, VK_IMAGE_LAYOUT_GENERAL, uploadBuffer, 1, &region );
std::vector<CVulkanTexture *> refs;
refs.push_back( pTex );
submit_command_buffer( handle, refs );
return handle;
}
void vulkan_wait_for_fence( uint32_t handle )
{
assert( g_scratchCommandBuffers[ handle ].busy == true &&
g_scratchCommandBuffers[ handle ].haswaiter == true );
vkWaitForFences( device, 1, &g_scratchCommandBuffers[ handle ].fence, VK_TRUE, ~0 );
g_scratchCommandBuffers[ handle ].haswaiter = false;
return pTex->m_FD;
}
@ -1883,8 +1861,6 @@ void vulkan_wait_for_fence( uint32_t handle )

View file

@ -87,6 +87,8 @@ public:
uint32_t m_unRowPitch = 0;
uint32_t m_FBID = 0;
int m_FD = -1;
int32_t nRefCount = 1;
@ -102,8 +104,7 @@ int vulkan_init(void);
VulkanTexture_t vulkan_create_texture_from_dmabuf( struct wlr_dmabuf_attributes *pDMA );
VulkanTexture_t vulkan_create_texture_from_bits( uint32_t width, uint32_t height, VkFormat format, void *bits );
uint32_t vulkan_get_texture_fence( VulkanTexture_t vulkanTex );
void vulkan_wait_for_fence( uint32_t );
int vulkan_get_texture_fence( VulkanTexture_t vulkanTex );
uint32_t vulkan_texture_get_fbid( VulkanTexture_t vulkanTex );

View file

@ -269,7 +269,7 @@ private:
sem waitListSem;
std::mutex waitListLock;
std::vector< std::pair< uint32_t, uint64_t > > waitList;
std::vector< std::pair< int, uint64_t > > waitList;
void imageWaitThreadRun( void )
{
@ -277,7 +277,7 @@ wait:
waitListSem.wait();
bool bFound = false;
uint32_t fence;
int fence;
uint64_t commitID;
retry:
@ -298,7 +298,8 @@ retry:
assert( bFound == true );
gpuvis_trace_printf( "wait fence begin_ctx=%lu\n", commitID );
vulkan_wait_for_fence( fence );
struct pollfd fd = { fence, POLLOUT, 0 };
poll( &fd, 1, -1 );
gpuvis_trace_printf( "wait fence end_ctx=%lu\n", commitID );
{
@ -2155,7 +2156,13 @@ void check_new_wayland_res( void )
w->commit_queue.push_back( newCommit );
}
uint32_t fence = vulkan_get_texture_fence( newCommit.vulkanTex );
int fence = vulkan_get_texture_fence( newCommit.vulkanTex );
if ( fence < 0 )
{
fprintf (stderr, "no fence for texture\n");
continue;
}
gpuvis_trace_printf( "pushing wait for commit %lu\n", newCommit.commitID );
{