diff --git a/src/rendervulkan.cpp b/src/rendervulkan.cpp index dbcc02c..00f7f41 100644 --- a/src/rendervulkan.cpp +++ b/src/rendervulkan.cpp @@ -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, ®ion ); - - std::vector 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 ) - - diff --git a/src/rendervulkan.hpp b/src/rendervulkan.hpp index 8960cae..717282b 100644 --- a/src/rendervulkan.hpp +++ b/src/rendervulkan.hpp @@ -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 ); diff --git a/src/steamcompmgr.cpp b/src/steamcompmgr.cpp index d836235..ceb226b 100644 --- a/src/steamcompmgr.cpp +++ b/src/steamcompmgr.cpp @@ -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 ); {