| @@ -80,6 +80,7 @@ typedef struct VulkanDeviceFeatures { · 79 unmodified lines |
| 80 | VkPhysicalDeviceVulkan13Features vulkan_1_3; | 80 | VkPhysicalDeviceVulkan13Features vulkan_1_3; |
| 81 | VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore; | 81 | VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore; |
| 82 | VkPhysicalDeviceShaderSubgroupRotateFeaturesKHR subgroup_rotate; | 82 | VkPhysicalDeviceShaderSubgroupRotateFeaturesKHR subgroup_rotate; |
| | 83 | VkPhysicalDeviceHostImageCopyFeaturesEXT host_image_copy; |
| 83 | | 84 | |
| 84 | #ifdef VK_KHR_shader_expect_assume | 85 | #ifdef VK_KHR_shader_expect_assume |
| 85 | VkPhysicalDeviceShaderExpectAssumeFeaturesKHR expect_assume; | 86 | VkPhysicalDeviceShaderExpectAssumeFeaturesKHR expect_assume; |
| @@ -209,6 +210,8 @@ static void device_features_init(AVHWDeviceContext *ctx, VulkanDeviceFeatures *f · 123 unmodified lines |
| 209 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES); | 210 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES); |
| 210 | FF_VK_STRUCT_EXT(s, &feats->device, &feats->subgroup_rotate, FF_VK_EXT_SUBGROUP_ROTATE, | 211 | FF_VK_STRUCT_EXT(s, &feats->device, &feats->subgroup_rotate, FF_VK_EXT_SUBGROUP_ROTATE, |
| 211 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES_KHR); | 212 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES_KHR); |
| | 213 | FF_VK_STRUCT_EXT(s, &feats->device, &feats->host_image_copy, FF_VK_EXT_HOST_IMAGE_COPY, |
| | 214 | VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT); |
| 212 | | 215 | |
| 213 | #ifdef VK_KHR_shader_expect_assume | 216 | #ifdef VK_KHR_shader_expect_assume |
| 214 | FF_VK_STRUCT_EXT(s, &feats->device, &feats->expect_assume, FF_VK_EXT_EXPECT_ASSUME, | 217 | FF_VK_STRUCT_EXT(s, &feats->device, &feats->expect_assume, FF_VK_EXT_EXPECT_ASSUME, |
| @@ -285,6 +288,7 @@ static void device_features_copy_needed(VulkanDeviceFeatures *dst, VulkanDeviceF · 70 unmodified lines |
| 285 | | 288 | |
| 286 | COPY_VAL(timeline_semaphore.timelineSemaphore); | 289 | COPY_VAL(timeline_semaphore.timelineSemaphore); |
| 287 | COPY_VAL(subgroup_rotate.shaderSubgroupRotate); | 290 | COPY_VAL(subgroup_rotate.shaderSubgroupRotate); |
| | 291 | COPY_VAL(host_image_copy.hostImageCopy); |
| 288 | | 292 | |
| 289 | COPY_VAL(video_maintenance_1.videoMaintenance1); | 293 | COPY_VAL(video_maintenance_1.videoMaintenance1); |
| 290 | #ifdef VK_KHR_video_maintenance2 | 294 | #ifdef VK_KHR_video_maintenance2 |
| @@ -606,6 +610,7 @@ static const VulkanOptExtension optional_device_exts[] = { · 315 unmodified lines |
| 606 | { VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME, FF_VK_EXT_COOP_MATRIX }, | 610 | { VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME, FF_VK_EXT_COOP_MATRIX }, |
| 607 | { VK_EXT_SHADER_OBJECT_EXTENSION_NAME, FF_VK_EXT_SHADER_OBJECT }, | 611 | { VK_EXT_SHADER_OBJECT_EXTENSION_NAME, FF_VK_EXT_SHADER_OBJECT }, |
| 608 | { VK_KHR_SHADER_SUBGROUP_ROTATE_EXTENSION_NAME, FF_VK_EXT_SUBGROUP_ROTATE }, | 612 | { VK_KHR_SHADER_SUBGROUP_ROTATE_EXTENSION_NAME, FF_VK_EXT_SUBGROUP_ROTATE }, |
| | 613 | { VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME, FF_VK_EXT_HOST_IMAGE_COPY }, |
| 609 | #ifdef VK_KHR_shader_expect_assume | 614 | #ifdef VK_KHR_shader_expect_assume |
| 610 | { VK_KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME, FF_VK_EXT_EXPECT_ASSUME }, | 615 | { VK_KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME, FF_VK_EXT_EXPECT_ASSUME }, |
| 611 | #endif | 616 | #endif |
| @@ -2825,11 +2830,15 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) · 2213 unmodified lines |
| 2825 | | 2830 | |
| 2826 | /* Image usage flags */ | 2831 | /* Image usage flags */ |
| 2827 | if (!hwctx->usage) { | 2832 | if (!hwctx->usage) { |
| 2828 | hwctx->usage = supported_usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT | | 2833 | hwctx->usage = supported_usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | |
| 2829 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | | | |
| 2830 | VK_IMAGE_USAGE_STORAGE_BIT | | 2834 | VK_IMAGE_USAGE_STORAGE_BIT | |
| 2831 | VK_IMAGE_USAGE_SAMPLED_BIT); | 2835 | VK_IMAGE_USAGE_SAMPLED_BIT); |
| 2832 | | 2836 | |
| | 2837 | if (p->vkctx.extensions & FF_VK_EXT_HOST_IMAGE_COPY) |
| | 2838 | hwctx->usage |= supported_usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT; |
| | 2839 | else |
| | 2840 | hwctx->usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; |
| | 2841 | |
| 2833 | /* Enables encoding of images, if supported by format and extensions */ | 2842 | /* Enables encoding of images, if supported by format and extensions */ |
| 2834 | if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) && | 2843 | if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) && |
| 2835 | (p->vkctx.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE | | 2844 | (p->vkctx.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE | |
| @@ -4148,6 +4157,113 @@ fail: · 1312 unmodified lines |
| 4148 | return err; | 4157 | return err; |
| 4149 | } | 4158 | } |
| 4150 | | 4159 | |
| | 4160 | static int vulkan_transfer_host(AVHWFramesContext *hwfc, AVFrame *hwf, |
| | 4161 | AVFrame *swf, int upload) |
| | 4162 | { |
| | 4163 | VulkanDevicePriv *p = hwfc->device_ctx->hwctx; |
| | 4164 | AVVulkanFramesContext *hwfc_vk = hwfc->hwctx; |
| | 4165 | AVVulkanDeviceContext *hwctx = &p->p; |
| | 4166 | FFVulkanFunctions *vk = &p->vkctx.vkfn; |
| | 4167 | |
| | 4168 | AVVkFrame *hwf_vk = (AVVkFrame *)hwf->data[0]; |
| | 4169 | const int planes = av_pix_fmt_count_planes(swf->format); |
| | 4170 | const int nb_images = ff_vk_count_images(hwf_vk); |
| | 4171 | |
| | 4172 | VkSemaphoreWaitInfo sem_wait; |
| | 4173 | VkHostImageLayoutTransitionInfo layout_ch_info[]; |
| | 4174 | int nb_layout_ch = 0; |
| | 4175 | |
| | 4176 | hwfc_vk->lock_frame(hwfc, hwf_vk); |
| | 4177 | |
| | 4178 | for (int i = 0; i < nb_images; i++) { |
| | 4179 | if (hwf_vk->layout[i]) |
| | 4180 | continue; |
| | 4181 | |
| | 4182 | layout_ch_info[nb_layout_ch++] = (VkHostImageLayoutTransitionInfo) { |
| | 4183 | .sType = VK_STRUCTURE_TYPE_HOST_IMAGE_LAYOUT_TRANSITION_INFO, |
| | 4184 | .image = hwf_vk->img[i], |
| | 4185 | .oldLayout = hwf_vk->layout[i], |
| | 4186 | .newLayout = VK_IMAGE_LAYOUT_GENERAL, |
| | 4187 | .subresourceRange = { |
| | 4188 | .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, |
| | 4189 | .levelCount = 1, |
| | 4190 | .layerCount = 1, |
| | 4191 | }; |
| | 4192 | }; |
| | 4193 | } |
| | 4194 | |
| | 4195 | if (nb_layout_ch) |
| | 4196 | vk->TransitionImageLayoutEXT(hwctx->act_dev, |
| | 4197 | nb_layout_ch, layout_ch_info); |
| | 4198 | |
| | 4199 | sem_wait = (VkSemaphoreWaitInfo) { |
| | 4200 | .sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO, |
| | 4201 | .pSemaphores = hwf_vk->sem, |
| | 4202 | .pValues = hwf_vk->sem_value, |
| | 4203 | .semaphoreCount = nb_images, |
| | 4204 | }; |
| | 4205 | |
| | 4206 | vk->WaitSemaphores(hwctx->act_dev, &sem_wait, UINT64_MAX); |
| | 4207 | |
| | 4208 | if (upload) { |
| | 4209 | VkMemoryToImageCopy region_info = { |
| | 4210 | .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY, |
| | 4211 | .imageSubresource = { |
| | 4212 | .layerCount = 1, |
| | 4213 | }, |
| | 4214 | }; |
| | 4215 | VkCopyMemoryToImageInfo copy_info = { |
| | 4216 | .sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO, |
| | 4217 | .flags = VK_HOST_IMAGE_COPY_MEMCPY, |
| | 4218 | .regionCount = 1, |
| | 4219 | .pRegions = ®ion_info, |
| | 4220 | }; |
| | 4221 | for (int i = 0; i < planes; i++) { |
| | 4222 | int img_idx = FFMIN(i, (nb_images - 1)); |
| | 4223 | uint32_t p_w, p_h; |
| | 4224 | get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); |
| | 4225 | |
| | 4226 | region_info.pHostPointer = swf->data[i]; |
| | 4227 | region_info.imageSubresource.aspectMask = ff_vk_aspect_flag(hwf, i); |
| | 4228 | region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 }; |
| | 4229 | copy_info.dstImage = hwf_vk->img[img_idx]; |
| | 4230 | copy_info.dstImageLayout = hwf_vk->layout[img_idx]; |
| | 4231 | |
| | 4232 | vk->CopyMemoryToImageEXT(hwctx->act_dev, ©_info); |
| | 4233 | } |
| | 4234 | } else { |
| | 4235 | VkImageToMemoryCopy region_info = { |
| | 4236 | .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY, |
| | 4237 | .imageSubresource = { |
| | 4238 | .layerCount = 1, |
| | 4239 | }, |
| | 4240 | }; |
| | 4241 | VkCopyImageToMemoryInfo copy_info = { |
| | 4242 | .sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO, |
| | 4243 | .flags = VK_HOST_IMAGE_COPY_MEMCPY, |
| | 4244 | .regionCount = 1, |
| | 4245 | .pRegions = ®ion_info, |
| | 4246 | }; |
| | 4247 | for (int i = 0; i < planes; i++) { |
| | 4248 | int img_idx = FFMIN(i, (nb_images - 1)); |
| | 4249 | uint32_t p_w, p_h; |
| | 4250 | get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); |
| | 4251 | |
| | 4252 | region_info.pHostPointer = swf->data[i]; |
| | 4253 | region_info.imageSubresource.aspectMask = ff_vk_aspect_flag(hwf, i); |
| | 4254 | region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 }; |
| | 4255 | copy_info.srcImage = hwf_vk->img[img_idx]; |
| | 4256 | copy_info.srcImageLayout = hwf_vk->layout[img_idx]; |
| | 4257 | |
| | 4258 | vk->CopyImageToMemoryEXT(hwctx->act_dev, ©_info); |
| | 4259 | } |
| | 4260 | } |
| | 4261 | |
| | 4262 | hwfc_vk->unlock_frame(hwfc, hwf_vk); |
| | 4263 | |
| | 4264 | return 0; |
| | 4265 | } |
| | 4266 | |
| 4151 | static int vulkan_transfer_frame(AVHWFramesContext *hwfc, | 4267 | static int vulkan_transfer_frame(AVHWFramesContext *hwfc, |
| 4152 | AVFrame *swf, AVFrame *hwf, | 4268 | AVFrame *swf, AVFrame *hwf, |
| 4153 | int upload) | 4269 | int upload) |
| @@ -4184,6 +4300,9 @@ static int vulkan_transfer_frame(AVHWFramesContext *hwfc, · 30 unmodified lines |
| 4184 | if (swf->width > hwfc->width || swf->height > hwfc->height) | 4300 | if (swf->width > hwfc->width || swf->height > hwfc->height) |
| 4185 | return AVERROR(EINVAL); | 4301 | return AVERROR(EINVAL); |
| 4186 | | 4302 | |
| | 4303 | if (p->vkctx.extensions & FF_VK_EXT_HOST_IMAGE_COPY) |
| | 4304 | return vulkan_transfer_host(hwfc, hwf, swf, upload); |
| | 4305 | |
| 4187 | for (int i = 0; i < av_pix_fmt_count_planes(swf->format); i++) { | 4306 | for (int i = 0; i < av_pix_fmt_count_planes(swf->format); i++) { |
| 4188 | uint32_t p_w, p_h; | 4307 | uint32_t p_w, p_h; |
| 4189 | get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); | 4308 | get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); |