FFmpeg
Loading...
Searching...
No Matches
ffv1enc_vulkan.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 Lynne <dev@lynne.ee>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "libavutil/mem.h"
22#include "libavutil/vulkan.h"
23
24#include "avcodec.h"
25#include "internal.h"
26#include "hwconfig.h"
27#include "encode.h"
28#include "libavutil/opt.h"
29#include "codec_internal.h"
30
31#include "ffv1.h"
32#include "ffv1enc.h"
33#include "ffv1_vulkan.h"
34#include "vulkan_video.h"
35
36/* Parallel Golomb alignment */
37#define LG_ALIGN_W 32
38#define LG_ALIGN_H 32
39
40/* Unlike the decoder, we need 4 lines (but really only 3) */
41#define RGB_LINECACHE 4
42
51
106
107extern const char *ff_source_common_comp;
108extern const char *ff_source_rangecoder_comp;
109extern const char *ff_source_ffv1_vlc_comp;
110extern const char *ff_source_ffv1_common_comp;
111extern const char *ff_source_ffv1_enc_comp;
112
113extern const unsigned char ff_ffv1_enc_setup_comp_spv_data[];
114extern const unsigned int ff_ffv1_enc_setup_comp_spv_len;
115
116extern const unsigned char ff_ffv1_enc_reset_comp_spv_data[];
117extern const unsigned int ff_ffv1_enc_reset_comp_spv_len;
118
119extern const unsigned char ff_ffv1_enc_reset_golomb_comp_spv_data[];
120extern const unsigned int ff_ffv1_enc_reset_golomb_comp_spv_len;
121
122extern const unsigned char ff_ffv1_enc_comp_spv_data[];
123extern const unsigned int ff_ffv1_enc_comp_spv_len;
124
125extern const unsigned char ff_ffv1_enc_rgb_comp_spv_data[];
126extern const unsigned int ff_ffv1_enc_rgb_comp_spv_len;
127
128extern const unsigned char ff_ffv1_enc_golomb_comp_spv_data[];
129extern const unsigned int ff_ffv1_enc_golomb_comp_spv_len;
130
131extern const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[];
132extern const unsigned int ff_ffv1_enc_rgb_golomb_comp_spv_len;
133
134extern const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[];
135extern const unsigned int ff_ffv1_enc_rct_search_comp_spv_len;
136
137extern const unsigned char ff_ffv1_enc_remap_comp_spv_data[];
138extern const unsigned int ff_ffv1_enc_remap_comp_spv_len;
139
140extern const unsigned char ff_ffv1_enc_rgb_float_comp_spv_data[];
141extern const unsigned int ff_ffv1_enc_rgb_float_comp_spv_len;
142
143extern const unsigned char ff_ffv1_enc_rgb_float_golomb_comp_spv_data[];
144extern const unsigned int ff_ffv1_enc_rgb_float_golomb_comp_spv_len;
145
146extern const unsigned char ff_ffv1_enc_sort32_comp_spv_data[];
147extern const unsigned int ff_ffv1_enc_sort32_comp_spv_len;
148
149extern const unsigned char ff_ffv1_enc_bayer_comp_spv_data[];
150extern const unsigned int ff_ffv1_enc_bayer_comp_spv_len;
151
152extern const unsigned char ff_ffv1_enc_bayer_golomb_comp_spv_data[];
153extern const unsigned int ff_ffv1_enc_bayer_golomb_comp_spv_len;
154
155/* Size output slots with the v4 worst case; v3's ~(2*bits+5) bytes/sample runs
156 * to gigabytes on large frames. The bitstream version is unaffected. */
158{
160 FFV1Context *f = &fv->ctx;
161 int version = f->version;
162 size_t size;
163
164 f->version = 4;
166 f->version = version;
167
168 return size;
169}
170
172 AVFrame *enc_in, VkImageView *enc_in_views,
173 FFVkBuffer *slice_data_buf, uint32_t slice_data_size,
175{
177 FFV1Context *f = &fv->ctx;
178 FFVulkanFunctions *vk = &fv->s.vkfn;
179
180 /* Update descriptors */
182 1, 0, 0,
183 slice_data_buf,
184 0, slice_data_size*f->slice_count,
185 VK_FORMAT_UNDEFINED);
187 enc_in, enc_in_views,
188 1, 1,
189 VK_IMAGE_LAYOUT_GENERAL,
190 VK_NULL_HANDLE);
191
192 ff_vk_exec_bind_shader(&fv->s, exec, &fv->rct_search);
194 VK_SHADER_STAGE_COMPUTE_BIT,
195 0, sizeof(FFv1ShaderParams), pd);
196
197 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
198
199 return 0;
200}
201
202static int run_remap(AVCodecContext *avctx, FFVkExecContext *exec,
203 AVFrame *enc_in, VkImageView *enc_in_views,
204 FFVkBuffer *fltmap_buf, uint32_t fltmap_size,
206{
208 FFV1Context *f = &fv->ctx;
209 FFVulkanFunctions *vk = &fv->s.vkfn;
210
211 /* Update descriptors */
212 ff_vk_shader_update_img_array(&fv->s, exec, &fv->remap,
213 enc_in, enc_in_views,
214 1, 1,
215 VK_IMAGE_LAYOUT_GENERAL,
216 VK_NULL_HANDLE);
217 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->remap,
218 1, 2, 0,
219 fltmap_buf,
220 0, fltmap_size*f->slice_count,
221 VK_FORMAT_UNDEFINED);
222
223 ff_vk_exec_bind_shader(&fv->s, exec, &fv->remap);
224 ff_vk_shader_update_push_const(&fv->s, exec, &fv->remap,
225 VK_SHADER_STAGE_COMPUTE_BIT,
226 0, sizeof(FFv1ShaderParams), pd);
227
228 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
229
230 return 0;
231}
232
234 AVFrame *enc_in, VkImageView *enc_in_views,
235 FFVkBuffer *units_buf, uint32_t units_size,
237{
239 FFV1Context *f = &fv->ctx;
240 FFVulkanFunctions *vk = &fv->s.vkfn;
241
242 /* Update descriptors */
243 ff_vk_shader_update_img_array(&fv->s, exec, &fv->sort32,
244 enc_in, enc_in_views,
245 1, 1,
246 VK_IMAGE_LAYOUT_GENERAL,
247 VK_NULL_HANDLE);
249 1, 2, 0,
250 units_buf,
251 0, units_size*f->slice_count,
252 VK_FORMAT_UNDEFINED);
253
254 ff_vk_exec_bind_shader(&fv->s, exec, &fv->sort32);
255 ff_vk_shader_update_push_const(&fv->s, exec, &fv->sort32,
256 VK_SHADER_STAGE_COMPUTE_BIT,
257 0, sizeof(FFv1ShaderParams), pd);
258
259 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
260
261 return 0;
262}
263
265 FFVkExecContext *exec,
266 AVFrame *pict)
267{
268 int err;
270 FFV1Context *f = &fv->ctx;
271 FFVulkanFunctions *vk = &fv->s.vkfn;
272
274
275 /* Slice data */
276 FFVkBuffer *slice_data_buf;
277 uint32_t plane_state_size;
278 uint32_t slice_state_size;
279 uint32_t slice_data_size;
280
281 /* Remap data */
282 FFVkBuffer *remap_data_buf = NULL;
283 uint32_t remap_data_size = 0;
284
285 /* Output data */
286 size_t maxsize;
287 FFVkBuffer *out_data_buf;
288 FFVkBuffer *compacted_buf;
289
290 int has_inter = avctx->gop_size > 1;
291 uint32_t context_count = f->context_count[f->context_model];
292
293 VkImageMemoryBarrier2 img_bar[37];
294 int nb_img_bar = 0;
295 VkBufferMemoryBarrier2 buf_bar[8];
296 int nb_buf_bar = 0;
297
298 /* Start recording */
299 err = ff_vk_exec_start(&fv->s, exec);
300 if (err < 0)
301 return err;
302
303 /* Frame state */
304 f->cur_enc_frame = pict;
305 if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) {
307 f->key_frame = fd->key_frame = 1;
308 f->gob_count++;
309 } else {
310 f->key_frame = fd->key_frame = 0;
311 }
312
313 f->slice_count = f->max_slice_count;
314
315 /* Allocate slice buffer data */
316 if (f->ac == AC_GOLOMB_RICE)
317 plane_state_size = 8;
318 else
319 plane_state_size = CONTEXT_SIZE;
320
321 plane_state_size *= context_count;
322 slice_state_size = plane_state_size*f->plane_count;
323
324 slice_data_size = 256; /* Overestimation for the SliceContext struct */
325 slice_state_size += slice_data_size;
326 slice_state_size = FFALIGN(slice_state_size, 8);
327
328 /* Allocate slice data buffer */
329 slice_data_buf = fv->keyframe_slice_data_ref ?
331 if (!slice_data_buf) {
333 &slice_data_buf,
334 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
335 NULL, slice_state_size*f->slice_count,
336 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
337
338 /* Only save it if we're going to use it again */
339 if (has_inter)
340 fv->keyframe_slice_data_ref = av_refstruct_ref(slice_data_buf);
341 }
342
343 if (f->remap_mode) {
344 if (fv->is_float32) {
345 /* Per slice: [units : 4*max_pixels*2 uints] + [bitmaps : 4*max_pixels uints]. */
346 remap_data_size = 4*fv->max_pixels_per_slice*3*sizeof(uint32_t);
347 } else {
349 remap_data_size = 4*(1 << desc->comp[0].depth)*sizeof(uint32_t);
350 }
351
353 &remap_data_buf,
354 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
355 NULL, remap_data_size*f->slice_count,
356 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
357 }
358
359 /* Output buffer size */
360 maxsize = ffv1_vk_buffer_size(avctx);
361 maxsize = FFMIN(maxsize, fv->s.props_11.maxMemoryAllocationSize);
362
363 /* Sparse per-slice slots: written by encode, read by gather. */
365 &fd->out_data_ref,
366 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
367 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
368 NULL, maxsize,
369 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT));
370 out_data_buf = fd->out_data_ref;
371
372 /* Contiguous output, read back by the CPU. */
375 VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
377 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
378 fv->s.host_cached_flag));
379 compacted_buf = fd->compacted_data_ref;
380
381 /* Image views */
382 AVFrame *src = pict;
383 VkImageView src_views[AV_NUM_DATA_POINTERS];
384
385 AVFrame *tmp = NULL;
386 VkImageView tmp_views[AV_NUM_DATA_POINTERS];
387 if (fv->is_rgb) {
388 /* Create a temporaty frame */
390 if (!(tmp)) {
391 err = AVERROR(ENOMEM);
392 goto fail;
393 }
394
396 tmp, 0));
397 }
398
399 /* With everything allocated, setup push data */
400 FFv1ShaderParams pd = {
401 .slice_data = out_data_buf->address,
402
403 .img_size[0] = fv->s.frames->width,
404 .img_size[1] = fv->s.frames->height,
405
406 .plane_state_size = plane_state_size,
407 .key_frame = f->key_frame,
408 .crcref = f->crcref,
409 .micro_version = f->micro_version,
410
411 .sar[0] = pict->sample_aspect_ratio.num,
412 .sar[1] = pict->sample_aspect_ratio.den,
413 .pic_mode = !(pict->flags & AV_FRAME_FLAG_INTERLACED) ? 3 :
414 !(pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 2 : 1,
415
416 /* 16-byte aligned so the gather can use wide loads */
417 .slice_size_max = (out_data_buf->size / f->slice_count) & ~(size_t)15,
418 .max_pixels_per_slice = fv->max_pixels_per_slice,
419 };
420
421 for (int i = 0; i < f->quant_table_count; i++) {
422 pd.context_count[i] = f->context_count[i];
423 pd.extend_lookup[i] = f->quant_tables[i][3][127] ||
424 f->quant_tables[i][4][127];
425 }
426
427 /* For some reason the C FFv1 encoder/decoder treats these differently */
428 if (avctx->sw_pix_fmt == AV_PIX_FMT_GBRP10 ||
429 avctx->sw_pix_fmt == AV_PIX_FMT_GBRP12 ||
431 memcpy(pd.fmt_lut, (int [4]) { 2, 1, 0, 3 }, 4*sizeof(int));
432 else
433 ff_vk_set_perm(avctx->sw_pix_fmt, pd.fmt_lut, 1);
434
435 /* For float pixel formats we want the raw bit pattern, not a value
436 * already passed through fp16/fp32 conversion (which can flush
437 * denormals). Use a UINT view in that case. */
438 RET(ff_vk_create_imageviews(&fv->s, exec, src_views, src,
439 f->remap_mode ? FF_VK_REP_UINT
441
444
445 RET(ff_vk_exec_add_dep_frame(&fv->s, exec, src,
446 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
447 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
448 if (fv->is_rgb)
449 RET(ff_vk_exec_add_dep_frame(&fv->s, exec, tmp,
450 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
451 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
452
453 /* Inter frames continue the state the previous frame wrote */
454 if (!f->key_frame)
456 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT);
457 fv->prev_sem = exec->sem;
458 fv->prev_sem_val = exec->sem_value;
459
460 if (fv->optimize_rct || f->remap_mode) {
461 /* Prepare the frame for reading */
462 ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
463 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
464 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
465 VK_ACCESS_SHADER_READ_BIT,
466 VK_IMAGE_LAYOUT_GENERAL,
467 VK_QUEUE_FAMILY_IGNORED);
468
469 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
470 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
471 .pImageMemoryBarriers = img_bar,
472 .imageMemoryBarrierCount = nb_img_bar,
473 });
474 nb_img_bar = 0;
475 }
476
477 /* Run RCT search if needed */
478 if (fv->optimize_rct) {
479 RET(run_rct_search(avctx, exec, src, src_views,
480 slice_data_buf, slice_data_size, &pd));
481
482 /* Make sure the writes are visible to the setup shader */
483 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
484 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
485 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
486 0, slice_data_size*f->slice_count);
487 }
488
489 if (f->remap_mode) {
490 if (fv->is_float32) {
491 RET(run_sort32(avctx, exec, src, src_views,
492 remap_data_buf, remap_data_size, &pd));
493 } else {
494 RET(run_remap(avctx, exec, src, src_views,
495 remap_data_buf, remap_data_size, &pd));
496 }
497
498 /* Make sure the writes are visible to the setup shader */
499 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
500 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
501 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
502 0, remap_data_size*f->slice_count);
503 }
504
505 if (fv->optimize_rct || f->remap_mode) {
506 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
507 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
508 .pBufferMemoryBarriers = buf_bar,
509 .bufferMemoryBarrierCount = nb_buf_bar,
510 });
511 nb_buf_bar = 0;
512 }
513
514 /* Setup shader */
515 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->setup,
516 1, 0, 0,
517 slice_data_buf,
518 0, slice_data_size*f->slice_count,
519 VK_FORMAT_UNDEFINED);
520 /* The remap table is only read in remap mode, but must be a valid buffer */
522 &fv->setup, 1, 1, 0,
523 f->remap_mode ? remap_data_buf : slice_data_buf,
524 0, VK_WHOLE_SIZE,
525 VK_FORMAT_UNDEFINED);
526
527 ff_vk_exec_bind_shader(&fv->s, exec, &fv->setup);
528 ff_vk_shader_update_push_const(&fv->s, exec, &fv->setup,
529 VK_SHADER_STAGE_COMPUTE_BIT,
530 0, sizeof(FFv1ShaderParams), &pd);
531
532 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
533
534 /* Clean up temporary image if needed */
535 if (fv->is_rgb) {
536 AVVkFrame *vkf = (AVVkFrame *)tmp->data[0];
537 vkf->layout[0] = VK_IMAGE_LAYOUT_UNDEFINED;
538 vkf->access[0] = VK_ACCESS_2_NONE;
539
540 RET(ff_vk_create_imageviews(&fv->s, exec, tmp_views,
541 tmp,
543
544 ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
545 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
546 VK_PIPELINE_STAGE_2_CLEAR_BIT,
547 VK_ACCESS_2_TRANSFER_WRITE_BIT,
548 VK_IMAGE_LAYOUT_GENERAL,
549 VK_QUEUE_FAMILY_IGNORED);
550 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
551 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
552 .pImageMemoryBarriers = img_bar,
553 .imageMemoryBarrierCount = nb_img_bar,
554 });
555 nb_img_bar = 0;
556
557 vk->CmdClearColorImage(exec->buf, vkf->img[0], VK_IMAGE_LAYOUT_GENERAL,
558 &((VkClearColorValue) { 0 }),
559 1, &((VkImageSubresourceRange) {
560 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
561 .levelCount = 1,
562 .layerCount = 1,
563 }));
564 }
565
566 /* Run reset shader */
567 if (f->key_frame || fv->force_pcm) {
568 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
569 1, 0, 0,
570 slice_data_buf,
571 0, slice_data_size*f->slice_count,
572 VK_FORMAT_UNDEFINED);
573 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->reset,
574 1, 1, 0,
575 slice_data_buf,
576 f->slice_count*256,
577 VK_WHOLE_SIZE,
578 VK_FORMAT_UNDEFINED);
579
580 ff_vk_exec_bind_shader(&fv->s, exec, &fv->reset);
581 ff_vk_shader_update_push_const(&fv->s, exec, &fv->reset,
582 VK_SHADER_STAGE_COMPUTE_BIT,
583 0, sizeof(FFv1ShaderParams), &pd);
584
585 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices,
586 f->plane_count);
587 }
588
589 /* Sync between reset and encode shaders */
590 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
591 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
592 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
593 0, slice_data_size*f->slice_count);
594
595 /* Setup writes the per-pixel compact_idx (or compact_idx-of-value)
596 * back into the remap buffer; the encode shader reads it. */
597 if (f->remap_mode)
598 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], remap_data_buf,
599 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
600 COMPUTE_SHADER_BIT, SHADER_READ_BIT, NONE_KHR,
601 0, remap_data_size*f->slice_count);
602 if (f->key_frame || fv->force_pcm)
603 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
604 COMPUTE_SHADER_BIT, SHADER_WRITE_BIT, NONE_KHR,
605 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
606 slice_data_size*f->slice_count, VK_WHOLE_SIZE);
607 else
608 ff_vk_buf_barrier(buf_bar[nb_buf_bar++], slice_data_buf,
609 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
610 COMPUTE_SHADER_BIT, SHADER_READ_BIT, SHADER_WRITE_BIT,
611 slice_data_size*f->slice_count, VK_WHOLE_SIZE);
612
613 ff_vk_frame_barrier(&fv->s, exec, src, img_bar, &nb_img_bar,
614 fv->optimize_rct ? VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT :
615 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
616 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
617 VK_ACCESS_SHADER_READ_BIT,
618 VK_IMAGE_LAYOUT_GENERAL,
619 VK_QUEUE_FAMILY_IGNORED);
620
621 if (fv->is_rgb)
622 ff_vk_frame_barrier(&fv->s, exec, tmp, img_bar, &nb_img_bar,
623 VK_PIPELINE_STAGE_2_CLEAR_BIT,
624 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
625 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
626 VK_IMAGE_LAYOUT_GENERAL,
627 VK_QUEUE_FAMILY_IGNORED);
628
629 vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
630 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
631 .pImageMemoryBarriers = img_bar,
632 .imageMemoryBarrierCount = nb_img_bar,
633 .pBufferMemoryBarriers = buf_bar,
634 .bufferMemoryBarrierCount = nb_buf_bar,
635 });
636 nb_img_bar = 0;
637 nb_buf_bar = 0;
638
639 /* Main encode shader */
640 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
641 1, 0, 0,
642 slice_data_buf,
643 0, slice_data_size*f->slice_count,
644 VK_FORMAT_UNDEFINED);
646 &fv->enc, 1, 1, 0,
647 &fv->results_buf,
648 fd->idx*(f->max_slice_count + 1)*sizeof(uint32_t),
649 f->slice_count*sizeof(uint32_t),
650 VK_FORMAT_UNDEFINED);
651 ff_vk_shader_update_desc_buffer(&fv->s, exec, &fv->enc,
652 1, 2, 0,
653 slice_data_buf,
654 f->slice_count*256,
655 VK_WHOLE_SIZE,
656 VK_FORMAT_UNDEFINED);
657 ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
658 src, src_views,
659 1, 3,
660 VK_IMAGE_LAYOUT_GENERAL,
661 VK_NULL_HANDLE);
662 if (fv->is_rgb)
663 ff_vk_shader_update_img_array(&fv->s, exec, &fv->enc,
664 tmp, tmp_views,
665 1, 4,
666 VK_IMAGE_LAYOUT_GENERAL,
667 VK_NULL_HANDLE);
668 if (f->remap_mode)
670 &fv->enc, 1, 5, 0,
671 remap_data_buf,
672 0, remap_data_size*f->slice_count,
673 VK_FORMAT_UNDEFINED);
674
675 ff_vk_exec_bind_shader(&fv->s, exec, &fv->enc);
676 ff_vk_shader_update_push_const(&fv->s, exec, &fv->enc,
677 VK_SHADER_STAGE_COMPUTE_BIT,
678 0, sizeof(FFv1ShaderParams), &pd);
679 vk->CmdDispatch(exec->buf, fv->ctx.num_h_slices, fv->ctx.num_v_slices, 1);
680
681 /* Gather the per-slice slots into the packet buffer, in the same
682 * submission. */
683 RET(ff_vk_seg_gather(&fv->s, exec, &fv->gather,
684 &fv->results_buf, fd->idx*(f->max_slice_count + 1)*sizeof(uint32_t),
685 f->slice_count,
686 out_data_buf, (out_data_buf->size / f->slice_count) & ~(size_t)15,
687 compacted_buf, 0, 0));
688
689 /* Submit */
690 ff_vk_exec_move_dep_refstruct(&fv->s, exec, &slice_data_buf);
691 if (remap_data_buf)
692 ff_vk_exec_move_dep_refstruct(&fv->s, exec, &remap_data_buf);
693 err = ff_vk_exec_submit(&fv->s, exec);
694 if (err < 0) {
696 return err;
697 }
698
699 f->picture_number++;
700
702 return 0;
703
704fail:
705 ff_vk_exec_discard(&fv->s, exec);
707 av_refstruct_unref(&slice_data_buf);
708 av_refstruct_unref(&remap_data_buf);
709
710 return err;
711}
712
713/* Return the gathered-output buffer to its pool when the packet is freed. */
714static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
715{
716 av_refstruct_unref(&opaque);
717}
718
720 AVPacket *pkt)
721{
723 FFV1Context *f = &fv->ctx;
724 FFVulkanFunctions *vk = &fv->s.vkfn;
726
727 FFVkBuffer *compacted_buf = fd->compacted_data_ref;
728
729 /* Make sure the encode + gather submission is done */
730 ff_vk_exec_wait(&fv->s, exec);
731
732 /* Invalidate the packed size if needed */
733 size_t total_off = (fd->idx*(f->max_slice_count + 1) + f->slice_count)*sizeof(uint32_t);
734 if (!(fv->results_buf.flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
735 VkMappedMemoryRange invalidate_data = {
736 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
737 .memory = fv->results_buf.mem,
738 .offset = total_off,
739 .size = sizeof(uint32_t),
740 };
741 vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
742 1, &invalidate_data);
743 }
744
745 pkt->size = AV_RN32(fv->results_buf.mapped_mem + total_off);
746 av_log(avctx, AV_LOG_VERBOSE, "Encoded data: %iMiB\n", pkt->size / (1024*1024));
747
748 /* Invalidate the gathered bitstream if needed */
749 if (!(compacted_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
750 VkMappedMemoryRange invalidate_data = {
751 .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
752 .memory = compacted_buf->mem,
753 .offset = 0,
754 .size = VK_WHOLE_SIZE,
755 };
756 vk->InvalidateMappedMemoryRanges(fv->s.hwctx->act_dev,
757 1, &invalidate_data);
758 }
759
760 memset(compacted_buf->mapped_mem + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
761
762 /* Hand the gathered buffer to the packet with no copy: pkt->buf references
763 * the pooled Vulkan buffer, returned to its pool when the packet is freed. */
764 pkt->buf = av_buffer_create(compacted_buf->mapped_mem, compacted_buf->size,
766 if (!pkt->buf) {
769 return AVERROR(ENOMEM);
770 }
771 fd->compacted_data_ref = NULL; /* ownership passed to pkt->buf */
772 pkt->data = compacted_buf->mapped_mem;
773 pkt->flags |= AV_PKT_FLAG_KEY * fd->key_frame;
774
776
777 return 0;
778}
779
786
788{
790 ff_vk_encode_loop_flush(avctx, &fv->loop);
791 fv->ctx.picture_number = 0;
792}
793
794static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
795{
796 int err;
798 FFV1Context *f = &fv->ctx;
799 AVHWFramesContext *frames_ctx;
800 AVVulkanFramesContext *vk_frames;
801
804 return AVERROR(ENOMEM);
805
807 frames_ctx->format = AV_PIX_FMT_VULKAN;
808 frames_ctx->sw_format = sw_format;
809 frames_ctx->width = fv->s.frames->width;
810 frames_ctx->height = f->num_v_slices*RGB_LINECACHE;
811
812 vk_frames = frames_ctx->hwctx;
813 vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
814 vk_frames->usage = VK_IMAGE_USAGE_STORAGE_BIT |
815 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
816 vk_frames->img_flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
817
819 if (err < 0) {
820 av_log(avctx, AV_LOG_ERROR, "Unable to initialize frame pool with format %s: %s\n",
821 av_get_pix_fmt_name(sw_format), av_err2str(err));
823 return err;
824 }
825
826 return 0;
827}
828
829static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
830{
831 int err;
833 FFVulkanShader *shd = &fv->rct_search;
834
835 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
836 (uint32_t []) { 32, 32, 1 }, 0);
837
839 VK_SHADER_STAGE_COMPUTE_BIT);
840
841 const FFVulkanDescriptorSetBinding desc_set_const[] = {
842 { /* rangecoder_buf */
843 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
844 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
845 },
846 };
847 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
848
849 const FFVulkanDescriptorSetBinding desc_set[] = {
850 { /* slice_data_buf */
851 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
852 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
853 },
854 { /* src */
855 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
856 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
858 },
859 };
860 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
861
862 RET(ff_vk_shader_link(&fv->s, shd,
865
866 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
867
868fail:
869 return err;
870}
871
872static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
873{
874 int err;
876 FFVulkanShader *shd = &fv->sort32;
877
878 uint32_t wg_x = FFMIN3(fv->max_pixels_per_slice, 1024,
879 fv->s.props.properties.limits.maxComputeWorkGroupSize[0]);
880 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
881 (uint32_t []) { wg_x, 1, 1 }, 0);
882
884 VK_SHADER_STAGE_COMPUTE_BIT);
885
886 const FFVulkanDescriptorSetBinding desc_set_const[] = {
887 { /* rangecoder_buf */
888 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
889 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
890 },
891 };
892 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
893
894 const FFVulkanDescriptorSetBinding desc_set[] = {
895 { /* slice_data_buf */
896 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
897 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
898 },
899 { /* src */
900 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
901 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
903 },
904 { /* units */
905 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
906 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
907 },
908 };
909 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
910
911 RET(ff_vk_shader_link(&fv->s, shd,
914
915 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
916
917fail:
918 return err;
919}
920
921static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
922{
923 int err;
925 FFVulkanShader *shd = &fv->remap;
926
927 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
928 (uint32_t []) { 32, 32, 1 }, 0);
929
931 VK_SHADER_STAGE_COMPUTE_BIT);
932
933 const FFVulkanDescriptorSetBinding desc_set_const[] = {
934 { /* rangecoder_buf */
935 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
936 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
937 },
938 };
939 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
940
941 const FFVulkanDescriptorSetBinding desc_set[] = {
942 { /* slice_data_buf */
943 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
944 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
945 },
946 { /* src */
947 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
948 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
950 },
951 { /* fltmap */
952 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
953 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
954 },
955 };
956 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 3, 0);
957
958 RET(ff_vk_shader_link(&fv->s, shd,
961
962 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
963
964fail:
965 return err;
966}
967
968static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
969{
970 int err;
972 FFVulkanShader *shd = &fv->setup;
973
974 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
975 (uint32_t []) { 1, 1, 1 }, 0);
976
978 VK_SHADER_STAGE_COMPUTE_BIT);
979
980 const FFVulkanDescriptorSetBinding desc_set_const[] = {
981 { /* rangecoder_buf */
982 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
983 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
984 },
985 };
986 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
987
988 const FFVulkanDescriptorSetBinding desc_set[] = {
989 { /* slice_data_buf */
990 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
991 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
992 },
993 { /* fltmap */
994 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
995 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
996 },
997 };
998 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
999
1000 RET(ff_vk_shader_link(&fv->s, shd,
1003
1004 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1005
1006fail:
1007 return err;
1008}
1009
1010static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1011{
1012 int err;
1014 FFVulkanShader *shd = &fv->reset;
1015
1016 int wg_dim = FFMIN(fv->s.props.properties.limits.maxComputeWorkGroupSize[0], 1024);
1017
1018 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1019 (uint32_t []) { wg_dim, 1, 1 }, 0);
1020
1022 VK_SHADER_STAGE_COMPUTE_BIT);
1023
1024 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1025 { /* rangecoder_buf */
1026 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1027 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1028 },
1029 };
1030 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 1, 1);
1031
1032 const FFVulkanDescriptorSetBinding desc_set[] = {
1033 { /* slice_data_buf */
1034 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1035 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1036 },
1037 { /* slice_state_buf */
1038 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1039 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1040 },
1041 };
1042 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set, 2, 0);
1043
1044 if (fv->ctx.ac == AC_GOLOMB_RICE)
1045 RET(ff_vk_shader_link(&fv->s, shd,
1048 else
1049 RET(ff_vk_shader_link(&fv->s, shd,
1052
1053 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1054
1055fail:
1056 return err;
1057}
1058
1059static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
1060{
1061 int err;
1063 FFV1Context *f = &fv->ctx;
1064 FFVulkanShader *shd = &fv->enc;
1065
1066 uint32_t wg_x = fv->ctx.ac != AC_GOLOMB_RICE ? CONTEXT_SIZE : 1;
1067 ff_vk_shader_load(shd, VK_SHADER_STAGE_COMPUTE_BIT, sl,
1068 (uint32_t []) { wg_x, 1, 1 }, 0);
1069
1071 VK_SHADER_STAGE_COMPUTE_BIT);
1072
1073 const FFVulkanDescriptorSetBinding desc_set_const[] = {
1074 { /* rangecoder_buf */
1075 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1076 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1077 },
1078 { /* quant_buf */
1079 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1080 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1081 },
1082 { /* crc_ieee_buf */
1083 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
1084 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1085 },
1086 };
1087 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set_const, 3, 1);
1088
1089 const FFVulkanDescriptorSetBinding desc_set[] = {
1090 { /* slice_data_buf */
1091 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1092 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1093 },
1094 { /* slice_results_buf */
1095 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1096 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1097 },
1098 { /* slice_state_buf */
1099 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1100 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1101 },
1102 { /* src */
1103 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1104 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1106 },
1107 { /* tmp */
1108 .type = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
1109 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1110 },
1111 { /* fltmap */
1112 .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
1113 .stages = VK_SHADER_STAGE_COMPUTE_BIT,
1114 },
1115 };
1116 ff_vk_shader_add_descriptor_set(&fv->s, shd, desc_set,
1117 4 + fv->is_rgb + !!f->remap_mode, 0);
1118
1119 if (f->bayer) {
1120 if (fv->ctx.ac == AC_GOLOMB_RICE)
1121 ff_vk_shader_link(&fv->s, shd,
1124 else
1125 ff_vk_shader_link(&fv->s, shd,
1128 } else if (f->remap_mode) {
1129 if (fv->ctx.ac == AC_GOLOMB_RICE)
1130 ff_vk_shader_link(&fv->s, shd,
1133 else
1134 ff_vk_shader_link(&fv->s, shd,
1137 } else if (fv->ctx.ac == AC_GOLOMB_RICE) {
1138 if (fv->is_rgb)
1139 ff_vk_shader_link(&fv->s, shd,
1142 else
1143 ff_vk_shader_link(&fv->s, shd,
1146 } else {
1147 if (fv->is_rgb)
1148 ff_vk_shader_link(&fv->s, shd,
1151 else
1152 ff_vk_shader_link(&fv->s, shd,
1154 ff_ffv1_enc_comp_spv_len, "main");
1155 }
1156
1157 RET(ff_vk_shader_register_exec(&fv->s, &fv->exec_pool, shd));
1158
1159fail:
1160 return err;
1161}
1162
1164{
1165 int err;
1166 size_t maxsize;
1168 FFV1Context *f = &fv->ctx;
1169
1170 if ((err = ff_ffv1_common_init(avctx, f)) < 0)
1171 return err;
1172
1173 if (f->ac == 1)
1174 f->ac = AC_RANGE_CUSTOM_TAB;
1175
1176 err = ff_ffv1_encode_setup_plane_info(avctx, avctx->sw_pix_fmt);
1177 if (err < 0)
1178 return err;
1179
1180 /* Target version 3 by default; Bayer is a version 4 feature (the legacy
1181 * v3 bits-per-plane increment would mismatch the shaders' c_bits-1). */
1182 f->version = f->bayer ? 4 : 3;
1183
1184 err = ff_ffv1_encode_init(avctx);
1185 if (err < 0)
1186 return err;
1187
1188 /* Rice coding did not support high bit depths */
1189 if (f->bits_per_raw_sample > (f->version > 3 ? 16 : 8)) {
1190 if (f->ac == AC_GOLOMB_RICE) {
1191 av_log(avctx, AV_LOG_WARNING, "bits_per_raw_sample > 8, "
1192 "forcing range coder\n");
1193 f->ac = AC_RANGE_CUSTOM_TAB;
1194 }
1195 }
1196
1197 if (f->version < 4 && avctx->gop_size > 1) {
1198 av_log(avctx, AV_LOG_ERROR, "Using inter frames requires version 4 (-level 4)\n");
1199 return AVERROR_INVALIDDATA;
1200 }
1201
1202 if (f->version == 4 && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) {
1203 av_log(avctx, AV_LOG_ERROR, "Version 4 is experimental and requires -strict -2\n");
1204 return AVERROR_INVALIDDATA;
1205 }
1206
1207 /* We target version 4.3 by default, remap is 4.9, Bayer is 4.10 */
1208 if (f->version == 4)
1209 f->micro_version = f->bayer ? 10 : (f->remap_mode ? 9 : 3);
1210
1211 f->num_h_slices = fv->num_h_slices;
1212 f->num_v_slices = fv->num_v_slices;
1213
1214 if (f->num_h_slices <= 0 && f->num_v_slices <= 0) {
1215 if (avctx->slices) {
1217 if (err < 0)
1218 return err;
1219 } else {
1220 f->num_h_slices = 32;
1221 f->num_v_slices = 32;
1222 }
1223 } else if (f->num_h_slices && f->num_v_slices <= 0) {
1224 f->num_v_slices = MAX_SLICES / f->num_h_slices;
1225 } else if (f->num_v_slices && f->num_h_slices <= 0) {
1226 f->num_h_slices = MAX_SLICES / f->num_v_slices;
1227 }
1228
1229 f->num_h_slices = FFMIN(f->num_h_slices, avctx->width);
1230 f->num_v_slices = FFMIN(f->num_v_slices, avctx->height);
1231
1232 if (f->num_h_slices * f->num_v_slices > MAX_SLICES) {
1233 av_log(avctx, AV_LOG_ERROR, "Too many slices (%i), maximum supported "
1234 "by the standard is %i\n",
1235 f->num_h_slices * f->num_v_slices, MAX_SLICES);
1236 return AVERROR_PATCHWELCOME;
1237 }
1238
1239 f->max_slice_count = f->num_h_slices * f->num_v_slices;
1240
1241 if ((err = ff_ffv1_write_extradata(avctx)) < 0)
1242 return err;
1243
1244 if (f->version < 4) {
1245 if (((f->chroma_h_shift > 0) && (avctx->width % (64 << f->chroma_h_shift))) ||
1246 ((f->chroma_v_shift > 0) && (avctx->height % (64 << f->chroma_v_shift)))) {
1247 av_log(avctx, AV_LOG_ERROR, "Encoding frames with subsampling and unaligned "
1248 "dimensions is only supported in version 4 (-level 4)\n");
1249 return AVERROR_PATCHWELCOME;
1250 }
1251 }
1252
1253 if (fv->force_pcm) {
1254 if (f->version < 4) {
1255 av_log(avctx, AV_LOG_ERROR, "PCM coding only supported by version 4 (-level 4)\n");
1256 return AVERROR_INVALIDDATA;
1257 } else if (f->ac == AC_GOLOMB_RICE) {
1258 av_log(avctx, AV_LOG_ERROR, "PCM coding requires range coding\n");
1259 return AVERROR_INVALIDDATA;
1260 }
1261 }
1262
1263 /* Init Vulkan */
1264 err = ff_vk_init(&fv->s, avctx, NULL, avctx->hw_frames_ctx);
1265 if (err < 0)
1266 return err;
1267
1268 fv->qf = ff_vk_qf_find(&fv->s, VK_QUEUE_COMPUTE_BIT, 0);
1269 if (!fv->qf) {
1270 av_log(avctx, AV_LOG_ERROR, "Device has no compute queues!\n");
1271 return err;
1272 }
1273
1274 maxsize = ffv1_vk_buffer_size(avctx);
1275 if (maxsize > fv->s.props_11.maxMemoryAllocationSize) {
1276 av_log(avctx, AV_LOG_WARNING, "Encoding buffer size (%zu) larger "
1277 "than maximum device allocation (%"PRIu64"), clipping\n",
1278 maxsize, fv->s.props_11.maxMemoryAllocationSize);
1279 maxsize = fv->s.props_11.maxMemoryAllocationSize;
1280 }
1281
1282 av_log(avctx, AV_LOG_INFO, "Async buffers: %zuMiB per context, %zuMiB total, depth: %i\n",
1283 2*maxsize / (1024*1024),
1284 (fv->async_depth * 2*maxsize) / (1024*1024),
1285 fv->async_depth);
1286
1287 err = ff_vk_exec_pool_init(&fv->s, fv->qf, &fv->exec_pool,
1288 fv->async_depth,
1289 0, 0, 0, NULL);
1290 if (err < 0)
1291 return err;
1292
1293 /* Detect the special RGB coding mode */
1294 fv->is_rgb = !(f->colorspace == 0 && avctx->sw_pix_fmt != AV_PIX_FMT_YA8) &&
1295 !(avctx->sw_pix_fmt == AV_PIX_FMT_YA8);
1296
1297 fv->is_float32 = (avctx->sw_pix_fmt == AV_PIX_FMT_GBRPF32 ||
1299
1300 if (fv->is_float32) {
1301 /* Compute the worst-case slice geometry. With version >= 4 the slice
1302 * boundaries are computed via slice_coord() which rounds up, so any
1303 * single slice has at most ceil(width/num_h_slices) * ceil(height/num_v_slices)
1304 * pixels. */
1305 uint32_t mw = (avctx->width + f->num_h_slices - 1) / f->num_h_slices;
1306 uint32_t mh = (avctx->height + f->num_v_slices - 1) / f->num_v_slices;
1307 /* Round up to next pow2 for bitonic sort */
1308 uint32_t n = 1;
1309 uint32_t pn = mw*mh;
1310 while (n < pn)
1311 n <<= 1;
1312 if (n < 2)
1313 n = 2;
1314 fv->max_pixels_per_slice = n;
1315 }
1316
1317 /* Init rct search shader */
1318 fv->optimize_rct = fv->is_rgb && f->version >= 4 &&
1319 !fv->force_pcm && fv->optimize_rct && !f->bayer;
1320
1321 /* Init shader specialization consts */
1322 SPEC_LIST_CREATE(sl, 19, 19*sizeof(uint32_t))
1323 SPEC_LIST_ADD(sl, 0, 32, RGB_LINECACHE);
1324 SPEC_LIST_ADD(sl, 1, 32, f->ec);
1325 ff_ffv1_vk_set_common_sl(avctx, f, sl, fv->s.frames->sw_format);
1326 SPEC_LIST_ADD(sl, 15, 32, fv->force_pcm);
1327 SPEC_LIST_ADD(sl, 16, 32, fv->optimize_rct);
1328 SPEC_LIST_ADD(sl, 17, 32, f->context_model);
1329 SPEC_LIST_ADD(sl, 18, 32, f->remap_mode);
1330
1331 if (fv->optimize_rct) {
1332 err = init_rct_search_shader(avctx, sl);
1333 if (err < 0)
1334 return err;
1335 }
1336
1337 if (f->remap_mode) {
1338 if (fv->is_float32)
1339 err = init_sort32_shader(avctx, sl);
1340 else
1341 err = init_remap_shader(avctx, sl);
1342 if (err < 0)
1343 return err;
1344 }
1345
1346 /* Init setup shader */
1347 err = init_setup_shader(avctx, sl);
1348 if (err < 0)
1349 return err;
1350
1351 /* Init reset shader */
1352 err = init_reset_shader(avctx, sl);
1353 if (err < 0)
1354 return err;
1355
1356 if (fv->is_rgb)
1357 RET(init_indirect(avctx, fv->ctx.use32bit ?
1359
1360 /* Encode shader */
1361 err = init_encode_shader(avctx, sl);
1362 if (err < 0)
1363 return err;
1364
1365 /* Gather shader */
1366 err = ff_vk_seg_gather_init(&fv->s, &fv->exec_pool, &fv->gather);
1367 if (err < 0)
1368 return err;
1369
1370 /* Constant data */
1371 err = ff_ffv1_vk_init_consts(&fv->s, &fv->consts_buf, f);
1372 if (err < 0)
1373 return err;
1374
1375 /* Update setup global descriptors */
1377 &fv->setup, 0, 0, 0,
1378 &fv->consts_buf,
1379 256*sizeof(uint32_t), 512*sizeof(uint8_t),
1380 VK_FORMAT_UNDEFINED));
1381
1382 /* Update encode global descriptors */
1384 &fv->enc, 0, 0, 0,
1385 &fv->consts_buf,
1386 256*sizeof(uint32_t), 512*sizeof(uint8_t),
1387 VK_FORMAT_UNDEFINED));
1389 &fv->enc, 0, 1, 0,
1390 &fv->consts_buf,
1391 256*sizeof(uint32_t) + 512*sizeof(uint8_t),
1392 VK_WHOLE_SIZE,
1393 VK_FORMAT_UNDEFINED));
1395 &fv->enc, 0, 2, 0,
1396 &fv->consts_buf,
1397 0, 256*sizeof(uint32_t),
1398 VK_FORMAT_UNDEFINED));
1399
1400 RET(ff_vk_encode_loop_init(&fv->s, &fv->exec_pool, &fv->loop,
1402
1403 /* Async data pool */
1405 fv->exec_ctx_info = av_calloc(fv->async_depth, sizeof(*fv->exec_ctx_info));
1406 if (!fv->exec_ctx_info)
1407 return AVERROR(ENOMEM);
1408 for (int i = 0; i < fv->async_depth; i++) {
1411 }
1412
1413 /* Buffers */
1414 RET(ff_vk_create_buf(&fv->s, &fv->results_buf,
1415 fv->async_depth*(f->max_slice_count + 1)*sizeof(uint32_t),
1416 NULL, NULL,
1417 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
1418 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
1419 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT));
1420 RET(ff_vk_map_buffer(&fv->s, &fv->results_buf, NULL, 0));
1421
1422fail:
1423 return err;
1424}
1425
1427{
1429
1430 ff_vk_exec_pool_free(&fv->s, &fv->exec_pool);
1431
1432 ff_vk_shader_free(&fv->s, &fv->enc);
1433 ff_vk_shader_free(&fv->s, &fv->gather);
1434 ff_vk_shader_free(&fv->s, &fv->reset);
1435 ff_vk_shader_free(&fv->s, &fv->setup);
1436 ff_vk_shader_free(&fv->s, &fv->remap);
1437 ff_vk_shader_free(&fv->s, &fv->sort32);
1438 ff_vk_shader_free(&fv->s, &fv->rct_search);
1439
1440 if (fv->exec_ctx_info) {
1441 for (int i = 0; i < fv->async_depth; i++) {
1445 }
1446 }
1448
1450
1453
1457
1458 ff_vk_free_buf(&fv->s, &fv->results_buf);
1459
1460 ff_vk_free_buf(&fv->s, &fv->consts_buf);
1461
1463 ff_vk_uninit(&fv->s);
1464
1465 return 0;
1466}
1467
1468#define OFFSET(x) offsetof(VulkanEncodeFFv1Context, x)
1469#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1471 { "slicecrc", "Protect slices with CRCs", OFFSET(ctx.ec), AV_OPT_TYPE_INT,
1472 { .i64 = -1 }, -1, 2, VE },
1473 { "context", "Context model", OFFSET(ctx.context_model), AV_OPT_TYPE_INT,
1474 { .i64 = 0 }, 0, 1, VE },
1475 { "coder", "Coder type", OFFSET(ctx.ac), AV_OPT_TYPE_INT,
1476 { .i64 = AC_RANGE_CUSTOM_TAB }, -2, 2, VE, .unit = "coder" },
1477 { "rice", "Golomb rice", 0, AV_OPT_TYPE_CONST,
1478 { .i64 = AC_GOLOMB_RICE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1479 { "range_def", "Range with default table", 0, AV_OPT_TYPE_CONST,
1480 { .i64 = AC_RANGE_DEFAULT_TAB_FORCE }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1481 { "range_tab", "Range with custom table", 0, AV_OPT_TYPE_CONST,
1482 { .i64 = AC_RANGE_CUSTOM_TAB }, INT_MIN, INT_MAX, VE, .unit = "coder" },
1483 { "qtable", "Quantization table", OFFSET(ctx.qtable), AV_OPT_TYPE_INT,
1484 { .i64 = -1 }, -1, 2, VE , .unit = "qtable"},
1485 { "default", NULL, 0, AV_OPT_TYPE_CONST,
1486 { .i64 = QTABLE_DEFAULT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1487 { "8bit", NULL, 0, AV_OPT_TYPE_CONST,
1488 { .i64 = QTABLE_8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1489 { "greater8bit", NULL, 0, AV_OPT_TYPE_CONST,
1490 { .i64 = QTABLE_GT8BIT }, INT_MIN, INT_MAX, VE, .unit = "qtable" },
1491
1492 { "slices_h", "Number of horizontal slices", OFFSET(num_h_slices), AV_OPT_TYPE_INT,
1493 { .i64 = -1 }, -1, MAX_SLICES, VE },
1494 { "slices_v", "Number of vertical slices", OFFSET(num_v_slices), AV_OPT_TYPE_INT,
1495 { .i64 = -1 }, -1, MAX_SLICES, VE },
1496
1497 { "force_pcm", "Code all slices with no prediction", OFFSET(force_pcm), AV_OPT_TYPE_BOOL,
1498 { .i64 = 0 }, 0, 1, VE },
1499
1500 { "rct_search", "Run a search for RCT parameters (level 4 only)", OFFSET(optimize_rct), AV_OPT_TYPE_BOOL,
1501 { .i64 = 1 }, 0, 1, VE },
1502
1503 { "async_depth", "Internal parallelization depth", OFFSET(async_depth), AV_OPT_TYPE_INT,
1504 { .i64 = 2 }, 1, INT_MAX, VE },
1505
1506 { "remap_mode", "Remap Mode", OFFSET(ctx.remap_mode), AV_OPT_TYPE_INT,
1507 { .i64 = -1 }, -1, 2, VE, .unit = "remap_mode" },
1508 { "auto", "Automatic", 0, AV_OPT_TYPE_CONST,
1509 { .i64 = -1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1510 { "off", "Disabled", 0, AV_OPT_TYPE_CONST,
1511 { .i64 = 0 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1512 { "dualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1513 { .i64 = 1 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1514 { "flipdualrle", "Dual RLE", 0, AV_OPT_TYPE_CONST,
1515 { .i64 = 2 }, INT_MIN, INT_MAX, VE, .unit = "remap_mode" },
1516
1517 { NULL }
1518};
1519
1521 { "g", "1" },
1522 { NULL },
1523};
1524
1526 .class_name = "ffv1_vulkan",
1527 .item_name = av_default_item_name,
1529 .version = LIBAVUTIL_VERSION_INT,
1530};
1531
1533 HW_CONFIG_ENCODER_FRAMES(VULKAN, VULKAN),
1534 NULL,
1535};
1536
1538 .p.name = "ffv1_vulkan",
1539 CODEC_LONG_NAME("FFmpeg video codec #1 (Vulkan)"),
1540 .p.type = AVMEDIA_TYPE_VIDEO,
1541 .p.id = AV_CODEC_ID_FFV1,
1542 .priv_data_size = sizeof(VulkanEncodeFFv1Context),
1545 .flush = &vulkan_encode_ffv1_flush,
1546 .close = &vulkan_encode_ffv1_close,
1547 .p.priv_class = &vulkan_encode_ffv1_class,
1548 .p.capabilities = AV_CODEC_CAP_DELAY |
1553 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1554 .defaults = vulkan_encode_ffv1_defaults,
1556 .hw_configs = vulkan_encode_ffv1_hw_configs,
1557 .p.wrapper_name = "vulkan",
1558};
const FFCodec ff_ffv1_vulkan_encoder
#define VE
Definition amfenc_av1.c:30
static AVFormatContext * ctx
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define CODEC_PIXFMTS(...)
#define FF_CODEC_RECEIVE_PACKET_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define NULL
Definition coverity.c:32
#define MAX_SLICES
#define FF_COMPLIANCE_EXPERIMENTAL
Allow nonstandardized experimental things.
Definition defs.h:62
static AVPacket * pkt
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
av_cold int ff_ffv1_common_init(AVCodecContext *avctx, FFV1Context *s)
Definition ffv1.c:36
FF Video Codec 1 (a lossless codec)
#define CONTEXT_SIZE
Definition ffv1.h:45
#define AC_GOLOMB_RICE
Definition ffv1.h:52
#define AC_RANGE_DEFAULT_TAB_FORCE
Definition ffv1.h:55
#define AC_RANGE_CUSTOM_TAB
Definition ffv1.h:54
int ff_ffv1_vk_init_consts(FFVulkanContext *s, FFVkBuffer *vkb, FFV1Context *f)
Definition ffv1_vulkan.c:85
void ff_ffv1_vk_set_common_sl(AVCodecContext *avctx, FFV1Context *f, VkSpecializationInfo *sl, enum AVPixelFormat sw_format)
Definition ffv1_vulkan.c:24
int ff_ffv1_encode_determine_slices(AVCodecContext *avctx)
Definition ffv1enc.c:570
av_cold int ff_ffv1_encode_init(AVCodecContext *avctx)
Definition ffv1enc.c:605
size_t ff_ffv1_encode_buffer_size(AVCodecContext *avctx)
Definition ffv1enc.c:1863
av_cold int ff_ffv1_encode_setup_plane_info(AVCodecContext *avctx, enum AVPixelFormat pix_fmt)
Definition ffv1enc.c:807
av_cold int ff_ffv1_write_extradata(AVCodecContext *avctx)
Definition ffv1enc.c:447
@ QTABLE_DEFAULT
Definition ffv1enc.h:29
@ QTABLE_8BIT
Definition ffv1enc.h:30
@ QTABLE_GT8BIT
Definition ffv1enc.h:31
static int run_remap(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, FFVkBuffer *fltmap_buf, uint32_t fltmap_size, FFv1ShaderParams *pd)
static int vulkan_encode_ffv1_submit_frame(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *pict)
const char * ff_source_ffv1_enc_comp
const unsigned char ff_ffv1_enc_reset_comp_spv_data[]
static const FFCodecDefault vulkan_encode_ffv1_defaults[]
const unsigned int ff_ffv1_enc_sort32_comp_spv_len
static int init_reset_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
static int get_packet(AVCodecContext *avctx, FFVkExecContext *exec, AVPacket *pkt)
const char * ff_source_rangecoder_comp
const unsigned int ff_ffv1_enc_bayer_comp_spv_len
static int init_sort32_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
static const AVOption vulkan_encode_ffv1_options[]
const char * ff_source_ffv1_common_comp
const unsigned char ff_ffv1_enc_reset_golomb_comp_spv_data[]
const unsigned int ff_ffv1_enc_bayer_golomb_comp_spv_len
const unsigned char ff_ffv1_enc_bayer_comp_spv_data[]
static int init_rct_search_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
static size_t ffv1_vk_buffer_size(AVCodecContext *avctx)
static int init_remap_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
static int run_sort32(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, FFVkBuffer *units_buf, uint32_t units_size, FFv1ShaderParams *pd)
const unsigned int ff_ffv1_enc_reset_comp_spv_len
const unsigned int ff_ffv1_enc_rct_search_comp_spv_len
const unsigned char ff_ffv1_enc_rgb_golomb_comp_spv_data[]
const unsigned int ff_ffv1_enc_rgb_golomb_comp_spv_len
const unsigned int ff_ffv1_enc_remap_comp_spv_len
const char * ff_source_ffv1_vlc_comp
static void ffv1_vk_packet_free(void *opaque, uint8_t *data)
static av_cold int vulkan_encode_ffv1_init(AVCodecContext *avctx)
static int init_encode_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
const unsigned char ff_ffv1_enc_bayer_golomb_comp_spv_data[]
static int init_setup_shader(AVCodecContext *avctx, VkSpecializationInfo *sl)
const unsigned int ff_ffv1_enc_golomb_comp_spv_len
static av_cold int vulkan_encode_ffv1_close(AVCodecContext *avctx)
const unsigned int ff_ffv1_enc_setup_comp_spv_len
const unsigned char ff_ffv1_enc_setup_comp_spv_data[]
const unsigned int ff_ffv1_enc_rgb_float_comp_spv_len
const unsigned char ff_ffv1_enc_remap_comp_spv_data[]
const unsigned int ff_ffv1_enc_comp_spv_len
const unsigned int ff_ffv1_enc_rgb_comp_spv_len
static av_cold void vulkan_encode_ffv1_flush(AVCodecContext *avctx)
#define RGB_LINECACHE
const AVCodecHWConfigInternal *const vulkan_encode_ffv1_hw_configs[]
const unsigned int ff_ffv1_enc_reset_golomb_comp_spv_len
const unsigned char ff_ffv1_enc_rgb_float_golomb_comp_spv_data[]
static int vulkan_encode_ffv1_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
static const AVClass vulkan_encode_ffv1_class
#define OFFSET(x)
const unsigned char ff_ffv1_enc_sort32_comp_spv_data[]
const unsigned char ff_ffv1_enc_rgb_comp_spv_data[]
const unsigned char ff_ffv1_enc_golomb_comp_spv_data[]
const unsigned char ff_ffv1_enc_rgb_float_comp_spv_data[]
static int init_indirect(AVCodecContext *avctx, enum AVPixelFormat sw_format)
const unsigned int ff_ffv1_enc_rgb_float_golomb_comp_spv_len
static int run_rct_search(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *enc_in, VkImageView *enc_in_views, FFVkBuffer *slice_data_buf, uint32_t slice_data_size, FFv1ShaderParams *pd)
const unsigned char ff_ffv1_enc_comp_spv_data[]
const unsigned char ff_ffv1_enc_rct_search_comp_spv_data[]
const char * ff_source_common_comp
#define AV_NUM_DATA_POINTERS
Definition frame.h:480
#define fail
Definition test.h:479
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
Definition opt.h:326
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition codec.h:147
#define AV_CODEC_CAP_ENCODER_FLUSH
This encoder can be flushed using avcodec_flush_buffers().
Definition codec.h:154
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition codec.h:79
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_CAP_HARDWARE
Codec is backed by a hardware implementation.
Definition codec.h:133
@ AV_CODEC_ID_FFV1
Definition codec_id.h:83
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:650
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition buffer.c:140
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition buffer.c:56
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
Definition frame.h:702
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition frame.h:707
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_INFO
Standard information.
Definition log.h:221
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
Definition hwconfig.h:100
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition hwcontext.c:337
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition hwcontext.c:263
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition hwcontext.c:506
#define AV_RN32(p)
common internal api header.
#define av_cold
Definition attributes.h:117
void ff_vk_set_perm(enum AVPixelFormat pix_fmt, int lut[4], int inv)
Since storage images may not be swizzled, we have to do this in the shader itself.
Definition vulkan.c:1715
void ff_vk_shader_update_img_array(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, AVFrame *f, VkImageView *views, int set, int binding, VkImageLayout layout, VkSampler sampler)
Update a descriptor in a buffer with an image array.
Definition vulkan.c:2690
int ff_vk_shader_load(FFVulkanShader *shd, VkPipelineStageFlags stage, VkSpecializationInfo *spec, uint32_t wg_size[3], uint32_t required_subgroup_size)
Initialize a shader object.
Definition vulkan.c:2262
void ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd, const FFVulkanDescriptorSetBinding *desc, int nb, int singular)
Add descriptor to a shader.
Definition vulkan.c:2521
void ff_vk_exec_pool_free(FFVulkanContext *s, FFVkExecPool *pool)
Definition vulkan.c:335
int ff_vk_create_buf(FFVulkanContext *s, FFVkBuffer *buf, size_t size, void *pNext, void *alloc_pNext, VkBufferUsageFlags usage, VkMemoryPropertyFlagBits flags)
Definition vulkan.c:1204
int ff_vk_exec_pool_init(FFVulkanContext *s, AVVulkanDeviceQueueFamily *qf, FFVkExecPool *pool, int nb_contexts, int nb_queries, VkQueryType query_type, int query_64bit, const void *query_create_pnext)
Allocates/frees an execution pool.
Definition vulkan.c:399
void ff_vk_exec_wait(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:649
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size, VkShaderStageFlagBits stage)
Add/update push constants for execution.
Definition vulkan.c:1631
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
Definition vulkan.c:2779
int ff_vk_init(FFVulkanContext *s, void *log_parent, AVBufferRef *device_ref, AVBufferRef *frames_ref)
Initializes the AVClass, in case this context is not used as the main user's context.
Definition vulkan.c:2795
void ff_vk_free_buf(FFVulkanContext *s, FFVkBuffer *buf)
Definition vulkan.c:1418
void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e, AVFrame *pic, VkImageMemoryBarrier2 *bar, int *nb_bar, VkPipelineStageFlags2 src_stage, VkPipelineStageFlags2 dst_stage, VkAccessFlagBits2 new_access, VkImageLayout new_layout, uint32_t new_qf)
Definition vulkan.c:2216
int ff_vk_exec_start(FFVulkanContext *s, FFVkExecContext *e)
Start/submit/wait an execution.
Definition vulkan.c:664
int ff_vk_create_imageviews(FFVulkanContext *s, FFVkExecContext *e, VkImageView views[AV_NUM_DATA_POINTERS], AVFrame *f, enum FFVkShaderRepFormat rep_fmt)
Create an imageview and add it as a dependency to an execution.
Definition vulkan.c:2147
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
Free a shader.
Definition vulkan.c:2757
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Register a shader with an exec pool.
Definition vulkan.c:2555
int ff_vk_exec_submit(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:987
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e, const FFVulkanShader *shd)
Bind a shader.
Definition vulkan.c:2739
void ff_vk_exec_move_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Definition vulkan.c:790
int ff_vk_shader_update_desc_buffer(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, int set, int bind, int elem, FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len, VkFormat fmt)
Update a descriptor in a buffer with a buffer.
Definition vulkan.c:2703
AVVulkanDeviceQueueFamily * ff_vk_qf_find(FFVulkanContext *s, VkQueueFlagBits dev_family, VkVideoCodecOperationFlagBitsKHR vid_ops)
Chooses an appropriate QF.
Definition vulkan.c:320
void ff_vk_exec_add_dep_refstruct(FFVulkanContext *s, FFVkExecContext *e, void *obj)
Execution dependency management.
Definition vulkan.c:783
int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVRefStructPool **buf_pool, FFVkBuffer **buf, VkBufferUsageFlags usage, void *create_pNext, size_t size, VkMemoryPropertyFlagBits mem_props)
Initialize a pool and create AVBufferRefs containing FFVkBuffer.
Definition vulkan.c:1444
void ff_vk_exec_discard(FFVulkanContext *s, FFVkExecContext *e)
Definition vulkan.c:767
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd, const char *spirv, size_t spirv_len, const char *entrypoint)
Link a shader into an executable.
Definition vulkan.c:2425
int ff_vk_exec_add_dep_frame(FFVulkanContext *s, FFVkExecContext *e, AVFrame *f, VkPipelineStageFlagBits2 wait_stage, VkPipelineStageFlagBits2 signal_stage)
Definition vulkan.c:885
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e, FFVulkanShader *shd, VkShaderStageFlagBits stage, int offset, size_t size, void *src)
Update push constant in a shader.
Definition vulkan.c:2729
void ff_vk_exec_add_dep_wait_sem(FFVulkanContext *s, FFVkExecContext *e, VkSemaphore sem, uint64_t val, VkPipelineStageFlagBits2 stage)
Definition vulkan.c:829
version
Definition libkvazaar.c:313
const char * desc
Definition libsvtav1.c:83
#define FFMIN(a, b)
Definition macros.h:49
#define FFALIGN(x, a)
Definition macros.h:78
#define FFMIN3(a, b, c)
Definition macros.h:50
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:370
Memory handling functions.
const char data[16]
Definition mxf.c:149
AVOptions.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3500
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
Definition pixdesc.c:3380
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3460
#define AV_PIX_FMT_GBRPF32
Definition pixfmt.h:584
#define AV_PIX_FMT_GBRP10
Definition pixfmt.h:564
#define AV_PIX_FMT_RGBA128
Definition pixfmt.h:636
#define AV_PIX_FMT_RGBA64
Definition pixfmt.h:535
#define AV_PIX_FMT_GBRP12
Definition pixfmt.h:565
AVPixelFormat
Pixel format.
Definition pixfmt.h:71
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
Definition pixfmt.h:379
@ AV_PIX_FMT_YA8
8 bits gray, 8 bits alpha
Definition pixfmt.h:140
#define AV_PIX_FMT_GBRP14
Definition pixfmt.h:566
#define AV_PIX_FMT_GBRAPF32
Definition pixfmt.h:585
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition refstruct.c:121
void * av_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition refstruct.c:141
static void av_refstruct_pool_uninit(AVRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition refstruct.h:292
A reference to a data buffer.
Definition buffer.h:82
uint8_t * data
The data buffer.
Definition buffer.h:90
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
int width
picture width / height.
Definition avcodec.h:604
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:650
int strict_std_compliance
strictly follow the standard (MPEG-4, ...).
Definition avcodec.h:1376
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition avcodec.h:1472
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition avcodec.h:1021
void * priv_data
Definition avcodec.h:470
int slices
Number of slices.
Definition avcodec.h:1037
This structure describes decoded (raw) audio or video data.
Definition frame.h:479
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition frame.h:723
AVRational sample_aspect_ratio
Sample aspect ratio for the video frame, 0/1 if unknown/unspecified.
Definition frame.h:576
This struct describes a set or pool of "hardware" frames (i.e.
Definition hwcontext.h:118
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition hwcontext.h:200
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
Definition hwcontext.h:153
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition hwcontext.h:213
int width
The allocated dimensions of the frames in this pool.
Definition hwcontext.h:220
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition pixdesc.h:69
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
Definition refstruct.c:184
VkImageLayout layout[AV_NUM_DATA_POINTERS]
VkAccessFlagBits2 access[AV_NUM_DATA_POINTERS]
Updated after every barrier.
VkImage img[AV_NUM_DATA_POINTERS]
Vulkan images to which the memory is bound to.
VkDevice act_dev
Active device.
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
VkImageTiling tiling
Controls the tiling of allocated frames.
VkImageCreateFlags img_flags
Flags to set during image creation.
VkImageUsageFlagBits usage
Defines extra usage of output frames.
int ac
1=range coder <-> 0=golomb rice
Definition ffv1.h:147
int num_v_slices
Definition ffv1.h:176
int num_h_slices
Definition ffv1.h:177
int use32bit
Definition ffv1.h:160
int64_t picture_number
Definition ffv1.h:135
VkDeviceAddress address
Definition vulkan.h:99
size_t size
Definition vulkan.h:98
VkMemoryPropertyFlagBits flags
Definition vulkan.h:97
VkDeviceMemory mem
Definition vulkan.h:96
uint8_t * mapped_mem
Definition vulkan.h:103
Frame loop for compute encoders.
uint32_t idx
Definition vulkan.h:129
void * opaque
Definition vulkan.h:154
uint64_t sem_value
Definition vulkan.h:147
VkSemaphore sem
Definition vulkan.h:146
VkCommandBuffer buf
Definition vulkan.h:142
FFVkExecContext * contexts
Definition vulkan.h:271
int pool_size
Definition vulkan.h:276
AVHWFramesContext * frames
Definition vulkan.h:344
AVVulkanDeviceContext * hwctx
Definition vulkan.h:340
VkMemoryPropertyFlagBits host_cached_flag
Definition vulkan.h:336
VkPhysicalDeviceVulkan11Properties props_11
Definition vulkan.h:299
FFVulkanFunctions vkfn
Definition vulkan.h:296
VkPhysicalDeviceProperties2 props
Definition vulkan.h:298
AVBufferRef * device_ref
Definition vulkan.h:338
uint16_t context_count[8]
Definition ffv1_vulkan.h:37
uint32_t extend_lookup[8]
Definition ffv1_vulkan.h:36
AVRefStructPool * remap_data_pool
FFVkBuffer * keyframe_slice_data_ref
AVRefStructPool * out_data_pool
AVRefStructPool * compacted_data_pool
AVRefStructPool * slice_data_pool
FFVulkanShader rct_search
AVVulkanDeviceQueueFamily * qf
AVBufferRef * intermediate_frames_ref
VulkanEncodeFFv1FrameData * exec_ctx_info
#define av_free(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define src
Definition vp8dsp.c:248
int size
#define mh
#define ff_vk_buf_barrier(dst, vkb, s_stage, s_access, s_access2, d_stage, d_access, d_access2, offs, bsz)
Definition vulkan.h:579
@ FF_VK_REP_UINT
Definition vulkan.h:446
@ FF_VK_REP_NATIVE
Definition vulkan.h:440
#define RET(x)
Definition vulkan.h:37
#define SPEC_LIST_ADD(name, idx, val_bits, val)
Definition vulkan.h:55
#define SPEC_LIST_CREATE(name, max_length, max_size)
Definition vulkan.h:45
static int ff_vk_map_buffer(FFVulkanContext *s, FFVkBuffer *buf, uint8_t **mem, int invalidate)
Definition vulkan.h:646
int ff_vk_encode_loop_receive_packet(AVCodecContext *avctx, FFVkEncodeLoop *l, AVPacket *pkt)
Call from FFCodec.cb.receive_packet; the packet metadata is carried from the submitted frame to its p...
void ff_vk_encode_loop_uninit(FFVkEncodeLoop *l)
void ff_vk_encode_loop_flush(AVCodecContext *avctx, FFVkEncodeLoop *l)
Waits for and discards every frame in flight.
int ff_vk_encode_loop_init(FFVulkanContext *s, FFVkExecPool *pool, FFVkEncodeLoop *l, int(*submit_frame)(AVCodecContext *avctx, FFVkExecContext *exec, AVFrame *frame), int(*get_packet)(AVCodecContext *avctx, FFVkExecContext *exec, AVPacket *pkt))
int ff_vk_seg_gather_init(FFVulkanContext *s, FFVkExecPool *pool, FFVulkanShader *shd)
Packs fixed-stride segment slots back to back into a contiguous buffer.
int ff_vk_seg_gather(FFVulkanContext *s, FFVkExecContext *exec, FFVulkanShader *shd, FFVkBuffer *sizes, size_t sizes_offset, uint32_t nb_segs, FFVkBuffer *sparse, uint32_t slot_size, FFVkBuffer *compacted, size_t compacted_offset, VkDeviceAddress offset_addr)
Gathers nb_segs slots of slot_size bytes from sparse into compacted, with the segment sizes given as ...