| @@ -20,6 +20,7 @@ · 19 unmodified lines |
| 20 | 20 | #include "vulkan.h" |
| 21 | 21 | #include "glslang.h" |
| 22 | 22 | |
| 23 | +#include "libavutil/avassert.h" |
| 23 | 24 | #include "libavutil/vulkan_loader.h" |
| 24 | 25 | |
| 25 | 26 | /* Generic macro for creating contexts which need to keep their addresses |
| @@ -88,15 +89,54 @@ const char *ff_vk_ret2str(VkResult res) · 62 unmodified lines |
| 88 | 89 | #undef CASE |
| 89 | 90 | } |
| 90 | 91 | |
| 92 | +void ff_vk_qf_init(AVFilterContext *avctx, FFVkQueueFamilyCtx *qf, |
| 93 | + VkQueueFlagBits dev_family, int queue_limit) |
| 94 | +{ |
| 95 | + FFVulkanContext *s = avctx->priv; |
| 96 | + |
| 97 | + if (!queue_limit) |
| 98 | + queue_limit = INT32_MAX; |
| 99 | + |
| 100 | + switch (dev_family) { |
| 101 | + case VK_QUEUE_GRAPHICS_BIT: |
| 102 | + qf->queue_family = s->hwctx->queue_family_index; |
| 103 | + qf->nb_queues = FFMIN(s->hwctx->nb_graphics_queues, queue_limit); |
| 104 | + return; |
| 105 | + case VK_QUEUE_COMPUTE_BIT: |
| 106 | + qf->queue_family = s->hwctx->queue_family_comp_index; |
| 107 | + qf->nb_queues = FFMIN(s->hwctx->nb_comp_queues, queue_limit); |
| 108 | + return; |
| 109 | + case VK_QUEUE_TRANSFER_BIT: |
| 110 | + qf->queue_family = s->hwctx->queue_family_tx_index; |
| 111 | + qf->nb_queues = FFMIN(s->hwctx->nb_tx_queues, queue_limit); |
| 112 | + return; |
| 113 | + case VK_QUEUE_VIDEO_ENCODE_BIT_KHR: |
| 114 | + qf->queue_family = s->hwctx->queue_family_encode_index; |
| 115 | + qf->nb_queues = FFMIN(s->hwctx->nb_encode_queues, queue_limit); |
| 116 | + return; |
| 117 | + case VK_QUEUE_VIDEO_DECODE_BIT_KHR: |
| 118 | + qf->queue_family = s->hwctx->queue_family_decode_index; |
| 119 | + qf->nb_queues = FFMIN(s->hwctx->nb_decode_queues, queue_limit); |
| 120 | + return; |
| 121 | + default: |
| 122 | + av_assert0(0); /* Should never happen */ |
| 123 | + } |
| 124 | + |
| 125 | + return; |
| 126 | +} |
| 127 | + |
| 128 | +void ff_vk_qf_rotate(FFVkQueueFamilyCtx *qf) |
| 129 | +{ |
| 130 | + qf->cur_queue = (qf->cur_queue + 1) % qf->nb_queues; |
| 131 | +} |
| 132 | + |
| 91 | 133 | static int vk_alloc_mem(AVFilterContext *avctx, VkMemoryRequirements *req, |
| 92 | 134 | VkMemoryPropertyFlagBits req_flags, void *alloc_extension, |
| 93 | 135 | VkMemoryPropertyFlagBits *mem_flags, VkDeviceMemory *mem) |
| 94 | 136 | { |
| 95 | 137 | VkResult ret; |
| 96 | 138 | int index = -1; |
| 97 | | − VkPhysicalDeviceProperties props; |
| 98 | | − VkPhysicalDeviceMemoryProperties mprops; |
| 99 | | − VulkanFilterContext *s = avctx->priv; |
| 139 | + FFVulkanContext *s = avctx->priv; |
| 100 | 140 | FFVulkanFunctions *vk = &s->vkfn; |
| 101 | 141 | |
| 102 | 142 | VkMemoryAllocateInfo alloc_info = { |
| @@ -104,24 +144,21 @@ static int vk_alloc_mem(AVFilterContext *avctx, VkMemoryRequirements *req, · 1 unmodified line |
| 104 | 144 | .pNext = alloc_extension, |
| 105 | 145 | }; |
| 106 | 146 | |
| 107 | | − vk->GetPhysicalDeviceProperties(s->hwctx->phys_dev, &props); |
| 108 | | − vk->GetPhysicalDeviceMemoryProperties(s->hwctx->phys_dev, &mprops); |
| 109 | | − |
| 110 | 147 | /* Align if we need to */ |
| 111 | 148 | if (req_flags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) |
| 112 | | − req->size = FFALIGN(req->size, props.limits.minMemoryMapAlignment); |
| 149 | + req->size = FFALIGN(req->size, s->props.limits.minMemoryMapAlignment); |
| 113 | 150 | |
| 114 | 151 | alloc_info.allocationSize = req->size; |
| 115 | 152 | |
| 116 | 153 | /* The vulkan spec requires memory types to be sorted in the "optimal" |
| 117 | 154 | * order, so the first matching type we find will be the best/fastest one */ |
| 118 | | − for (int i = 0; i < mprops.memoryTypeCount; i++) { |
| 155 | + for (int i = 0; i < s->mprops.memoryTypeCount; i++) { |
| 119 | 156 | /* The memory type must be supported by the requirements (bitfield) */ |
| 120 | 157 | if (!(req->memoryTypeBits & (1 << i))) |
| 121 | 158 | continue; |
| 122 | 159 | |
| 123 | 160 | /* The memory type flags must include our properties */ |
| 124 | | − if ((mprops.memoryTypes[i].propertyFlags & req_flags) != req_flags) |
| 161 | + if ((s->mprops.memoryTypes[i].propertyFlags & req_flags) != req_flags) |
| 125 | 162 | continue; |
| 126 | 163 | |
| 127 | 164 | /* Found a suitable memory type */ |
| @@ -145,7 +182,7 @@ static int vk_alloc_mem(AVFilterContext *avctx, VkMemoryRequirements *req, · 17 unmodified lines |
| 145 | 182 | return AVERROR(ENOMEM); |
| 146 | 183 | } |
| 147 | 184 | |
| 148 | | − *mem_flags |= mprops.memoryTypes[index].propertyFlags; |
| 185 | + *mem_flags |= s->mprops.memoryTypes[index].propertyFlags; |
| 149 | 186 | |
| 150 | 187 | return 0; |
| 151 | 188 | } |
| @@ -156,7 +193,7 @@ int ff_vk_create_buf(AVFilterContext *avctx, FFVkBuffer *buf, size_t size, · 4 unmodified lines |
| 156 | 193 | int err; |
| 157 | 194 | VkResult ret; |
| 158 | 195 | int use_ded_mem; |
| 159 | | − VulkanFilterContext *s = avctx->priv; |
| 196 | + FFVulkanContext *s = avctx->priv; |
| 160 | 197 | FFVulkanFunctions *vk = &s->vkfn; |
| 161 | 198 | |
| 162 | 199 | VkBufferCreateInfo buf_spawn = { |
| @@ -220,7 +257,7 @@ int ff_vk_map_buffers(AVFilterContext *avctx, FFVkBuffer *buf, uint8_t *mem[], · 57 unmodified lines |
| 220 | 257 | int nb_buffers, int invalidate) |
| 221 | 258 | { |
| 222 | 259 | VkResult ret; |
| 223 | | − VulkanFilterContext *s = avctx->priv; |
| 260 | + FFVulkanContext *s = avctx->priv; |
| 224 | 261 | FFVulkanFunctions *vk = &s->vkfn; |
| 225 | 262 | VkMappedMemoryRange *inval_list = NULL; |
| 226 | 263 | int inval_count = 0; |
| @@ -271,7 +308,7 @@ int ff_vk_unmap_buffers(AVFilterContext *avctx, FFVkBuffer *buf, int nb_buffers, · 44 unmodified lines |
| 271 | 308 | { |
| 272 | 309 | int err = 0; |
| 273 | 310 | VkResult ret; |
| 274 | | − VulkanFilterContext *s = avctx->priv; |
| 311 | + FFVulkanContext *s = avctx->priv; |
| 275 | 312 | FFVulkanFunctions *vk = &s->vkfn; |
| 276 | 313 | VkMappedMemoryRange *flush_list = NULL; |
| 277 | 314 | int flush_count = 0; |
| @@ -311,7 +348,7 @@ int ff_vk_unmap_buffers(AVFilterContext *avctx, FFVkBuffer *buf, int nb_buffers, · 33 unmodified lines |
| 311 | 348 | |
| 312 | 349 | void ff_vk_free_buf(AVFilterContext *avctx, FFVkBuffer *buf) |
| 313 | 350 | { |
| 314 | | − VulkanFilterContext *s = avctx->priv; |
| 351 | + FFVulkanContext *s = avctx->priv; |
| 315 | 352 | FFVulkanFunctions *vk = &s->vkfn; |
| 316 | 353 | |
| 317 | 354 | if (!buf) |
| @@ -323,7 +360,7 @@ void ff_vk_free_buf(AVFilterContext *avctx, FFVkBuffer *buf) · 5 unmodified lines |
| 323 | 360 | vk->FreeMemory(s->hwctx->act_dev, buf->mem, s->hwctx->alloc); |
| 324 | 361 | } |
| 325 | 362 | |
| 326 | | −int ff_vk_add_push_constant(AVFilterContext *avctx, VulkanPipeline *pl, |
| 363 | +int ff_vk_add_push_constant(AVFilterContext *avctx, FFVulkanPipeline *pl, |
| 327 | 364 | int offset, int size, VkShaderStageFlagBits stage) |
| 328 | 365 | { |
| 329 | 366 | VkPushConstantRange *pc; |
| @@ -343,37 +380,37 @@ int ff_vk_add_push_constant(AVFilterContext *avctx, VulkanPipeline *pl, · 13 unmodified lines |
| 343 | 380 | return 0; |
| 344 | 381 | } |
| 345 | 382 | |
| 346 | | −FN_CREATING(VulkanFilterContext, FFVkExecContext, exec_ctx, exec_ctx, exec_ctx_num) |
| 347 | | −int ff_vk_create_exec_ctx(AVFilterContext *avctx, FFVkExecContext **ctx) |
| 383 | +FN_CREATING(FFVulkanContext, FFVkExecContext, exec_ctx, exec_ctx, exec_ctx_num) |
| 384 | +int ff_vk_create_exec_ctx(AVFilterContext *avctx, FFVkExecContext **ctx, |
| 385 | + FFVkQueueFamilyCtx *qf) |
| 348 | 386 | { |
| 349 | 387 | VkResult ret; |
| 350 | 388 | FFVkExecContext *e; |
| 351 | | − VulkanFilterContext *s = avctx->priv; |
| 389 | + FFVulkanContext *s = avctx->priv; |
| 352 | 390 | FFVulkanFunctions *vk = &s->vkfn; |
| 353 | 391 | |
| 354 | | − int queue_family = s->queue_family_idx; |
| 355 | | − int nb_queues = s->queue_count; |
| 356 | | − |
| 357 | 392 | VkCommandPoolCreateInfo cqueue_create = { |
| 358 | 393 | .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, |
| 359 | 394 | .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, |
| 360 | | − .queueFamilyIndex = queue_family, |
| 395 | + .queueFamilyIndex = qf->queue_family, |
| 361 | 396 | }; |
| 362 | 397 | VkCommandBufferAllocateInfo cbuf_create = { |
| 363 | 398 | .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, |
| 364 | 399 | .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, |
| 365 | | − .commandBufferCount = nb_queues, |
| 400 | + .commandBufferCount = qf->nb_queues, |
| 366 | 401 | }; |
| 367 | 402 | |
| 368 | 403 | e = create_exec_ctx(s); |
| 369 | 404 | if (!e) |
| 370 | 405 | return AVERROR(ENOMEM); |
| 371 | 406 | |
| 372 | | − e->queues = av_mallocz(nb_queues * sizeof(*e->queues)); |
| 407 | + e->qf = qf; |
| 408 | + |
| 409 | + e->queues = av_mallocz(qf->nb_queues * sizeof(*e->queues)); |
| 373 | 410 | if (!e->queues) |
| 374 | 411 | return AVERROR(ENOMEM); |
| 375 | 412 | |
| 376 | | − e->bufs = av_mallocz(nb_queues * sizeof(*e->bufs)); |
| 413 | + e->bufs = av_mallocz(qf->nb_queues * sizeof(*e->bufs)); |
| 377 | 414 | if (!e->bufs) |
| 378 | 415 | return AVERROR(ENOMEM); |
| 379 | 416 | |
| @@ -396,9 +433,9 @@ int ff_vk_create_exec_ctx(AVFilterContext *avctx, FFVkExecContext **ctx) · 16 unmodified lines |
| 396 | 433 | return AVERROR_EXTERNAL; |
| 397 | 434 | } |
| 398 | 435 | |
| 399 | | − for (int i = 0; i < nb_queues; i++) { |
| 436 | + for (int i = 0; i < qf->nb_queues; i++) { |
| 400 | 437 | FFVkQueueCtx *q = &e->queues[i]; |
| 401 | | − vk->GetDeviceQueue(s->hwctx->act_dev, queue_family, i, &q->queue); |
| 438 | + vk->GetDeviceQueue(s->hwctx->act_dev, qf->queue_family, i, &q->queue); |
| 402 | 439 | } |
| 403 | 440 | |
| 404 | 441 | *ctx = e; |
| @@ -408,8 +445,7 @@ int ff_vk_create_exec_ctx(AVFilterContext *avctx, FFVkExecContext **ctx) · 3 unmodified lines |
| 408 | 445 | |
| 409 | 446 | void ff_vk_discard_exec_deps(AVFilterContext *avctx, FFVkExecContext *e) |
| 410 | 447 | { |
| 411 | | − VulkanFilterContext *s = avctx->priv; |
| 412 | | − FFVkQueueCtx *q = &e->queues[s->cur_queue_idx]; |
| 448 | + FFVkQueueCtx *q = &e->queues[e->qf->cur_queue]; |
| 413 | 449 | |
| 414 | 450 | for (int j = 0; j < q->nb_buf_deps; j++) |
| 415 | 451 | av_buffer_unref(&q->buf_deps[j]); |
| @@ -426,9 +462,9 @@ void ff_vk_discard_exec_deps(AVFilterContext *avctx, FFVkExecContext *e) · 10 unmodified lines |
| 426 | 462 | int ff_vk_start_exec_recording(AVFilterContext *avctx, FFVkExecContext *e) |
| 427 | 463 | { |
| 428 | 464 | VkResult ret; |
| 429 | | − VulkanFilterContext *s = avctx->priv; |
| 465 | + FFVulkanContext *s = avctx->priv; |
| 430 | 466 | FFVulkanFunctions *vk = &s->vkfn; |
| 431 | | − FFVkQueueCtx *q = &e->queues[s->cur_queue_idx]; |
| 467 | + FFVkQueueCtx *q = &e->queues[e->qf->cur_queue]; |
| 432 | 468 | |
| 433 | 469 | VkCommandBufferBeginInfo cmd_start = { |
| 434 | 470 | .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, |
| @@ -455,7 +491,7 @@ int ff_vk_start_exec_recording(AVFilterContext *avctx, FFVkExecContext *e) · 20 unmodified lines |
| 455 | 491 | /* Discard queue dependencies */ |
| 456 | 492 | ff_vk_discard_exec_deps(avctx, e); |
| 457 | 493 | |
| 458 | | − ret = vk->BeginCommandBuffer(e->bufs[s->cur_queue_idx], &cmd_start); |
| 494 | + ret = vk->BeginCommandBuffer(e->bufs[e->qf->cur_queue], &cmd_start); |
| 459 | 495 | if (ret != VK_SUCCESS) { |
| 460 | 496 | av_log(avctx, AV_LOG_ERROR, "Failed to start command recoding: %s\n", |
| 461 | 497 | ff_vk_ret2str(ret)); |
| @@ -467,17 +503,15 @@ int ff_vk_start_exec_recording(AVFilterContext *avctx, FFVkExecContext *e) · 5 unmodified lines |
| 467 | 503 | |
| 468 | 504 | VkCommandBuffer ff_vk_get_exec_buf(AVFilterContext *avctx, FFVkExecContext *e) |
| 469 | 505 | { |
| 470 | | − VulkanFilterContext *s = avctx->priv; |
| 471 | | − return e->bufs[s->cur_queue_idx]; |
| 506 | + return e->bufs[e->qf->cur_queue]; |
| 472 | 507 | } |
| 473 | 508 | |
| 474 | 509 | int ff_vk_add_exec_dep(AVFilterContext *avctx, FFVkExecContext *e, |
| 475 | 510 | AVFrame *frame, VkPipelineStageFlagBits in_wait_dst_flag) |
| 476 | 511 | { |
| 477 | 512 | AVFrame **dst; |
| 478 | | − VulkanFilterContext *s = avctx->priv; |
| 479 | 513 | AVVkFrame *f = (AVVkFrame *)frame->data[0]; |
| 480 | | − FFVkQueueCtx *q = &e->queues[s->cur_queue_idx]; |
| 514 | + FFVkQueueCtx *q = &e->queues[e->qf->cur_queue]; |
| 481 | 515 | AVHWFramesContext *fc = (AVHWFramesContext *)frame->hw_frames_ctx->data; |
| 482 | 516 | int planes = av_pix_fmt_count_planes(fc->sw_format); |
| 483 | 517 | |
| @@ -517,16 +551,21 @@ int ff_vk_add_exec_dep(AVFilterContext *avctx, FFVkExecContext *e, · 33 unmodified lines |
| 517 | 551 | return AVERROR(ENOMEM); |
| 518 | 552 | } |
| 519 | 553 | |
| 554 | + e->sem_sig_val_dst = av_fast_realloc(e->sem_sig_val_dst, &e->sem_sig_val_dst_alloc, |
| 555 | + (e->sem_sig_cnt + 1)*sizeof(*e->sem_sig_val_dst)); |
| 556 | + if (!e->sem_sig_val_dst) { |
| 557 | + ff_vk_discard_exec_deps(avctx, e); |
| 558 | + return AVERROR(ENOMEM); |
| 559 | + } |
| 560 | + |
| 520 | 561 | e->sem_wait[e->sem_wait_cnt] = f->sem[i]; |
| 521 | 562 | e->sem_wait_dst[e->sem_wait_cnt] = in_wait_dst_flag; |
| 522 | 563 | e->sem_wait_val[e->sem_wait_cnt] = f->sem_value[i]; |
| 523 | 564 | e->sem_wait_cnt++; |
| 524 | 565 | |
| 525 | | − /* TODO: fix this in case execution fails */ |
| 526 | | − f->sem_value[i]++; |
| 527 | | − |
| 528 | 566 | e->sem_sig[e->sem_sig_cnt] = f->sem[i]; |
| 529 | | − e->sem_sig_val[e->sem_sig_cnt] = f->sem_value[i]; |
| 567 | + e->sem_sig_val[e->sem_sig_cnt] = f->sem_value[i] + 1; |
| 568 | + e->sem_sig_val_dst[e->sem_sig_cnt] = &f->sem_value[i]; |
| 530 | 569 | e->sem_sig_cnt++; |
| 531 | 570 | } |
| 532 | 571 | |
| @@ -551,9 +590,9 @@ int ff_vk_add_exec_dep(AVFilterContext *avctx, FFVkExecContext *e, · 18 unmodified lines |
| 551 | 590 | int ff_vk_submit_exec_queue(AVFilterContext *avctx, FFVkExecContext *e) |
| 552 | 591 | { |
| 553 | 592 | VkResult ret; |
| 554 | | − VulkanFilterContext *s = avctx->priv; |
| 593 | + FFVulkanContext *s = avctx->priv; |
| 555 | 594 | FFVulkanFunctions *vk = &s->vkfn; |
| 556 | | − FFVkQueueCtx *q = &e->queues[s->cur_queue_idx]; |
| 595 | + FFVkQueueCtx *q = &e->queues[e->qf->cur_queue]; |
| 557 | 596 | |
| 558 | 597 | VkTimelineSemaphoreSubmitInfo s_timeline_sem_info = { |
| 559 | 598 | .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, |
| @@ -568,7 +607,7 @@ int ff_vk_submit_exec_queue(AVFilterContext *avctx, FFVkExecContext *e) · 8 unmodified lines |
| 568 | 607 | .pNext = &s_timeline_sem_info, |
| 569 | 608 | |
| 570 | 609 | .commandBufferCount = 1, |
| 571 | | − .pCommandBuffers = &e->bufs[s->cur_queue_idx], |
| 610 | + .pCommandBuffers = &e->bufs[e->qf->cur_queue], |
| 572 | 611 | |
| 573 | 612 | .pWaitSemaphores = e->sem_wait, |
| 574 | 613 | .pWaitDstStageMask = e->sem_wait_dst, |
| @@ -578,7 +617,7 @@ int ff_vk_submit_exec_queue(AVFilterContext *avctx, FFVkExecContext *e) · 3 unmodified lines |
| 578 | 617 | .signalSemaphoreCount = e->sem_sig_cnt, |
| 579 | 618 | }; |
| 580 | 619 | |
| 581 | | − ret = vk->EndCommandBuffer(e->bufs[s->cur_queue_idx]); |
| 620 | + ret = vk->EndCommandBuffer(e->bufs[e->qf->cur_queue]); |
| 582 | 621 | if (ret != VK_SUCCESS) { |
| 583 | 622 | av_log(avctx, AV_LOG_ERROR, "Unable to finish command buffer: %s\n", |
| 584 | 623 | ff_vk_ret2str(ret)); |
| @@ -592,8 +631,8 @@ int ff_vk_submit_exec_queue(AVFilterContext *avctx, FFVkExecContext *e) · 7 unmodified lines |
| 592 | 631 | return AVERROR_EXTERNAL; |
| 593 | 632 | } |
| 594 | 633 | |
| 595 | | − /* Rotate queues */ |
| 596 | | − s->cur_queue_idx = (s->cur_queue_idx + 1) % s->queue_count; |
| 634 | + for (int i = 0; i < e->sem_sig_cnt; i++) |
| 635 | + *e->sem_sig_val_dst[i] += 1; |
| 597 | 636 | |
| 598 | 637 | return 0; |
| 599 | 638 | } |
| @@ -602,8 +641,7 @@ int ff_vk_add_dep_exec_ctx(AVFilterContext *avctx, FFVkExecContext *e, · 2 unmodified lines |
| 602 | 641 | AVBufferRef **deps, int nb_deps) |
| 603 | 642 | { |
| 604 | 643 | AVBufferRef **dst; |
| 605 | | − VulkanFilterContext *s = avctx->priv; |
| 606 | | − FFVkQueueCtx *q = &e->queues[s->cur_queue_idx]; |
| 644 | + FFVkQueueCtx *q = &e->queues[e->qf->cur_queue]; |
| 607 | 645 | |
| 608 | 646 | if (!deps || !nb_deps) |
| 609 | 647 | return 0; |
| @@ -632,7 +670,7 @@ err: · 22 unmodified lines |
| 632 | 670 | static int vulkan_filter_set_device(AVFilterContext *avctx, |
| 633 | 671 | AVBufferRef *device) |
| 634 | 672 | { |
| 635 | | − VulkanFilterContext *s = avctx->priv; |
| 673 | + FFVulkanContext *s = avctx->priv; |
| 636 | 674 | |
| 637 | 675 | av_buffer_unref(&s->device_ref); |
| 638 | 676 | |
| @@ -649,7 +687,7 @@ static int vulkan_filter_set_device(AVFilterContext *avctx, · 10 unmodified lines |
| 649 | 687 | static int vulkan_filter_set_frames(AVFilterContext *avctx, |
| 650 | 688 | AVBufferRef *frames) |
| 651 | 689 | { |
| 652 | | − VulkanFilterContext *s = avctx->priv; |
| 690 | + FFVulkanContext *s = avctx->priv; |
| 653 | 691 | |
| 654 | 692 | av_buffer_unref(&s->frames_ref); |
| 655 | 693 | |
| @@ -664,7 +702,8 @@ int ff_vk_filter_config_input(AVFilterLink *inlink) · 8 unmodified lines |
| 664 | 702 | { |
| 665 | 703 | int err; |
| 666 | 704 | AVFilterContext *avctx = inlink->dst; |
| 667 | | − VulkanFilterContext *s = avctx->priv; |
| 705 | + FFVulkanContext *s = avctx->priv; |
| 706 | + FFVulkanFunctions *vk = &s->vkfn; |
| 668 | 707 | AVHWFramesContext *input_frames; |
| 669 | 708 | |
| 670 | 709 | if (!inlink->hw_frames_ctx) { |
| @@ -695,6 +734,9 @@ int ff_vk_filter_config_input(AVFilterLink *inlink) · 24 unmodified lines |
| 695 | 734 | if (err < 0) |
| 696 | 735 | return err; |
| 697 | 736 | |
| 737 | + vk->GetPhysicalDeviceProperties(s->hwctx->phys_dev, &s->props); |
| 738 | + vk->GetPhysicalDeviceMemoryProperties(s->hwctx->phys_dev, &s->mprops); |
| 739 | + |
| 698 | 740 | /* Default output parameters match input parameters. */ |
| 699 | 741 | s->input_format = input_frames->sw_format; |
| 700 | 742 | if (s->output_format == AV_PIX_FMT_NONE) |
| @@ -711,7 +753,7 @@ int ff_vk_filter_config_output_inplace(AVFilterLink *outlink) · 10 unmodified lines |
| 711 | 753 | { |
| 712 | 754 | int err; |
| 713 | 755 | AVFilterContext *avctx = outlink->src; |
| 714 | | − VulkanFilterContext *s = avctx->priv; |
| 756 | + FFVulkanContext *s = avctx->priv; |
| 715 | 757 | |
| 716 | 758 | av_buffer_unref(&outlink->hw_frames_ctx); |
| 717 | 759 | |
| @@ -741,7 +783,7 @@ int ff_vk_filter_config_output(AVFilterLink *outlink) · 23 unmodified lines |
| 741 | 783 | { |
| 742 | 784 | int err; |
| 743 | 785 | AVFilterContext *avctx = outlink->src; |
| 744 | | − VulkanFilterContext *s = avctx->priv; |
| 786 | + FFVulkanContext *s = avctx->priv; |
| 745 | 787 | AVBufferRef *output_frames_ref; |
| 746 | 788 | AVHWFramesContext *output_frames; |
| 747 | 789 | |
| @@ -790,7 +832,7 @@ fail: · 42 unmodified lines |
| 790 | 832 | |
| 791 | 833 | int ff_vk_filter_init(AVFilterContext *avctx) |
| 792 | 834 | { |
| 793 | | − VulkanFilterContext *s = avctx->priv; |
| 835 | + FFVulkanContext *s = avctx->priv; |
| 794 | 836 | |
| 795 | 837 | s->output_format = AV_PIX_FMT_NONE; |
| 796 | 838 | |
| @@ -800,12 +842,12 @@ int ff_vk_filter_init(AVFilterContext *avctx) · 3 unmodified lines |
| 800 | 842 | return 0; |
| 801 | 843 | } |
| 802 | 844 | |
| 803 | | −FN_CREATING(VulkanFilterContext, VkSampler, sampler, samplers, samplers_num) |
| 804 | | −VkSampler *ff_vk_init_sampler(AVFilterContext *avctx, int unnorm_coords, |
| 805 | | − VkFilter filt) |
| 845 | +FN_CREATING(FFVulkanContext, FFVkSampler, sampler, samplers, samplers_num) |
| 846 | +FFVkSampler *ff_vk_init_sampler(AVFilterContext *avctx, int unnorm_coords, |
| 847 | + VkFilter filt) |
| 806 | 848 | { |
| 807 | 849 | VkResult ret; |
| 808 | | − VulkanFilterContext *s = avctx->priv; |
| 850 | + FFVulkanContext *s = avctx->priv; |
| 809 | 851 | FFVulkanFunctions *vk = &s->vkfn; |
| 810 | 852 | |
| 811 | 853 | VkSamplerCreateInfo sampler_info = { |
| @@ -823,19 +865,22 @@ VkSampler *ff_vk_init_sampler(AVFilterContext *avctx, int unnorm_coords, · 11 unmodified lines |
| 823 | 865 | .unnormalizedCoordinates = unnorm_coords, |
| 824 | 866 | }; |
| 825 | 867 | |
| 826 | | − VkSampler *sampler = create_sampler(s); |
| 827 | | − if (!sampler) |
| 868 | + FFVkSampler *sctx = create_sampler(s); |
| 869 | + if (!sctx) |
| 828 | 870 | return NULL; |
| 829 | 871 | |
| 830 | 872 | ret = vk->CreateSampler(s->hwctx->act_dev, &sampler_info, |
| 831 | | − s->hwctx->alloc, sampler); |
| 873 | + s->hwctx->alloc, &sctx->sampler[0]); |
| 832 | 874 | if (ret != VK_SUCCESS) { |
| 833 | 875 | av_log(avctx, AV_LOG_ERROR, "Unable to init sampler: %s\n", |
| 834 | 876 | ff_vk_ret2str(ret)); |
| 835 | 877 | return NULL; |
| 836 | 878 | } |
| 837 | 879 | |
| 838 | | − return sampler; |
| 880 | + for (int i = 1; i < 4; i++) |
| 881 | + sctx->sampler[i] = sctx->sampler[0]; |
| 882 | + |
| 883 | + return sctx; |
| 839 | 884 | } |
| 840 | 885 | |
| 841 | 886 | int ff_vk_mt_is_np_rgb(enum AVPixelFormat pix_fmt) |
| @@ -863,7 +908,7 @@ typedef struct ImageViewCtx { · 21 unmodified lines |
| 863 | 908 | |
| 864 | 909 | static void destroy_imageview(void *opaque, uint8_t *data) |
| 865 | 910 | { |
| 866 | | − VulkanFilterContext *s = opaque; |
| 911 | + FFVulkanContext *s = opaque; |
| 867 | 912 | FFVulkanFunctions *vk = &s->vkfn; |
| 868 | 913 | ImageViewCtx *iv = (ImageViewCtx *)data; |
| 869 | 914 | |
| @@ -877,7 +922,7 @@ int ff_vk_create_imageview(AVFilterContext *avctx, FFVkExecContext *e, · 7 unmodified lines |
| 877 | 922 | { |
| 878 | 923 | int err; |
| 879 | 924 | AVBufferRef *buf; |
| 880 | | − VulkanFilterContext *s = avctx->priv; |
| 925 | + FFVulkanContext *s = avctx->priv; |
| 881 | 926 | FFVulkanFunctions *vk = &s->vkfn; |
| 882 | 927 | |
| 883 | 928 | VkImageViewCreateInfo imgview_spawn = { |
| @@ -924,8 +969,8 @@ int ff_vk_create_imageview(AVFilterContext *avctx, FFVkExecContext *e, · 40 unmodified lines |
| 924 | 969 | return 0; |
| 925 | 970 | } |
| 926 | 971 | |
| 927 | | −FN_CREATING(VulkanPipeline, FFSPIRVShader, shader, shaders, shaders_num) |
| 928 | | −FFSPIRVShader *ff_vk_init_shader(AVFilterContext *avctx, VulkanPipeline *pl, |
| 972 | +FN_CREATING(FFVulkanPipeline, FFSPIRVShader, shader, shaders, shaders_num) |
| 973 | +FFSPIRVShader *ff_vk_init_shader(AVFilterContext *avctx, FFVulkanPipeline *pl, |
| 929 | 974 | const char *name, VkShaderStageFlags stage) |
| 930 | 975 | { |
| 931 | 976 | FFSPIRVShader *shd = create_shader(pl); |
| @@ -984,7 +1029,7 @@ int ff_vk_compile_shader(AVFilterContext *avctx, FFSPIRVShader *shd, · 52 unmodified lines |
| 984 | 1029 | { |
| 985 | 1030 | int err; |
| 986 | 1031 | VkResult ret; |
| 987 | | − VulkanFilterContext *s = avctx->priv; |
| 1032 | + FFVulkanContext *s = avctx->priv; |
| 988 | 1033 | FFVulkanFunctions *vk = &s->vkfn; |
| 989 | 1034 | VkShaderModuleCreateInfo shader_create; |
| 990 | 1035 | uint8_t *spirv; |
| @@ -1043,25 +1088,24 @@ static const struct descriptor_props { · 52 unmodified lines |
| 1043 | 1088 | [VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER] = { sizeof(VkBufferView), "imageBuffer", 1, 0, 0, 0, }, |
| 1044 | 1089 | }; |
| 1045 | 1090 | |
| 1046 | | −int ff_vk_add_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl, |
| 1047 | | − FFSPIRVShader *shd, VulkanDescriptorSetBinding *desc, |
| 1091 | +int ff_vk_add_descriptor_set(AVFilterContext *avctx, FFVulkanPipeline *pl, |
| 1092 | + FFSPIRVShader *shd, FFVulkanDescriptorSetBinding *desc, |
| 1048 | 1093 | int num, int only_print_to_shader) |
| 1049 | 1094 | { |
| 1050 | 1095 | VkResult ret; |
| 1051 | 1096 | VkDescriptorSetLayout *layout; |
| 1052 | | − VulkanFilterContext *s = avctx->priv; |
| 1097 | + FFVulkanContext *s = avctx->priv; |
| 1053 | 1098 | FFVulkanFunctions *vk = &s->vkfn; |
| 1054 | 1099 | |
| 1055 | 1100 | if (only_print_to_shader) |
| 1056 | 1101 | goto print; |
| 1057 | 1102 | |
| 1058 | 1103 | pl->desc_layout = av_realloc_array(pl->desc_layout, sizeof(*pl->desc_layout), |
| 1059 | | − pl->desc_layout_num + 1); |
| 1104 | + pl->desc_layout_num + pl->qf->nb_queues); |
| 1060 | 1105 | if (!pl->desc_layout) |
| 1061 | 1106 | return AVERROR(ENOMEM); |
| 1062 | 1107 | |
| 1063 | 1108 | layout = &pl->desc_layout[pl->desc_layout_num]; |
| 1064 | | − memset(layout, 0, sizeof(*layout)); |
| 1065 | 1109 | |
| 1066 | 1110 | { /* Create descriptor set layout descriptions */ |
| 1067 | 1111 | VkDescriptorSetLayoutCreateInfo desc_create_layout = { 0 }; |
| @@ -1076,21 +1120,27 @@ int ff_vk_add_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl, · 8 unmodified lines |
| 1076 | 1120 | desc_binding[i].descriptorType = desc[i].type; |
| 1077 | 1121 | desc_binding[i].descriptorCount = FFMAX(desc[i].elems, 1); |
| 1078 | 1122 | desc_binding[i].stageFlags = desc[i].stages; |
| 1079 | | − desc_binding[i].pImmutableSamplers = desc[i].samplers; |
| 1123 | + desc_binding[i].pImmutableSamplers = desc[i].sampler ? |
| 1124 | + desc[i].sampler->sampler : |
| 1125 | + NULL; |
| 1080 | 1126 | } |
| 1081 | 1127 | |
| 1082 | 1128 | desc_create_layout.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; |
| 1083 | 1129 | desc_create_layout.pBindings = desc_binding; |
| 1084 | 1130 | desc_create_layout.bindingCount = num; |
| 1085 | 1131 | |
| 1086 | | − ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev, &desc_create_layout, |
| 1087 | | − s->hwctx->alloc, layout); |
| 1088 | | − av_free(desc_binding); |
| 1089 | | − if (ret != VK_SUCCESS) { |
| 1090 | | − av_log(avctx, AV_LOG_ERROR, "Unable to init descriptor set " |
| 1091 | | − "layout: %s\n", ff_vk_ret2str(ret)); |
| 1092 | | − return AVERROR_EXTERNAL; |
| 1132 | + for (int i = 0; i < pl->qf->nb_queues; i++) { |
| 1133 | + ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev, &desc_create_layout, |
| 1134 | + s->hwctx->alloc, &layout[i]); |
| 1135 | + if (ret != VK_SUCCESS) { |
| 1136 | + av_log(avctx, AV_LOG_ERROR, "Unable to init descriptor set " |
| 1137 | + "layout: %s\n", ff_vk_ret2str(ret)); |
| 1138 | + av_free(desc_binding); |
| 1139 | + return AVERROR_EXTERNAL; |
| 1140 | + } |
| 1093 | 1141 | } |
| 1142 | + |
| 1143 | + av_free(desc_binding); |
| 1094 | 1144 | } |
| 1095 | 1145 | |
| 1096 | 1146 | { /* Pool each descriptor by type and update pool counts */ |
| @@ -1108,7 +1158,7 @@ int ff_vk_add_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl, · 11 unmodified lines |
| 1108 | 1158 | memset(&pl->pool_size_desc[j], 0, sizeof(VkDescriptorPoolSize)); |
| 1109 | 1159 | } |
| 1110 | 1160 | pl->pool_size_desc[j].type = desc[i].type; |
| 1111 | | − pl->pool_size_desc[j].descriptorCount += FFMAX(desc[i].elems, 1); |
| 1161 | + pl->pool_size_desc[j].descriptorCount += FFMAX(desc[i].elems, 1)*pl->qf->nb_queues; |
| 1112 | 1162 | } |
| 1113 | 1163 | } |
| 1114 | 1164 | |
| @@ -1132,27 +1182,32 @@ int ff_vk_add_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl, · 17 unmodified lines |
| 1132 | 1182 | |
| 1133 | 1183 | pl->desc_template_info = av_realloc_array(pl->desc_template_info, |
| 1134 | 1184 | sizeof(*pl->desc_template_info), |
| 1135 | | − pl->desc_layout_num + 1); |
| 1185 | + pl->total_descriptor_sets + pl->qf->nb_queues); |
| 1136 | 1186 | if (!pl->desc_template_info) |
| 1137 | 1187 | return AVERROR(ENOMEM); |
| 1138 | 1188 | |
| 1139 | | − dt = &pl->desc_template_info[pl->desc_layout_num]; |
| 1140 | | − memset(dt, 0, sizeof(*dt)); |
| 1189 | + dt = &pl->desc_template_info[pl->total_descriptor_sets]; |
| 1190 | + memset(dt, 0, sizeof(*dt)*pl->qf->nb_queues); |
| 1141 | 1191 | |
| 1142 | | − dt->sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO; |
| 1143 | | − dt->templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET; |
| 1144 | | − dt->descriptorSetLayout = *layout; |
| 1145 | | − dt->pDescriptorUpdateEntries = des_entries; |
| 1146 | | − dt->descriptorUpdateEntryCount = num; |
| 1192 | + for (int i = 0; i < pl->qf->nb_queues; i++) { |
| 1193 | + dt[i].sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO; |
| 1194 | + dt[i].templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET; |
| 1195 | + dt[i].descriptorSetLayout = layout[i]; |
| 1196 | + dt[i].pDescriptorUpdateEntries = des_entries; |
| 1197 | + dt[i].descriptorUpdateEntryCount = num; |
| 1198 | + } |
| 1147 | 1199 | } |
| 1148 | 1200 | |
| 1149 | | − pl->desc_layout_num++; |
| 1201 | + pl->descriptor_sets_num++; |
| 1202 | + |
| 1203 | + pl->desc_layout_num += pl->qf->nb_queues; |
| 1204 | + pl->total_descriptor_sets += pl->qf->nb_queues; |
| 1150 | 1205 | |
| 1151 | 1206 | print: |
| 1152 | 1207 | /* Write shader info */ |
| 1153 | 1208 | for (int i = 0; i < num; i++) { |
| 1154 | 1209 | const struct descriptor_props *prop = &descriptor_props[desc[i].type]; |
| 1155 | | − GLSLA("layout (set = %i, binding = %i", pl->desc_layout_num - 1, i); |
| 1210 | + GLSLA("layout (set = %i, binding = %i", pl->descriptor_sets_num - 1, i); |
| 1156 | 1211 | |
| 1157 | 1212 | if (desc[i].mem_layout) |
| 1158 | 1213 | GLSLA(", %s", desc[i].mem_layout); |
| @@ -1184,12 +1239,14 @@ print: · 25 unmodified lines |
| 1184 | 1239 | return 0; |
| 1185 | 1240 | } |
| 1186 | 1241 | |
| 1187 | | −void ff_vk_update_descriptor_set(AVFilterContext *avctx, VulkanPipeline *pl, |
| 1242 | +void ff_vk_update_descriptor_set(AVFilterContext *avctx, FFVulkanPipeline *pl, |
| 1188 | 1243 | int set_id) |
| 1189 | 1244 | { |
| 1190 | | − VulkanFilterContext *s = avctx->priv; |
| 1245 | + FFVulkanContext *s = avctx->priv; |
| 1191 | 1246 | FFVulkanFunctions *vk = &s->vkfn; |
| 1192 | 1247 | |
| 1248 | + set_id = set_id*pl->qf->nb_queues + pl->qf->cur_queue; |
| 1249 | + |
| 1193 | 1250 | vk->UpdateDescriptorSetWithTemplate(s->hwctx->act_dev, |
| 1194 | 1251 | pl->desc_set[set_id], |
| 1195 | 1252 | pl->desc_template[set_id], |
| @@ -1200,27 +1257,29 @@ void ff_vk_update_push_exec(AVFilterContext *avctx, FFVkExecContext *e, · 4 unmodified lines |
| 1200 | 1257 | VkShaderStageFlagBits stage, int offset, |
| 1201 | 1258 | size_t size, void *src) |
| 1202 | 1259 | { |
| 1203 | | − VulkanFilterContext *s = avctx->priv; |
| 1260 | + FFVulkanContext *s = avctx->priv; |
| 1204 | 1261 | FFVulkanFunctions *vk = &s->vkfn; |
| 1205 | 1262 | |
| 1206 | | − vk->CmdPushConstants(e->bufs[s->cur_queue_idx], e->bound_pl->pipeline_layout, |
| 1263 | + vk->CmdPushConstants(e->bufs[e->qf->cur_queue], e->bound_pl->pipeline_layout, |
| 1207 | 1264 | stage, offset, size, src); |
| 1208 | 1265 | } |
| 1209 | 1266 | |
| 1210 | | −int ff_vk_init_pipeline_layout(AVFilterContext *avctx, VulkanPipeline *pl) |
| 1267 | +int ff_vk_init_pipeline_layout(AVFilterContext *avctx, FFVulkanPipeline *pl) |
| 1211 | 1268 | { |
| 1212 | 1269 | VkResult ret; |
| 1213 | | − VulkanFilterContext *s = avctx->priv; |
| 1270 | + FFVulkanContext *s = avctx->priv; |
| 1214 | 1271 | FFVulkanFunctions *vk = &s->vkfn; |
| 1215 | 1272 | |
| 1216 | | − pl->descriptor_sets_num = pl->desc_layout_num * s->queue_count; |
| 1273 | + pl->desc_staging = av_malloc(pl->descriptor_sets_num*sizeof(*pl->desc_staging)); |
| 1274 | + if (!pl->desc_staging) |
| 1275 | + return AVERROR(ENOMEM); |
| 1217 | 1276 | |
| 1218 | 1277 | { /* Init descriptor set pool */ |
| 1219 | 1278 | VkDescriptorPoolCreateInfo pool_create_info = { |
| 1220 | 1279 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, |
| 1221 | 1280 | .poolSizeCount = pl->pool_size_desc_num, |
| 1222 | 1281 | .pPoolSizes = pl->pool_size_desc, |
| 1223 | | − .maxSets = pl->descriptor_sets_num, |
| 1282 | + .maxSets = pl->total_descriptor_sets, |
| 1224 | 1283 | }; |
| 1225 | 1284 | |
| 1226 | 1285 | ret = vk->CreateDescriptorPool(s->hwctx->act_dev, &pool_create_info, |
| @@ -1237,11 +1296,11 @@ int ff_vk_init_pipeline_layout(AVFilterContext *avctx, VulkanPipeline *pl) · 10 unmodified lines |
| 1237 | 1296 | VkDescriptorSetAllocateInfo alloc_info = { |
| 1238 | 1297 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, |
| 1239 | 1298 | .descriptorPool = pl->desc_pool, |
| 1240 | | − .descriptorSetCount = pl->descriptor_sets_num, |
| 1299 | + .descriptorSetCount = pl->total_descriptor_sets, |
| 1241 | 1300 | .pSetLayouts = pl->desc_layout, |
| 1242 | 1301 | }; |
| 1243 | 1302 | |
| 1244 | | − pl->desc_set = av_malloc(pl->descriptor_sets_num*sizeof(*pl->desc_set)); |
| 1303 | + pl->desc_set = av_malloc(pl->total_descriptor_sets*sizeof(*pl->desc_set)); |
| 1245 | 1304 | if (!pl->desc_set) |
| 1246 | 1305 | return AVERROR(ENOMEM); |
| 1247 | 1306 | |
| @@ -1257,12 +1316,14 @@ int ff_vk_init_pipeline_layout(AVFilterContext *avctx, VulkanPipeline *pl) · 9 unmodified lines |
| 1257 | 1316 | { /* Finally create the pipeline layout */ |
| 1258 | 1317 | VkPipelineLayoutCreateInfo spawn_pipeline_layout = { |
| 1259 | 1318 | .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, |
| 1260 | | − .setLayoutCount = pl->desc_layout_num, |
| 1261 | | − .pSetLayouts = pl->desc_layout, |
| 1319 | + .pSetLayouts = (VkDescriptorSetLayout *)pl->desc_staging, |
| 1262 | 1320 | .pushConstantRangeCount = pl->push_consts_num, |
| 1263 | 1321 | .pPushConstantRanges = pl->push_consts, |
| 1264 | 1322 | }; |
| 1265 | 1323 | |
| 1324 | + for (int i = 0; i < pl->total_descriptor_sets; i += pl->qf->nb_queues) |
| 1325 | + pl->desc_staging[spawn_pipeline_layout.setLayoutCount++] = pl->desc_layout[i]; |
| 1326 | + |
| 1266 | 1327 | ret = vk->CreatePipelineLayout(s->hwctx->act_dev, &spawn_pipeline_layout, |
| 1267 | 1328 | s->hwctx->alloc, &pl->pipeline_layout); |
| 1268 | 1329 | av_freep(&pl->push_consts); |
| @@ -1275,21 +1336,19 @@ int ff_vk_init_pipeline_layout(AVFilterContext *avctx, VulkanPipeline *pl) · 6 unmodified lines |
| 1275 | 1336 | } |
| 1276 | 1337 | |
| 1277 | 1338 | { /* Descriptor template (for tightly packed descriptors) */ |
| 1278 | | − VkDescriptorUpdateTemplateCreateInfo *desc_template_info; |
| 1339 | + VkDescriptorUpdateTemplateCreateInfo *dt; |
| 1279 | 1340 | |
| 1280 | | − pl->desc_template = av_malloc(pl->descriptor_sets_num*sizeof(*pl->desc_template)); |
| 1341 | + pl->desc_template = av_malloc(pl->total_descriptor_sets*sizeof(*pl->desc_template)); |
| 1281 | 1342 | if (!pl->desc_template) |
| 1282 | 1343 | return AVERROR(ENOMEM); |
| 1283 | 1344 | |
| 1284 | 1345 | /* Create update templates for the descriptor sets */ |
| 1285 | | − for (int i = 0; i < pl->descriptor_sets_num; i++) { |
| 1286 | | − desc_template_info = &pl->desc_template_info[i % pl->desc_layout_num]; |
| 1287 | | − desc_template_info->pipelineLayout = pl->pipeline_layout; |
| 1346 | + for (int i = 0; i < pl->total_descriptor_sets; i++) { |
| 1347 | + dt = &pl->desc_template_info[i]; |
| 1348 | + dt->pipelineLayout = pl->pipeline_layout; |
| 1288 | 1349 | ret = vk->CreateDescriptorUpdateTemplate(s->hwctx->act_dev, |
| 1289 | | − desc_template_info, |
| 1290 | | − s->hwctx->alloc, |
| 1350 | + dt, s->hwctx->alloc, |
| 1291 | 1351 | &pl->desc_template[i]); |
| 1292 | | − av_free((void *)desc_template_info->pDescriptorUpdateEntries); |
| 1293 | 1352 | if (ret != VK_SUCCESS) { |
| 1294 | 1353 | av_log(avctx, AV_LOG_ERROR, "Unable to init descriptor " |
| 1295 | 1354 | "template: %s\n", ff_vk_ret2str(ret)); |
| @@ -1297,23 +1356,34 @@ int ff_vk_init_pipeline_layout(AVFilterContext *avctx, VulkanPipeline *pl) · 1 unmodified line |
| 1297 | 1356 | } |
| 1298 | 1357 | } |
| 1299 | 1358 | |
| 1359 | + /* Free the duplicated memory used for the template entries */ |
| 1360 | + for (int i = 0; i < pl->total_descriptor_sets; i += pl->qf->nb_queues) { |
| 1361 | + dt = &pl->desc_template_info[i]; |
| 1362 | + av_free((void *)dt->pDescriptorUpdateEntries); |
| 1363 | + } |
| 1364 | + |
| 1300 | 1365 | av_freep(&pl->desc_template_info); |
| 1301 | 1366 | } |
| 1302 | 1367 | |
| 1303 | 1368 | return 0; |
| 1304 | 1369 | } |
| 1305 | 1370 | |
| 1306 | | −FN_CREATING(VulkanFilterContext, VulkanPipeline, pipeline, pipelines, pipelines_num) |
| 1307 | | −VulkanPipeline *ff_vk_create_pipeline(AVFilterContext *avctx) |
| 1371 | +FN_CREATING(FFVulkanContext, FFVulkanPipeline, pipeline, pipelines, pipelines_num) |
| 1372 | +FFVulkanPipeline *ff_vk_create_pipeline(AVFilterContext *avctx, |
| 1373 | + FFVkQueueFamilyCtx *qf) |
| 1308 | 1374 | { |
| 1309 | | − return create_pipeline(avctx->priv); |
| 1375 | + FFVulkanPipeline *pl = create_pipeline(avctx->priv); |
| 1376 | + if (pl) |
| 1377 | + pl->qf = qf; |
| 1378 | + |
| 1379 | + return pl; |
| 1310 | 1380 | } |
| 1311 | 1381 | |
| 1312 | | −int ff_vk_init_compute_pipeline(AVFilterContext *avctx, VulkanPipeline *pl) |
| 1382 | +int ff_vk_init_compute_pipeline(AVFilterContext *avctx, FFVulkanPipeline *pl) |
| 1313 | 1383 | { |
| 1314 | 1384 | int i; |
| 1315 | 1385 | VkResult ret; |
| 1316 | | − VulkanFilterContext *s = avctx->priv; |
| 1386 | + FFVulkanContext *s = avctx->priv; |
| 1317 | 1387 | FFVulkanFunctions *vk = &s->vkfn; |
| 1318 | 1388 | |
| 1319 | 1389 | VkComputePipelineCreateInfo pipe = { |
| @@ -1346,26 +1416,31 @@ int ff_vk_init_compute_pipeline(AVFilterContext *avctx, VulkanPipeline *pl) · 26 unmodified lines |
| 1346 | 1416 | } |
| 1347 | 1417 | |
| 1348 | 1418 | void ff_vk_bind_pipeline_exec(AVFilterContext *avctx, FFVkExecContext *e, |
| 1349 | | − VulkanPipeline *pl) |
| 1419 | + FFVulkanPipeline *pl) |
| 1350 | 1420 | { |
| 1351 | | − VulkanFilterContext *s = avctx->priv; |
| 1421 | + FFVulkanContext *s = avctx->priv; |
| 1352 | 1422 | FFVulkanFunctions *vk = &s->vkfn; |
| 1353 | 1423 | |
| 1354 | | − vk->CmdBindPipeline(e->bufs[s->cur_queue_idx], pl->bind_point, pl->pipeline); |
| 1424 | + vk->CmdBindPipeline(e->bufs[e->qf->cur_queue], pl->bind_point, pl->pipeline); |
| 1355 | 1425 | |
| 1356 | | − vk->CmdBindDescriptorSets(e->bufs[s->cur_queue_idx], pl->bind_point, |
| 1357 | | − pl->pipeline_layout, 0, pl->descriptor_sets_num, |
| 1358 | | − pl->desc_set, 0, 0); |
| 1426 | + for (int i = 0; i < pl->descriptor_sets_num; i++) |
| 1427 | + pl->desc_staging[i] = pl->desc_set[i*pl->qf->nb_queues + pl->qf->cur_queue]; |
| 1428 | + |
| 1429 | + vk->CmdBindDescriptorSets(e->bufs[e->qf->cur_queue], pl->bind_point, |
| 1430 | + pl->pipeline_layout, 0, |
| 1431 | + pl->descriptor_sets_num, |
| 1432 | + (VkDescriptorSet *)pl->desc_staging, |
| 1433 | + 0, NULL); |
| 1359 | 1434 | |
| 1360 | 1435 | e->bound_pl = pl; |
| 1361 | 1436 | } |
| 1362 | 1437 | |
| 1363 | | −static void free_exec_ctx(VulkanFilterContext *s, FFVkExecContext *e) |
| 1438 | +static void free_exec_ctx(FFVulkanContext *s, FFVkExecContext *e) |
| 1364 | 1439 | { |
| 1365 | 1440 | FFVulkanFunctions *vk = &s->vkfn; |
| 1366 | 1441 | |
| 1367 | 1442 | /* Make sure all queues have finished executing */ |
| 1368 | | − for (int i = 0; i < s->queue_count; i++) { |
| 1443 | + for (int i = 0; i < e->qf->nb_queues; i++) { |
| 1369 | 1444 | FFVkQueueCtx *q = &e->queues[i]; |
| 1370 | 1445 | |
| 1371 | 1446 | if (q->fence) { |
| @@ -1389,7 +1464,7 @@ static void free_exec_ctx(VulkanFilterContext *s, FFVkExecContext *e) · 17 unmodified lines |
| 1389 | 1464 | } |
| 1390 | 1465 | |
| 1391 | 1466 | if (e->bufs) |
| 1392 | | − vk->FreeCommandBuffers(s->hwctx->act_dev, e->pool, s->queue_count, e->bufs); |
| 1467 | + vk->FreeCommandBuffers(s->hwctx->act_dev, e->pool, e->qf->nb_queues, e->bufs); |
| 1393 | 1468 | if (e->pool) |
| 1394 | 1469 | vk->DestroyCommandPool(s->hwctx->act_dev, e->pool, s->hwctx->alloc); |
| 1395 | 1470 | |
| @@ -1397,13 +1472,14 @@ static void free_exec_ctx(VulkanFilterContext *s, FFVkExecContext *e) · 1 unmodified line |
| 1397 | 1472 | av_freep(&e->queues); |
| 1398 | 1473 | av_freep(&e->sem_sig); |
| 1399 | 1474 | av_freep(&e->sem_sig_val); |
| 1475 | + av_freep(&e->sem_sig_val_dst); |
| 1400 | 1476 | av_freep(&e->sem_wait); |
| 1401 | 1477 | av_freep(&e->sem_wait_dst); |
| 1402 | 1478 | av_freep(&e->sem_wait_val); |
| 1403 | 1479 | av_free(e); |
| 1404 | 1480 | } |
| 1405 | 1481 | |
| 1406 | | −static void free_pipeline(VulkanFilterContext *s, VulkanPipeline *pl) |
| 1482 | +static void free_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl) |
| 1407 | 1483 | { |
| 1408 | 1484 | FFVulkanFunctions *vk = &s->vkfn; |
| 1409 | 1485 | |
| @@ -1433,6 +1509,7 @@ static void free_pipeline(VulkanFilterContext *s, VulkanPipeline *pl) · 23 unmodified lines |
| 1433 | 1509 | vk->DestroyDescriptorPool(s->hwctx->act_dev, pl->desc_pool, |
| 1434 | 1510 | s->hwctx->alloc); |
| 1435 | 1511 | |
| 1512 | + av_freep(&pl->desc_staging); |
| 1436 | 1513 | av_freep(&pl->desc_set); |
| 1437 | 1514 | av_freep(&pl->shaders); |
| 1438 | 1515 | av_freep(&pl->desc_layout); |
| @@ -1443,8 +1520,10 @@ static void free_pipeline(VulkanFilterContext *s, VulkanPipeline *pl) · 4 unmodified lines |
| 1443 | 1520 | /* Only freed in case of failure */ |
| 1444 | 1521 | av_freep(&pl->pool_size_desc); |
| 1445 | 1522 | if (pl->desc_template_info) { |
| 1446 | | − for (int i = 0; i < pl->descriptor_sets_num; i++) |
| 1447 | | − av_free((void *)pl->desc_template_info[i].pDescriptorUpdateEntries); |
| 1523 | + for (int i = 0; i < pl->total_descriptor_sets; i += pl->qf->nb_queues) { |
| 1524 | + VkDescriptorUpdateTemplateCreateInfo *dt = &pl->desc_template_info[i]; |
| 1525 | + av_free((void *)dt->pDescriptorUpdateEntries); |
| 1526 | + } |
| 1448 | 1527 | av_freep(&pl->desc_template_info); |
| 1449 | 1528 | } |
| 1450 | 1529 | |
| @@ -1453,7 +1532,7 @@ static void free_pipeline(VulkanFilterContext *s, VulkanPipeline *pl) · 2 unmodified lines |
| 1453 | 1532 | |
| 1454 | 1533 | void ff_vk_filter_uninit(AVFilterContext *avctx) |
| 1455 | 1534 | { |
| 1456 | | − VulkanFilterContext *s = avctx->priv; |
| 1535 | + FFVulkanContext *s = avctx->priv; |
| 1457 | 1536 | FFVulkanFunctions *vk = &s->vkfn; |
| 1458 | 1537 | |
| 1459 | 1538 | ff_vk_glslang_uninit(); |
| @@ -1463,7 +1542,8 @@ void ff_vk_filter_uninit(AVFilterContext *avctx) · 3 unmodified lines |
| 1463 | 1542 | av_freep(&s->exec_ctx); |
| 1464 | 1543 | |
| 1465 | 1544 | for (int i = 0; i < s->samplers_num; i++) { |
| 1466 | | − vk->DestroySampler(s->hwctx->act_dev, *s->samplers[i], s->hwctx->alloc); |
| 1545 | + vk->DestroySampler(s->hwctx->act_dev, s->samplers[i]->sampler[0], |
| 1546 | + s->hwctx->alloc); |
| 1467 | 1547 | av_free(s->samplers[i]); |
| 1468 | 1548 | } |
| 1469 | 1549 | av_freep(&s->samplers); |