diff options
author | Lynne <dev@lynne.ee> | 2021-11-19 12:07:10 +0100 |
---|---|---|
committer | Lynne <dev@lynne.ee> | 2021-11-19 13:44:47 +0100 |
commit | b2aec70bd6bbf4620d363dfdc7d9e54f2f32f9ee (patch) | |
tree | 1762efe01831e0e0d9804c1d551c739b3bb58bbf | |
parent | d1133e8c44f457f0698c48f2efcedbd8626b3cee (diff) | |
download | ffmpeg-b2aec70bd6bbf4620d363dfdc7d9e54f2f32f9ee.tar.gz |
lavu/vulkan: add option to switch between shader compilers and cleanup glslang
-rw-r--r-- | libavfilter/Makefile | 2 | ||||
-rw-r--r-- | libavfilter/glslang.c | 19 | ||||
-rw-r--r-- | libavfilter/vulkan.c | 3 | ||||
-rw-r--r-- | libavutil/vulkan.c | 33 | ||||
-rw-r--r-- | libavutil/vulkan.h | 15 | ||||
-rw-r--r-- | libavutil/vulkan_glslang.c | 68 | ||||
-rw-r--r-- | libavutil/vulkan_glslang.h | 41 |
7 files changed, 82 insertions, 99 deletions
diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 07b4a639ec..868ba68b79 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -578,8 +578,6 @@ SKIPHEADERS-$(CONFIG_OPENCL) += opencl.h SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_vpp.h SKIPHEADERS-$(CONFIG_VULKAN) += vulkan.h -OBJS-$(CONFIG_LIBGLSLANG) += glslang.o - TOOLS = graph2dot TESTPROGS = drawutils filtfmts formats integral diff --git a/libavfilter/glslang.c b/libavfilter/glslang.c deleted file mode 100644 index 9aa41567a3..0000000000 --- a/libavfilter/glslang.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/vulkan_glslang.c" diff --git a/libavfilter/vulkan.c b/libavfilter/vulkan.c index e0fcf87f21..08e0c37cc4 100644 --- a/libavfilter/vulkan.c +++ b/libavfilter/vulkan.c @@ -188,8 +188,5 @@ int ff_vk_filter_init(AVFilterContext *avctx) s->output_format = AV_PIX_FMT_NONE; - if (ff_vk_glslang_init()) - return AVERROR_EXTERNAL; - return 0; } diff --git a/libavutil/vulkan.c b/libavutil/vulkan.c index fba9543cce..22f9bf7eb6 100644 --- a/libavutil/vulkan.c +++ b/libavutil/vulkan.c @@ -16,12 +16,15 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "vulkan.h" -#include "vulkan_glslang.h" - #include "avassert.h" + +#include "vulkan.h" #include "vulkan_loader.h" +#if FF_VK_ENABLE_SHADER_COMPILATION && CONFIG_LIBGLSLANG +#include "vulkan_glslang.c" +#endif + /* Generic macro for creating contexts which need to keep their addresses * if another context is created. */ #define FN_CREATING(ctx, type, shortname, array, num) \ @@ -843,7 +846,6 @@ void ff_vk_print_shader(void *ctx, FFVkSPIRVShader *shd, int prio) int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, const char *entrypoint) { -#if CONFIG_LIBGLSLANG int err; VkResult ret; FFVulkanFunctions *vk = &s->vkfn; @@ -854,12 +856,21 @@ int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, shd->shader.pName = entrypoint; - err = ff_vk_glslang_shader_compile(s, shd, &spirv, &spirv_size, &priv); + if (!s->spirv_compiler) { +#if FF_VK_ENABLE_SHADER_COMPILATION && CONFIG_LIBGLSLANG + s->spirv_compiler = ff_vk_glslang_init(); +#else + return AVERROR(ENOSYS); +#endif + if (!s->spirv_compiler) + return AVERROR(ENOMEM); + } + + err = s->spirv_compiler->compile_shader(s->spirv_compiler, s, shd, &spirv, + &spirv_size, entrypoint, &priv); if (err < 0) return err; - ff_vk_print_shader(s, shd, AV_LOG_VERBOSE); - av_log(s, AV_LOG_VERBOSE, "Shader %s compiled! Size: %zu bytes\n", shd->name, spirv_size); @@ -872,7 +883,7 @@ int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_create, NULL, &shd->shader.module); - ff_vk_glslang_shader_free(priv); + s->spirv_compiler->free_shader(s->spirv_compiler, &priv); if (ret != VK_SUCCESS) { av_log(s, AV_LOG_ERROR, "Unable to create shader module: %s\n", @@ -881,9 +892,6 @@ int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, } return 0; -#else - return AVERROR(ENOSYS); -#endif } static const struct descriptor_props { @@ -1367,7 +1375,8 @@ void ff_vk_uninit(FFVulkanContext *s) { FFVulkanFunctions *vk = &s->vkfn; - ff_vk_glslang_uninit(); + if (s->spirv_compiler) + s->spirv_compiler->uninit(&s->spirv_compiler); for (int i = 0; i < s->exec_ctx_num; i++) free_exec_ctx(s, s->exec_ctx[i]); diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h index 14c69ce015..3d89f02732 100644 --- a/libavutil/vulkan.h +++ b/libavutil/vulkan.h @@ -22,6 +22,10 @@ #define VK_NO_PROTOTYPES #define VK_ENABLE_BETA_EXTENSIONS +#ifndef FF_VK_ENABLE_SHADER_COMPILATION +#define FF_VK_ENABLE_SHADER_COMPILATION 1 +#endif + #include "pixdesc.h" #include "bprint.h" #include "hwcontext.h" @@ -64,6 +68,15 @@ typedef struct FFVkSPIRVShader { VkPipelineShaderStageCreateInfo shader; } FFVkSPIRVShader; +typedef struct FFVkSPIRVCompiler { + void *priv; + int (*compile_shader)(struct FFVkSPIRVCompiler *ctx, void *avctx, + struct FFVkSPIRVShader *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); +} FFVkSPIRVCompiler; + typedef struct FFVkSampler { VkSampler sampler[4]; } FFVkSampler; @@ -194,6 +207,8 @@ typedef struct FFVulkanContext { AVHWFramesContext *frames; AVVulkanFramesContext *hwfc; + FFVkSPIRVCompiler *spirv_compiler; + /* Properties */ int output_width; int output_height; diff --git a/libavutil/vulkan_glslang.c b/libavutil/vulkan_glslang.c index 51f76c9418..ac5efe2365 100644 --- a/libavutil/vulkan_glslang.c +++ b/libavutil/vulkan_glslang.c @@ -24,10 +24,8 @@ #include "mem.h" #include "avassert.h" -#include "vulkan_glslang.h" - -static pthread_mutex_t glslang_mutex = PTHREAD_MUTEX_INITIALIZER; -static int glslang_refcount = 0; +static pthread_mutex_t glslc_mutex = PTHREAD_MUTEX_INITIALIZER; +static int glslc_refcount = 0; static const glslang_resource_t glslc_resource_limits = { .max_lights = 32, @@ -137,8 +135,10 @@ static const glslang_resource_t glslc_resource_limits = { } }; -int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, - uint8_t **data, size_t *size, void **opaque) +static int glslc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx, + FFVkSPIRVShader *shd, uint8_t **data, + size_t *size, const char *entrypoint, + void **opaque) { const char *messages; glslang_shader_t *glslc_shader; @@ -174,7 +174,7 @@ int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, .resource = &glslc_resource_limits, }; - av_assert0(glslang_refcount); + av_assert0(glslc_refcount); if (!(glslc_shader = glslang_shader_create(&glslc_input))) return AVERROR(ENOMEM); @@ -218,8 +218,12 @@ int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, glslang_program_SPIRV_generate(glslc_program, glslc_input.stage); messages = glslang_program_SPIRV_get_messages(glslc_program); - if (messages) + if (messages) { + ff_vk_print_shader(s, shd, AV_LOG_WARNING); av_log(avctx, AV_LOG_WARNING, "%s\n", messages); + } else { + ff_vk_print_shader(s, shd, AV_LOG_VERBOSE); + } glslang_shader_delete(glslc_shader); @@ -230,27 +234,47 @@ int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, return 0; } -void ff_vk_glslang_shader_free(void *opaque) +static void glslc_shader_free(FFVkSPIRVCompiler *ctx, void **opaque) { - glslang_program_delete(opaque); + if (!opaque || !*opaque) + return; + + av_assert0(glslc_refcount); + glslang_program_delete(*opaque); + *opaque = NULL; } -int ff_vk_glslang_init(void) +static void glslc_uninit(FFVkSPIRVCompiler **ctx) { - int ret = 0; + if (!ctx || !*ctx) + return; - pthread_mutex_lock(&glslang_mutex); - if (glslang_refcount++ == 0) - ret = !glslang_initialize_process(); - pthread_mutex_unlock(&glslang_mutex); + pthread_mutex_lock(&glslc_mutex); + if (glslc_refcount && (--glslc_refcount == 0)) + glslang_finalize_process(); + pthread_mutex_unlock(&glslc_mutex); - return ret; + av_freep(ctx); } -void ff_vk_glslang_uninit(void) +static FFVkSPIRVCompiler *ff_vk_glslang_init(void) { - pthread_mutex_lock(&glslang_mutex); - if (glslang_refcount && (--glslang_refcount == 0)) - glslang_finalize_process(); - pthread_mutex_unlock(&glslang_mutex); + FFVkSPIRVCompiler *ret = av_mallocz(sizeof(*ret)); + if (!ret) + return NULL; + + ret->compile_shader = glslc_shader_compile; + ret->free_shader = glslc_shader_free; + ret->uninit = glslc_uninit; + + pthread_mutex_lock(&glslc_mutex); + if (!glslc_refcount++) { + if (!glslang_initialize_process()) { + av_freep(&ret); + glslc_refcount--; + } + } + pthread_mutex_unlock(&glslc_mutex); + + return ret; } diff --git a/libavutil/vulkan_glslang.h b/libavutil/vulkan_glslang.h deleted file mode 100644 index b09d1251bf..0000000000 --- a/libavutil/vulkan_glslang.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef AVUTIL_GLSLANG_H -#define AVUTIL_GLSLANG_H - -#include "vulkan.h" - -/** - * Un/initialize glslang's global state. Thread-safe and reference counted. - */ -int ff_vk_glslang_init(void); -void ff_vk_glslang_uninit(void); - -/** - * Compile GLSL into SPIR-V using glslang. - */ -int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, - uint8_t **data, size_t *size, void **opaque); - -/** - * Frees the shader-specific context. - */ -void ff_vk_glslang_shader_free(void *opaque); - -#endif /* AVUTIL_GLSLANG_H */ |