../../../ffmpeg/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 / 215
0.0%
Branches:
0 / 116
0.0%
Functions:
0 / 7
0.0%

libavfilter/vulkan_filter.c
Line Branch Exec Source
1 /*
2 * Copyright (c) Lynne
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 "filters.h"
22 #include "vulkan_filter.h"
23 #include "libavutil/vulkan_loader.h"
24
25 ✗ int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s,
26 AVBufferRef *frames_ref,
27 int width, int height, enum AVPixelFormat sw_format)
28 {
29 int err;
30 AVHWFramesContext *frames_ctx;
31 AVHWDeviceContext *device_ctx;
32 AVVulkanFramesContext *vk_frames;
33 AVVulkanDeviceContext *vk_dev;
34 ✗ AVBufferRef *device_ref = avctx->hw_device_ctx;
35
36 /* Check if context is reusable as-is */
37
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 36 not taken.
✗ if (frames_ref) {
38 ✗ int no_storage = 0;
39 FFVulkanFunctions *vk;
40 VkImageUsageFlagBits usage_req;
41 ✗ const VkFormat *sub = av_vkfmt_from_pixfmt(sw_format);
42
43 ✗ frames_ctx = (AVHWFramesContext *)frames_ref->data;
44 ✗ device_ctx = (AVHWDeviceContext *)frames_ctx->device_ref->data;
45 ✗ vk_frames = frames_ctx->hwctx;
46 ✗ vk_dev = device_ctx->hwctx;
47
48 /* Width and height mismatch */
49
0/2
✗ Branch 4 → 5 not taken.
✗ Branch 4 → 6 not taken.
✗ if (width != frames_ctx->width ||
50
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
✗ height != frames_ctx->height)
51 ✗ goto skip;
52
53 /* Format mismatch */
54
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
✗ if (sw_format != frames_ctx->sw_format)
55 ✗ goto skip;
56
57 /* Don't let linear through. */
58
0/2
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 11 not taken.
✗ if (vk_frames->tiling == VK_IMAGE_TILING_LINEAR)
59 ✗ goto skip;
60
61 ✗ s->extensions = ff_vk_extensions_to_mask(vk_dev->enabled_dev_extensions,
62 vk_dev->nb_enabled_dev_extensions);
63
64 /* More advanced format checks */
65 ✗ err = ff_vk_load_functions(device_ctx, &s->vkfn, s->extensions, 1, 1);
66
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
✗ if (err < 0)
67 ✗ return err;
68 ✗ vk = &s->vkfn;
69
70 /* Usage mismatch */
71 ✗ usage_req = VK_IMAGE_USAGE_SAMPLED_BIT |
72 VK_IMAGE_USAGE_STORAGE_BIT;
73
74 /* If format supports hardware encoding, make sure
75 * the context includes it. */
76
0/2
✗ Branch 15 → 16 not taken.
✗ Branch 15 → 22 not taken.
✗ if (vk_frames->format[1] == VK_FORMAT_UNDEFINED &&
77
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 22 not taken.
✗ (s->extensions & FF_VK_EXT_VIDEO_ENCODE_QUEUE) &&
78
0/2
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 22 not taken.
✗ (s->extensions & FF_VK_EXT_VIDEO_MAINTENANCE_1)) {
79 ✗ VkFormatProperties3 fprops = {
80 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3,
81 };
82 ✗ VkFormatProperties2 prop = {
83 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
84 .pNext = &fprops,
85 };
86 ✗ vk->GetPhysicalDeviceFormatProperties2(vk_dev->phys_dev,
87 vk_frames->format[0],
88 &prop);
89
0/2
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 21 not taken.
✗ if (fprops.optimalTilingFeatures & VK_FORMAT_FEATURE_2_VIDEO_ENCODE_INPUT_BIT_KHR)
90 ✗ usage_req |= VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR;
91 }
92
93
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 24 not taken.
✗ if ((vk_frames->usage & usage_req) != usage_req)
94 ✗ goto skip;
95
96 /* Check if the subformats can do storage */
97
0/2
✗ Branch 27 → 25 not taken.
✗ Branch 27 → 28 not taken.
✗ for (int i = 0; sub[i] != VK_FORMAT_UNDEFINED; i++) {
98 ✗ VkFormatProperties2 prop = {
99 .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
100 };
101 ✗ vk->GetPhysicalDeviceFormatProperties2(vk_dev->phys_dev, sub[i],
102 &prop);
103 ✗ no_storage |= !(prop.formatProperties.optimalTilingFeatures &
104 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
105 }
106
107 /* Check if it's usable */
108
0/2
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 32 not taken.
✗ if (no_storage) {
109 ✗ skip:
110 ✗ av_log(avctx, AV_LOG_VERBOSE, "Cannot reuse context, creating a new one\n");
111 ✗ device_ref = frames_ctx->device_ref;
112 ✗ frames_ref = NULL;
113 } else {
114 ✗ av_log(avctx, AV_LOG_VERBOSE, "Reusing existing frames context\n");
115 ✗ frames_ref = av_buffer_ref(frames_ref);
116
0/2
✗ Branch 34 → 35 not taken.
✗ Branch 34 → 36 not taken.
✗ if (!frames_ref)
117 ✗ return AVERROR(ENOMEM);
118 }
119 }
120
121
0/2
✗ Branch 36 → 37 not taken.
✗ Branch 36 → 46 not taken.
✗ if (!frames_ref) {
122
0/2
✗ Branch 37 → 38 not taken.
✗ Branch 37 → 40 not taken.
✗ if (!device_ref) {
123 ✗ av_log(avctx, AV_LOG_ERROR,
124 "Vulkan filtering requires a device context!\n");
125 ✗ return AVERROR(EINVAL);
126 }
127
128 ✗ frames_ref = av_hwframe_ctx_alloc(device_ref);
129
130 ✗ frames_ctx = (AVHWFramesContext *)frames_ref->data;
131 ✗ frames_ctx->format = AV_PIX_FMT_VULKAN;
132 ✗ frames_ctx->sw_format = sw_format;
133 ✗ frames_ctx->width = width;
134 ✗ frames_ctx->height = height;
135
136 ✗ vk_frames = frames_ctx->hwctx;
137 ✗ vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
138 ✗ vk_frames->usage = VK_IMAGE_USAGE_SAMPLED_BIT |
139 VK_IMAGE_USAGE_STORAGE_BIT |
140 VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
141
142 ✗ err = av_hwframe_ctx_init(frames_ref);
143
0/2
✗ Branch 42 → 43 not taken.
✗ Branch 42 → 45 not taken.
✗ if (err < 0) {
144 ✗ av_buffer_unref(&frames_ref);
145 ✗ return err;
146 }
147
148 ✗ device_ctx = (AVHWDeviceContext *)frames_ctx->device_ref->data;
149 ✗ vk_dev = device_ctx->hwctx;
150 }
151
152 ✗ s->extensions = ff_vk_extensions_to_mask(vk_dev->enabled_dev_extensions,
153 vk_dev->nb_enabled_dev_extensions);
154 ✗ s->extensions |= ff_vk_extensions_to_mask(vk_dev->enabled_inst_extensions,
155 vk_dev->nb_enabled_inst_extensions);
156
157 ✗ err = ff_vk_load_functions(device_ctx, &s->vkfn, s->extensions, 1, 1);
158
0/2
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 52 not taken.
✗ if (err < 0) {
159 ✗ av_buffer_unref(&frames_ref);
160 ✗ return err;
161 }
162
163 ✗ s->frames_ref = frames_ref;
164 ✗ s->frames = frames_ctx;
165 ✗ s->hwfc = vk_frames;
166 ✗ s->device = device_ctx;
167 ✗ s->hwctx = device_ctx->hwctx;
168
169 ✗ err = ff_vk_load_props(s);
170
0/2
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 55 not taken.
✗ if (err < 0)
171 ✗ av_buffer_unref(&s->frames_ref);
172
173 ✗ return err;
174 }
175
176 ✗ int ff_vk_filter_config_input(AVFilterLink *inlink)
177 {
178 ✗ FilterLink *l = ff_filter_link(inlink);
179 AVHWFramesContext *input_frames;
180 ✗ AVFilterContext *avctx = inlink->dst;
181 ✗ FFVulkanContext *s = inlink->dst->priv;
182
183
0/2
✗ Branch 3 → 4 not taken.
✗ Branch 3 → 6 not taken.
✗ if (!l->hw_frames_ctx) {
184 ✗ av_log(inlink->dst, AV_LOG_ERROR, "Vulkan filtering requires a "
185 "hardware frames context on the input.\n");
186 ✗ return AVERROR(EINVAL);
187 }
188
189 ✗ input_frames = (AVHWFramesContext *)l->hw_frames_ctx->data;
190
0/2
✗ Branch 6 → 7 not taken.
✗ Branch 6 → 8 not taken.
✗ if (input_frames->format != AV_PIX_FMT_VULKAN)
191 ✗ return AVERROR(EINVAL);
192
193 /* Extract the device and default output format from the first input. */
194
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 10 not taken.
✗ if (avctx->inputs[0] != inlink)
195 ✗ return 0;
196
197 /* Save the ref, without reffing it */
198 ✗ s->input_frames_ref = l->hw_frames_ctx;
199
200 /* Defaults */
201 ✗ s->input_format = input_frames->sw_format;
202 ✗ s->output_format = input_frames->sw_format;
203 ✗ s->output_width = inlink->w;
204 ✗ s->output_height = inlink->h;
205
206 ✗ return 0;
207 }
208
209 ✗ int ff_vk_filter_config_output(AVFilterLink *outlink)
210 {
211 int err;
212 ✗ FilterLink *l = ff_filter_link(outlink);
213 ✗ FFVulkanContext *s = outlink->src->priv;
214
215 ✗ av_buffer_unref(&l->hw_frames_ctx);
216
217 ✗ err = ff_vk_filter_init_context(outlink->src, s, s->input_frames_ref,
218 s->output_width, s->output_height,
219 s->output_format);
220
0/2
✗ Branch 5 → 6 not taken.
✗ Branch 5 → 7 not taken.
✗ if (err < 0)
221 ✗ return err;
222
223 ✗ l->hw_frames_ctx = av_buffer_ref(s->frames_ref);
224
0/2
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 10 not taken.
✗ if (!l->hw_frames_ctx)
225 ✗ return AVERROR(ENOMEM);
226
227 ✗ outlink->w = s->output_width;
228 ✗ outlink->h = s->output_height;
229
230 ✗ return err;
231 }
232
233 ✗ int ff_vk_filter_init(AVFilterContext *avctx)
234 {
235 ✗ FFVulkanContext *s = avctx->priv;
236
237 ✗ s->output_format = AV_PIX_FMT_NONE;
238
239 ✗ return 0;
240 }
241
242 ✗ int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e,
243 FFVulkanShader *shd, AVFrame *out_f, AVFrame *in_f,
244 VkSampler sampler, uint32_t wgc_z,
245 void *push_src, size_t push_size)
246 {
247 ✗ int err = 0;
248 ✗ FFVulkanFunctions *vk = &vkctx->vkfn;
249 VkImageView in_views[AV_NUM_DATA_POINTERS];
250 VkImageView out_views[AV_NUM_DATA_POINTERS];
251 VkImageMemoryBarrier2 img_bar[37];
252 ✗ int nb_img_bar = 0;
253 ✗ VkImageLayout in_layout = sampler != VK_NULL_HANDLE ?
254
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
✗ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL :
255 VK_IMAGE_LAYOUT_GENERAL;
256
257 /* Update descriptors and init the exec context */
258 ✗ FFVkExecContext *exec = ff_vk_exec_get(vkctx, e);
259 ✗ err = ff_vk_exec_start(vkctx, exec);
260
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
✗ if (err < 0)
261 ✗ return err;
262
263
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
✗ RET(ff_vk_exec_add_dep_frame(vkctx, exec, out_f,
264 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
265 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
266
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
✗ RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f, FF_VK_REP_FLOAT));
267 ✗ ff_vk_shader_update_img_array(vkctx, exec, shd, out_f, out_views, 0, !!in_f,
268 VK_IMAGE_LAYOUT_GENERAL,
269 VK_NULL_HANDLE);
270
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 24 not taken.
✗ if (in_f) {
271
0/2
✗ Branch 18 → 19 not taken.
✗ Branch 18 → 20 not taken.
✗ RET(ff_vk_exec_add_dep_frame(vkctx, exec, in_f,
272 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
273 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
274
0/2
✗ Branch 21 → 22 not taken.
✗ Branch 21 → 23 not taken.
✗ RET(ff_vk_create_imageviews(vkctx, exec, in_views, in_f, FF_VK_REP_FLOAT));
275 ✗ ff_vk_shader_update_img_array(vkctx, exec, shd, in_f, in_views, 0, 0,
276 in_layout,
277 sampler);
278 }
279
280 /* Bind pipeline, update push data */
281 ✗ ff_vk_exec_bind_shader(vkctx, exec, shd);
282
0/2
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
✗ if (push_src)
283 ✗ ff_vk_shader_update_push_const(vkctx, exec, shd, VK_SHADER_STAGE_COMPUTE_BIT,
284 0, push_size, push_src);
285
286 /* Add data sync barriers */
287 ✗ ff_vk_frame_barrier(vkctx, exec, out_f, img_bar, &nb_img_bar,
288 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
289 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
290 VK_ACCESS_SHADER_WRITE_BIT,
291 VK_IMAGE_LAYOUT_GENERAL,
292 VK_QUEUE_FAMILY_IGNORED);
293
0/2
✗ Branch 28 → 29 not taken.
✗ Branch 28 → 30 not taken.
✗ if (in_f)
294 ✗ ff_vk_frame_barrier(vkctx, exec, in_f, img_bar, &nb_img_bar,
295 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
296 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
297 VK_ACCESS_SHADER_READ_BIT,
298 in_layout,
299 VK_QUEUE_FAMILY_IGNORED);
300
301 ✗ vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
302 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
303 .pImageMemoryBarriers = img_bar,
304 .imageMemoryBarrierCount = nb_img_bar,
305 });
306
307 ✗ vk->CmdDispatch(exec->buf,
308 ✗ FFALIGN(vkctx->output_width, shd->lg_size[0])/shd->lg_size[0],
309 ✗ FFALIGN(vkctx->output_height, shd->lg_size[1])/shd->lg_size[1],
310 wgc_z);
311
312 ✗ return ff_vk_exec_submit(vkctx, exec);
313 ✗ fail:
314 ✗ ff_vk_exec_discard(vkctx, exec);
315 ✗ return err;
316 }
317
318 ✗ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e,
319 FFVulkanShader *shd_list[2],
320 AVFrame *out, AVFrame *tmp, AVFrame *in,
321 VkSampler sampler, uint32_t wgc_z,
322 void *push_src, size_t push_size)
323 {
324 ✗ int err = 0;
325 ✗ FFVulkanFunctions *vk = &vkctx->vkfn;
326 VkImageView in_views[AV_NUM_DATA_POINTERS];
327 VkImageView tmp_views[AV_NUM_DATA_POINTERS];
328 VkImageView out_views[AV_NUM_DATA_POINTERS];
329 VkImageMemoryBarrier2 img_bar[37];
330 ✗ int nb_img_bar = 0;
331 ✗ VkImageLayout in_layout = sampler != VK_NULL_HANDLE ?
332
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
✗ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL :
333 VK_IMAGE_LAYOUT_GENERAL;
334
335 /* Update descriptors and init the exec context */
336 ✗ FFVkExecContext *exec = ff_vk_exec_get(vkctx, e);
337 ✗ err = ff_vk_exec_start(vkctx, exec);
338
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
✗ if (err < 0)
339 ✗ return err;
340
341
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
✗ RET(ff_vk_exec_add_dep_frame(vkctx, exec, in,
342 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
343 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
344
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
✗ RET(ff_vk_exec_add_dep_frame(vkctx, exec, tmp,
345 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
346 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
347
0/2
✗ Branch 16 → 17 not taken.
✗ Branch 16 → 18 not taken.
✗ RET(ff_vk_exec_add_dep_frame(vkctx, exec, out,
348 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
349 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
350
351
0/2
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 21 not taken.
✗ RET(ff_vk_create_imageviews(vkctx, exec, in_views, in, FF_VK_REP_FLOAT));
352
0/2
✗ Branch 22 → 23 not taken.
✗ Branch 22 → 24 not taken.
✗ RET(ff_vk_create_imageviews(vkctx, exec, tmp_views, tmp, FF_VK_REP_FLOAT));
353
0/2
✗ Branch 25 → 26 not taken.
✗ Branch 25 → 27 not taken.
✗ RET(ff_vk_create_imageviews(vkctx, exec, out_views, out, FF_VK_REP_FLOAT));
354
355 ✗ ff_vk_frame_barrier(vkctx, exec, in, img_bar, &nb_img_bar,
356 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
357 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
358 VK_ACCESS_SHADER_READ_BIT,
359 in_layout,
360 VK_QUEUE_FAMILY_IGNORED);
361 ✗ ff_vk_frame_barrier(vkctx, exec, tmp, img_bar, &nb_img_bar,
362 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
363 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
364 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT,
365 VK_IMAGE_LAYOUT_GENERAL,
366 VK_QUEUE_FAMILY_IGNORED);
367 ✗ ff_vk_frame_barrier(vkctx, exec, out, img_bar, &nb_img_bar,
368 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
369 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
370 VK_ACCESS_SHADER_WRITE_BIT,
371 VK_IMAGE_LAYOUT_GENERAL,
372 VK_QUEUE_FAMILY_IGNORED);
373
374 ✗ vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
375 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
376 .pImageMemoryBarriers = img_bar,
377 .imageMemoryBarrierCount = nb_img_bar,
378 });
379
380
0/2
✗ Branch 54 → 32 not taken.
✗ Branch 54 → 55 not taken.
✗ for (int i = 0; i < 2; i++) {
381 ✗ FFVulkanShader *shd = shd_list[i];
382
0/2
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 34 not taken.
✗ AVFrame *src_f = !i ? in : tmp;
383
0/2
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 37 not taken.
✗ AVFrame *dst_f = !i ? tmp : out;
384
0/2
✗ Branch 38 → 39 not taken.
✗ Branch 38 → 40 not taken.
✗ VkImageView *src_views = !i ? in_views : tmp_views;
385
0/2
✗ Branch 41 → 42 not taken.
✗ Branch 41 → 43 not taken.
✗ VkImageView *dst_views = !i ? tmp_views : out_views;
386
387
0/2
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 46 not taken.
✗ ff_vk_shader_update_img_array(vkctx, exec, shd, src_f, src_views, 0, 0,
388 !i ? in_layout :
389 VK_IMAGE_LAYOUT_GENERAL,
390 sampler);
391 ✗ ff_vk_shader_update_img_array(vkctx, exec, shd, dst_f, dst_views, 0, 1,
392 VK_IMAGE_LAYOUT_GENERAL,
393 VK_NULL_HANDLE);
394
395 /* Bind pipeline, update push data */
396 ✗ ff_vk_exec_bind_shader(vkctx, exec, shd);
397
0/2
✗ Branch 50 → 51 not taken.
✗ Branch 50 → 52 not taken.
✗ if (push_src)
398 ✗ ff_vk_shader_update_push_const(vkctx, exec, shd, VK_SHADER_STAGE_COMPUTE_BIT,
399 0, push_size, push_src);
400
401 ✗ vk->CmdDispatch(exec->buf,
402 ✗ FFALIGN(vkctx->output_width, shd->lg_size[0])/shd->lg_size[0],
403 ✗ FFALIGN(vkctx->output_height, shd->lg_size[1])/shd->lg_size[1],
404 wgc_z);
405 }
406
407 ✗ return ff_vk_exec_submit(vkctx, exec);
408 ✗ fail:
409 ✗ ff_vk_exec_discard(vkctx, exec);
410 ✗ return err;
411 }
412
413 ✗ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e,
414 FFVulkanShader *shd,
415 AVFrame *out, AVFrame *in[], int nb_in,
416 VkSampler sampler, uint32_t wgc_z,
417 void *push_src, size_t push_size)
418 {
419 ✗ int err = 0;
420 ✗ FFVulkanFunctions *vk = &vkctx->vkfn;
421 VkImageView in_views[16][AV_NUM_DATA_POINTERS];
422 VkImageView out_views[AV_NUM_DATA_POINTERS];
423 VkImageMemoryBarrier2 img_bar[128];
424 ✗ int nb_img_bar = 0;
425 ✗ VkImageLayout in_layout = sampler != VK_NULL_HANDLE ?
426
0/2
✗ Branch 2 → 3 not taken.
✗ Branch 2 → 4 not taken.
✗ VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL :
427 VK_IMAGE_LAYOUT_GENERAL;
428
429 /* Update descriptors and init the exec context */
430 ✗ FFVkExecContext *exec = ff_vk_exec_get(vkctx, e);
431 ✗ err = ff_vk_exec_start(vkctx, exec);
432
0/2
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 9 not taken.
✗ if (err < 0)
433 ✗ return err;
434
435 /* Add deps and create temporary imageviews */
436
0/2
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
✗ RET(ff_vk_exec_add_dep_frame(vkctx, exec, out,
437 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
438 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
439
0/2
✗ Branch 13 → 14 not taken.
✗ Branch 13 → 15 not taken.
✗ RET(ff_vk_create_imageviews(vkctx, exec, out_views, out, FF_VK_REP_FLOAT));
440
0/2
✗ Branch 23 → 16 not taken.
✗ Branch 23 → 24 not taken.
✗ for (int i = 0; i < nb_in; i++) {
441
0/2
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
✗ RET(ff_vk_exec_add_dep_frame(vkctx, exec, in[i],
442 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
443 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
444
0/2
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 22 not taken.
✗ RET(ff_vk_create_imageviews(vkctx, exec, in_views[i], in[i], FF_VK_REP_FLOAT));
445 }
446
447 /* Update descriptor sets */
448 ✗ ff_vk_shader_update_img_array(vkctx, exec, shd, out, out_views, 0, 0,
449 VK_IMAGE_LAYOUT_GENERAL,
450 VK_NULL_HANDLE);
451
0/2
✗ Branch 28 → 26 not taken.
✗ Branch 28 → 29 not taken.
✗ for (int i = 0; i < nb_in; i++)
452 ✗ ff_vk_shader_update_img_array(vkctx, exec, shd, in[i], in_views[i], 0, 1 + i,
453 in_layout,
454 sampler);
455
456 /* Bind pipeline, update push data */
457 ✗ ff_vk_exec_bind_shader(vkctx, exec, shd);
458
0/2
✗ Branch 30 → 31 not taken.
✗ Branch 30 → 32 not taken.
✗ if (push_src)
459 ✗ ff_vk_shader_update_push_const(vkctx, exec, shd, VK_SHADER_STAGE_COMPUTE_BIT,
460 0, push_size, push_src);
461
462 /* Add data sync barriers */
463 ✗ ff_vk_frame_barrier(vkctx, exec, out, img_bar, &nb_img_bar,
464 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
465 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
466 VK_ACCESS_SHADER_WRITE_BIT,
467 VK_IMAGE_LAYOUT_GENERAL,
468 VK_QUEUE_FAMILY_IGNORED);
469
0/2
✗ Branch 36 → 34 not taken.
✗ Branch 36 → 37 not taken.
✗ for (int i = 0; i < nb_in; i++)
470 ✗ ff_vk_frame_barrier(vkctx, exec, in[i], img_bar, &nb_img_bar,
471 VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
472 VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
473 VK_ACCESS_SHADER_READ_BIT,
474 in_layout,
475 VK_QUEUE_FAMILY_IGNORED);
476
477 ✗ vk->CmdPipelineBarrier2(exec->buf, &(VkDependencyInfo) {
478 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
479 .pImageMemoryBarriers = img_bar,
480 .imageMemoryBarrierCount = nb_img_bar,
481 });
482
483 ✗ vk->CmdDispatch(exec->buf,
484 ✗ FFALIGN(vkctx->output_width, shd->lg_size[0])/shd->lg_size[0],
485 ✗ FFALIGN(vkctx->output_height, shd->lg_size[1])/shd->lg_size[1],
486 wgc_z);
487
488 ✗ return ff_vk_exec_submit(vkctx, exec);
489 ✗ fail:
490 ✗ ff_vk_exec_discard(vkctx, exec);
491 ✗ return err;
492 }
493