Vulkan: fix a nasty race.
We could garbage-collect fences before/during their wait.
This commit is contained in:
parent
578849e429
commit
1bcd0bd930
1 changed files with 16 additions and 6 deletions
|
@ -83,6 +83,7 @@ struct scratchCmdBuffer_t
|
||||||
|
|
||||||
std::vector<CVulkanTexture *> refs;
|
std::vector<CVulkanTexture *> refs;
|
||||||
|
|
||||||
|
std::atomic<bool> haswaiter;
|
||||||
std::atomic<bool> busy;
|
std::atomic<bool> busy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1082,14 +1083,17 @@ int vulkan_init(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t get_command_buffer( VkCommandBuffer &cmdBuf, VkFence &fence )
|
static inline uint32_t get_command_buffer( VkCommandBuffer &cmdBuf, VkFence *pFence )
|
||||||
{
|
{
|
||||||
for ( uint32_t i = 0; i < k_nScratchCmdBufferCount; i++ )
|
for ( uint32_t i = 0; i < k_nScratchCmdBufferCount; i++ )
|
||||||
{
|
{
|
||||||
if ( g_scratchCommandBuffers[ i ].busy == false )
|
if ( g_scratchCommandBuffers[ i ].busy == false )
|
||||||
{
|
{
|
||||||
cmdBuf = g_scratchCommandBuffers[ i ].cmdBuf;
|
cmdBuf = g_scratchCommandBuffers[ i ].cmdBuf;
|
||||||
fence = g_scratchCommandBuffers[ i ].fence;
|
if ( pFence != nullptr )
|
||||||
|
{
|
||||||
|
*pFence = g_scratchCommandBuffers[ i ].fence;
|
||||||
|
}
|
||||||
|
|
||||||
VkCommandBufferBeginInfo commandBufferBeginInfo = {
|
VkCommandBufferBeginInfo commandBufferBeginInfo = {
|
||||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||||
|
@ -1105,6 +1109,8 @@ static inline uint32_t get_command_buffer( VkCommandBuffer &cmdBuf, VkFence &fen
|
||||||
|
|
||||||
g_scratchCommandBuffers[ i ].refs.clear();
|
g_scratchCommandBuffers[ i ].refs.clear();
|
||||||
|
|
||||||
|
g_scratchCommandBuffers[ i ].haswaiter = pFence != nullptr;
|
||||||
|
|
||||||
g_scratchCommandBuffers[ i ].busy = true;
|
g_scratchCommandBuffers[ i ].busy = true;
|
||||||
|
|
||||||
return i;
|
return i;
|
||||||
|
@ -1153,7 +1159,8 @@ void vulkan_garbage_collect( void )
|
||||||
// Probably just differentiate "busy" and "submitted"
|
// Probably just differentiate "busy" and "submitted"
|
||||||
for ( uint32_t i = 0; i < k_nScratchCmdBufferCount; i++ )
|
for ( uint32_t i = 0; i < k_nScratchCmdBufferCount; i++ )
|
||||||
{
|
{
|
||||||
if ( g_scratchCommandBuffers[ i ].busy == true )
|
if ( g_scratchCommandBuffers[ i ].busy == true &&
|
||||||
|
g_scratchCommandBuffers[ i ].haswaiter == false )
|
||||||
{
|
{
|
||||||
VkResult res = vkGetFenceStatus( device, g_scratchCommandBuffers[ i ].fence );
|
VkResult res = vkGetFenceStatus( device, g_scratchCommandBuffers[ i ].fence );
|
||||||
|
|
||||||
|
@ -1215,8 +1222,7 @@ VulkanTexture_t vulkan_create_texture_from_bits( uint32_t width, uint32_t height
|
||||||
memcpy( pUploadBuffer, bits, width * height * 4 );
|
memcpy( pUploadBuffer, bits, width * height * 4 );
|
||||||
|
|
||||||
VkCommandBuffer commandBuffer;
|
VkCommandBuffer commandBuffer;
|
||||||
VkFence fence;
|
uint32_t handle = get_command_buffer( commandBuffer, nullptr );
|
||||||
uint32_t handle = get_command_buffer( commandBuffer, fence );
|
|
||||||
|
|
||||||
VkBufferImageCopy region = {};
|
VkBufferImageCopy region = {};
|
||||||
|
|
||||||
|
@ -1612,7 +1618,7 @@ uint32_t vulkan_get_texture_fence( VulkanTexture_t vulkanTex )
|
||||||
|
|
||||||
VkCommandBuffer commandBuffer;
|
VkCommandBuffer commandBuffer;
|
||||||
VkFence fence;
|
VkFence fence;
|
||||||
uint32_t handle = get_command_buffer( commandBuffer, fence );
|
uint32_t handle = get_command_buffer( commandBuffer, &fence );
|
||||||
|
|
||||||
VkBufferImageCopy region = {};
|
VkBufferImageCopy region = {};
|
||||||
|
|
||||||
|
@ -1639,7 +1645,11 @@ uint32_t vulkan_get_texture_fence( VulkanTexture_t vulkanTex )
|
||||||
|
|
||||||
void vulkan_wait_for_fence( uint32_t 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 );
|
vkWaitForFences( device, 1, &g_scratchCommandBuffers[ handle ].fence, VK_TRUE, ~0 );
|
||||||
|
|
||||||
|
g_scratchCommandBuffers[ handle ].haswaiter = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue