On 21/06/18 17:55, Rostislav Pehlivanov wrote: > This commit adds a common code for use in Vulkan filters. It attempts > to ease the burden of writing Vulkan image filtering to a minimum, > which is pretty much a requirement considering how verbose the API is. > > It supports both compute and graphic pipelines and manages to abstract > the API to such a level there's no need to call any Vulkan functions > inside the init path of the code. Handling shader descriptors is probably > the bulk of the code, and despite the abstraction, it loses none of the > features for describing shader IO. > > In order to produce linkable shaders, it depends on the libshaderc > library (and depends on the latest stable version of it). This allows > for greater performance and flexibility than static built-in shaders > and also eliminates the cumbersome process of interfacing with glslang > to compile GLSL to SPIR-V. > > It's based off of the common opencl and provides similar interfaces for > filter pad init and config, with the addition that it also supports > in-place filtering. > > Signed-off-by: Rostislav Pehlivanov <atomnu...@gmail.com> > --- > configure | 12 +- > libavfilter/vulkan.c | 1192 ++++++++++++++++++++++++++++++++++++++++++ > libavfilter/vulkan.h | 223 ++++++++ > 3 files changed, 1425 insertions(+), 2 deletions(-) > create mode 100644 libavfilter/vulkan.c > create mode 100644 libavfilter/vulkan.h > > diff --git a/configure b/configure > index 7623a1205a..97bd4225dc 100755 > --- a/configure > +++ b/configure > @@ -252,6 +252,7 @@ External library support: > --enable-librsvg enable SVG rasterization via librsvg [no] > --enable-librubberband enable rubberband needed for rubberband filter > [no] > --enable-librtmp enable RTMP[E] support via librtmp [no] > + --enable-libshaderc enable GLSL->SPIRV compilation via libshaderc [no] > --enable-libshine enable fixed-point MP3 encoding via libshine [no] > --enable-libsmbclient enable Samba protocol via libsmbclient [no] > --enable-libsnappy enable Snappy compression, needed for hap > encoding [no] > @@ -1709,6 +1710,7 @@ EXTERNAL_LIBRARY_LIST=" > libpulse > librsvg > librtmp > + libshaderc > libshine > libsmbclient > libsnappy > @@ -2228,6 +2230,7 @@ HAVE_LIST=" > opencl_dxva2 > opencl_vaapi_beignet > opencl_vaapi_intel_media > + shaderc_opt_perf > vulkan_drm_mod > perl > pod2man > @@ -3462,12 +3465,12 @@ avcodec_select="null_bsf" > avdevice_deps="avformat avcodec avutil" > avdevice_suggest="libm" > avfilter_deps="avutil" > -avfilter_suggest="libm" > +avfilter_suggest="libm libshaderc" > avformat_deps="avcodec avutil" > avformat_suggest="libm network zlib" > avresample_deps="avutil" > avresample_suggest="libm" > -avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl user32 > vaapi videotoolbox corefoundation corevideo coremedia bcrypt" > +avutil_suggest="clock_gettime ffnvcodec libm libdrm libmfx opencl vulkan > user32 vaapi videotoolbox corefoundation corevideo coremedia bcrypt" > postproc_deps="avutil gpl" > postproc_suggest="libm" > swresample_deps="avutil" > @@ -6056,6 +6059,7 @@ enabled libpulse && require_pkg_config > libpulse libpulse pulse/pulseaud > enabled librsvg && require_pkg_config librsvg librsvg-2.0 > librsvg-2.0/librsvg/rsvg.h rsvg_handle_render_cairo > enabled librtmp && require_pkg_config librtmp librtmp > librtmp/rtmp.h RTMP_Socket > enabled librubberband && require_pkg_config librubberband "rubberband >= > 1.8.1" rubberband/rubberband-c.h rubberband_new -lstdc++ && append > librubberband_extralibs "-lstdc++" > +enabled libshaderc && require libshaderc shaderc/shaderc.h > shaderc_compiler_initialize -lshaderc_shared > enabled libshine && require_pkg_config libshine shine > shine/layer3.h shine_encode_buffer > enabled libsmbclient && { check_pkg_config libsmbclient smbclient > libsmbclient.h smbc_init || > require libsmbclient libsmbclient.h smbc_init > -lsmbclient; } > @@ -6363,6 +6367,10 @@ enabled crystalhd && check_lib crystalhd "stdint.h > libcrystalhd/libcrystalhd_if. > enabled vulkan && > require_pkg_config vulkan "vulkan >= 1.1.73" "vulkan/vulkan.h" > vkCreateInstance > > +if enabled_all vulkan libshaderc ; then > + check_cc shaderc_opt_perf shaderc/shaderc.h "int t = > shaderc_optimization_level_performance" > +fi
Is there really no way to do this without a configure test? A preprocessor version check? (Or requiring a recent libshaderc, given that there is no compatibility to maintain.) > + > if enabled_all vulkan libdrm ; then > check_cpp_condition vulkan_drm_mod vulkan/vulkan.h "defined > VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME" > fi > diff --git a/libavfilter/vulkan.c b/libavfilter/vulkan.c > new file mode 100644 > index 0000000000..976e846fa3 > --- /dev/null > +++ b/libavfilter/vulkan.c > ... > +int ff_vk_init_pipeline_layout(AVFilterContext *avctx) > +{ > + VkResult ret; > + VulkanFilterContext *s = avctx->priv; > + > + { /* Init descriptor set pool */ > + VkDescriptorPoolCreateInfo pool_create_info = { > + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, > + .poolSizeCount = s->pool_size_desc_num, > + .pPoolSizes = s->pool_size_desc, > + .maxSets = s->descriptor_sets_num, > + }; > + > + ret = vkCreateDescriptorPool(s->hwctx->act_dev, &pool_create_info, > + s->hwctx->alloc, &s->desc_pool); > + av_freep(&s->pool_size_desc); > + if (ret != VK_SUCCESS) { > + av_log(avctx, AV_LOG_ERROR, "Unable to init descriptor set " > + "pool: %s\n", ff_vk_ret2str(ret)); > + return AVERROR_EXTERNAL; > + } > + } > + > + { /* Allocate descriptor sets */ > + VkDescriptorSetAllocateInfo alloc_info = { > + .sType = > VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, > + .descriptorPool = s->desc_pool, > + .descriptorSetCount = s->descriptor_sets_num, > + .pSetLayouts = s->desc_layout, > + }; > + > + s->desc_set = av_malloc(s->descriptor_sets_num*sizeof(*s->desc_set)); > + if (!s->desc_set) > + return AVERROR(ENOMEM); > + > + ret = vkAllocateDescriptorSets(s->hwctx->act_dev, &alloc_info, > + s->desc_set); > + if (ret != VK_SUCCESS) { > + av_log(avctx, AV_LOG_ERROR, "Unable to allocate descriptor set: > %s\n", > + ff_vk_ret2str(ret)); > + return AVERROR_EXTERNAL; > + } > + } > + > + { /* Finally create the pipeline layout */ > + VkPipelineLayoutCreateInfo spawn_pipeline_layout = { > + .sType = > VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, > + .setLayoutCount = s->descriptor_sets_num, > + .pSetLayouts = s->desc_layout, > + .pushConstantRangeCount = s->push_consts_num, > + .pPushConstantRanges = s->push_consts, > + }; > + > + ret = vkCreatePipelineLayout(s->hwctx->act_dev, > &spawn_pipeline_layout, > + s->hwctx->alloc, &s->pipeline_layout); > + av_freep(&s->push_consts); > + s->push_consts_num = 0; > + if (ret != VK_SUCCESS) { > + av_log(avctx, AV_LOG_ERROR, "Unable to init pipeline layout: > %s\n", > + ff_vk_ret2str(ret)); > + return AVERROR_EXTERNAL; > + } > + } > + > + { /* Descriptor template (for tightly packed descriptors) */ > + VK_LOAD_PFN(s->hwctx->inst, vkCreateDescriptorUpdateTemplateKHR); > + VkDescriptorUpdateTemplateCreateInfo *desc_template_info; > + > + s->desc_template = > av_malloc(s->descriptor_sets_num*sizeof(*s->desc_template)); > + if (!s->desc_template) > + return AVERROR(ENOMEM); > + > + /* Create update templates for the descriptor sets */ > + for (int i = 0; i < s->descriptor_sets_num; i++) { > + desc_template_info = &s->desc_template_info[i]; > + desc_template_info->pipelineLayout = s->pipeline_layout; > + ret = pfn_vkCreateDescriptorUpdateTemplateKHR(s->hwctx->act_dev, > + desc_template_info, > + s->hwctx->alloc, > + > &s->desc_template[i]); > + av_free((void *)desc_template_info->pDescriptorUpdateEntries); > + if (ret != VK_SUCCESS) { > + av_log(avctx, AV_LOG_ERROR, "Unable to init descriptor " > + "template: %s\n", ff_vk_ret2str(ret)); > + return AVERROR_EXTERNAL; > + } > + } > + > + av_freep(&s->desc_template_info); > + } > + > + return 0; > +} A number of the things here seem to leak - desc_sets, desc_template, and some of the Vulkan structures too. I suggest going through this with valgrind to make sure you've cleaned up everything. Not much else I can usefully comment on here, but looks generally ok. Thanks, - Mark _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel