History

lavu/vulkan: add option to switch between shader compilers and cleanup glslang

Lynne committed 4 years ago

Commit b2aec701 parent d1133e87 files · +82 −99Browse files

Unified · Split

7 files
  1. libavfilter/Makefile +0 −2
  2. libavfilter/glslang.c +0 −19
  3. libavfilter/vulkan.c +0 −3
  4. libavutil/vulkan.c +21 −12
  5. libavutil/vulkan.h +15 −0
  6. libavutil/vulkan_glslang.c +46 −22
  7. libavutil/vulkan_glslang.h +0 −41
libavfilter/Makefile+0−2
@@ -578,8 +578,6 @@ SKIPHEADERS-$(CONFIG_OPENCL) += opencl.h · 577 unmodified lines
578578 SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_vpp.h
579579 SKIPHEADERS-$(CONFIG_VULKAN) += vulkan.h
580580
581−OBJS-$(CONFIG_LIBGLSLANG) += glslang.o
582−
583581 TOOLS = graph2dot
584582 TESTPROGS = drawutils filtfmts formats integral
585583
libavfilter/glslang.c+0−19
@@ -1,19 +0,0 @@
1−/*
2− * This file is part of FFmpeg.
3− *
4− * FFmpeg is free software; you can redistribute it and/or
5− * modify it under the terms of the GNU Lesser General Public
6− * License as published by the Free Software Foundation; either
7− * version 2.1 of the License, or (at your option) any later version.
8− *
9− * FFmpeg is distributed in the hope that it will be useful,
10− * but WITHOUT ANY WARRANTY; without even the implied warranty of
11− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12− * Lesser General Public License for more details.
13− *
14− * You should have received a copy of the GNU Lesser General Public
15− * License along with FFmpeg; if not, write to the Free Software
16− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17− */
18−
19−#include "libavutil/vulkan_glslang.c"
libavfilter/vulkan.c+0−3
@@ -188,8 +188,5 @@ int ff_vk_filter_init(AVFilterContext *avctx) · 187 unmodified lines
188188
189189 s->output_format = AV_PIX_FMT_NONE;
190190
191− if (ff_vk_glslang_init())
192− return AVERROR_EXTERNAL;
193−
194191 return 0;
195192 }
libavutil/vulkan.c+21−12
@@ -16,12 +16,15 @@ · 15 unmodified lines
1616 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1717 */
1818
19−#include "vulkan.h"
20−#include "vulkan_glslang.h"
21−
2219 #include "avassert.h"
20+
21+#include "vulkan.h"
2322 #include "vulkan_loader.h"
2423
24+#if FF_VK_ENABLE_SHADER_COMPILATION && CONFIG_LIBGLSLANG
25+#include "vulkan_glslang.c"
26+#endif
27+
2528 /* Generic macro for creating contexts which need to keep their addresses
2629 * if another context is created. */
2730 #define FN_CREATING(ctx, type, shortname, array, num) \
@@ -843,7 +846,6 @@ void ff_vk_print_shader(void *ctx, FFVkSPIRVShader *shd, int prio) · 815 unmodified lines
843846 int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd,
844847 const char *entrypoint)
845848 {
846−#if CONFIG_LIBGLSLANG
847849 int err;
848850 VkResult ret;
849851 FFVulkanFunctions *vk = &s->vkfn;
@@ -854,12 +856,21 @@ int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, · 4 unmodified lines
854856
855857 shd->shader.pName = entrypoint;
856858
857− err = ff_vk_glslang_shader_compile(s, shd, &spirv, &spirv_size, &priv);
859+ if (!s->spirv_compiler) {
860+#if FF_VK_ENABLE_SHADER_COMPILATION && CONFIG_LIBGLSLANG
861+ s->spirv_compiler = ff_vk_glslang_init();
862+#else
863+ return AVERROR(ENOSYS);
864+#endif
865+ if (!s->spirv_compiler)
866+ return AVERROR(ENOMEM);
867+ }
868+
869+ err = s->spirv_compiler->compile_shader(s->spirv_compiler, s, shd, &spirv,
870+ &spirv_size, entrypoint, &priv);
858871 if (err < 0)
859872 return err;
860873
861− ff_vk_print_shader(s, shd, AV_LOG_VERBOSE);
862−
863874 av_log(s, AV_LOG_VERBOSE, "Shader %s compiled! Size: %zu bytes\n",
864875 shd->name, spirv_size);
865876
@@ -872,7 +883,7 @@ int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, · 6 unmodified lines
872883 ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_create, NULL,
873884 &shd->shader.module);
874885
875− ff_vk_glslang_shader_free(priv);
886+ s->spirv_compiler->free_shader(s->spirv_compiler, &priv);
876887
877888 if (ret != VK_SUCCESS) {
878889 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, · 2 unmodified lines
881892 }
882893
883894 return 0;
884−#else
885− return AVERROR(ENOSYS);
886−#endif
887895 }
888896
889897 static const struct descriptor_props {
@@ -1367,7 +1375,8 @@ void ff_vk_uninit(FFVulkanContext *s) · 477 unmodified lines
13671375 {
13681376 FFVulkanFunctions *vk = &s->vkfn;
13691377
1370− ff_vk_glslang_uninit();
1378+ if (s->spirv_compiler)
1379+ s->spirv_compiler->uninit(&s->spirv_compiler);
13711380
13721381 for (int i = 0; i < s->exec_ctx_num; i++)
13731382 free_exec_ctx(s, s->exec_ctx[i]);
libavutil/vulkan.h+15−0
@@ -22,6 +22,10 @@ · 21 unmodified lines
2222 #define VK_NO_PROTOTYPES
2323 #define VK_ENABLE_BETA_EXTENSIONS
2424
25+#ifndef FF_VK_ENABLE_SHADER_COMPILATION
26+#define FF_VK_ENABLE_SHADER_COMPILATION 1
27+#endif
28+
2529 #include "pixdesc.h"
2630 #include "bprint.h"
2731 #include "hwcontext.h"
@@ -64,6 +68,15 @@ typedef struct FFVkSPIRVShader { · 36 unmodified lines
6468 VkPipelineShaderStageCreateInfo shader;
6569 } FFVkSPIRVShader;
6670
71+typedef struct FFVkSPIRVCompiler {
72+ void *priv;
73+ int (*compile_shader)(struct FFVkSPIRVCompiler *ctx, void *avctx,
74+ struct FFVkSPIRVShader *shd, uint8_t **data,
75+ size_t *size, const char *entrypoint, void **opaque);
76+ void (*free_shader)(struct FFVkSPIRVCompiler *ctx, void **opaque);
77+ void (*uninit)(struct FFVkSPIRVCompiler **ctx);
78+} FFVkSPIRVCompiler;
79+
6780 typedef struct FFVkSampler {
6881 VkSampler sampler[4];
6982 } FFVkSampler;
@@ -194,6 +207,8 @@ typedef struct FFVulkanContext { · 124 unmodified lines
194207 AVHWFramesContext *frames;
195208 AVVulkanFramesContext *hwfc;
196209
210+ FFVkSPIRVCompiler *spirv_compiler;
211+
197212 /* Properties */
198213 int output_width;
199214 int output_height;
libavutil/vulkan_glslang.c+46−22
@@ -24,10 +24,8 @@ · 23 unmodified lines
2424 #include "mem.h"
2525 #include "avassert.h"
2626
27−#include "vulkan_glslang.h"
28−
29−static pthread_mutex_t glslang_mutex = PTHREAD_MUTEX_INITIALIZER;
30−static int glslang_refcount = 0;
27+static pthread_mutex_t glslc_mutex = PTHREAD_MUTEX_INITIALIZER;
28+static int glslc_refcount = 0;
3129
3230 static const glslang_resource_t glslc_resource_limits = {
3331 .max_lights = 32,
@@ -137,8 +135,10 @@ static const glslang_resource_t glslc_resource_limits = { · 103 unmodified lines
137135 }
138136 };
139137
140−int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd,
141− uint8_t **data, size_t *size, void **opaque)
138+static int glslc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx,
139+ FFVkSPIRVShader *shd, uint8_t **data,
140+ size_t *size, const char *entrypoint,
141+ void **opaque)
142142 {
143143 const char *messages;
144144 glslang_shader_t *glslc_shader;
@@ -174,7 +174,7 @@ int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, · 29 unmodified lines
174174 .resource = &glslc_resource_limits,
175175 };
176176
177− av_assert0(glslang_refcount);
177+ av_assert0(glslc_refcount);
178178
179179 if (!(glslc_shader = glslang_shader_create(&glslc_input)))
180180 return AVERROR(ENOMEM);
@@ -218,8 +218,12 @@ int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, · 37 unmodified lines
218218 glslang_program_SPIRV_generate(glslc_program, glslc_input.stage);
219219
220220 messages = glslang_program_SPIRV_get_messages(glslc_program);
221− if (messages)
221+ if (messages) {
222+ ff_vk_print_shader(s, shd, AV_LOG_WARNING);
222223 av_log(avctx, AV_LOG_WARNING, "%s\n", messages);
224+ } else {
225+ ff_vk_print_shader(s, shd, AV_LOG_VERBOSE);
226+ }
223227
224228 glslang_shader_delete(glslc_shader);
225229
@@ -230,27 +234,47 @@ int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, · 4 unmodified lines
230234 return 0;
231235 }
232236
233−void ff_vk_glslang_shader_free(void *opaque)
237+static void glslc_shader_free(FFVkSPIRVCompiler *ctx, void **opaque)
234238 {
235− glslang_program_delete(opaque);
239+ if (!opaque || !*opaque)
240+ return;
241+
242+ av_assert0(glslc_refcount);
243+ glslang_program_delete(*opaque);
244+ *opaque = NULL;
236245 }
237246
238−int ff_vk_glslang_init(void)
247+static void glslc_uninit(FFVkSPIRVCompiler **ctx)
239248 {
240− int ret = 0;
249+ if (!ctx || !*ctx)
250+ return;
241251
242− pthread_mutex_lock(&glslang_mutex);
243− if (glslang_refcount++ == 0)
244− ret = !glslang_initialize_process();
245− pthread_mutex_unlock(&glslang_mutex);
252+ pthread_mutex_lock(&glslc_mutex);
253+ if (glslc_refcount && (--glslc_refcount == 0))
254+ glslang_finalize_process();
255+ pthread_mutex_unlock(&glslc_mutex);
246256
247− return ret;
257+ av_freep(ctx);
248258 }
249259
250−void ff_vk_glslang_uninit(void)
260+static FFVkSPIRVCompiler *ff_vk_glslang_init(void)
251261 {
252− pthread_mutex_lock(&glslang_mutex);
253− if (glslang_refcount && (--glslang_refcount == 0))
254− glslang_finalize_process();
255− pthread_mutex_unlock(&glslang_mutex);
262+ FFVkSPIRVCompiler *ret = av_mallocz(sizeof(*ret));
263+ if (!ret)
264+ return NULL;
265+
266+ ret->compile_shader = glslc_shader_compile;
267+ ret->free_shader = glslc_shader_free;
268+ ret->uninit = glslc_uninit;
269+
270+ pthread_mutex_lock(&glslc_mutex);
271+ if (!glslc_refcount++) {
272+ if (!glslang_initialize_process()) {
273+ av_freep(&ret);
274+ glslc_refcount--;
275+ }
276+ }
277+ pthread_mutex_unlock(&glslc_mutex);
278+
279+ return ret;
256280 }
libavutil/vulkan_glslang.h+0−41
@@ -1,41 +0,0 @@
1−/*
2− * This file is part of FFmpeg.
3− *
4− * FFmpeg is free software; you can redistribute it and/or
5− * modify it under the terms of the GNU Lesser General Public
6− * License as published by the Free Software Foundation; either
7− * version 2.1 of the License, or (at your option) any later version.
8− *
9− * FFmpeg is distributed in the hope that it will be useful,
10− * but WITHOUT ANY WARRANTY; without even the implied warranty of
11− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12− * Lesser General Public License for more details.
13− *
14− * You should have received a copy of the GNU Lesser General Public
15− * License along with FFmpeg; if not, write to the Free Software
16− * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17− */
18−
19−#ifndef AVUTIL_GLSLANG_H
20−#define AVUTIL_GLSLANG_H
21−
22−#include "vulkan.h"
23−
24−/**
25− * Un/initialize glslang's global state. Thread-safe and reference counted.
26− */
27−int ff_vk_glslang_init(void);
28−void ff_vk_glslang_uninit(void);
29−
30−/**
31− * Compile GLSL into SPIR-V using glslang.
32− */
33−int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd,
34− uint8_t **data, size_t *size, void **opaque);
35−
36−/**
37− * Frees the shader-specific context.
38− */
39−void ff_vk_glslang_shader_free(void *opaque);
40−
41−#endif /* AVUTIL_GLSLANG_H */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t