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
578SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_vpp.h578SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_vpp.h
579SKIPHEADERS-$(CONFIG_VULKAN) += vulkan.h579SKIPHEADERS-$(CONFIG_VULKAN) += vulkan.h
580 580
581OBJS-$(CONFIG_LIBGLSLANG) += glslang.o
582
583TOOLS = graph2dot581TOOLS = graph2dot
584TESTPROGS = drawutils filtfmts formats integral582TESTPROGS = drawutils filtfmts formats integral
585 583
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
188 188
189 s->output_format = AV_PIX_FMT_NONE;189 s->output_format = AV_PIX_FMT_NONE;
190 190
191 if (ff_vk_glslang_init())
192 return AVERROR_EXTERNAL;
193
194 return 0;191 return 0;
195}192}
libavutil/vulkan.c+21−12
@@ -16,12 +16,15 @@ · 15 unmodified lines
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */17 */
18 18
19#include "vulkan.h"
20#include "vulkan_glslang.h"
21
22#include "avassert.h"19#include "avassert.h"
20
21#include "vulkan.h"
23#include "vulkan_loader.h"22#include "vulkan_loader.h"
24 23
24#if FF_VK_ENABLE_SHADER_COMPILATION && CONFIG_LIBGLSLANG
25#include "vulkan_glslang.c"
26#endif
27
25/* Generic macro for creating contexts which need to keep their addresses28/* Generic macro for creating contexts which need to keep their addresses
26 * if another context is created. */29 * if another context is created. */
27#define FN_CREATING(ctx, type, shortname, array, num) \30#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
843int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd,846int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd,
844 const char *entrypoint)847 const char *entrypoint)
845{848{
846#if CONFIG_LIBGLSLANG
847 int err;849 int err;
848 VkResult ret;850 VkResult ret;
849 FFVulkanFunctions *vk = &s->vkfn;851 FFVulkanFunctions *vk = &s->vkfn;
@@ -854,12 +856,21 @@ int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, · 4 unmodified lines
854 856
855 shd->shader.pName = entrypoint;857 shd->shader.pName = entrypoint;
856 858
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);
858 if (err < 0)871 if (err < 0)
859 return err;872 return err;
860 873
861 ff_vk_print_shader(s, shd, AV_LOG_VERBOSE);
862
863 av_log(s, AV_LOG_VERBOSE, "Shader %s compiled! Size: %zu bytes\n",874 av_log(s, AV_LOG_VERBOSE, "Shader %s compiled! Size: %zu bytes\n",
864 shd->name, spirv_size);875 shd->name, spirv_size);
865 876
@@ -872,7 +883,7 @@ int ff_vk_compile_shader(FFVulkanContext *s, FFVkSPIRVShader *shd, · 6 unmodified lines
872 ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_create, NULL,883 ret = vk->CreateShaderModule(s->hwctx->act_dev, &shader_create, NULL,
873 &shd->shader.module);884 &shd->shader.module);
874 885
875 ff_vk_glslang_shader_free(priv);886 s->spirv_compiler->free_shader(s->spirv_compiler, &priv);
876 887
877 if (ret != VK_SUCCESS) {888 if (ret != VK_SUCCESS) {
878 av_log(s, AV_LOG_ERROR, "Unable to create shader module: %s\n",889 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
881 }892 }
882 893
883 return 0;894 return 0;
884#else
885 return AVERROR(ENOSYS);
886#endif
887}895}
888 896
889static const struct descriptor_props {897static const struct descriptor_props {
@@ -1367,7 +1375,8 @@ void ff_vk_uninit(FFVulkanContext *s) · 477 unmodified lines
1367{1375{
1368 FFVulkanFunctions *vk = &s->vkfn;1376 FFVulkanFunctions *vk = &s->vkfn;
1369 1377
1370 ff_vk_glslang_uninit();1378 if (s->spirv_compiler)
1379 s->spirv_compiler->uninit(&s->spirv_compiler);
1371 1380
1372 for (int i = 0; i < s->exec_ctx_num; i++)1381 for (int i = 0; i < s->exec_ctx_num; i++)
1373 free_exec_ctx(s, s->exec_ctx[i]);1382 free_exec_ctx(s, s->exec_ctx[i]);
libavutil/vulkan.h+15−0
@@ -22,6 +22,10 @@ · 21 unmodified lines
22#define VK_NO_PROTOTYPES22#define VK_NO_PROTOTYPES
23#define VK_ENABLE_BETA_EXTENSIONS23#define VK_ENABLE_BETA_EXTENSIONS
24 24
25#ifndef FF_VK_ENABLE_SHADER_COMPILATION
26#define FF_VK_ENABLE_SHADER_COMPILATION 1
27#endif
28
25#include "pixdesc.h"29#include "pixdesc.h"
26#include "bprint.h"30#include "bprint.h"
27#include "hwcontext.h"31#include "hwcontext.h"
@@ -64,6 +68,15 @@ typedef struct FFVkSPIRVShader { · 36 unmodified lines
64 VkPipelineShaderStageCreateInfo shader;68 VkPipelineShaderStageCreateInfo shader;
65} FFVkSPIRVShader;69} FFVkSPIRVShader;
66 70
71typedef 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
67typedef struct FFVkSampler {80typedef struct FFVkSampler {
68 VkSampler sampler[4];81 VkSampler sampler[4];
69} FFVkSampler;82} FFVkSampler;
@@ -194,6 +207,8 @@ typedef struct FFVulkanContext { · 124 unmodified lines
194 AVHWFramesContext *frames;207 AVHWFramesContext *frames;
195 AVVulkanFramesContext *hwfc;208 AVVulkanFramesContext *hwfc;
196 209
210 FFVkSPIRVCompiler *spirv_compiler;
211
197 /* Properties */212 /* Properties */
198 int output_width;213 int output_width;
199 int output_height;214 int output_height;
libavutil/vulkan_glslang.c+46−22
@@ -24,10 +24,8 @@ · 23 unmodified lines
24#include "mem.h"24#include "mem.h"
25#include "avassert.h"25#include "avassert.h"
26 26
27#include "vulkan_glslang.h"27static pthread_mutex_t glslc_mutex = PTHREAD_MUTEX_INITIALIZER;
28 28static int glslc_refcount = 0;
29static pthread_mutex_t glslang_mutex = PTHREAD_MUTEX_INITIALIZER;
30static int glslang_refcount = 0;
31 29
32static const glslang_resource_t glslc_resource_limits = {30static const glslang_resource_t glslc_resource_limits = {
33 .max_lights = 32,31 .max_lights = 32,
@@ -137,8 +135,10 @@ static const glslang_resource_t glslc_resource_limits = { · 103 unmodified lines
137 }135 }
138};136};
139 137
140int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd,138static int glslc_shader_compile(FFVkSPIRVCompiler *ctx, void *avctx,
141 uint8_t **data, size_t *size, void **opaque)139 FFVkSPIRVShader *shd, uint8_t **data,
140 size_t *size, const char *entrypoint,
141 void **opaque)
142{142{
143 const char *messages;143 const char *messages;
144 glslang_shader_t *glslc_shader;144 glslang_shader_t *glslc_shader;
@@ -174,7 +174,7 @@ int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, · 29 unmodified lines
174 .resource = &glslc_resource_limits,174 .resource = &glslc_resource_limits,
175 };175 };
176 176
177 av_assert0(glslang_refcount);177 av_assert0(glslc_refcount);
178 178
179 if (!(glslc_shader = glslang_shader_create(&glslc_input)))179 if (!(glslc_shader = glslang_shader_create(&glslc_input)))
180 return AVERROR(ENOMEM);180 return AVERROR(ENOMEM);
@@ -218,8 +218,12 @@ int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, · 37 unmodified lines
218 glslang_program_SPIRV_generate(glslc_program, glslc_input.stage);218 glslang_program_SPIRV_generate(glslc_program, glslc_input.stage);
219 219
220 messages = glslang_program_SPIRV_get_messages(glslc_program);220 messages = glslang_program_SPIRV_get_messages(glslc_program);
221 if (messages)221 if (messages) {
222 ff_vk_print_shader(s, shd, AV_LOG_WARNING);
222 av_log(avctx, AV_LOG_WARNING, "%s\n", messages);223 av_log(avctx, AV_LOG_WARNING, "%s\n", messages);
224 } else {
225 ff_vk_print_shader(s, shd, AV_LOG_VERBOSE);
226 }
223 227
224 glslang_shader_delete(glslc_shader);228 glslang_shader_delete(glslc_shader);
225 229
@@ -230,27 +234,47 @@ int ff_vk_glslang_shader_compile(void *avctx, FFVkSPIRVShader *shd, · 4 unmodified lines
230 return 0;234 return 0;
231}235}
232 236
233void ff_vk_glslang_shader_free(void *opaque)237static void glslc_shader_free(FFVkSPIRVCompiler *ctx, void **opaque)
234{238{
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;
236}245}
237 246
238int ff_vk_glslang_init(void)247static void glslc_uninit(FFVkSPIRVCompiler **ctx)
239{248{
240 int ret = 0;249 if (!ctx || !*ctx)
250 return;
241 251
242 pthread_mutex_lock(&glslang_mutex);252 pthread_mutex_lock(&glslc_mutex);
243 if (glslang_refcount++ == 0)253 if (glslc_refcount && (--glslc_refcount == 0))
244 ret = !glslang_initialize_process();254 glslang_finalize_process();
245 pthread_mutex_unlock(&glslang_mutex);255 pthread_mutex_unlock(&glslc_mutex);
246 256
247 return ret;257 av_freep(ctx);
248}258}
249 259
250void ff_vk_glslang_uninit(void)260static FFVkSPIRVCompiler *ff_vk_glslang_init(void)
251{261{
252 pthread_mutex_lock(&glslang_mutex);262 FFVkSPIRVCompiler *ret = av_mallocz(sizeof(*ret));
253 if (glslang_refcount && (--glslang_refcount == 0))263 if (!ret)
254 glslang_finalize_process();264 return NULL;
255 pthread_mutex_unlock(&glslang_mutex);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;
256}280}
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 */
27int ff_vk_glslang_init(void);
28void ff_vk_glslang_uninit(void);
29
30/**
31 * Compile GLSL into SPIR-V using glslang.
32 */
33int 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 */
39void 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