Update glslang
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / framework / vulkan / vkShaderToSpirV.cpp
1 /*-------------------------------------------------------------------------
2  * Vulkan CTS Framework
3  * --------------------
4  *
5  * Copyright (c) 2015 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Shading language (GLSL/HLSL) to SPIR-V.
22  *//*--------------------------------------------------------------------*/
23
24 #include "vkShaderToSpirV.hpp"
25 #include "deArrayUtil.hpp"
26 #include "deSingleton.h"
27 #include "deMemory.h"
28 #include "deClock.h"
29 #include "qpDebugOut.h"
30
31 #include "SPIRV/GlslangToSpv.h"
32 #include "SPIRV/disassemble.h"
33 #include "SPIRV/SPVRemapper.h"
34 #include "SPIRV/doc.h"
35 #include "glslang/Include/InfoSink.h"
36 #include "glslang/Include/ShHandle.h"
37 #include "glslang/MachineIndependent/localintermediate.h"
38 #include "glslang/Public/ShaderLang.h"
39
40 namespace vk
41 {
42
43 using std::string;
44 using std::vector;
45
46 namespace
47 {
48
49 EShLanguage getGlslangStage (glu::ShaderType type)
50 {
51         static const EShLanguage stageMap[] =
52         {
53                 EShLangVertex,
54                 EShLangFragment,
55                 EShLangGeometry,
56                 EShLangTessControl,
57                 EShLangTessEvaluation,
58                 EShLangCompute,
59         };
60         return de::getSizedArrayElement<glu::SHADERTYPE_LAST>(stageMap, type);
61 }
62
63 static volatile deSingletonState        s_glslangInitState      = DE_SINGLETON_STATE_NOT_INITIALIZED;
64
65 void initGlslang (void*)
66 {
67         // Main compiler
68         glslang::InitializeProcess();
69
70         // SPIR-V disassembly
71         spv::Parameterize();
72 }
73
74 void prepareGlslang (void)
75 {
76         deInitSingleton(&s_glslangInitState, initGlslang, DE_NULL);
77 }
78
79 // \todo [2015-06-19 pyry] Specialize these per GLSL version
80
81 // Fail compilation if more members are added to TLimits or TBuiltInResource
82 struct LimitsSizeHelper_s                       { bool m0, m1, m2, m3, m4, m5, m6, m7, m8; };
83 struct BuiltInResourceSizeHelper_s      { int m[93]; LimitsSizeHelper_s l; };
84
85 DE_STATIC_ASSERT(sizeof(TLimits)                        == sizeof(LimitsSizeHelper_s));
86 DE_STATIC_ASSERT(sizeof(TBuiltInResource)       == sizeof(BuiltInResourceSizeHelper_s));
87
88 void getDefaultLimits (TLimits* limits)
89 {
90         limits->nonInductiveForLoops                                    = true;
91         limits->whileLoops                                                              = true;
92         limits->doWhileLoops                                                    = true;
93         limits->generalUniformIndexing                                  = true;
94         limits->generalAttributeMatrixVectorIndexing    = true;
95         limits->generalVaryingIndexing                                  = true;
96         limits->generalSamplerIndexing                                  = true;
97         limits->generalVariableIndexing                                 = true;
98         limits->generalConstantMatrixVectorIndexing             = true;
99 }
100
101 void getDefaultBuiltInResources (TBuiltInResource* builtin)
102 {
103         getDefaultLimits(&builtin->limits);
104
105         builtin->maxLights                                                                      = 32;
106         builtin->maxClipPlanes                                                          = 6;
107         builtin->maxTextureUnits                                                        = 32;
108         builtin->maxTextureCoords                                                       = 32;
109         builtin->maxVertexAttribs                                                       = 64;
110         builtin->maxVertexUniformComponents                                     = 4096;
111         builtin->maxVaryingFloats                                                       = 64;
112         builtin->maxVertexTextureImageUnits                                     = 32;
113         builtin->maxCombinedTextureImageUnits                           = 80;
114         builtin->maxTextureImageUnits                                           = 32;
115         builtin->maxFragmentUniformComponents                           = 4096;
116         builtin->maxDrawBuffers                                                         = 32;
117         builtin->maxVertexUniformVectors                                        = 128;
118         builtin->maxVaryingVectors                                                      = 8;
119         builtin->maxFragmentUniformVectors                                      = 16;
120         builtin->maxVertexOutputVectors                                         = 16;
121         builtin->maxFragmentInputVectors                                        = 15;
122         builtin->minProgramTexelOffset                                          = -8;
123         builtin->maxProgramTexelOffset                                          = 7;
124         builtin->maxClipDistances                                                       = 8;
125         builtin->maxComputeWorkGroupCountX                                      = 65535;
126         builtin->maxComputeWorkGroupCountY                                      = 65535;
127         builtin->maxComputeWorkGroupCountZ                                      = 65535;
128         builtin->maxComputeWorkGroupSizeX                                       = 1024;
129         builtin->maxComputeWorkGroupSizeY                                       = 1024;
130         builtin->maxComputeWorkGroupSizeZ                                       = 64;
131         builtin->maxComputeUniformComponents                            = 1024;
132         builtin->maxComputeTextureImageUnits                            = 16;
133         builtin->maxComputeImageUniforms                                        = 8;
134         builtin->maxComputeAtomicCounters                                       = 8;
135         builtin->maxComputeAtomicCounterBuffers                         = 1;
136         builtin->maxVaryingComponents                                           = 60;
137         builtin->maxVertexOutputComponents                                      = 64;
138         builtin->maxGeometryInputComponents                                     = 64;
139         builtin->maxGeometryOutputComponents                            = 128;
140         builtin->maxFragmentInputComponents                                     = 128;
141         builtin->maxImageUnits                                                          = 8;
142         builtin->maxCombinedImageUnitsAndFragmentOutputs        = 8;
143         builtin->maxCombinedShaderOutputResources                       = 8;
144         builtin->maxImageSamples                                                        = 0;
145         builtin->maxVertexImageUniforms                                         = 0;
146         builtin->maxTessControlImageUniforms                            = 0;
147         builtin->maxTessEvaluationImageUniforms                         = 0;
148         builtin->maxGeometryImageUniforms                                       = 0;
149         builtin->maxFragmentImageUniforms                                       = 8;
150         builtin->maxCombinedImageUniforms                                       = 8;
151         builtin->maxGeometryTextureImageUnits                           = 16;
152         builtin->maxGeometryOutputVertices                                      = 256;
153         builtin->maxGeometryTotalOutputComponents                       = 1024;
154         builtin->maxGeometryUniformComponents                           = 1024;
155         builtin->maxGeometryVaryingComponents                           = 64;
156         builtin->maxTessControlInputComponents                          = 128;
157         builtin->maxTessControlOutputComponents                         = 128;
158         builtin->maxTessControlTextureImageUnits                        = 16;
159         builtin->maxTessControlUniformComponents                        = 1024;
160         builtin->maxTessControlTotalOutputComponents            = 4096;
161         builtin->maxTessEvaluationInputComponents                       = 128;
162         builtin->maxTessEvaluationOutputComponents                      = 128;
163         builtin->maxTessEvaluationTextureImageUnits                     = 16;
164         builtin->maxTessEvaluationUniformComponents                     = 1024;
165         builtin->maxTessPatchComponents                                         = 120;
166         builtin->maxPatchVertices                                                       = 32;
167         builtin->maxTessGenLevel                                                        = 64;
168         builtin->maxViewports                                                           = 16;
169         builtin->maxVertexAtomicCounters                                        = 0;
170         builtin->maxTessControlAtomicCounters                           = 0;
171         builtin->maxTessEvaluationAtomicCounters                        = 0;
172         builtin->maxGeometryAtomicCounters                                      = 0;
173         builtin->maxFragmentAtomicCounters                                      = 8;
174         builtin->maxCombinedAtomicCounters                                      = 8;
175         builtin->maxAtomicCounterBindings                                       = 1;
176         builtin->maxVertexAtomicCounterBuffers                          = 0;
177         builtin->maxTessControlAtomicCounterBuffers                     = 0;
178         builtin->maxTessEvaluationAtomicCounterBuffers          = 0;
179         builtin->maxGeometryAtomicCounterBuffers                        = 0;
180         builtin->maxFragmentAtomicCounterBuffers                        = 1;
181         builtin->maxCombinedAtomicCounterBuffers                        = 1;
182         builtin->maxAtomicCounterBufferSize                                     = 16384;
183         builtin->maxTransformFeedbackBuffers                            = 8;
184         builtin->maxTransformFeedbackInterleavedComponents      = 16382;
185         builtin->maxCullDistances                                                       = 8;
186         builtin->maxCombinedClipAndCullDistances                        = 8;
187         builtin->maxSamples                                                                     = 4;
188         builtin->maxMeshOutputVerticesNV                                        = 256;
189         builtin->maxMeshOutputPrimitivesNV                                      = 256;
190         builtin->maxMeshWorkGroupSizeX_NV                                       = 32;
191         builtin->maxMeshWorkGroupSizeY_NV                                       = 1;
192         builtin->maxMeshWorkGroupSizeZ_NV                                       = 1;
193         builtin->maxTaskWorkGroupSizeX_NV                                       = 32;
194         builtin->maxTaskWorkGroupSizeY_NV                                       = 1;
195         builtin->maxTaskWorkGroupSizeZ_NV                                       = 1;
196         builtin->maxMeshViewCountNV                                                     = 4;
197         builtin->maxDualSourceDrawBuffersEXT                            = 1;
198 };
199
200 int getNumShaderStages (const std::vector<std::string>* sources)
201 {
202         int numShaderStages = 0;
203
204         for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
205         {
206                 if (!sources[shaderType].empty())
207                         numShaderStages += 1;
208         }
209
210         return numShaderStages;
211 }
212
213 std::string getShaderStageSource (const std::vector<std::string>* sources, const ShaderBuildOptions buildOptions, glu::ShaderType shaderType)
214 {
215         if (sources[shaderType].size() != 1)
216                 TCU_THROW(InternalError, "Linking multiple compilation units is not supported");
217
218         if ((buildOptions.flags & ShaderBuildOptions::FLAG_USE_STORAGE_BUFFER_STORAGE_CLASS) != 0)
219         {
220                 // Hack to inject #pragma right after first #version statement
221                 std::string src                 = sources[shaderType][0];
222                 size_t          injectPos       = 0;
223
224                 if (de::beginsWith(src, "#version"))
225                         injectPos = src.find('\n') + 1;
226
227                 src.insert(injectPos, "#pragma use_storage_buffer\n");
228
229                 return src;
230         }
231         else
232                 return sources[shaderType][0];
233 }
234
235 EShMessages getCompileFlags (const ShaderBuildOptions& buildOpts, const ShaderLanguage shaderLanguage)
236 {
237         EShMessages             flags   = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
238
239         if ((buildOpts.flags & ShaderBuildOptions::FLAG_ALLOW_RELAXED_OFFSETS) != 0)
240                 flags = (EShMessages)(flags | EShMsgHlslOffsets);
241
242         if (shaderLanguage == SHADER_LANGUAGE_HLSL)
243                 flags = (EShMessages)(flags | EShMsgReadHlsl);
244
245         return flags;
246 }
247
248 } // anonymous
249
250 bool compileShaderToSpirV (const std::vector<std::string>* sources, const ShaderBuildOptions& buildOptions, const ShaderLanguage shaderLanguage, std::vector<deUint32>* dst, glu::ShaderProgramInfo* buildInfo)
251 {
252         TBuiltInResource        builtinRes = {};
253         const EShMessages       compileFlags    = getCompileFlags(buildOptions, shaderLanguage);
254
255         if (buildOptions.targetVersion >= SPIRV_VERSION_LAST)
256                 TCU_THROW(InternalError, "Unsupported SPIR-V target version");
257
258         if (getNumShaderStages(sources) > 1)
259                 TCU_THROW(InternalError, "Linking multiple shader stages into a single SPIR-V binary is not supported");
260
261         prepareGlslang();
262         getDefaultBuiltInResources(&builtinRes);
263
264         // \note Compiles only first found shader
265         for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; shaderType++)
266         {
267                 if (!sources[shaderType].empty())
268                 {
269                         const std::string&              srcText                         = getShaderStageSource(sources, buildOptions, (glu::ShaderType)shaderType);
270                         const char*                             srcPtrs[]                       = { srcText.c_str() };
271                         const EShLanguage               shaderStage                     = getGlslangStage(glu::ShaderType(shaderType));
272                         glslang::TShader                shader                          (shaderStage);
273                         glslang::TProgram               glslangProgram;
274
275                         shader.setStrings(srcPtrs, DE_LENGTH_OF_ARRAY(srcPtrs));
276
277                         switch ( buildOptions.targetVersion )
278                         {
279                         case SPIRV_VERSION_1_0:
280                                 shader.setEnvTarget(glslang::EshTargetSpv, (glslang::EShTargetLanguageVersion)0x10000);
281                                 break;
282                         case SPIRV_VERSION_1_1:
283                                 shader.setEnvTarget(glslang::EshTargetSpv, (glslang::EShTargetLanguageVersion)0x10100);
284                                 break;
285                         case SPIRV_VERSION_1_2:
286                                 shader.setEnvTarget(glslang::EshTargetSpv, (glslang::EShTargetLanguageVersion)0x10200);
287                                 break;
288                         case SPIRV_VERSION_1_3:
289                                 shader.setEnvTarget(glslang::EshTargetSpv, (glslang::EShTargetLanguageVersion)0x10300);
290                                 break;
291                         case SPIRV_VERSION_1_4:
292                                 shader.setEnvTarget(glslang::EshTargetSpv, (glslang::EShTargetLanguageVersion)0x10400);
293                                 break;
294                         case SPIRV_VERSION_1_5:
295                                 shader.setEnvTarget(glslang::EshTargetSpv, (glslang::EShTargetLanguageVersion)0x10500);
296                                 break;
297                         default:
298                                 TCU_THROW(InternalError, "Unsupported SPIR-V target version");
299                         }
300
301                         glslangProgram.addShader(&shader);
302
303                         if (shaderLanguage == SHADER_LANGUAGE_HLSL)
304                         {
305                                 // Entry point assumed to be named main.
306                                 shader.setEntryPoint("main");
307                         }
308
309                         {
310                                 const deUint64  compileStartTime        = deGetMicroseconds();
311                                 const int               compileRes                      = shader.parse(&builtinRes, 110, false, compileFlags);
312                                 glu::ShaderInfo shaderBuildInfo;
313
314                                 shaderBuildInfo.type                    = (glu::ShaderType)shaderType;
315                                 shaderBuildInfo.source                  = srcText;
316                                 shaderBuildInfo.infoLog                 = shader.getInfoLog(); // \todo [2015-07-13 pyry] Include debug log?
317                                 shaderBuildInfo.compileTimeUs   = deGetMicroseconds()-compileStartTime;
318                                 shaderBuildInfo.compileOk               = (compileRes != 0);
319
320                                 buildInfo->shaders.push_back(shaderBuildInfo);
321                         }
322
323                         DE_ASSERT(buildInfo->shaders.size() == 1);
324                         if (buildInfo->shaders[0].compileOk)
325                         {
326                                 const deUint64  linkStartTime   = deGetMicroseconds();
327                                 const int               linkRes                 = glslangProgram.link(compileFlags);
328
329                                 buildInfo->program.infoLog              = glslangProgram.getInfoLog(); // \todo [2015-11-05 scygan] Include debug log?
330                                 buildInfo->program.linkOk               = (linkRes != 0);
331                                 buildInfo->program.linkTimeUs   = deGetMicroseconds()-linkStartTime;
332                         }
333
334                         if (buildInfo->program.linkOk)
335                         {
336                                 const glslang::TIntermediate* const     intermediate    = glslangProgram.getIntermediate(shaderStage);
337                                 glslang::GlslangToSpv(*intermediate, *dst);
338                         }
339
340                         return buildInfo->program.linkOk;
341                 }
342         }
343
344         TCU_THROW(InternalError, "Can't compile empty program");
345 }
346
347 bool compileGlslToSpirV (const GlslSource& program, std::vector<deUint32>* dst, glu::ShaderProgramInfo* buildInfo)
348 {
349         return compileShaderToSpirV(program.sources, program.buildOptions, program.shaderLanguage, dst, buildInfo);
350 }
351
352 bool compileHlslToSpirV (const HlslSource& program, std::vector<deUint32>* dst, glu::ShaderProgramInfo* buildInfo)
353 {
354         return compileShaderToSpirV(program.sources, program.buildOptions, program.shaderLanguage, dst, buildInfo);
355 }
356
357 void stripSpirVDebugInfo (const size_t numSrcInstrs, const deUint32* srcInstrs, std::vector<deUint32>* dst)
358 {
359         spv::spirvbin_t remapper;
360
361         // glslang operates in-place
362         dst->resize(numSrcInstrs);
363         std::copy(srcInstrs, srcInstrs+numSrcInstrs, dst->begin());
364         remapper.remap(*dst, spv::spirvbin_base_t::STRIP);
365 }
366
367 } // vk