History

lavfi: add Vulkan filtering framework

This commit adds a Vulkan filtering infrastructure for libavfilter. It attempts to abstract as much as possible of the Vulkan API from filters. The way the hwcontext and the framework are designed permits for parallel, non-CPU-blocking filtering throughout, with the exception of up/downloading and mapping.

Lynne committed 7 years ago

Commit 6fca61b1 parent 88d2ccb6 files · +1864 −5Browse files

Showing the changes to libavfilter/glslang.cpp (1 of 6 files). Show all

Unified · Split

libavfilter/glslang.cpp+243−0
@@ -0,0 +1,243 @@
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 <pthread.h>
20
21extern "C" {
22#include "libavutil/mem.h"
23#include "libavutil/avassert.h"
24}
25
26#include <glslang/Include/ResourceLimits.h>
27#include <glslang/Include/revision.h>
28#include <glslang/Public/ShaderLang.h>
29#include <glslang/SPIRV/GlslangToSpv.h>
30
31#include "glslang.h"
32
33using namespace glslang;
34
35static pthread_mutex_t glslang_mutex = PTHREAD_MUTEX_INITIALIZER;
36static int glslang_refcount = 0;
37
38/* We require Vulkan 1.1 */
39#define GLSL_VERSION EShTargetVulkan_1_1
40
41/* Vulkan 1.1 implementations require SPIR-V 1.3 to be implemented */
42#define SPIRV_VERSION EShTargetSpv_1_3
43
44// Taken from glslang's examples, which apparently generally bases the choices
45// on OpenGL specification limits
46static const TBuiltInResource DefaultTBuiltInResource = {
47 /* .MaxLights = */ 32,
48 /* .MaxClipPlanes = */ 6,
49 /* .MaxTextureUnits = */ 32,
50 /* .MaxTextureCoords = */ 32,
51 /* .MaxVertexAttribs = */ 64,
52 /* .MaxVertexUniformComponents = */ 4096,
53 /* .MaxVaryingFloats = */ 64,
54 /* .MaxVertexTextureImageUnits = */ 32,
55 /* .MaxCombinedTextureImageUnits = */ 80,
56 /* .MaxTextureImageUnits = */ 32,
57 /* .MaxFragmentUniformComponents = */ 4096,
58 /* .MaxDrawBuffers = */ 32,
59 /* .MaxVertexUniformVectors = */ 128,
60 /* .MaxVaryingVectors = */ 8,
61 /* .MaxFragmentUniformVectors = */ 16,
62 /* .MaxVertexOutputVectors = */ 16,
63 /* .MaxFragmentInputVectors = */ 15,
64 /* .MinProgramTexelOffset = */ -8,
65 /* .MaxProgramTexelOffset = */ 7,
66 /* .MaxClipDistances = */ 8,
67 /* .MaxComputeWorkGroupCountX = */ 65535,
68 /* .MaxComputeWorkGroupCountY = */ 65535,
69 /* .MaxComputeWorkGroupCountZ = */ 65535,
70 /* .MaxComputeWorkGroupSizeX = */ 1024,
71 /* .MaxComputeWorkGroupSizeY = */ 1024,
72 /* .MaxComputeWorkGroupSizeZ = */ 64,
73 /* .MaxComputeUniformComponents = */ 1024,
74 /* .MaxComputeTextureImageUnits = */ 16,
75 /* .MaxComputeImageUniforms = */ 8,
76 /* .MaxComputeAtomicCounters = */ 8,
77 /* .MaxComputeAtomicCounterBuffers = */ 1,
78 /* .MaxVaryingComponents = */ 60,
79 /* .MaxVertexOutputComponents = */ 64,
80 /* .MaxGeometryInputComponents = */ 64,
81 /* .MaxGeometryOutputComponents = */ 128,
82 /* .MaxFragmentInputComponents = */ 128,
83 /* .MaxImageUnits = */ 8,
84 /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
85 /* .MaxCombinedShaderOutputResources = */ 8,
86 /* .MaxImageSamples = */ 0,
87 /* .MaxVertexImageUniforms = */ 0,
88 /* .MaxTessControlImageUniforms = */ 0,
89 /* .MaxTessEvaluationImageUniforms = */ 0,
90 /* .MaxGeometryImageUniforms = */ 0,
91 /* .MaxFragmentImageUniforms = */ 8,
92 /* .MaxCombinedImageUniforms = */ 8,
93 /* .MaxGeometryTextureImageUnits = */ 16,
94 /* .MaxGeometryOutputVertices = */ 256,
95 /* .MaxGeometryTotalOutputComponents = */ 1024,
96 /* .MaxGeometryUniformComponents = */ 1024,
97 /* .MaxGeometryVaryingComponents = */ 64,
98 /* .MaxTessControlInputComponents = */ 128,
99 /* .MaxTessControlOutputComponents = */ 128,
100 /* .MaxTessControlTextureImageUnits = */ 16,
101 /* .MaxTessControlUniformComponents = */ 1024,
102 /* .MaxTessControlTotalOutputComponents = */ 4096,
103 /* .MaxTessEvaluationInputComponents = */ 128,
104 /* .MaxTessEvaluationOutputComponents = */ 128,
105 /* .MaxTessEvaluationTextureImageUnits = */ 16,
106 /* .MaxTessEvaluationUniformComponents = */ 1024,
107 /* .MaxTessPatchComponents = */ 120,
108 /* .MaxPatchVertices = */ 32,
109 /* .MaxTessGenLevel = */ 64,
110 /* .MaxViewports = */ 16,
111 /* .MaxVertexAtomicCounters = */ 0,
112 /* .MaxTessControlAtomicCounters = */ 0,
113 /* .MaxTessEvaluationAtomicCounters = */ 0,
114 /* .MaxGeometryAtomicCounters = */ 0,
115 /* .MaxFragmentAtomicCounters = */ 8,
116 /* .MaxCombinedAtomicCounters = */ 8,
117 /* .MaxAtomicCounterBindings = */ 1,
118 /* .MaxVertexAtomicCounterBuffers = */ 0,
119 /* .MaxTessControlAtomicCounterBuffers = */ 0,
120 /* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
121 /* .MaxGeometryAtomicCounterBuffers = */ 0,
122 /* .MaxFragmentAtomicCounterBuffers = */ 1,
123 /* .MaxCombinedAtomicCounterBuffers = */ 1,
124 /* .MaxAtomicCounterBufferSize = */ 16384,
125 /* .MaxTransformFeedbackBuffers = */ 4,
126 /* .MaxTransformFeedbackInterleavedComponents = */ 64,
127 /* .MaxCullDistances = */ 8,
128 /* .MaxCombinedClipAndCullDistances = */ 8,
129 /* .MaxSamples = */ 4,
130 /* .maxMeshOutputVerticesNV = */ 256,
131 /* .maxMeshOutputPrimitivesNV = */ 512,
132 /* .maxMeshWorkGroupSizeX_NV = */ 32,
133 /* .maxMeshWorkGroupSizeY_NV = */ 1,
134 /* .maxMeshWorkGroupSizeZ_NV = */ 1,
135 /* .maxTaskWorkGroupSizeX_NV = */ 32,
136 /* .maxTaskWorkGroupSizeY_NV = */ 1,
137 /* .maxTaskWorkGroupSizeZ_NV = */ 1,
138 /* .maxMeshViewCountNV = */ 4,
139
140 .limits = {
141 /* .nonInductiveForLoops = */ 1,
142 /* .whileLoops = */ 1,
143 /* .doWhileLoops = */ 1,
144 /* .generalUniformIndexing = */ 1,
145 /* .generalAttributeMatrixVectorIndexing = */ 1,
146 /* .generalVaryingIndexing = */ 1,
147 /* .generalSamplerIndexing = */ 1,
148 /* .generalVariableIndexing = */ 1,
149 /* .generalConstantMatrixVectorIndexing = */ 1,
150 }
151};
152
153GLSlangResult *glslang_compile(const char *glsl, enum GLSlangStage stage)
154{
155 GLSlangResult *res = (GLSlangResult *)av_mallocz(sizeof(*res));
156 if (!res)
157 return NULL;
158
159 static const EShLanguage lang[] = {
160 [GLSLANG_VERTEX] = EShLangVertex,
161 [GLSLANG_FRAGMENT] = EShLangFragment,
162 [GLSLANG_COMPUTE] = EShLangCompute,
163 };
164
165 assert(glslang_refcount);
166 TShader *shader = new TShader(lang[stage]);
167 if (!shader) {
168 res->rval = AVERROR(ENOMEM);
169 return res;
170 }
171
172 shader->setEnvClient(EShClientVulkan, GLSL_VERSION);
173 shader->setEnvTarget(EShTargetSpv, SPIRV_VERSION);
174 shader->setStrings(&glsl, 1);
175 if (!shader->parse(&DefaultTBuiltInResource, GLSL_VERSION, true, EShMsgDefault)) {
176 res->error_msg = av_strdup(shader->getInfoLog());
177 res->rval = AVERROR_EXTERNAL;
178 delete shader;
179 return res;
180 }
181
182 TProgram *prog = new TProgram();
183 if (!prog) {
184 res->rval = AVERROR(ENOMEM);
185 delete shader;
186 return res;
187 }
188
189 prog->addShader(shader);
190 if (!prog->link(EShMsgDefault)) {
191 res->error_msg = av_strdup(prog->getInfoLog());
192 res->rval = AVERROR_EXTERNAL;
193 delete shader;
194 delete prog;
195 return res;
196 }
197
198 std::vector<unsigned int> spirv; /* Result */
199
200 SpvOptions options; /* Options - by default all optimizations are off */
201 options.generateDebugInfo = false; /* Makes sense for files but not here */
202 options.disassemble = false; /* Will print disassembly on compilation */
203 options.validate = false; /* Validates the generated SPIRV, unneeded */
204 options.disableOptimizer = false; /* For debugging */
205 options.optimizeSize = true; /* Its faster */
206
207 GlslangToSpv(*prog->getIntermediate(lang[stage]), spirv, NULL, &options);
208
209 res->size = spirv.size()*sizeof(unsigned int);
210 res->data = av_memdup(spirv.data(), res->size);
211 if (!res->data) {
212 res->rval = AVERROR(ENOMEM);
213 delete shader;
214 delete prog;
215 return res;
216 }
217
218 delete shader;
219 delete prog;
220
221 return res;
222}
223
224int glslang_init(void)
225{
226 int ret = 0;
227
228 pthread_mutex_lock(&glslang_mutex);
229 if (glslang_refcount++ == 0)
230 ret = !InitializeProcess();
231 pthread_mutex_unlock(&glslang_mutex);
232
233 return ret;
234}
235
236void glslang_uninit(void)
237{
238 pthread_mutex_lock(&glslang_mutex);
239 av_assert0(glslang_refcount > 0);
240 if (--glslang_refcount == 0)
241 FinalizeProcess();
242 pthread_mutex_unlock(&glslang_mutex);
243}

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