vulkan: merge FFVkSPIRVShader and FFVkPipeline into FFVkShader

Pipelines are just shaders. There's no reason to treat them
differently.
This also lets us implement shader objects and is an overall
cleanup.
pull/153/merge
Lynne 5 months ago
parent aad4d5745d
commit 0a37d5a3b1
No known key found for this signature in database
GPG Key ID: A2FEA5F03F034464
  1. 28
      libavfilter/vf_avgblur_vulkan.c
  2. 24
      libavfilter/vf_blend_vulkan.c
  3. 29
      libavfilter/vf_bwdif_vulkan.c
  4. 28
      libavfilter/vf_chromaber_vulkan.c
  5. 24
      libavfilter/vf_flip_vulkan.c
  6. 54
      libavfilter/vf_gblur_vulkan.c
  7. 135
      libavfilter/vf_nlmeans_vulkan.c
  8. 28
      libavfilter/vf_overlay_vulkan.c
  9. 28
      libavfilter/vf_scale_vulkan.c
  10. 24
      libavfilter/vf_transpose_vulkan.c
  11. 28
      libavfilter/vf_xfade_vulkan.c
  12. 30
      libavfilter/vsrc_testsrc_vulkan.c
  13. 78
      libavfilter/vulkan_filter.c
  14. 6
      libavfilter/vulkan_filter.h
  15. 4
      libavfilter/vulkan_glslang.c
  16. 4
      libavfilter/vulkan_shaderc.c
  17. 2
      libavfilter/vulkan_spirv.h
  18. 626
      libavutil/vulkan.c
  19. 146
      libavutil/vulkan.h

@ -33,8 +33,7 @@ typedef struct AvgBlurVulkanContext {
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
VkSampler sampler;
FFVulkanPipeline pl;
FFVkSPIRVShader shd;
FFVulkanShader shd;
/* Push constants / options */
struct {
@ -68,7 +67,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
AvgBlurVulkanContext *s = ctx->priv;
FFVulkanContext *vkctx = &s->vkctx;
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
FFVkSPIRVShader *shd;
FFVulkanShader *shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@ -81,12 +80,13 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR));
RET(ff_vk_shader_init(&s->pl, &s->shd, "avgblur_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
RET(ff_vk_shader_init(vkctx, &s->shd, "avgblur",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 1, 1,
0));
shd = &s->shd;
ff_vk_shader_set_compute_sizes(shd, 32, 1, 1);
desc = (FFVulkanDescriptorSetBinding []) {
{
.name = "input_img",
@ -107,7 +107,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 2, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc, 2, 0, 0));
GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
GLSLC(1, vec4 filter_norm; );
@ -115,8 +115,8 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
GLSLC(0, }; );
GLSLC(0, );
ff_vk_add_push_constant(&s->pl, 0, sizeof(s->opts),
VK_SHADER_STAGE_COMPUTE_BIT);
ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
VK_SHADER_STAGE_COMPUTE_BIT);
GLSLD( blur_kernel );
GLSLC(0, void main() );
@ -139,10 +139,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
RET(spv->compile_shader(spv, ctx, &s->shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(vkctx, &s->shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, &s->shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, &s->shd));
RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->initialized = 1;
s->opts.filter_len[0] = s->size_x - 1;
@ -180,7 +179,7 @@ static int avgblur_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
if (!s->initialized)
RET(init_filter(ctx, in));
RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl,
RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd,
out, in, s->sampler, &s->opts, sizeof(s->opts)));
err = av_frame_copy_props(out, in);
@ -204,7 +203,6 @@ static void avgblur_vulkan_uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
ff_vk_shader_free(vkctx, &s->shd);
if (s->sampler)

@ -46,10 +46,9 @@ typedef struct BlendVulkanContext {
FFFrameSync fs;
int initialized;
FFVulkanPipeline pl;
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
FFVkSPIRVShader shd;
FFVulkanShader shd;
VkSampler sampler;
FilterParamsVulkan params[4];
@ -132,7 +131,7 @@ static av_cold int init_filter(AVFilterContext *avctx)
BlendVulkanContext *s = avctx->priv;
FFVulkanContext *vkctx = &s->vkctx;
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
FFVkSPIRVShader *shd = &s->shd;
FFVulkanShader *shd = &s->shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@ -145,10 +144,11 @@ static av_cold int init_filter(AVFilterContext *avctx)
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
RET(ff_vk_shader_init(&s->pl, &s->shd, "blend_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1);
RET(ff_vk_shader_init(vkctx, &s->shd, "blend",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 32, 1,
0));
desc = (FFVulkanDescriptorSetBinding []) {
{
@ -178,7 +178,7 @@ static av_cold int init_filter(AVFilterContext *avctx)
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 3, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 3, 0, 0));
for (int i = 0, j = 0; i < planes; i++) {
for (j = 0; j < i; j++)
@ -210,10 +210,9 @@ static av_cold int init_filter(AVFilterContext *avctx)
RET(spv->compile_shader(spv, avctx, shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd));
RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->initialized = 1;
@ -257,7 +256,7 @@ static int blend_frame(FFFrameSync *fs)
RET(init_filter(avctx));
}
RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->pl,
RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->shd,
out, (AVFrame *[]){ top, bottom }, 2,
s->sampler, NULL, 0));
@ -284,7 +283,6 @@ static av_cold void uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
ff_vk_shader_free(vkctx, &s->shd);
if (s->sampler)

@ -35,8 +35,7 @@ typedef struct BWDIFVulkanContext {
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
VkSampler sampler;
FFVulkanPipeline pl;
FFVkSPIRVShader shd;
FFVulkanShader shd;
} BWDIFVulkanContext;
typedef struct BWDIFParameters {
@ -100,7 +99,7 @@ static av_cold int init_filter(AVFilterContext *ctx)
BWDIFVulkanContext *s = ctx->priv;
FFVulkanContext *vkctx = &s->vkctx;
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
FFVkSPIRVShader *shd;
FFVulkanShader *shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@ -113,11 +112,13 @@ static av_cold int init_filter(AVFilterContext *ctx)
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
RET(ff_vk_shader_init(&s->pl, &s->shd, "bwdif_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
shd = &s->shd;
ff_vk_shader_set_compute_sizes(shd, 1, 64, 1);
RET(ff_vk_shader_init(vkctx, &s->shd, "bwdif",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
1, 64, 1,
0));
shd = &s->shd;
desc = (FFVulkanDescriptorSetBinding []) {
{
@ -155,7 +156,7 @@ static av_cold int init_filter(AVFilterContext *ctx)
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 4, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 4, 0, 0));
GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
GLSLC(1, int parity; );
@ -163,8 +164,8 @@ static av_cold int init_filter(AVFilterContext *ctx)
GLSLC(1, int current_field; );
GLSLC(0, }; );
ff_vk_add_push_constant(&s->pl, 0, sizeof(BWDIFParameters),
VK_SHADER_STAGE_COMPUTE_BIT);
ff_vk_shader_add_push_const(&s->shd, 0, sizeof(BWDIFParameters),
VK_SHADER_STAGE_COMPUTE_BIT);
GLSLD( filter_fn );
GLSLC(0, void main() );
@ -245,10 +246,9 @@ static av_cold int init_filter(AVFilterContext *ctx)
RET(spv->compile_shader(spv, ctx, &s->shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(vkctx, &s->shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, &s->shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, &s->shd));
RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->initialized = 1;
@ -272,7 +272,7 @@ static void bwdif_vulkan_filter_frame(AVFilterContext *ctx, AVFrame *dst,
.current_field = y->current_field,
};
ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->pl, dst,
ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->shd, dst,
(AVFrame *[]){ y->prev, y->cur, y->next }, 3,
s->sampler, &params, sizeof(params));
@ -287,7 +287,6 @@ static void bwdif_vulkan_uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
ff_vk_shader_free(vkctx, &s->shd);
if (s->sampler)

@ -30,10 +30,9 @@ typedef struct ChromaticAberrationVulkanContext {
FFVulkanContext vkctx;
int initialized;
FFVulkanPipeline pl;
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
FFVkSPIRVShader shd;
FFVulkanShader shd;
VkSampler sampler;
/* Push constants / options */
@ -75,7 +74,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
ChromaticAberrationVulkanContext *s = ctx->priv;
FFVulkanContext *vkctx = &s->vkctx;
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
FFVkSPIRVShader *shd = &s->shd;
FFVulkanShader *shd = &s->shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@ -92,18 +91,19 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, VK_FILTER_LINEAR));
RET(ff_vk_shader_init(&s->pl, &s->shd, "chromaber_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1);
RET(ff_vk_shader_init(vkctx, &s->shd, "chromatic_abberation",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 32, 1,
0));
GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
GLSLC(1, vec2 dist; );
GLSLC(0, }; );
GLSLC(0, );
ff_vk_add_push_constant(&s->pl, 0, sizeof(s->opts),
VK_SHADER_STAGE_COMPUTE_BIT);
ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
VK_SHADER_STAGE_COMPUTE_BIT);
desc = (FFVulkanDescriptorSetBinding []) {
{
@ -125,7 +125,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 2, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0));
GLSLD( distort_chroma_kernel );
GLSLC(0, void main() );
@ -150,10 +150,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd));
RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->initialized = 1;
@ -182,7 +181,7 @@ static int chromaber_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
if (!s->initialized)
RET(init_filter(ctx, in));
RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, out, in,
RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in,
s->sampler, &s->opts, sizeof(s->opts)));
err = av_frame_copy_props(out, in);
@ -206,7 +205,6 @@ static void chromaber_vulkan_uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
ff_vk_shader_free(vkctx, &s->shd);
if (s->sampler)

@ -37,10 +37,9 @@ typedef struct FlipVulkanContext {
FFVulkanContext vkctx;
int initialized;
FFVulkanPipeline pl;
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
FFVkSPIRVShader shd;
FFVulkanShader shd;
VkSampler sampler;
} FlipVulkanContext;
@ -53,7 +52,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType
FlipVulkanContext *s = ctx->priv;
FFVulkanContext *vkctx = &s->vkctx;
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
FFVkSPIRVShader *shd = &s->shd;
FFVulkanShader *shd = &s->shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@ -66,10 +65,11 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR));
RET(ff_vk_shader_init(&s->pl, &s->shd, "flip_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1);
RET(ff_vk_shader_init(vkctx, &s->shd, "flip",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 32, 1,
0));
desc = (FFVulkanDescriptorSetBinding []) {
{
@ -91,7 +91,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 2, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0));
GLSLC(0, void main() );
GLSLC(0, { );
@ -123,10 +123,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in, enum FlipType
RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd));
RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->initialized = 1;
@ -147,7 +146,6 @@ static av_cold void flip_vulkan_uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
ff_vk_shader_free(vkctx, &s->shd);
if (s->sampler)
@ -176,7 +174,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *in, enum FlipType type)
if (!s->initialized)
RET(init_filter(ctx, in, type));
RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, out, in,
RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in,
s->sampler, NULL, 0));
RET(av_frame_copy_props(out, in));

@ -38,11 +38,9 @@ typedef struct GBlurVulkanContext {
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
VkSampler sampler;
FFVulkanPipeline pl_hor;
FFVkSPIRVShader shd_hor;
FFVulkanShader shd_hor;
FFVkBuffer params_hor;
FFVulkanPipeline pl_ver;
FFVkSPIRVShader shd_ver;
FFVulkanShader shd_ver;
FFVkBuffer params_ver;
int size;
@ -123,8 +121,8 @@ static av_cold void init_gaussian_params(GBlurVulkanContext *s)
init_kernel_size(s, &s->sizeV);
}
static int init_gblur_pipeline(GBlurVulkanContext *s, FFVulkanPipeline *pl,
FFVkSPIRVShader *shd, FFVkBuffer *params_buf,
static int init_gblur_pipeline(GBlurVulkanContext *s,
FFVulkanShader *shd, FFVkBuffer *params_buf,
int ksize, float sigma, FFVkSPIRVCompiler *spv)
{
int err = 0;
@ -150,7 +148,7 @@ static int init_gblur_pipeline(GBlurVulkanContext *s, FFVulkanPipeline *pl,
buf_desc.buf_content = kernel_def;
RET(ff_vk_pipeline_descriptor_set_add(&s->vkctx, pl, shd, &buf_desc, 1, 1, 0));
RET(ff_vk_shader_add_descriptor_set(&s->vkctx, shd, &buf_desc, 1, 1, 0));
GLSLD( gblur_func );
GLSLC(0, void main() );
@ -173,10 +171,9 @@ static int init_gblur_pipeline(GBlurVulkanContext *s, FFVulkanPipeline *pl,
RET(spv->compile_shader(spv, s, shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(&s->vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(&s->vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(&s->vkctx, pl, shd));
RET(ff_vk_exec_pipeline_register(&s->vkctx, &s->e, pl));
RET(ff_vk_shader_register_exec(&s->vkctx, &s->e, shd));
RET(ff_vk_create_buf(&s->vkctx, params_buf, sizeof(float) * ksize, NULL, NULL,
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT |
@ -187,10 +184,9 @@ static int init_gblur_pipeline(GBlurVulkanContext *s, FFVulkanPipeline *pl,
init_gaussian_kernel((float *)kernel_mapped, sigma, ksize);
RET(ff_vk_unmap_buffer(&s->vkctx, params_buf, 1));
RET(ff_vk_set_descriptor_buffer(&s->vkctx, pl, NULL, 1, 0, 0,
params_buf, 0, params_buf->size,
VK_FORMAT_UNDEFINED));
RET(ff_vk_shader_update_desc_buffer(&s->vkctx, &s->e.contexts[0], shd, 1, 0, 0,
params_buf, 0, params_buf->size,
VK_FORMAT_UNDEFINED));
fail:
av_free(kernel_def);
@ -206,7 +202,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
FFVulkanContext *vkctx = &s->vkctx;
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
FFVkSPIRVShader *shd;
FFVulkanShader *shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@ -219,10 +215,6 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR));
RET(ff_vk_shader_init(&s->pl_hor, &s->shd_hor, "gblur_hor_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
RET(ff_vk_shader_init(&s->pl_ver, &s->shd_ver, "gblur_ver_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
desc = (FFVulkanDescriptorSetBinding []) {
{
@ -248,22 +240,30 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
{
shd = &s->shd_hor;
ff_vk_shader_set_compute_sizes(shd, 32, 1, 1);
RET(ff_vk_shader_init(vkctx, shd, "gblur_hor",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 1, 1,
0));
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl_hor, shd, desc, 2, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc, 2, 0, 0));
GLSLC(0, #define OFFSET (vec2(i, 0.0)));
RET(init_gblur_pipeline(s, &s->pl_hor, shd, &s->params_hor, s->size, s->sigma, spv));
RET(init_gblur_pipeline(s, shd, &s->params_hor, s->size, s->sigma, spv));
}
{
shd = &s->shd_ver;
ff_vk_shader_set_compute_sizes(shd, 1, 32, 1);
RET(ff_vk_shader_init(vkctx, shd, "gblur_hor",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
1, 32, 1,
0));
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl_ver, shd, desc, 2, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc, 2, 0, 0));
GLSLC(0, #define OFFSET (vec2(0.0, i)));
RET(init_gblur_pipeline(s, &s->pl_ver, shd, &s->params_ver, s->sizeV, s->sigmaV, spv));
RET(init_gblur_pipeline(s, shd, &s->params_ver, s->sizeV, s->sigmaV, spv));
}
s->initialized = 1;
@ -282,8 +282,6 @@ static av_cold void gblur_vulkan_uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl_hor);
ff_vk_pipeline_free(vkctx, &s->pl_ver);
ff_vk_shader_free(vkctx, &s->shd_hor);
ff_vk_shader_free(vkctx, &s->shd_ver);
ff_vk_free_buf(vkctx, &s->params_hor);
@ -322,7 +320,7 @@ static int gblur_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
RET(init_filter(ctx, in));
RET(ff_vk_filter_process_2pass(&s->vkctx, &s->e,
(FFVulkanPipeline *[2]){ &s->pl_hor, &s->pl_ver },
(FFVulkanShader *[2]){ &s->shd_hor, &s->shd_ver },
out, tmp, in, s->sampler, NULL, 0));
err = av_frame_copy_props(out, in);

@ -45,11 +45,8 @@ typedef struct NLMeansVulkanContext {
FFVkBuffer xyoffsets_buf;
int pl_weights_rows;
FFVulkanPipeline pl_weights;
FFVkSPIRVShader shd_weights;
FFVulkanPipeline pl_denoise;
FFVkSPIRVShader shd_denoise;
FFVulkanShader shd_weights;
FFVulkanShader shd_denoise;
int *xoffsets;
int *yoffsets;
@ -69,7 +66,7 @@ typedef struct NLMeansVulkanContext {
extern const char *ff_source_prefix_sum_comp;
static void insert_first(FFVkSPIRVShader *shd, int r, const char *off, int horiz, int plane, int comp)
static void insert_first(FFVulkanShader *shd, int r, const char *off, int horiz, int plane, int comp)
{
GLSLF(4, s1 = texture(input_img[%i], pos + ivec2(%i + %s, %i + %s))[%i];
,plane, horiz ? r : 0, horiz ? off : "0", !horiz ? r : 0, !horiz ? off : "0", comp);
@ -86,7 +83,7 @@ static void insert_first(FFVkSPIRVShader *shd, int r, const char *off, int horiz
GLSLC(4, s2 = (s1 - s2) * (s1 - s2); );
}
static void insert_horizontal_pass(FFVkSPIRVShader *shd, int nb_rows, int first, int plane, int comp)
static void insert_horizontal_pass(FFVulkanShader *shd, int nb_rows, int first, int plane, int comp)
{
GLSLF(1, pos.y = int(gl_GlobalInvocationID.x) * %i; ,nb_rows);
if (!first)
@ -112,7 +109,7 @@ static void insert_horizontal_pass(FFVkSPIRVShader *shd, int nb_rows, int first,
GLSLC(0, );
}
static void insert_vertical_pass(FFVkSPIRVShader *shd, int nb_rows, int first, int plane, int comp)
static void insert_vertical_pass(FFVulkanShader *shd, int nb_rows, int first, int plane, int comp)
{
GLSLF(1, pos.x = int(gl_GlobalInvocationID.x) * %i; ,nb_rows);
GLSLC(1, #pragma unroll(1) );
@ -141,7 +138,7 @@ static void insert_vertical_pass(FFVkSPIRVShader *shd, int nb_rows, int first, i
GLSLC(0, );
}
static void insert_weights_pass(FFVkSPIRVShader *shd, int nb_rows, int vert,
static void insert_weights_pass(FFVulkanShader *shd, int nb_rows, int vert,
int t, int dst_comp, int plane, int comp)
{
GLSLF(1, p = patch_size[%i]; ,dst_comp);
@ -214,7 +211,7 @@ typedef struct HorizontalPushData {
} HorizontalPushData;
static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *exec,
FFVulkanPipeline *pl, FFVkSPIRVShader *shd,
FFVulkanShader *shd,
VkSampler sampler, FFVkSPIRVCompiler *spv,
int width, int height, int t,
const AVPixFmtDescriptor *desc,
@ -241,8 +238,12 @@ static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e
wg_rows++;
}
RET(ff_vk_shader_init(pl, shd, "nlmeans_weights", VK_SHADER_STAGE_COMPUTE_BIT, 0));
ff_vk_shader_set_compute_sizes(shd, wg_size, 1, 1);
RET(ff_vk_shader_init(vkctx, shd, "nlmeans_weights",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
wg_size, 1, 1,
0));
*nb_rows = wg_rows;
if (t > 1)
@ -269,7 +270,8 @@ static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e
GLSLC(0, }; );
GLSLC(0, );
ff_vk_add_push_constant(pl, 0, sizeof(HorizontalPushData), VK_SHADER_STAGE_COMPUTE_BIT);
ff_vk_shader_add_push_const(shd, 0, sizeof(HorizontalPushData),
VK_SHADER_STAGE_COMPUTE_BIT);
desc_set = (FFVulkanDescriptorSetBinding []) {
{
@ -329,7 +331,7 @@ static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e
.buf_content = "float sums_3[];",
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, pl, shd, desc_set, 1 + 2*desc->nb_components, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc_set, 1 + 2*desc->nb_components, 0, 0));
desc_set = (FFVulkanDescriptorSetBinding []) {
{
@ -340,7 +342,7 @@ static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e
.buf_content = "ivec2 xyoffsets[];",
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, pl, shd, desc_set, 1, 1, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc_set, 1, 1, 0));
GLSLC(0, );
GLSLC(0, void main() );
@ -401,10 +403,9 @@ static av_cold int init_weights_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e
GLSLC(0, } );
RET(spv->compile_shader(spv, vkctx, shd, &spv_data, &spv_len, "main", &spv_opaque));
RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, pl, shd));
RET(ff_vk_exec_pipeline_register(vkctx, exec, pl));
RET(ff_vk_shader_register_exec(vkctx, exec, shd));
fail:
if (spv_opaque)
@ -418,7 +419,7 @@ typedef struct DenoisePushData {
} DenoisePushData;
static av_cold int init_denoise_pipeline(FFVulkanContext *vkctx, FFVkExecPool *exec,
FFVulkanPipeline *pl, FFVkSPIRVShader *shd,
FFVulkanShader *shd,
VkSampler sampler, FFVkSPIRVCompiler *spv,
const AVPixFmtDescriptor *desc, int planes)
{
@ -428,16 +429,18 @@ static av_cold int init_denoise_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e
void *spv_opaque = NULL;
FFVulkanDescriptorSetBinding *desc_set;
RET(ff_vk_shader_init(pl, shd, "nlmeans_denoise",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
ff_vk_shader_set_compute_sizes(shd, 32, 32, 1);
RET(ff_vk_shader_init(vkctx, shd, "nlmeans_denoise",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 32, 1,
0));
GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
GLSLC(1, uvec4 ws_stride; );
GLSLC(0, }; );
ff_vk_add_push_constant(pl, 0, sizeof(DenoisePushData), VK_SHADER_STAGE_COMPUTE_BIT);
ff_vk_shader_add_push_const(shd, 0, sizeof(DenoisePushData),
VK_SHADER_STAGE_COMPUTE_BIT);
desc_set = (FFVulkanDescriptorSetBinding []) {
{
@ -458,7 +461,7 @@ static av_cold int init_denoise_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e
.stages = VK_SHADER_STAGE_COMPUTE_BIT,
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, pl, shd, desc_set, 2, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc_set, 2, 0, 0));
desc_set = (FFVulkanDescriptorSetBinding []) {
{
@ -519,7 +522,7 @@ static av_cold int init_denoise_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, pl, shd, desc_set, 2*desc->nb_components, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, shd, desc_set, 2*desc->nb_components, 0, 0));
GLSLC(0, void main() );
GLSLC(0, { );
@ -551,10 +554,9 @@ static av_cold int init_denoise_pipeline(FFVulkanContext *vkctx, FFVkExecPool *e
GLSLC(0, } );
RET(spv->compile_shader(spv, vkctx, shd, &spv_data, &spv_len, "main", &spv_opaque));
RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, pl, shd));
RET(ff_vk_exec_pipeline_register(vkctx, exec, pl));
RET(ff_vk_shader_register_exec(vkctx, exec, shd));
fail:
if (spv_opaque)
@ -654,14 +656,15 @@ static av_cold int init_filter(AVFilterContext *ctx)
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, 1, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
RET(init_weights_pipeline(vkctx, &s->e, &s->pl_weights, &s->shd_weights, s->sampler,
RET(init_weights_pipeline(vkctx, &s->e, &s->shd_weights, s->sampler,
spv, s->vkctx.output_width, s->vkctx.output_height,
s->opts.t, desc, planes, &s->pl_weights_rows));
RET(init_denoise_pipeline(vkctx, &s->e, &s->pl_denoise, &s->shd_denoise, s->sampler,
RET(init_denoise_pipeline(vkctx, &s->e, &s->shd_denoise, s->sampler,
spv, desc, planes));
RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_weights, NULL, 1, 0, 0,
RET(ff_vk_shader_update_desc_buffer(vkctx, &s->e.contexts[0], &s->shd_weights,
1, 0, 0,
&s->xyoffsets_buf, 0, s->xyoffsets_buf.size,
VK_FORMAT_UNDEFINED));
@ -697,11 +700,12 @@ static int denoise_pass(NLMeansVulkanContext *s, FFVkExecContext *exec,
};
/* Denoise pass pipeline */
ff_vk_exec_bind_pipeline(vkctx, exec, &s->pl_denoise);
ff_vk_exec_bind_shader(vkctx, exec, &s->shd_denoise);
/* Push data */
ff_vk_update_push_exec(vkctx, exec, &s->pl_denoise, VK_SHADER_STAGE_COMPUTE_BIT,
0, sizeof(pd), &pd);
ff_vk_shader_update_push_const(vkctx, exec, &s->shd_denoise,
VK_SHADER_STAGE_COMPUTE_BIT,
0, sizeof(pd), &pd);
buf_bar[nb_buf_bar++] = (VkBufferMemoryBarrier2) {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2,
@ -726,8 +730,8 @@ static int denoise_pass(NLMeansVulkanContext *s, FFVkExecContext *exec,
/* End of denoise pass */
vk->CmdDispatch(exec->buf,
FFALIGN(vkctx->output_width, s->pl_denoise.wg_size[0])/s->pl_denoise.wg_size[0],
FFALIGN(vkctx->output_height, s->pl_denoise.wg_size[1])/s->pl_denoise.wg_size[1],
FFALIGN(vkctx->output_width, s->shd_denoise.lg_size[0])/s->shd_denoise.lg_size[0],
FFALIGN(vkctx->output_height, s->shd_denoise.lg_size[1])/s->shd_denoise.lg_size[1],
av_pix_fmt_count_planes(s->vkctx.output_format));
return 0;
@ -780,15 +784,15 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
return AVERROR(EINVAL);
/* Integral image */
int_stride = s->pl_weights.wg_size[0]*s->pl_weights_rows*TYPE_SIZE;
int_size = s->pl_weights.wg_size[0]*s->pl_weights_rows*int_stride;
int_stride = s->shd_weights.lg_size[0]*s->pl_weights_rows*TYPE_SIZE;
int_size = s->shd_weights.lg_size[0]*s->pl_weights_rows*int_stride;
/* Plane dimensions */
for (int i = 0; i < desc->nb_components; i++) {
plane_widths[i] = !i || (i == 3) ? vkctx->output_width : AV_CEIL_RSHIFT(vkctx->output_width, desc->log2_chroma_w);
plane_heights[i] = !i || (i == 3) ? vkctx->output_height : AV_CEIL_RSHIFT(vkctx->output_height, desc->log2_chroma_w);
plane_widths[i] = FFALIGN(plane_widths[i], s->pl_denoise.wg_size[0]);
plane_heights[i] = FFALIGN(plane_heights[i], s->pl_denoise.wg_size[1]);
plane_widths[i] = FFALIGN(plane_widths[i], s->shd_denoise.lg_size[0]);
plane_heights[i] = FFALIGN(plane_heights[i], s->shd_denoise.lg_size[1]);
ws_stride[i] = plane_widths[i];
ws_size[i] = ws_stride[i] * plane_heights[i] * sizeof(float);
@ -933,35 +937,35 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
ws_vk->access = buf_bar[0].dstAccessMask;
/* Update weights descriptors */
ff_vk_update_descriptor_img_array(vkctx, &s->pl_weights, exec, in, in_views, 0, 0,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
s->sampler);
ff_vk_shader_update_img_array(vkctx, exec, &s->shd_weights, in, in_views, 0, 0,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
s->sampler);
for (int i = 0; i < desc->nb_components; i++) {
RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_weights, exec, 0, 1 + i*2 + 0, 0,
ws_vk, weights_offs[i], ws_size[i],
VK_FORMAT_UNDEFINED));
RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_weights, exec, 0, 1 + i*2 + 1, 0,
ws_vk, sums_offs[i], ws_size[i],
VK_FORMAT_UNDEFINED));
RET(ff_vk_shader_update_desc_buffer(&s->vkctx, exec, &s->shd_weights, 0, 1 + i*2 + 0, 0,
ws_vk, weights_offs[i], ws_size[i],
VK_FORMAT_UNDEFINED));
RET(ff_vk_shader_update_desc_buffer(&s->vkctx, exec, &s->shd_weights, 0, 1 + i*2 + 1, 0,
ws_vk, sums_offs[i], ws_size[i],
VK_FORMAT_UNDEFINED));
}
/* Update denoise descriptors */
ff_vk_update_descriptor_img_array(vkctx, &s->pl_denoise, exec, in, in_views, 0, 0,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
s->sampler);
ff_vk_update_descriptor_img_array(vkctx, &s->pl_denoise, exec, out, out_views, 0, 1,
VK_IMAGE_LAYOUT_GENERAL, s->sampler);
ff_vk_shader_update_img_array(vkctx, exec, &s->shd_denoise, in, in_views, 0, 0,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
s->sampler);
ff_vk_shader_update_img_array(vkctx, exec, &s->shd_denoise, out, out_views, 0, 1,
VK_IMAGE_LAYOUT_GENERAL, s->sampler);
for (int i = 0; i < desc->nb_components; i++) {
RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_denoise, exec, 1, i*2 + 0, 0,
ws_vk, weights_offs[i], ws_size[i],
VK_FORMAT_UNDEFINED));
RET(ff_vk_set_descriptor_buffer(&s->vkctx, &s->pl_denoise, exec, 1, i*2 + 1, 0,
ws_vk, sums_offs[i], ws_size[i],
VK_FORMAT_UNDEFINED));
RET(ff_vk_shader_update_desc_buffer(&s->vkctx, exec, &s->shd_denoise, 1, i*2 + 0, 0,
ws_vk, weights_offs[i], ws_size[i],
VK_FORMAT_UNDEFINED));
RET(ff_vk_shader_update_desc_buffer(&s->vkctx, exec, &s->shd_denoise, 1, i*2 + 1, 0,
ws_vk, sums_offs[i], ws_size[i],
VK_FORMAT_UNDEFINED));
}
/* Weights pipeline */
ff_vk_exec_bind_pipeline(vkctx, exec, &s->pl_weights);
ff_vk_exec_bind_shader(vkctx, exec, &s->shd_weights);
do {
int wg_invoc;
@ -978,8 +982,9 @@ static int nlmeans_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
};
/* Push data */
ff_vk_update_push_exec(vkctx, exec, &s->pl_weights, VK_SHADER_STAGE_COMPUTE_BIT,
0, sizeof(pd), &pd);
ff_vk_shader_update_push_const(vkctx, exec, &s->shd_weights,
VK_SHADER_STAGE_COMPUTE_BIT,
0, sizeof(pd), &pd);
if (offsets_dispatched) {
nb_buf_bar = 0;
@ -1044,9 +1049,7 @@ static void nlmeans_vulkan_uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl_weights);
ff_vk_shader_free(vkctx, &s->shd_weights);
ff_vk_pipeline_free(vkctx, &s->pl_denoise);
ff_vk_shader_free(vkctx, &s->shd_denoise);
av_buffer_pool_uninit(&s->integral_buf_pool);

@ -32,10 +32,9 @@ typedef struct OverlayVulkanContext {
FFFrameSync fs;
int initialized;
FFVulkanPipeline pl;
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
FFVkSPIRVShader shd;
FFVulkanShader shd;
VkSampler sampler;
/* Push constants / options */
@ -92,7 +91,7 @@ static av_cold int init_filter(AVFilterContext *ctx)
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
const int ialpha = av_pix_fmt_desc_get(s->vkctx.input_format)->flags & AV_PIX_FMT_FLAG_ALPHA;
const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(s->vkctx.output_format);
FFVkSPIRVShader *shd = &s->shd;
FFVulkanShader *shd = &s->shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@ -105,10 +104,11 @@ static av_cold int init_filter(AVFilterContext *ctx)
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
RET(ff_vk_shader_init(&s->pl, &s->shd, "overlay_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1);
RET(ff_vk_shader_init(vkctx, &s->shd, "overlay",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 32, 1,
0));
GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
GLSLC(1, ivec2 o_offset[3]; );
@ -116,8 +116,8 @@ static av_cold int init_filter(AVFilterContext *ctx)
GLSLC(0, }; );
GLSLC(0, );
ff_vk_add_push_constant(&s->pl, 0, sizeof(s->opts),
VK_SHADER_STAGE_COMPUTE_BIT);
ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
VK_SHADER_STAGE_COMPUTE_BIT);
desc = (FFVulkanDescriptorSetBinding []) {
{
@ -147,7 +147,7 @@ static av_cold int init_filter(AVFilterContext *ctx)
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 3, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 3, 0, 0));
GLSLD( overlay_noalpha );
GLSLD( overlay_alpha );
@ -165,10 +165,9 @@ static av_cold int init_filter(AVFilterContext *ctx)
RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd));
RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->opts.o_offset[0] = s->overlay_x;
s->opts.o_offset[1] = s->overlay_y;
@ -233,7 +232,7 @@ static int overlay_vulkan_blend(FFFrameSync *fs)
goto fail;
}
RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->pl,
RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->shd,
out, (AVFrame *[]){ input_main, input_overlay }, 2,
s->sampler, &s->opts, sizeof(s->opts)));
@ -288,7 +287,6 @@ static void overlay_vulkan_uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
ff_vk_shader_free(vkctx, &s->shd);
if (s->sampler)

@ -38,10 +38,9 @@ typedef struct ScaleVulkanContext {
FFVulkanContext vkctx;
int initialized;
FFVulkanPipeline pl;
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
FFVkSPIRVShader shd;
FFVulkanShader shd;
VkSampler sampler;
/* Push constants / options */
@ -118,7 +117,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
VkFilter sampler_mode;
ScaleVulkanContext *s = ctx->priv;
FFVulkanContext *vkctx = &s->vkctx;
FFVkSPIRVShader *shd = &s->shd;
FFVulkanShader *shd = &s->shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@ -146,18 +145,19 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 0, sampler_mode));
RET(ff_vk_shader_init(&s->pl, &s->shd, "scale_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1);
RET(ff_vk_shader_init(vkctx, &s->shd, "scale",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 32, 1,
0));
GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
GLSLC(1, mat4 yuv_matrix; );
GLSLC(0, }; );
GLSLC(0, );
ff_vk_add_push_constant(&s->pl, 0, sizeof(s->opts),
VK_SHADER_STAGE_COMPUTE_BIT);
ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
VK_SHADER_STAGE_COMPUTE_BIT);
desc = (FFVulkanDescriptorSetBinding []) {
{
@ -179,7 +179,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 2, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0));
GLSLD( scale_bilinear );
@ -249,10 +249,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd));
RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->initialized = 1;
@ -281,7 +280,7 @@ static int scale_vulkan_filter_frame(AVFilterLink *link, AVFrame *in)
if (!s->initialized)
RET(init_filter(ctx, in));
RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, out, in,
RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in,
s->sampler, &s->opts, sizeof(s->opts)));
err = av_frame_copy_props(out, in);
@ -353,7 +352,6 @@ static void scale_vulkan_uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
ff_vk_shader_free(vkctx, &s->shd);
if (s->sampler)

@ -32,10 +32,9 @@ typedef struct TransposeVulkanContext {
FFVulkanContext vkctx;
int initialized;
FFVulkanPipeline pl;
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
FFVkSPIRVShader shd;
FFVulkanShader shd;
VkSampler sampler;
int dir;
@ -52,7 +51,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
FFVulkanContext *vkctx = &s->vkctx;
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
FFVkSPIRVShader *shd = &s->shd;
FFVulkanShader *shd = &s->shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@ -65,10 +64,11 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_LINEAR));
RET(ff_vk_shader_init(&s->pl, &s->shd, "transpose_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
ff_vk_shader_set_compute_sizes(&s->shd, 32, 1, 1);
RET(ff_vk_shader_init(vkctx, &s->shd, "transpose",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 1, 1,
0));
desc = (FFVulkanDescriptorSetBinding []) {
{
@ -90,7 +90,7 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 2, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 2, 0, 0));
GLSLC(0, void main() );
GLSLC(0, { );
@ -115,10 +115,9 @@ static av_cold int init_filter(AVFilterContext *ctx, AVFrame *in)
RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd));
RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->initialized = 1;
@ -151,7 +150,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
if (!s->initialized)
RET(init_filter(ctx, in));
RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, out, in,
RET(ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, out, in,
s->sampler, NULL, 0));
RET(av_frame_copy_props(out, in));
@ -180,7 +179,6 @@ static av_cold void transpose_vulkan_uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
ff_vk_shader_free(vkctx, &s->shd);
if (s->sampler)

@ -40,10 +40,9 @@ typedef struct XFadeVulkanContext {
int64_t offset;
int initialized;
FFVulkanPipeline pl;
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
FFVkSPIRVShader shd;
FFVulkanShader shd;
VkSampler sampler;
// PTS when the fade should start (in IN_A timebase)
@ -326,7 +325,7 @@ static av_cold int init_vulkan(AVFilterContext *avctx)
XFadeVulkanContext *s = avctx->priv;
FFVulkanContext *vkctx = &s->vkctx;
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
FFVkSPIRVShader *shd = &s->shd;
FFVulkanShader *shd = &s->shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc;
@ -339,10 +338,11 @@ static av_cold int init_vulkan(AVFilterContext *avctx)
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_init_sampler(vkctx, &s->sampler, 1, VK_FILTER_NEAREST));
RET(ff_vk_shader_init(&s->pl, &s->shd, "xfade_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1);
RET(ff_vk_shader_init(vkctx, &s->shd, "xfade",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 32, 1,
0));
desc = (FFVulkanDescriptorSetBinding []) {
{
@ -372,14 +372,14 @@ static av_cold int init_vulkan(AVFilterContext *avctx)
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc, 3, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc, 3, 0, 0));
GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
GLSLC(1, float progress; );
GLSLC(0, }; );
ff_vk_add_push_constant(&s->pl, 0, sizeof(XFadeParameters),
VK_SHADER_STAGE_COMPUTE_BIT);
ff_vk_shader_add_push_const(&s->shd, 0, sizeof(XFadeParameters),
VK_SHADER_STAGE_COMPUTE_BIT);
// Add the right transition type function to the shader
GLSLD(transitions_map[s->transition]);
@ -395,10 +395,9 @@ static av_cold int init_vulkan(AVFilterContext *avctx)
RET(spv->compile_shader(spv, avctx, shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd));
RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->initialized = 1;
@ -441,7 +440,7 @@ static int xfade_frame(AVFilterContext *avctx, AVFrame *frame_a, AVFrame *frame_
progress = av_clipf((float)(s->pts - s->start_pts) / s->duration_pts,
0.f, 1.f);
RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->pl, output,
RET(ff_vk_filter_process_Nin(&s->vkctx, &s->e, &s->shd, output,
(AVFrame *[]){ frame_a, frame_b }, 2, s->sampler,
&(XFadeParameters){ progress }, sizeof(XFadeParameters)));
@ -632,7 +631,6 @@ static av_cold void uninit(AVFilterContext *avctx)
FFVulkanFunctions *vk = &vkctx->vkfn;
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
ff_vk_shader_free(vkctx, &s->shd);
if (s->sampler)

@ -39,10 +39,9 @@ typedef struct TestSrcVulkanContext {
FFVulkanContext vkctx;
int initialized;
FFVulkanPipeline pl;
FFVkExecPool e;
FFVkQueueFamilyCtx qf;
FFVkSPIRVShader shd;
FFVulkanShader shd;
/* Only used by color_vulkan */
uint8_t color_rgba[4];
@ -72,7 +71,7 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode
TestSrcVulkanContext *s = ctx->priv;
FFVulkanContext *vkctx = &s->vkctx;
const int planes = av_pix_fmt_count_planes(s->vkctx.output_format);
FFVkSPIRVShader *shd = &s->shd;
FFVulkanShader *shd = &s->shd;
FFVkSPIRVCompiler *spv;
FFVulkanDescriptorSetBinding *desc_set;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->vkctx.output_format);
@ -85,18 +84,19 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode
ff_vk_qf_init(vkctx, &s->qf, VK_QUEUE_COMPUTE_BIT);
RET(ff_vk_exec_pool_init(vkctx, &s->qf, &s->e, s->qf.nb_queues*4, 0, 0, 0, NULL));
RET(ff_vk_shader_init(&s->pl, &s->shd, "testsrc_compute",
VK_SHADER_STAGE_COMPUTE_BIT, 0));
ff_vk_shader_set_compute_sizes(&s->shd, 32, 32, 1);
RET(ff_vk_shader_init(vkctx, &s->shd, "scale",
VK_SHADER_STAGE_COMPUTE_BIT,
NULL, 0,
32, 32, 1,
0));
GLSLC(0, layout(push_constant, std430) uniform pushConstants { );
GLSLC(1, vec4 color_comp; );
GLSLC(0, }; );
GLSLC(0, );
ff_vk_add_push_constant(&s->pl, 0, sizeof(s->opts),
VK_SHADER_STAGE_COMPUTE_BIT);
ff_vk_shader_add_push_const(&s->shd, 0, sizeof(s->opts),
VK_SHADER_STAGE_COMPUTE_BIT);
desc_set = (FFVulkanDescriptorSetBinding []) {
{
@ -110,7 +110,7 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode
},
};
RET(ff_vk_pipeline_descriptor_set_add(vkctx, &s->pl, shd, desc_set, 1, 0, 0));
RET(ff_vk_shader_add_descriptor_set(vkctx, &s->shd, desc_set, 1, 0, 0));
GLSLC(0, void main() );
GLSLC(0, { );
@ -181,10 +181,9 @@ static av_cold int init_filter(AVFilterContext *ctx, enum TestSrcVulkanMode mode
RET(spv->compile_shader(spv, ctx, shd, &spv_data, &spv_len, "main",
&spv_opaque));
RET(ff_vk_shader_create(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_shader_link(vkctx, shd, spv_data, spv_len, "main"));
RET(ff_vk_init_compute_pipeline(vkctx, &s->pl, shd));
RET(ff_vk_exec_pipeline_register(vkctx, &s->e, &s->pl));
RET(ff_vk_shader_register_exec(vkctx, &s->e, &s->shd));
s->initialized = 1;
@ -229,7 +228,7 @@ static int testsrc_vulkan_activate(AVFilterContext *ctx)
if (!s->picref)
return AVERROR(ENOMEM);
err = ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, s->picref, NULL,
err = ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, s->picref, NULL,
VK_NULL_HANDLE, &s->opts, sizeof(s->opts));
if (err < 0)
return err;
@ -248,7 +247,7 @@ static int testsrc_vulkan_activate(AVFilterContext *ctx)
frame->pict_type = AV_PICTURE_TYPE_I;
frame->sample_aspect_ratio = s->sar;
if (!s->draw_once) {
err = ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->pl, frame, NULL,
err = ff_vk_filter_process_simple(&s->vkctx, &s->e, &s->shd, frame, NULL,
VK_NULL_HANDLE, &s->opts, sizeof(s->opts));
if (err < 0) {
av_frame_free(&frame);
@ -311,7 +310,6 @@ static void testsrc_vulkan_uninit(AVFilterContext *avctx)
av_frame_free(&s->picref);
ff_vk_exec_pool_free(vkctx, &s->e);
ff_vk_pipeline_free(vkctx, &s->pl);
ff_vk_shader_free(vkctx, &s->shd);
ff_vk_uninit(&s->vkctx);

@ -238,7 +238,7 @@ int ff_vk_filter_init(AVFilterContext *avctx)
}
int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e,
FFVulkanPipeline *pl, AVFrame *out_f, AVFrame *in_f,
FFVulkanShader *shd, AVFrame *out_f, AVFrame *in_f,
VkSampler sampler, void *push_src, size_t push_size)
{
int err = 0;
@ -256,24 +256,24 @@ int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e,
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
RET(ff_vk_create_imageviews(vkctx, exec, out_views, out_f));
ff_vk_update_descriptor_img_array(vkctx, pl, exec, out_f, out_views, 0, !!in_f,
VK_IMAGE_LAYOUT_GENERAL,
VK_NULL_HANDLE);
ff_vk_shader_update_img_array(vkctx, exec, shd, out_f, out_views, 0, !!in_f,
VK_IMAGE_LAYOUT_GENERAL,
VK_NULL_HANDLE);
if (in_f) {
RET(ff_vk_exec_add_dep_frame(vkctx, exec, in_f,
VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT));
RET(ff_vk_create_imageviews(vkctx, exec, in_views, in_f));
ff_vk_update_descriptor_img_array(vkctx, pl, exec, in_f, in_views, 0, 0,
ff_vk_shader_update_img_array(vkctx, exec, shd, in_f, in_views, 0, 0,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
sampler);
}
/* Bind pipeline, update push data */
ff_vk_exec_bind_pipeline(vkctx, exec, pl);
ff_vk_exec_bind_shader(vkctx, exec, shd);
if (push_src)
ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT,
0, push_size, push_src);
ff_vk_shader_update_push_const(vkctx, exec, shd, VK_SHADER_STAGE_COMPUTE_BIT,
0, push_size, push_src);
/* Add data sync barriers */
ff_vk_frame_barrier(vkctx, exec, out_f, img_bar, &nb_img_bar,
@ -297,9 +297,9 @@ int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e,
});
vk->CmdDispatch(exec->buf,
FFALIGN(vkctx->output_width, pl->wg_size[0])/pl->wg_size[0],
FFALIGN(vkctx->output_height, pl->wg_size[1])/pl->wg_size[1],
pl->wg_size[2]);
FFALIGN(vkctx->output_width, shd->lg_size[0])/shd->lg_size[0],
FFALIGN(vkctx->output_height, shd->lg_size[1])/shd->lg_size[1],
shd->lg_size[2]);
return ff_vk_exec_submit(vkctx, exec);
fail:
@ -308,7 +308,7 @@ fail:
}
int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e,
FFVulkanPipeline *pls[2],
FFVulkanShader *shd_list[2],
AVFrame *out, AVFrame *tmp, AVFrame *in,
VkSampler sampler, void *push_src, size_t push_size)
{
@ -364,30 +364,30 @@ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e,
});
for (int i = 0; i < 2; i++) {
FFVulkanPipeline *pl = pls[i];
FFVulkanShader *shd = shd_list[i];
AVFrame *src_f = !i ? in : tmp;
AVFrame *dst_f = !i ? tmp : out;
VkImageView *src_views = !i ? in_views : tmp_views;
VkImageView *dst_views = !i ? tmp_views : out_views;
ff_vk_update_descriptor_img_array(vkctx, pl, exec, src_f, src_views, 0, 0,
!i ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL :
VK_IMAGE_LAYOUT_GENERAL,
sampler);
ff_vk_update_descriptor_img_array(vkctx, pl, exec, dst_f, dst_views, 0, 1,
VK_IMAGE_LAYOUT_GENERAL,
VK_NULL_HANDLE);
ff_vk_shader_update_img_array(vkctx, exec, shd, src_f, src_views, 0, 0,
!i ? VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL :
VK_IMAGE_LAYOUT_GENERAL,
sampler);
ff_vk_shader_update_img_array(vkctx, exec, shd, dst_f, dst_views, 0, 1,
VK_IMAGE_LAYOUT_GENERAL,
VK_NULL_HANDLE);
/* Bind pipeline, update push data */
ff_vk_exec_bind_pipeline(vkctx, exec, pl);
ff_vk_exec_bind_shader(vkctx, exec, shd);
if (push_src)
ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT,
0, push_size, push_src);
ff_vk_shader_update_push_const(vkctx, exec, shd, VK_SHADER_STAGE_COMPUTE_BIT,
0, push_size, push_src);
vk->CmdDispatch(exec->buf,
FFALIGN(vkctx->output_width, pl->wg_size[0])/pl->wg_size[0],
FFALIGN(vkctx->output_height, pl->wg_size[1])/pl->wg_size[1],
pl->wg_size[2]);
FFALIGN(vkctx->output_width, shd->lg_size[0])/shd->lg_size[0],
FFALIGN(vkctx->output_height, shd->lg_size[1])/shd->lg_size[1],
shd->lg_size[2]);
}
return ff_vk_exec_submit(vkctx, exec);
@ -397,7 +397,7 @@ fail:
}
int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e,
FFVulkanPipeline *pl,
FFVulkanShader *shd,
AVFrame *out, AVFrame *in[], int nb_in,
VkSampler sampler, void *push_src, size_t push_size)
{
@ -425,19 +425,19 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e,
}
/* Update descriptor sets */
ff_vk_update_descriptor_img_array(vkctx, pl, exec, out, out_views, 0, nb_in,
VK_IMAGE_LAYOUT_GENERAL,
VK_NULL_HANDLE);
ff_vk_shader_update_img_array(vkctx, exec, shd, out, out_views, 0, nb_in,
VK_IMAGE_LAYOUT_GENERAL,
VK_NULL_HANDLE);
for (int i = 0; i < nb_in; i++)
ff_vk_update_descriptor_img_array(vkctx, pl, exec, in[i], in_views[i], 0, i,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
sampler);
ff_vk_shader_update_img_array(vkctx, exec, shd, in[i], in_views[i], 0, i,
VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
sampler);
/* Bind pipeline, update push data */
ff_vk_exec_bind_pipeline(vkctx, exec, pl);
ff_vk_exec_bind_shader(vkctx, exec, shd);
if (push_src)
ff_vk_update_push_exec(vkctx, exec, pl, VK_SHADER_STAGE_COMPUTE_BIT,
0, push_size, push_src);
ff_vk_shader_update_push_const(vkctx, exec, shd, VK_SHADER_STAGE_COMPUTE_BIT,
0, push_size, push_src);
/* Add data sync barriers */
ff_vk_frame_barrier(vkctx, exec, out, img_bar, &nb_img_bar,
@ -461,9 +461,9 @@ int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e,
});
vk->CmdDispatch(exec->buf,
FFALIGN(vkctx->output_width, pl->wg_size[0])/pl->wg_size[0],
FFALIGN(vkctx->output_height, pl->wg_size[1])/pl->wg_size[1],
pl->wg_size[2]);
FFALIGN(vkctx->output_width, shd->lg_size[0])/shd->lg_size[0],
FFALIGN(vkctx->output_height, shd->lg_size[1])/shd->lg_size[1],
shd->lg_size[2]);
return ff_vk_exec_submit(vkctx, exec);
fail:

@ -43,14 +43,14 @@ int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s,
* Submit a compute shader with a zero/one input and single out for execution.
*/
int ff_vk_filter_process_simple(FFVulkanContext *vkctx, FFVkExecPool *e,
FFVulkanPipeline *pl, AVFrame *out_f, AVFrame *in_f,
FFVulkanShader *shd, AVFrame *out_f, AVFrame *in_f,
VkSampler sampler, void *push_src, size_t push_size);
/**
* Submit a compute shader with a single in and single out with 2 stages.
*/
int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e,
FFVulkanPipeline *pls[2],
FFVulkanShader *shd_list[2],
AVFrame *out, AVFrame *tmp, AVFrame *in,
VkSampler sampler, void *push_src, size_t push_size);
@ -58,7 +58,7 @@ int ff_vk_filter_process_2pass(FFVulkanContext *vkctx, FFVkExecPool *e,
* Up to 16 inputs, one output
*/
int ff_vk_filter_process_Nin(FFVulkanContext *vkctx, FFVkExecPool *e,
FFVulkanPipeline *pl,
FFVulkanShader *shd,
AVFrame *out, AVFrame *in[], int nb_in,
VkSampler sampler, void *push_src, size_t push_size);

@ -137,7 +137,7 @@ static const glslang_resource_t glslc_resource_limits = {
};
static int glslc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx,
FFVkSPIRVShader *shd, uint8_t **data,
FFVulkanShader *shd, uint8_t **data,
size_t *size, const char *entrypoint,
void **opaque)
{
@ -153,7 +153,7 @@ static int glslc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx,
const glslang_input_t glslc_input = {
.language = GLSLANG_SOURCE_GLSL,
.stage = glslc_stage[shd->shader.stage],
.stage = glslc_stage[shd->stage],
.client = GLSLANG_CLIENT_VULKAN,
/* GLSLANG_TARGET_VULKAN_1_2 before 11.6 resulted in targeting 1.0 */
#if (((GLSLANG_VERSION_MAJOR) > 11) || ((GLSLANG_VERSION_MAJOR) == 11 && \

@ -22,7 +22,7 @@
#include "vulkan_spirv.h"
static int shdc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx,
FFVkSPIRVShader *shd, uint8_t **data,
FFVulkanShader *shd, uint8_t **data,
size_t *size, const char *entrypoint,
void **opaque)
{
@ -57,7 +57,7 @@ static int shdc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx,
res = shaderc_compile_into_spv((shaderc_compiler_t)ctx->priv,
shd->src.str, strlen(shd->src.str),
shdc_kind[shd->shader.stage],
shdc_kind[shd->stage],
shd->name, entrypoint, opts);
shaderc_compile_options_release(opts);

@ -27,7 +27,7 @@
typedef struct FFVkSPIRVCompiler {
void *priv;
int (*compile_shader)(struct FFVkSPIRVCompiler *ctx, void *avctx,
struct FFVkSPIRVShader *shd, uint8_t **data,
struct FFVulkanShader *shd, uint8_t **data,
size_t *size, const char *entrypoint, void **opaque);
void (*free_shader)(struct FFVkSPIRVCompiler *ctx, void **opaque);
void (*uninit)(struct FFVkSPIRVCompiler **ctx);

@ -1191,17 +1191,18 @@ int ff_vk_get_pooled_buffer(FFVulkanContext *ctx, AVBufferPool **buf_pool,
return 0;
}
int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size,
VkShaderStageFlagBits stage)
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size,
VkShaderStageFlagBits stage)
{
VkPushConstantRange *pc;
pl->push_consts = av_realloc_array(pl->push_consts, sizeof(*pl->push_consts),
pl->push_consts_num + 1);
if (!pl->push_consts)
shd->push_consts = av_realloc_array(shd->push_consts,
sizeof(*shd->push_consts),
shd->push_consts_num + 1);
if (!shd->push_consts)
return AVERROR(ENOMEM);
pc = &pl->push_consts[pl->push_consts_num++];
pc = &shd->push_consts[shd->push_consts_num++];
memset(pc, 0, sizeof(*pc));
pc->stageFlags = stage;
@ -1397,44 +1398,76 @@ void ff_vk_frame_barrier(FFVulkanContext *s, FFVkExecContext *e,
ff_vk_exec_update_frame(s, e, pic, &bar[*nb_bar - nb_images], NULL);
}
int ff_vk_shader_init(FFVulkanPipeline *pl, FFVkSPIRVShader *shd, const char *name,
VkShaderStageFlags stage, uint32_t required_subgroup_size)
int ff_vk_shader_init(FFVulkanContext *s, FFVulkanShader *shd, const char *name,
VkPipelineStageFlags stage,
const char *extensions[], int nb_extensions,
int lg_x, int lg_y, int lg_z,
uint32_t required_subgroup_size)
{
av_bprint_init(&shd->src, 0, AV_BPRINT_SIZE_UNLIMITED);
shd->shader.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
shd->shader.stage = stage;
shd->name = name;
shd->stage = stage;
shd->lg_size[0] = lg_x;
shd->lg_size[1] = lg_y;
shd->lg_size[2] = lg_z;
switch (shd->stage) {
case VK_SHADER_STAGE_ANY_HIT_BIT_KHR:
case VK_SHADER_STAGE_CALLABLE_BIT_KHR:
case VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR:
case VK_SHADER_STAGE_INTERSECTION_BIT_KHR:
case VK_SHADER_STAGE_MISS_BIT_KHR:
case VK_SHADER_STAGE_RAYGEN_BIT_KHR:
shd->bind_point = VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR;
break;
case VK_SHADER_STAGE_COMPUTE_BIT:
shd->bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
break;
default:
shd->bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS;
break;
};
if (required_subgroup_size) {
shd->shader.flags |= VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT;
shd->shader.pNext = &shd->subgroup_info;
shd->subgroup_info.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO;
shd->subgroup_info.requiredSubgroupSize = required_subgroup_size;
}
shd->name = name;
av_bprintf(&shd->src, "/* %s shader: %s */\n",
(stage == VK_SHADER_STAGE_TASK_BIT_EXT ||
stage == VK_SHADER_STAGE_MESH_BIT_EXT) ?
"Mesh" :
(shd->bind_point == VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR) ?
"Raytrace" :
(shd->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE) ?
"Compute" : "Graphics",
name);
GLSLF(0, #version %i ,460);
GLSLC(0, );
/* Common utilities */
GLSLC(0, #define IS_WITHIN(v1, v2) ((v1.x < v2.x) && (v1.y < v2.y)) );
GLSLC(0, );
GLSLC(0, #extension GL_EXT_buffer_reference : require );
GLSLC(0, #extension GL_EXT_buffer_reference2 : require );
return 0;
}
if (stage == VK_SHADER_STAGE_TASK_BIT_EXT ||
stage == VK_SHADER_STAGE_MESH_BIT_EXT)
GLSLC(0, #extension GL_EXT_mesh_shader : require );
void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z)
{
shd->local_size[0] = x;
shd->local_size[1] = y;
shd->local_size[2] = z;
for (int i = 0; i < nb_extensions; i++)
GLSLF(0, #extension %s : %s ,extensions[i], "require");
GLSLC(0, );
GLSLF(0, layout (local_size_x = %i, local_size_y = %i, local_size_z = %i) in;
, shd->lg_size[0], shd->lg_size[1], shd->lg_size[2]);
GLSLC(0, );
av_bprintf(&shd->src, "layout (local_size_x = %i, "
"local_size_y = %i, local_size_z = %i) in;\n\n",
shd->local_size[0], shd->local_size[1], shd->local_size[2]);
return 0;
}
void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio)
void ff_vk_shader_print(void *ctx, FFVulkanShader *shd, int prio)
{
int line = 0;
const char *p = shd->src.str;
@ -1456,37 +1489,86 @@ void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio)
av_bprint_finalize(&buf, NULL);
}
void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd)
static int init_pipeline_layout(FFVulkanContext *s, FFVulkanShader *shd)
{
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
av_bprint_finalize(&shd->src, NULL);
VkPipelineLayoutCreateInfo pipeline_layout_info;
if (shd->shader.module)
vk->DestroyShaderModule(s->hwctx->act_dev, shd->shader.module, s->hwctx->alloc);
/* Finally create the pipeline layout */
pipeline_layout_info = (VkPipelineLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pSetLayouts = shd->desc_layout,
.setLayoutCount = shd->nb_descriptor_sets,
.pushConstantRangeCount = shd->push_consts_num,
.pPushConstantRanges = shd->push_consts,
};
ret = vk->CreatePipelineLayout(s->hwctx->act_dev, &pipeline_layout_info,
s->hwctx->alloc, &shd->pipeline_layout);
if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_ERROR, "Unable to init pipeline layout: %s\n",
ff_vk_ret2str(ret));
return AVERROR_EXTERNAL;
}
return 0;
}
int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd,
uint8_t *spirv, size_t spirv_size, const char *entrypoint)
static int create_shader_module(FFVulkanContext *s, FFVulkanShader *shd,
VkShaderModule *mod,
uint8_t *spirv, size_t spirv_len)
{
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
VkShaderModuleCreateInfo shader_create;
shd->shader.pName = entrypoint;
VkShaderModuleCreateInfo shader_module_info = {
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.pNext = NULL,
.flags = 0x0,
.pCode = (void *)spirv,
.codeSize = spirv_len,
};
ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_module_info,
s->hwctx->alloc, mod);
if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_VERBOSE, "Error creating shader module: %s\n",
ff_vk_ret2str(ret));
return AVERROR_EXTERNAL;
}
return 0;
}
av_log(s, AV_LOG_VERBOSE, "Shader %s compiled! Size: %zu bytes\n",
shd->name, spirv_size);
static int init_compute_pipeline(FFVulkanContext *s, FFVulkanShader *shd,
VkShaderModule mod, const char *entrypoint)
{
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
shader_create.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
shader_create.pNext = NULL;
shader_create.codeSize = spirv_size;
shader_create.flags = 0;
shader_create.pCode = (void *)spirv;
VkComputePipelineCreateInfo pipeline_create_info = {
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.flags = (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) ?
VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : 0x0,
.layout = shd->pipeline_layout,
.stage = (VkPipelineShaderStageCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext = shd->subgroup_info.requiredSubgroupSize ?
&shd->subgroup_info : NULL,
.pName = entrypoint,
.flags = shd->subgroup_info.requiredSubgroupSize ?
VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT : 0x0,
.stage = shd->stage,
.module = mod,
},
};
ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_create, NULL,
&shd->shader.module);
ret = vk->CreateComputePipelines(s->hwctx->act_dev, VK_NULL_HANDLE, 1,
&pipeline_create_info,
s->hwctx->alloc, &shd->pipeline);
if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_VERBOSE, "Error creating shader module: %s\n",
av_log(s, AV_LOG_ERROR, "Unable to init compute pipeline: %s\n",
ff_vk_ret2str(ret));
return AVERROR_EXTERNAL;
}
@ -1494,6 +1576,110 @@ int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd,
return 0;
}
static int init_descriptors(FFVulkanContext *s, FFVulkanShader *shd)
{
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
shd->desc_layout = av_malloc_array(shd->nb_descriptor_sets,
sizeof(*shd->desc_layout));
if (!shd->desc_layout)
return AVERROR(ENOMEM);
if (!(s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER)) {
int has_singular = 0;
for (int i = 0; i < shd->nb_descriptor_sets; i++) {
if (shd->desc_set[i].singular) {
has_singular = 1;
break;
}
}
shd->use_push = (s->extensions & FF_VK_EXT_PUSH_DESCRIPTOR) &&
(shd->nb_descriptor_sets == 1) &&
!has_singular;
}
for (int i = 0; i < shd->nb_descriptor_sets; i++) {
FFVulkanDescriptorSet *set = &shd->desc_set[i];
VkDescriptorSetLayoutCreateInfo desc_layout_create = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = set->nb_bindings,
.pBindings = set->binding,
.flags = (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) ?
VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT :
(shd->use_push) ?
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR :
0x0,
};
ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev,
&desc_layout_create,
s->hwctx->alloc,
&shd->desc_layout[i]);
if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_ERROR, "Unable to create descriptor set layout: %s",
ff_vk_ret2str(ret));
return AVERROR_EXTERNAL;
}
if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
vk->GetDescriptorSetLayoutSizeEXT(s->hwctx->act_dev, shd->desc_layout[i],
&set->layout_size);
set->aligned_size = FFALIGN(set->layout_size,
s->desc_buf_props.descriptorBufferOffsetAlignment);
for (int j = 0; j < set->nb_bindings; j++)
vk->GetDescriptorSetLayoutBindingOffsetEXT(s->hwctx->act_dev,
shd->desc_layout[i],
j,
&set->binding_offset[j]);
}
}
return 0;
}
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd,
uint8_t *spirv, size_t spirv_len,
const char *entrypoint)
{
int err;
FFVulkanFunctions *vk = &s->vkfn;
err = init_descriptors(s, shd);
if (err < 0)
return err;
err = init_pipeline_layout(s, shd);
if (err < 0)
return err;
{
VkShaderModule mod;
err = create_shader_module(s, shd, &mod, spirv, spirv_len);
if (err < 0)
return err;
switch (shd->bind_point) {
case VK_PIPELINE_BIND_POINT_COMPUTE:
err = init_compute_pipeline(s, shd, mod, entrypoint);
break;
default:
av_log(s, AV_LOG_ERROR, "Unsupported shader type: %i\n",
shd->bind_point);
err = AVERROR(EINVAL);
break;
};
vk->DestroyShaderModule(s->hwctx->act_dev, mod, s->hwctx->alloc);
if (err < 0)
return err;
}
return 0;
}
static const struct descriptor_props {
size_t struct_size; /* Size of the opaque which updates the descriptor */
const char *type;
@ -1515,10 +1701,9 @@ static const struct descriptor_props {
[VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER] = { sizeof(VkBufferView), "imageBuffer", 1, 0, 0, 0, },
};
int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkSPIRVShader *shd,
FFVulkanDescriptorSetBinding *desc, int nb,
int singular, int print_to_shader_only)
int ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd,
FFVulkanDescriptorSetBinding *desc, int nb,
int singular, int print_to_shader_only)
{
int has_sampler = 0;
FFVulkanDescriptorSet *set;
@ -1527,13 +1712,14 @@ int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
goto print;
/* Actual layout allocated for the pipeline */
set = av_realloc_array(pl->desc_set, sizeof(*pl->desc_set),
pl->nb_descriptor_sets + 1);
set = av_realloc_array(shd->desc_set,
sizeof(*shd->desc_set),
shd->nb_descriptor_sets + 1);
if (!set)
return AVERROR(ENOMEM);
pl->desc_set = set;
shd->desc_set = set;
set = &set[pl->nb_descriptor_sets];
set = &set[shd->nb_descriptor_sets];
memset(set, 0, sizeof(*set));
set->binding = av_calloc(nb, sizeof(*set->binding));
@ -1567,34 +1753,34 @@ int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
for (int i = 0; i < nb; i++) {
int j;
VkDescriptorPoolSize *desc_pool_size;
for (j = 0; j < pl->nb_desc_pool_size; j++)
if (pl->desc_pool_size[j].type == desc[i].type)
for (j = 0; j < shd->nb_desc_pool_size; j++)
if (shd->desc_pool_size[j].type == desc[i].type)
break;
if (j >= pl->nb_desc_pool_size) {
desc_pool_size = av_realloc_array(pl->desc_pool_size,
if (j >= shd->nb_desc_pool_size) {
desc_pool_size = av_realloc_array(shd->desc_pool_size,
sizeof(*desc_pool_size),
pl->nb_desc_pool_size + 1);
shd->nb_desc_pool_size + 1);
if (!desc_pool_size)
return AVERROR(ENOMEM);
pl->desc_pool_size = desc_pool_size;
pl->nb_desc_pool_size++;
shd->desc_pool_size = desc_pool_size;
shd->nb_desc_pool_size++;
memset(&desc_pool_size[j], 0, sizeof(VkDescriptorPoolSize));
}
pl->desc_pool_size[j].type = desc[i].type;
pl->desc_pool_size[j].descriptorCount += FFMAX(desc[i].elems, 1);
shd->desc_pool_size[j].type = desc[i].type;
shd->desc_pool_size[j].descriptorCount += FFMAX(desc[i].elems, 1);
}
}
set->singular = singular;
set->nb_bindings = nb;
pl->nb_descriptor_sets++;
shd->nb_descriptor_sets++;
print:
/* Write shader info */
for (int i = 0; i < nb; i++) {
const struct descriptor_props *prop = &descriptor_props[desc[i].type];
GLSLA("layout (set = %i, binding = %i", pl->nb_descriptor_sets - 1, i);
GLSLA("layout (set = %i, binding = %i", shd->nb_descriptor_sets - 1, i);
if (desc[i].mem_layout)
GLSLA(", %s", desc[i].mem_layout);
@ -1627,26 +1813,26 @@ print:
return 0;
}
int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
FFVulkanPipeline *pl)
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool,
FFVulkanShader *shd)
{
int err;
if (!pl->nb_descriptor_sets)
if (!shd->nb_descriptor_sets)
return 0;
if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
pl->desc_bind = av_calloc(pl->nb_descriptor_sets, sizeof(*pl->desc_bind));
if (!pl->desc_bind)
shd->desc_bind = av_calloc(shd->nb_descriptor_sets, sizeof(*shd->desc_bind));
if (!shd->desc_bind)
return AVERROR(ENOMEM);
pl->bound_buffer_indices = av_calloc(pl->nb_descriptor_sets,
sizeof(*pl->bound_buffer_indices));
if (!pl->bound_buffer_indices)
shd->bound_buffer_indices = av_calloc(shd->nb_descriptor_sets,
sizeof(*shd->bound_buffer_indices));
if (!shd->bound_buffer_indices)
return AVERROR(ENOMEM);
for (int i = 0; i < pl->nb_descriptor_sets; i++) {
FFVulkanDescriptorSet *set = &pl->desc_set[i];
for (int i = 0; i < shd->nb_descriptor_sets; i++) {
FFVulkanDescriptorSet *set = &shd->desc_set[i];
int nb = set->singular ? 1 : pool->pool_size;
err = ff_vk_create_buf(s, &set->buf, set->aligned_size*nb,
@ -1661,34 +1847,34 @@ int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
if (err < 0)
return err;
pl->desc_bind[i] = (VkDescriptorBufferBindingInfoEXT) {
shd->desc_bind[i] = (VkDescriptorBufferBindingInfoEXT) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_BUFFER_BINDING_INFO_EXT,
.usage = set->usage,
.address = set->buf.address,
};
pl->bound_buffer_indices[i] = i;
shd->bound_buffer_indices[i] = i;
}
} else if (!pl->use_push) {
} else if (!shd->use_push) {
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
VkDescriptorSetLayout *tmp_layouts;
VkDescriptorSetAllocateInfo set_alloc_info;
VkDescriptorPoolCreateInfo pool_create_info;
for (int i = 0; i < pl->nb_desc_pool_size; i++)
pl->desc_pool_size[i].descriptorCount *= pool->pool_size;
for (int i = 0; i < shd->nb_desc_pool_size; i++)
shd->desc_pool_size[i].descriptorCount *= pool->pool_size;
pool_create_info = (VkDescriptorPoolCreateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.flags = 0,
.pPoolSizes = pl->desc_pool_size,
.poolSizeCount = pl->nb_desc_pool_size,
.maxSets = pl->nb_descriptor_sets*pool->pool_size,
.pPoolSizes = shd->desc_pool_size,
.poolSizeCount = shd->nb_desc_pool_size,
.maxSets = shd->nb_descriptor_sets*pool->pool_size,
};
ret = vk->CreateDescriptorPool(s->hwctx->act_dev, &pool_create_info,
s->hwctx->alloc, &pl->desc_pool);
s->hwctx->alloc, &shd->desc_pool);
if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_ERROR, "Unable to create descriptor pool: %s\n",
ff_vk_ret2str(ret));
@ -1701,33 +1887,33 @@ int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
/* Colate each execution context's descriptor set layouts */
for (int i = 0; i < pool->pool_size; i++)
for (int j = 0; j < pl->nb_descriptor_sets; j++)
tmp_layouts[i*pl->nb_descriptor_sets + j] = pl->desc_layout[j];
for (int j = 0; j < shd->nb_descriptor_sets; j++)
tmp_layouts[i*shd->nb_descriptor_sets + j] = shd->desc_layout[j];
set_alloc_info = (VkDescriptorSetAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = pl->desc_pool,
.descriptorPool = shd->desc_pool,
.pSetLayouts = tmp_layouts,
.descriptorSetCount = pool_create_info.maxSets,
};
pl->desc_sets = av_malloc_array(pool_create_info.maxSets,
shd->desc_sets = av_malloc_array(pool_create_info.maxSets,
sizeof(*tmp_layouts));
if (!pl->desc_sets) {
if (!shd->desc_sets) {
av_free(tmp_layouts);
return AVERROR(ENOMEM);
}
ret = vk->AllocateDescriptorSets(s->hwctx->act_dev, &set_alloc_info,
pl->desc_sets);
shd->desc_sets);
av_free(tmp_layouts);
if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_ERROR, "Unable to allocate descriptor set: %s\n",
ff_vk_ret2str(ret));
av_freep(&pl->desc_sets);
av_freep(&shd->desc_sets);
return AVERROR_EXTERNAL;
}
pl->assoc_pool = pool;
shd->assoc_pool = pool;
}
return 0;
@ -1749,38 +1935,37 @@ static inline void update_set_descriptor(FFVulkanContext *s, FFVkExecContext *e,
vk->GetDescriptorEXT(s->hwctx->act_dev, desc_get_info, desc_size, desc);
}
static inline void update_set_pool_write(FFVulkanContext *s,
FFVulkanPipeline *pl,
static inline void update_set_pool_write(FFVulkanContext *s, FFVulkanShader *shd,
FFVkExecContext *e,
FFVulkanDescriptorSet *desc_set, int set,
VkWriteDescriptorSet *write_info)
{
FFVulkanFunctions *vk = &s->vkfn;
if (desc_set->singular) {
for (int i = 0; i < pl->assoc_pool->pool_size; i++) {
write_info->dstSet = pl->desc_sets[i*pl->nb_descriptor_sets + set];
for (int i = 0; i < shd->assoc_pool->pool_size; i++) {
write_info->dstSet = shd->desc_sets[i*shd->nb_descriptor_sets + set];
vk->UpdateDescriptorSets(s->hwctx->act_dev, 1, write_info, 0, NULL);
}
} else {
if (pl->use_push) {
if (shd->use_push) {
vk->CmdPushDescriptorSetKHR(e->buf,
pl->bind_point,
pl->pipeline_layout,
shd->bind_point,
shd->pipeline_layout,
set, 1,
write_info);
} else {
write_info->dstSet = pl->desc_sets[e->idx*pl->nb_descriptor_sets + set];
write_info->dstSet = shd->desc_sets[e->idx*shd->nb_descriptor_sets + set];
vk->UpdateDescriptorSets(s->hwctx->act_dev, 1, write_info, 0, NULL);
}
}
}
static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl,
static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanShader *shd,
FFVkExecContext *e, int set, int bind, int offs,
VkImageView view, VkImageLayout layout,
VkSampler sampler)
{
FFVulkanDescriptorSet *desc_set = &pl->desc_set[set];
FFVulkanDescriptorSet *desc_set = &shd->desc_set[set];
if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
VkDescriptorGetInfoEXT desc_get_info = {
@ -1834,18 +2019,19 @@ static int vk_set_descriptor_image(FFVulkanContext *s, FFVulkanPipeline *pl,
.descriptorType = desc_set->binding[bind].descriptorType,
.pImageInfo = &desc_pool_write_info_img,
};
update_set_pool_write(s, pl, e, desc_set, set, &desc_pool_write_info);
update_set_pool_write(s, shd, e, desc_set, set, &desc_pool_write_info);
}
return 0;
}
int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkExecContext *e, int set, int bind, int elem,
FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len,
VkFormat fmt)
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)
{
FFVulkanDescriptorSet *desc_set = &pl->desc_set[set];
FFVulkanDescriptorSet *desc_set = &shd->desc_set[set];
if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
VkDescriptorGetInfoEXT desc_get_info = {
@ -1899,208 +2085,84 @@ int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
.descriptorType = desc_set->binding[bind].descriptorType,
.pBufferInfo = &desc_pool_write_info_buf,
};
update_set_pool_write(s, pl, e, desc_set, set, &desc_pool_write_info);
update_set_pool_write(s, shd, e, desc_set, set, &desc_pool_write_info);
}
return 0;
}
void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkExecContext *e, AVFrame *f,
VkImageView *views, int set, int binding,
VkImageLayout layout, VkSampler sampler)
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)
{
AVHWFramesContext *hwfc = (AVHWFramesContext *)f->hw_frames_ctx->data;
const int nb_planes = av_pix_fmt_count_planes(hwfc->sw_format);
for (int i = 0; i < nb_planes; i++)
vk_set_descriptor_image(s, pl, e, set, binding, i,
vk_set_descriptor_image(s, shd, e, set, binding, i,
views[i], layout, sampler);
}
void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanPipeline *pl,
VkShaderStageFlagBits stage,
int offset, size_t size, void *src)
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanShader *shd,
VkShaderStageFlagBits stage,
int offset, size_t size, void *src)
{
FFVulkanFunctions *vk = &s->vkfn;
vk->CmdPushConstants(e->buf, pl->pipeline_layout,
vk->CmdPushConstants(e->buf, shd->pipeline_layout,
stage, offset, size, src);
}
static int init_descriptors(FFVulkanContext *s, FFVulkanPipeline *pl)
{
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
pl->desc_layout = av_malloc_array(pl->nb_descriptor_sets,
sizeof(*pl->desc_layout));
if (!pl->desc_layout)
return AVERROR(ENOMEM);
if (!(s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER)) {
int has_singular = 0;
for (int i = 0; i < pl->nb_descriptor_sets; i++) {
if (pl->desc_set[i].singular) {
has_singular = 1;
break;
}
}
pl->use_push = (s->extensions & FF_VK_EXT_PUSH_DESCRIPTOR) &&
(pl->nb_descriptor_sets == 1) &&
!has_singular;
}
for (int i = 0; i < pl->nb_descriptor_sets; i++) {
FFVulkanDescriptorSet *set = &pl->desc_set[i];
VkDescriptorSetLayoutCreateInfo desc_layout_create = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = set->nb_bindings,
.pBindings = set->binding,
.flags = (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) ?
VK_DESCRIPTOR_SET_LAYOUT_CREATE_DESCRIPTOR_BUFFER_BIT_EXT :
(pl->use_push) ?
VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR :
0x0,
};
ret = vk->CreateDescriptorSetLayout(s->hwctx->act_dev,
&desc_layout_create,
s->hwctx->alloc,
&pl->desc_layout[i]);
if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_ERROR, "Unable to create descriptor set layout: %s",
ff_vk_ret2str(ret));
return AVERROR_EXTERNAL;
}
if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
vk->GetDescriptorSetLayoutSizeEXT(s->hwctx->act_dev, pl->desc_layout[i],
&set->layout_size);
set->aligned_size = FFALIGN(set->layout_size,
s->desc_buf_props.descriptorBufferOffsetAlignment);
for (int j = 0; j < set->nb_bindings; j++)
vk->GetDescriptorSetLayoutBindingOffsetEXT(s->hwctx->act_dev,
pl->desc_layout[i],
j,
&set->binding_offset[j]);
}
}
return 0;
}
static int init_pipeline_layout(FFVulkanContext *s, FFVulkanPipeline *pl)
{
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
VkPipelineLayoutCreateInfo pipeline_layout_info;
/* Finally create the pipeline layout */
pipeline_layout_info = (VkPipelineLayoutCreateInfo) {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pSetLayouts = pl->desc_layout,
.setLayoutCount = pl->nb_descriptor_sets,
.pushConstantRangeCount = pl->push_consts_num,
.pPushConstantRanges = pl->push_consts,
};
ret = vk->CreatePipelineLayout(s->hwctx->act_dev, &pipeline_layout_info,
s->hwctx->alloc, &pl->pipeline_layout);
if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_ERROR, "Unable to init pipeline layout: %s\n",
ff_vk_ret2str(ret));
return AVERROR_EXTERNAL;
}
return 0;
}
int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkSPIRVShader *shd)
{
int err;
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
VkComputePipelineCreateInfo pipeline_create_info;
err = init_descriptors(s, pl);
if (err < 0)
return err;
err = init_pipeline_layout(s, pl);
if (err < 0)
return err;
pipeline_create_info = (VkComputePipelineCreateInfo) {
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.flags = (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) ?
VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT : 0x0,
.layout = pl->pipeline_layout,
.stage = shd->shader,
};
ret = vk->CreateComputePipelines(s->hwctx->act_dev, VK_NULL_HANDLE, 1,
&pipeline_create_info,
s->hwctx->alloc, &pl->pipeline);
if (ret != VK_SUCCESS) {
av_log(s, AV_LOG_ERROR, "Unable to init compute pipeline: %s\n",
ff_vk_ret2str(ret));
return AVERROR_EXTERNAL;
}
pl->bind_point = VK_PIPELINE_BIND_POINT_COMPUTE;
pl->wg_size[0] = shd->local_size[0];
pl->wg_size[1] = shd->local_size[1];
pl->wg_size[2] = shd->local_size[2];
return 0;
}
void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanPipeline *pl)
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanShader *shd)
{
FFVulkanFunctions *vk = &s->vkfn;
VkDeviceSize offsets[1024];
/* Bind pipeline */
vk->CmdBindPipeline(e->buf, pl->bind_point, pl->pipeline);
vk->CmdBindPipeline(e->buf, shd->bind_point, shd->pipeline);
if (pl->nb_descriptor_sets) {
if (shd->nb_descriptor_sets) {
if (s->extensions & FF_VK_EXT_DESCRIPTOR_BUFFER) {
for (int i = 0; i < pl->nb_descriptor_sets; i++)
offsets[i] = pl->desc_set[i].singular ? 0 : pl->desc_set[i].aligned_size*e->idx;
for (int i = 0; i < shd->nb_descriptor_sets; i++)
offsets[i] = shd->desc_set[i].singular ? 0 : shd->desc_set[i].aligned_size*e->idx;
/* Bind descriptor buffers */
vk->CmdBindDescriptorBuffersEXT(e->buf, pl->nb_descriptor_sets, pl->desc_bind);
vk->CmdBindDescriptorBuffersEXT(e->buf, shd->nb_descriptor_sets, shd->desc_bind);
/* Binding offsets */
vk->CmdSetDescriptorBufferOffsetsEXT(e->buf, pl->bind_point, pl->pipeline_layout,
0, pl->nb_descriptor_sets,
pl->bound_buffer_indices, offsets);
} else if (!pl->use_push) {
vk->CmdBindDescriptorSets(e->buf, pl->bind_point, pl->pipeline_layout,
0, pl->nb_descriptor_sets,
&pl->desc_sets[e->idx*pl->nb_descriptor_sets],
vk->CmdSetDescriptorBufferOffsetsEXT(e->buf, shd->bind_point, shd->pipeline_layout,
0, shd->nb_descriptor_sets,
shd->bound_buffer_indices, offsets);
} else if (!shd->use_push) {
vk->CmdBindDescriptorSets(e->buf, shd->bind_point, shd->pipeline_layout,
0, shd->nb_descriptor_sets,
&shd->desc_sets[e->idx*shd->nb_descriptor_sets],
0, NULL);
}
}
}
void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl)
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd)
{
FFVulkanFunctions *vk = &s->vkfn;
if (pl->pipeline)
vk->DestroyPipeline(s->hwctx->act_dev, pl->pipeline, s->hwctx->alloc);
if (pl->pipeline_layout)
vk->DestroyPipelineLayout(s->hwctx->act_dev, pl->pipeline_layout,
av_bprint_finalize(&shd->src, NULL);
#if 0
if (shd->shader.module)
vk->DestroyShaderModule(s->hwctx->act_dev, shd->shader.module,
s->hwctx->alloc);
#endif
if (shd->pipeline)
vk->DestroyPipeline(s->hwctx->act_dev, shd->pipeline, s->hwctx->alloc);
if (shd->pipeline_layout)
vk->DestroyPipelineLayout(s->hwctx->act_dev, shd->pipeline_layout,
s->hwctx->alloc);
for (int i = 0; i < pl->nb_descriptor_sets; i++) {
FFVulkanDescriptorSet *set = &pl->desc_set[i];
for (int i = 0; i < shd->nb_descriptor_sets; i++) {
FFVulkanDescriptorSet *set = &shd->desc_set[i];
if (set->buf.mem)
ff_vk_unmap_buffer(s, &set->buf, 0);
ff_vk_free_buf(s, &set->buf);
@ -2108,23 +2170,23 @@ void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl)
av_free(set->binding_offset);
}
for (int i = 0; i < pl->nb_descriptor_sets; i++)
if (pl->desc_layout[i])
vk->DestroyDescriptorSetLayout(s->hwctx->act_dev, pl->desc_layout[i],
for (int i = 0; i < shd->nb_descriptor_sets; i++)
if (shd->desc_layout[i])
vk->DestroyDescriptorSetLayout(s->hwctx->act_dev, shd->desc_layout[i],
s->hwctx->alloc);
if (pl->desc_pool)
vk->DestroyDescriptorPool(s->hwctx->act_dev, pl->desc_pool,
if (shd->desc_pool)
vk->DestroyDescriptorPool(s->hwctx->act_dev, shd->desc_pool,
s->hwctx->alloc);
av_freep(&pl->desc_pool_size);
av_freep(&pl->desc_layout);
av_freep(&pl->desc_sets);
av_freep(&pl->desc_set);
av_freep(&pl->desc_bind);
av_freep(&pl->bound_buffer_indices);
av_freep(&pl->push_consts);
pl->push_consts_num = 0;
av_freep(&shd->desc_pool_size);
av_freep(&shd->desc_layout);
av_freep(&shd->desc_sets);
av_freep(&shd->desc_set);
av_freep(&shd->desc_bind);
av_freep(&shd->bound_buffer_indices);
av_freep(&shd->push_consts);
shd->push_consts_num = 0;
}
void ff_vk_uninit(FFVulkanContext *s)

@ -72,14 +72,6 @@
#define DUP_SAMPLER(x) { x, x, x, x }
typedef struct FFVkSPIRVShader {
const char *name; /* Name for id/debugging purposes */
AVBPrint src;
int local_size[3]; /* Compute shader workgroup sizes */
VkPipelineShaderStageCreateInfo shader;
VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info;
} FFVkSPIRVShader;
typedef struct FFVulkanDescriptorSetBinding {
const char *name;
VkDescriptorType type;
@ -204,20 +196,35 @@ typedef struct FFVulkanDescriptorSet {
int singular;
} FFVulkanDescriptorSet;
typedef struct FFVulkanPipeline {
typedef struct FFVulkanShader {
/* Name for id/debugging purposes */
const char *name;
/* Shader text */
AVBPrint src;
/* Compute shader local group sizes */
int lg_size[3];
/* Shader bind point/type */
VkPipelineStageFlags stage;
VkPipelineBindPoint bind_point;
/* Contexts */
/* Creation info */
VkPipelineShaderStageRequiredSubgroupSizeCreateInfo subgroup_info;
/* Base shader object */
union {
VkPipeline pipeline;
};
/* Pipeline layout */
VkPipelineLayout pipeline_layout;
VkPipeline pipeline;
/* Push consts */
VkPushConstantRange *push_consts;
int push_consts_num;
/* Workgroup */
int wg_size[3];
/* Descriptor buffer */
VkDescriptorSetLayout *desc_layout;
FFVulkanDescriptorSet *desc_set;
@ -233,7 +240,7 @@ typedef struct FFVulkanPipeline {
int nb_desc_pool_size;
int total_desc_sets;
FFVkExecPool *assoc_pool;
} FFVulkanPipeline;
} FFVulkanShader;
typedef struct FFVulkanContext {
const AVClass *class;
@ -472,59 +479,86 @@ int ff_vk_init_sampler(FFVulkanContext *s, VkSampler *sampler,
int unnorm_coords, VkFilter filt);
/**
* Shader management.
* Initialize a shader object, with a specific set of extensions, type+bind,
* local group size, and subgroup requirements.
*/
int ff_vk_shader_init(FFVulkanPipeline *pl, FFVkSPIRVShader *shd, const char *name,
VkShaderStageFlags stage, uint32_t required_subgroup_size);
void ff_vk_shader_set_compute_sizes(FFVkSPIRVShader *shd, int x, int y, int z);
void ff_vk_shader_print(void *ctx, FFVkSPIRVShader *shd, int prio);
int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd,
uint8_t *spirv, size_t spirv_size, const char *entrypoint);
void ff_vk_shader_free(FFVulkanContext *s, FFVkSPIRVShader *shd);
int ff_vk_shader_init(FFVulkanContext *s, FFVulkanShader *shd, const char *name,
VkPipelineStageFlags stage,
const char *extensions[], int nb_extensions,
int lg_x, int lg_y, int lg_z,
uint32_t required_subgroup_size);
/**
* Add/update push constants for execution.
* Output the shader code as logging data, with a specific
* priority.
*/
int ff_vk_add_push_constant(FFVulkanPipeline *pl, int offset, int size,
VkShaderStageFlagBits stage);
void ff_vk_update_push_exec(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanPipeline *pl,
VkShaderStageFlagBits stage,
int offset, size_t size, void *src);
void ff_vk_shader_print(void *ctx, FFVulkanShader *shd, int prio);
/**
* Add descriptor to a pipeline. Must be called before pipeline init.
* Link a shader into an executable.
*/
int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkSPIRVShader *shd,
FFVulkanDescriptorSetBinding *desc, int nb,
int singular, int print_to_shader_only);
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd,
uint8_t *spirv, size_t spirv_len,
const char *entrypoint);
/* Initialize/free a pipeline. */
int ff_vk_init_compute_pipeline(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkSPIRVShader *shd);
void ff_vk_pipeline_free(FFVulkanContext *s, FFVulkanPipeline *pl);
/**
* Add/update push constants for execution.
*/
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size,
VkShaderStageFlagBits stage);
/**
* Register a pipeline with an exec pool.
* Add descriptor to a shader. Must be called before shader init.
*/
int ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd,
FFVulkanDescriptorSetBinding *desc, int nb,
int singular, int print_to_shader_only);
/**
* Register a shader with an exec pool.
* Pool may be NULL if all descriptor sets are read-only.
*/
int ff_vk_exec_pipeline_register(FFVulkanContext *s, FFVkExecPool *pool,
FFVulkanPipeline *pl);
/* Bind pipeline */
void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanPipeline *pl);
int ff_vk_set_descriptor_buffer(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkExecContext *e, int set, int bind, int elem,
FFVkBuffer *buf, VkDeviceSize offset, VkDeviceSize len,
VkFormat fmt);
void ff_vk_update_descriptor_img_array(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkExecContext *e, AVFrame *f,
VkImageView *views, int set, int binding,
VkImageLayout layout, VkSampler sampler);
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool,
FFVulkanShader *shd);
/**
* Bind a shader.
*/
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanShader *shd);
/**
* Update push constant in a shader.
* Must be called before binding the shader.
*/
void ff_vk_shader_update_push_const(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanShader *shd,
VkShaderStageFlagBits stage,
int offset, size_t size, void *src);
/**
* Update a descriptor in a buffer with a buffer.
* Must be called before binding the shader.
*/
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 an image array..
* Must be called before binding the shader.
*/
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);
/**
* Free a shader.
*/
void ff_vk_shader_free(FFVulkanContext *s, FFVulkanShader *shd);
/**
* Frees main context.

Loading…
Cancel
Save