@ -1139,12 +1139,19 @@ static int alloc_bind_mem(AVHWFramesContext *hwfc, AVVkFrame *f,
return 0 ;
}
static int prepare_frame ( AVHWFramesContext * hwfc , AVVkFrame * frame )
enum PrepMode {
PREP_MODE_WRITE ,
PREP_MODE_RO_SHADER ,
} ;
static int prepare_frame ( AVHWFramesContext * hwfc , VulkanExecCtx * ectx ,
AVVkFrame * frame , enum PrepMode pmode )
{
VkResult ret ;
VkImageLayout new_layout ;
VkAccessFlags new_access ;
AVHWDeviceContext * ctx = hwfc - > device_ctx ;
AVVulkanDeviceContext * hwctx = ctx - > hwctx ;
VulkanFramesPriv * s = hwfc - > internal - > priv ;
const int planes = av_pix_fmt_count_planes ( hwfc - > sw_format ) ;
VkImageMemoryBarrier img_bar [ AV_NUM_DATA_POINTERS ] = { 0 } ;
@ -1157,13 +1164,24 @@ static int prepare_frame(AVHWFramesContext *hwfc, AVVkFrame *frame)
VkSubmitInfo s_info = {
. sType = VK_STRUCTURE_TYPE_SUBMIT_INFO ,
. commandBufferCount = 1 ,
. pCommandBuffers = & s - > cmd . buf ,
. pCommandBuffers = & ectx - > buf ,
. pSignalSemaphores = frame - > sem ,
. signalSemaphoreCount = planes ,
} ;
ret = vkBeginCommandBuffer ( s - > cmd . buf , & cmd_start ) ;
switch ( pmode ) {
case PREP_MODE_WRITE :
new_layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ;
new_access = VK_ACCESS_TRANSFER_WRITE_BIT ;
break ;
case PREP_MODE_RO_SHADER :
new_layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL ;
new_access = VK_ACCESS_TRANSFER_READ_BIT ;
break ;
}
ret = vkBeginCommandBuffer ( ectx - > buf , & cmd_start ) ;
if ( ret ! = VK_SUCCESS )
return AVERROR_EXTERNAL ;
@ -1173,9 +1191,9 @@ static int prepare_frame(AVHWFramesContext *hwfc, AVVkFrame *frame)
for ( int i = 0 ; i < planes ; i + + ) {
img_bar [ i ] . sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER ;
img_bar [ i ] . srcAccessMask = 0x0 ;
img_bar [ i ] . dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT ;
img_bar [ i ] . dstAccessMask = new_access ;
img_bar [ i ] . oldLayout = frame - > layout [ i ] ;
img_bar [ i ] . newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ;
img_bar [ i ] . newLayout = new_layout ;
img_bar [ i ] . srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ;
img_bar [ i ] . dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED ;
img_bar [ i ] . image = frame - > img [ i ] ;
@ -1187,20 +1205,20 @@ static int prepare_frame(AVHWFramesContext *hwfc, AVVkFrame *frame)
frame - > access [ i ] = img_bar [ i ] . dstAccessMask ;
}
vkCmdPipelineBarrier ( s - > cmd . buf , VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ,
vkCmdPipelineBarrier ( ectx - > buf , VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT ,
VK_PIPELINE_STAGE_TRANSFER_BIT , 0 ,
0 , NULL , 0 , NULL , planes , img_bar ) ;
ret = vkEndCommandBuffer ( s - > cmd . buf ) ;
ret = vkEndCommandBuffer ( ectx - > buf ) ;
if ( ret ! = VK_SUCCESS )
return AVERROR_EXTERNAL ;
ret = vkQueueSubmit ( s - > cmd . queue , 1 , & s_info , s - > cmd . fence ) ;
ret = vkQueueSubmit ( ectx - > queue , 1 , & s_info , ectx - > fence ) ;
if ( ret ! = VK_SUCCESS ) {
return AVERROR_EXTERNAL ;
} else {
vkWaitForFences ( hwctx - > act_dev , 1 , & s - > cmd . fence , VK_TRUE , UINT64_MAX ) ;
vkResetFences ( hwctx - > act_dev , 1 , & s - > cmd . fence ) ;
vkWaitForFences ( hwctx - > act_dev , 1 , & ectx - > fence , VK_TRUE , UINT64_MAX ) ;
vkResetFences ( hwctx - > act_dev , 1 , & ectx - > fence ) ;
}
return 0 ;
@ -1371,7 +1389,7 @@ static AVBufferRef *vulkan_pool_alloc(void *opaque, int size)
if ( err )
goto fail ;
err = prepare_frame ( hwfc , f ) ;
err = prepare_frame ( hwfc , & p - > cmd , f , PREP_MODE_WRITE ) ;
if ( err )
goto fail ;
@ -1775,7 +1793,7 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
/* We'd import a semaphore onto the one we created using
* vkImportSemaphoreFdKHR but unfortunately neither DRM nor VAAPI
* offer us anything we could import and sync with , so instead
* leave the semaphore unsignalled and enjoy the validation spam . */
* just signal the semaphore we created . */
f - > layout [ i ] = image_create_info . initialLayout ;
f - > access [ i ] = 0x0 ;
@ -1796,6 +1814,13 @@ static int vulkan_map_from_drm_frame_desc(AVHWFramesContext *hwfc, AVVkFrame **f
return AVERROR_EXTERNAL ;
}
/* NOTE: This is completely uneccesary and unneeded once we can import
* semaphores from DRM . Otherwise we have to activate the semaphores .
* We ' re reusing the exec context that ' s also used for uploads / downloads . */
err = prepare_frame ( hwfc , & p - > cmd , f , PREP_MODE_RO_SHADER ) ;
if ( err )
goto fail ;
* frame = f ;
return 0 ;