1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

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.
This commit is contained in:
Lynne 2024-09-28 13:13:41 +02:00
parent aad4d5745d
commit 0a37d5a3b1
No known key found for this signature in database
GPG Key ID: A2FEA5F03F034464
19 changed files with 704 additions and 626 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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:

View File

@ -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);

View File

@ -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 && \

View File

@ -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);

View File

@ -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);

View File

@ -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 );
if (stage == VK_SHADER_STAGE_TASK_BIT_EXT ||
stage == VK_SHADER_STAGE_MESH_BIT_EXT)
GLSLC(0, #extension GL_EXT_mesh_shader : require );
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, );
return 0;
}
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;
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]);
}
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,35 +1489,49 @@ 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)
{
FFVulkanFunctions *vk = &s->vkfn;
av_bprint_finalize(&shd->src, NULL);
if (shd->shader.module)
vk->DestroyShaderModule(s->hwctx->act_dev, shd->shader.module, s->hwctx->alloc);
}
int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd,
uint8_t *spirv, size_t spirv_size, const char *entrypoint)
static int init_pipeline_layout(FFVulkanContext *s, FFVulkanShader *shd)
{
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
VkShaderModuleCreateInfo shader_create;
VkPipelineLayoutCreateInfo pipeline_layout_info;
shd->shader.pName = entrypoint;
/* 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,
};
av_log(s, AV_LOG_VERBOSE, "Shader %s compiled! Size: %zu bytes\n",
shd->name, spirv_size);
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;
}
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;
return 0;
}
ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_create, NULL,
&shd->shader.module);
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_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));
@ -1494,6 +1541,145 @@ int ff_vk_shader_create(FFVulkanContext *s, FFVkSPIRVShader *shd,
return 0;
}
static int init_compute_pipeline(FFVulkanContext *s, FFVulkanShader *shd,
VkShaderModule mod, const char *entrypoint)
{
VkResult ret;
FFVulkanFunctions *vk = &s->vkfn;
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->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_ERROR, "Unable to init compute pipeline: %s\n",
ff_vk_ret2str(ret));
return AVERROR_EXTERNAL;
}
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)

View File

@ -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);
/**
* Output the shader code as logging data, with a specific
* priority.
*/
void ff_vk_shader_print(void *ctx, FFVulkanShader *shd, int prio);
/**
* Link a shader into an executable.
*/
int ff_vk_shader_link(FFVulkanContext *s, FFVulkanShader *shd,
uint8_t *spirv, size_t spirv_len,
const char *entrypoint);
/**
* Add/update push constants for execution.
*/
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);
int ff_vk_shader_add_push_const(FFVulkanShader *shd, int offset, int size,
VkShaderStageFlagBits stage);
/**
* Add descriptor to a pipeline. Must be called before pipeline init.
* Add descriptor to a shader. Must be called before shader init.
*/
int ff_vk_pipeline_descriptor_set_add(FFVulkanContext *s, FFVulkanPipeline *pl,
FFVkSPIRVShader *shd,
FFVulkanDescriptorSetBinding *desc, int nb,
int singular, int print_to_shader_only);
/* 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);
int ff_vk_shader_add_descriptor_set(FFVulkanContext *s, FFVulkanShader *shd,
FFVulkanDescriptorSetBinding *desc, int nb,
int singular, int print_to_shader_only);
/**
* Register a pipeline with an exec pool.
* 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);
int ff_vk_shader_register_exec(FFVulkanContext *s, FFVkExecPool *pool,
FFVulkanShader *shd);
/* Bind pipeline */
void ff_vk_exec_bind_pipeline(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanPipeline *pl);
/**
* Bind a shader.
*/
void ff_vk_exec_bind_shader(FFVulkanContext *s, FFVkExecContext *e,
FFVulkanShader *shd);
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);
/**
* 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);
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);
/**
* 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.