This permits: - The use of Vulkan filtering on many more devices - Better debugging due to lack of descriptor buffer support in layers Much of the changes here are due to a requirement that updates to descriptors must happen between the command buffer being waited on, and the pipeline not being bound. We routinely did it the other way around, by updating only after we bind the pipeline.
Showing the changes to libavfilter (3 of 7 files). Show all
Unified · Split
| @@ -189,7 +189,7 @@ static int init_gblur_pipeline(GBlurVulkanContext *s, FFVulkanPipeline *pl, · 188 unmodified lines | ||
| 189 | 189 | RET(ff_vk_unmap_buffer(&s->vkctx, params_buf, 1)); |
| 190 | 190 | |
| 191 | 191 | RET(ff_vk_set_descriptor_buffer(&s->vkctx, pl, NULL, 1, 0, 0, |
| 192 | − params_buf->address, params_buf->size, | |
| 192 | + params_buf, 0, params_buf->size, | |
| 193 | 193 | VK_FORMAT_UNDEFINED)); |
| 194 | 194 | |
| 195 | 195 | fail: |
| @@ -657,7 +657,7 @@ static av_cold int init_filter(AVFilterContext *ctx) · 656 unmodified lines | ||
| 657 | 657 | spv, desc, planes)); |
| 658 | 658 | |
| 659 | 659 | RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_weights, NULL, 1, 0, 0, |
| 660 | − s->xyoffsets_buf.address, s->xyoffsets_buf.size, | |
| 660 | + &s->xyoffsets_buf, 0, s->xyoffsets_buf.size, | |
| 661 | 661 | VK_FORMAT_UNDEFINED)); |
| 662 | 662 | |
| 663 | 663 | do { |
| @@ -751,8 +751,8 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) · 87 unmodified lines | ||
| 751 | 751 | /* Weights/sums */ |
| 752 | 752 | AVBufferRef *ws_buf = NULL; |
| 753 | 753 | FFVkBuffer *ws_vk; |
| 754 | − VkDeviceAddress weights_addr[4]; | |
| 755 | − VkDeviceAddress sums_addr[4]; | |
| 754 | + VkDeviceSize weights_addr[4]; | |
| 755 | + VkDeviceSize sums_addr[4]; | |
| 756 | 756 | uint32_t ws_stride[4]; |
| 757 | 757 | size_t ws_size[4]; |
| 758 | 758 | size_t ws_total_size = 0; |
| @@ -810,8 +810,8 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) · 51 unmodified lines | ||
| 810 | 810 | return err; |
| 811 | 811 | ws_vk = (FFVkBuffer *)ws_buf->data; |
| 812 | 812 | |
| 813 | − weights_addr[0] = ws_vk->address; | |
| 814 | − sums_addr[0] = ws_vk->address + ws_total_size; | |
| 813 | + weights_addr[0] = 0; | |
| 814 | + sums_addr[0] = ws_total_size; | |
| 815 | 815 | for (int i = 1; i < desc->nb_components; i++) { |
| 816 | 816 | weights_addr[i] = weights_addr[i - 1] + ws_size[i - 1]; |
| 817 | 817 | sums_addr[i] = sums_addr[i - 1] + ws_size[i - 1]; |
| @@ -844,9 +844,6 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) · 26 unmodified lines | ||
| 844 | 844 | |
| 845 | 845 | /* Input frame prep */ |
| 846 | 846 | RET(ff_vk_create_imageviews(vkctx, exec, in_views, in)); |
| 847 | − ff_vk_update_descriptor_img_array(vkctx, &s->pl_weights, exec, in, in_views, 0, 0, | |
| 848 | − VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| 849 | − s->sampler); | |
| 850 | 847 | ff_vk_frame_barrier(vkctx, exec, in, img_bar, &nb_img_bar, |
| 851 | 848 | VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, |
| 852 | 849 | VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, |
| @@ -934,10 +931,10 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) · 81 unmodified lines | ||
| 934 | 931 | s->sampler); |
| 935 | 932 | for (int i = 0; i < desc->nb_components; i++) { |
| 936 | 933 | RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_weights, exec, 0, 1 + i*2 + 0, 0, |
| 937 | − weights_addr[i], ws_size[i], | |
| 934 | + ws_vk, weights_addr[i], ws_size[i], | |
| 938 | 935 | VK_FORMAT_UNDEFINED)); |
| 939 | 936 | RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_weights, exec, 0, 1 + i*2 + 1, 0, |
| 940 | − sums_addr[i], ws_size[i], | |
| 937 | + ws_vk, sums_addr[i], ws_size[i], | |
| 941 | 938 | VK_FORMAT_UNDEFINED)); |
| 942 | 939 | } |
| 943 | 940 | |
| @@ -949,10 +946,10 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in) · 5 unmodified lines | ||
| 949 | 946 | VK_IMAGE_LAYOUT_GENERAL, s->sampler); |
| 950 | 947 | for (int i = 0; i < desc->nb_components; i++) { |
| 951 | 948 | RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_denoise, exec, 0, 2 + i*2 + 0, 0, |
| 952 | − weights_addr[i], ws_size[i], | |
| 949 | + ws_vk, weights_addr[i], ws_size[i], | |
| 953 | 950 | VK_FORMAT_UNDEFINED)); |
| 954 | 951 | RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_denoise, exec, 0, 2 + i*2 + 1, 0, |
| 955 | − sums_addr[i], ws_size[i], | |
| 952 | + ws_vk, sums_addr[i], ws_size[i], | |
| 956 | 953 | VK_FORMAT_UNDEFINED)); |
| 957 | 954 | } |
| 958 | 955 | |
| @@ -152,18 +152,6 @@ skip: · 151 unmodified lines | ||
| 152 | 152 | s->extensions = ff_vk_extensions_to_mask(vk_dev->enabled_dev_extensions, |
| 153 | 153 | vk_dev->nb_enabled_dev_extensions); |
| 154 | 154 | |
| 155 | − /** | |
| 156 | − * libplacebo does not use descriptor buffers. | |
| 157 | − */ | |
| 158 | − if (!(s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) && | |
| 159 | − strcmp(avctx->filter->name, "libplacebo")) { | |
| 160 | − av_log(avctx, AV_LOG_ERROR, "Vulkan filtering requires that " | |
| 161 | − "the %s extension is supported!\n", | |
| 162 | − VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME); | |
| 163 | − av_buffer_unref(&frames_ref); | |
| 164 | − return AVERROR(EINVAL); | |
| 165 | − } | |
| 166 | − | |
| 167 | 155 | err = ff_vk_load_functions(device_ctx, &s->vkfn, s->extensions, 1, 1); |
| 168 | 156 | if (err < 0) { |
| 169 | 157 | av_buffer_unref(&frames_ref); |
| @@ -264,12 +252,13 @@ int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e, · 94 unmodified lines | ||
| 264 | 252 | FFVkExecContext *exec = ff_vk_exec_get(e); |
| 265 | 253 | ff_vk_exec_start(vkctx, exec); |
| 266 | 254 | |
| 267 | − ff_vk_exec_bind_pipeline(vkctx, exec, pl); | |
| 268 | − | |
| 269 | − if (push_src) | |
| 270 | − ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT, | |
| 271 | − 0, push_size, push_src); | |
| 272 | − | |
| 255 | + RET(ff_vk_exec_add_dep_frame(vkctx, exec, out_f, | |
| 256 | + VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, | |
| 257 | + VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT)); | |
| 258 | + RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f)); | |
| 259 | + ff_vk_update_descriptor_img_array(vkctx, pl, exec, out_f, out_views, 0, !!in_f, | |
| 260 | + VK_IMAGE_LAYOUT_GENERAL, | |
| 261 | + VK_NULL_HANDLE); | |
| 273 | 262 | if (in_f) { |
| 274 | 263 | RET(ff_vk_exec_add_dep_frame(vkctx, exec, in_f, |
| 275 | 264 | VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, |
| @@ -278,27 +267,28 @@ int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e, · 2 unmodified lines | ||
| 278 | 267 | ff_vk_update_descriptor_img_array(vkctx, pl, exec, in_f, in_views, 0, 0, |
| 279 | 268 | VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, |
| 280 | 269 | sampler); |
| 281 | − ff_vk_frame_barrier(vkctx, exec, in_f, img_bar, &nb_img_bar, | |
| 282 | − VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, | |
| 283 | − VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, | |
| 284 | − VK_ACCESS_SHADER_READ_BIT, | |
| 285 | − VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| 286 | − VK_QUEUE_FAMILY_IGNORED); | |
| 287 | 270 | } |
| 288 | 271 | |
| 289 | − RET(ff_vk_exec_add_dep_frame(vkctx, exec, out_f, | |
| 290 | − VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, | |
| 291 | − VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT)); | |
| 292 | − RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f)); | |
| 293 | − ff_vk_update_descriptor_img_array(vkctx, pl, exec, out_f, out_views, 0, !!in_f, | |
| 294 | − VK_IMAGE_LAYOUT_GENERAL, | |
| 295 | − VK_NULL_HANDLE); | |
| 272 | + /* Bind pipeline, update push data */ | |
| 273 | + ff_vk_exec_bind_pipeline(vkctx, exec, pl); | |
| 274 | + if (push_src) | |
| 275 | + ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT, | |
| 276 | + 0, push_size, push_src); | |
| 277 | + | |
| 278 | + /* Add data sync barriers */ | |
| 296 | 279 | ff_vk_frame_barrier(vkctx, exec, out_f, img_bar, &nb_img_bar, |
| 297 | 280 | VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, |
| 298 | 281 | VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, |
| 299 | 282 | VK_ACCESS_SHADER_WRITE_BIT, |
| 300 | 283 | VK_IMAGE_LAYOUT_GENERAL, |
| 301 | 284 | VK_QUEUE_FAMILY_IGNORED); |
| 285 | + if (in_f) | |
| 286 | + ff_vk_frame_barrier(vkctx, exec, in_f, img_bar, &nb_img_bar, | |
| 287 | + VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, | |
| 288 | + VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, | |
| 289 | + VK_ACCESS_SHADER_READ_BIT, | |
| 290 | + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| 291 | + VK_QUEUE_FAMILY_IGNORED); | |
| 302 | 292 | |
| 303 | 293 | vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) { |
| 304 | 294 | .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, |
| @@ -380,12 +370,6 @@ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e, · 75 unmodified lines | ||
| 380 | 370 | VkImageView *src_views = !i ? in_views : tmp_views; |
| 381 | 371 | VkImageView *dst_views = !i ? tmp_views : out_views; |
| 382 | 372 | |
| 383 | − ff_vk_exec_bind_pipeline(vkctx, exec, pl); | |
| 384 | − | |
| 385 | − if (push_src) | |
| 386 | − ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT, | |
| 387 | − 0, push_size, push_src); | |
| 388 | − | |
| 389 | 373 | ff_vk_update_descriptor_img_array(vkctx, pl, exec, src_f, src_views, 0, 0, |
| 390 | 374 | !i ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL : |
| 391 | 375 | VK_IMAGE_LAYOUT_GENERAL, |
| @@ -394,6 +378,12 @@ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e, · 2 unmodified lines | ||
| 394 | 378 | VK_IMAGE_LAYOUT_GENERAL, |
| 395 | 379 | VK_NULL_HANDLE); |
| 396 | 380 | |
| 381 | + /* Bind pipeline, update push data */ | |
| 382 | + ff_vk_exec_bind_pipeline(vkctx, exec, pl); | |
| 383 | + if (push_src) | |
| 384 | + ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT, | |
| 385 | + 0, push_size, push_src); | |
| 386 | + | |
| 397 | 387 | vk->CmdDispatch(exec->buf, |
| 398 | 388 | FFALIGN(vkctx->output_width, pl->wg_size[0])/pl->wg_size[0], |
| 399 | 389 | FFALIGN(vkctx->output_height, pl->wg_size[1])/pl->wg_size[1], |
| @@ -422,32 +412,47 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e, · 22 unmodified lines | ||
| 422 | 412 | FFVkExecContext *exec = ff_vk_exec_get(e); |
| 423 | 413 | ff_vk_exec_start(vkctx, exec); |
| 424 | 414 | |
| 425 | − /* Inputs */ | |
| 415 | + /* Add deps and create temporary imageviews */ | |
| 416 | + RET(ff_vk_exec_add_dep_frame(vkctx, exec, out, | |
| 417 | + VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, | |
| 418 | + VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT)); | |
| 419 | + RET(ff_vk_create_imageviews(vkctx, exec, out_views, out)); | |
| 426 | 420 | for (int i = 0; i < nb_in; i++) { |
| 427 | 421 | RET(ff_vk_exec_add_dep_frame(vkctx, exec, in[i], |
| 428 | 422 | VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, |
| 429 | 423 | VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT)); |
| 430 | 424 | RET(ff_vk_create_imageviews(vkctx, exec, in_views[i], in[i])); |
| 431 | − | |
| 432 | − ff_vk_frame_barrier(vkctx, exec, in[i], img_bar, &nb_img_bar, | |
| 433 | − VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, | |
| 434 | − VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, | |
| 435 | − VK_ACCESS_SHADER_READ_BIT, | |
| 436 | − VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| 437 | − VK_QUEUE_FAMILY_IGNORED); | |
| 438 | 425 | } |
| 439 | 426 | |
| 440 | − /* Output */ | |
| 441 | − RET(ff_vk_exec_add_dep_frame(vkctx, exec, out, | |
| 442 | − VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, | |
| 443 | − VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT)); | |
| 444 | − RET(ff_vk_create_imageviews(vkctx, exec, out_views, out)); | |
| 427 | + /* Update descriptor sets */ | |
| 428 | + ff_vk_update_descriptor_img_array(vkctx, pl, exec, out, out_views, 0, nb_in, | |
| 429 | + VK_IMAGE_LAYOUT_GENERAL, | |
| 430 | + VK_NULL_HANDLE); | |
| 431 | + for (int i = 0; i < nb_in; i++) | |
| 432 | + ff_vk_update_descriptor_img_array(vkctx, pl, exec, in[i], in_views[i], 0, i, | |
| 433 | + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| 434 | + sampler); | |
| 435 | + | |
| 436 | + /* Bind pipeline, update push data */ | |
| 437 | + ff_vk_exec_bind_pipeline(vkctx, exec, pl); | |
| 438 | + if (push_src) | |
| 439 | + ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT, | |
| 440 | + 0, push_size, push_src); | |
| 441 | + | |
| 442 | + /* Add data sync barriers */ | |
| 445 | 443 | ff_vk_frame_barrier(vkctx, exec, out, img_bar, &nb_img_bar, |
| 446 | 444 | VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, |
| 447 | 445 | VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, |
| 448 | 446 | VK_ACCESS_SHADER_WRITE_BIT, |
| 449 | 447 | VK_IMAGE_LAYOUT_GENERAL, |
| 450 | 448 | VK_QUEUE_FAMILY_IGNORED); |
| 449 | + for (int i = 0; i < nb_in; i++) | |
| 450 | + ff_vk_frame_barrier(vkctx, exec, in[i], img_bar, &nb_img_bar, | |
| 451 | + VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT, | |
| 452 | + VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT, | |
| 453 | + VK_ACCESS_SHADER_READ_BIT, | |
| 454 | + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| 455 | + VK_QUEUE_FAMILY_IGNORED); | |
| 451 | 456 | |
| 452 | 457 | vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) { |
| 453 | 458 | .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, |
| @@ -455,21 +460,6 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e, · 1 unmodified line | ||
| 455 | 460 | .imageMemoryBarrierCount = nb_img_bar, |
| 456 | 461 | }); |
| 457 | 462 | |
| 458 | − ff_vk_exec_bind_pipeline(vkctx, exec, pl); | |
| 459 | − | |
| 460 | − if (push_src) | |
| 461 | − ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT, | |
| 462 | − 0, push_size, push_src); | |
| 463 | − | |
| 464 | − for (int i = 0; i < nb_in; i++) | |
| 465 | − ff_vk_update_descriptor_img_array(vkctx, pl, exec, in[i], in_views[i], 0, i, | |
| 466 | − VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, | |
| 467 | − sampler); | |
| 468 | − | |
| 469 | − ff_vk_update_descriptor_img_array(vkctx, pl, exec, out, out_views, 0, nb_in, | |
| 470 | − VK_IMAGE_LAYOUT_GENERAL, | |
| 471 | − VK_NULL_HANDLE); | |
| 472 | − | |
| 473 | 463 | vk->CmdDispatch(exec->buf, |
| 474 | 464 | FFALIGN(vkctx->output_width, pl->wg_size[0])/pl->wg_size[0], |
| 475 | 465 | FFALIGN(vkctx->output_height, pl->wg_size[1])/pl->wg_size[1], |