Add runtime to CtsDeqpTestCases
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / framework / vulkan / vkGlslToSpirV.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 GLSL to SPIR-V.
22  *//*--------------------------------------------------------------------*/
23
24 #include "vkGlslToSpirV.hpp"
25 #include "deArrayUtil.hpp"
26 #include "deMutex.hpp"
27 #include "deSingleton.h"
28 #include "deMemory.h"
29 #include "deClock.h"
30 #include "qpDebugOut.h"
31
32 #if defined(DEQP_HAVE_GLSLANG)
33 #       include "SPIRV/GlslangToSpv.h"
34 #       include "SPIRV/disassemble.h"
35 #       include "SPIRV/SPVRemapper.h"
36 #       include "SPIRV/doc.h"
37 #       include "glslang/Include/InfoSink.h"
38 #       include "glslang/Include/ShHandle.h"
39 #       include "glslang/MachineIndependent/localintermediate.h"
40 #       include "glslang/Public/ShaderLang.h"
41 #endif
42
43 namespace vk
44 {
45
46 using std::string;
47 using std::vector;
48
49 #if defined(DEQP_HAVE_GLSLANG)
50
51 namespace
52 {
53
54 EShLanguage getGlslangStage (glu::ShaderType type)
55 {
56         static const EShLanguage stageMap[] =
57         {
58                 EShLangVertex,
59                 EShLangFragment,
60                 EShLangGeometry,
61                 EShLangTessControl,
62                 EShLangTessEvaluation,
63                 EShLangCompute,
64         };
65         return de::getSizedArrayElement<glu::SHADERTYPE_LAST>(stageMap, type);
66 }
67
68 static volatile deSingletonState        s_glslangInitState      = DE_SINGLETON_STATE_NOT_INITIALIZED;
69 static de::Mutex                                        s_glslangLock;
70
71 void initGlslang (void*)
72 {
73         // Main compiler
74         glslang::InitializeProcess();
75
76         // SPIR-V disassembly
77         spv::Parameterize();
78 }
79
80 void prepareGlslang (void)
81 {
82         deInitSingleton(&s_glslangInitState, initGlslang, DE_NULL);
83 }
84
85 // \todo [2015-06-19 pyry] Specialize these per GLSL version
86
87 // Fail compilation if more members are added to TLimits or TBuiltInResource
88 struct LimitsSizeHelper_s                       { bool m0, m1, m2, m3, m4, m5, m6, m7, m8; };
89 struct BuiltInResourceSizeHelper_s      { int m[83]; LimitsSizeHelper_s l; };
90
91 DE_STATIC_ASSERT(sizeof(TLimits)                        == sizeof(LimitsSizeHelper_s));
92 DE_STATIC_ASSERT(sizeof(TBuiltInResource)       == sizeof(BuiltInResourceSizeHelper_s));
93
94 void getDefaultLimits (TLimits* limits)
95 {
96         limits->nonInductiveForLoops                                    = true;
97         limits->whileLoops                                                              = true;
98         limits->doWhileLoops                                                    = true;
99         limits->generalUniformIndexing                                  = true;
100         limits->generalAttributeMatrixVectorIndexing    = true;
101         limits->generalVaryingIndexing                                  = true;
102         limits->generalSamplerIndexing                                  = true;
103         limits->generalVariableIndexing                                 = true;
104         limits->generalConstantMatrixVectorIndexing             = true;
105 }
106
107 void getDefaultBuiltInResources (TBuiltInResource* builtin)
108 {
109         getDefaultLimits(&builtin->limits);
110
111         builtin->maxLights                                                                      = 32;
112         builtin->maxClipPlanes                                                          = 6;
113         builtin->maxTextureUnits                                                        = 32;
114         builtin->maxTextureCoords                                                       = 32;
115         builtin->maxVertexAttribs                                                       = 64;
116         builtin->maxVertexUniformComponents                                     = 4096;
117         builtin->maxVaryingFloats                                                       = 64;
118         builtin->maxVertexTextureImageUnits                                     = 32;
119         builtin->maxCombinedTextureImageUnits                           = 80;
120         builtin->maxTextureImageUnits                                           = 32;
121         builtin->maxFragmentUniformComponents                           = 4096;
122         builtin->maxDrawBuffers                                                         = 32;
123         builtin->maxVertexUniformVectors                                        = 128;
124         builtin->maxVaryingVectors                                                      = 8;
125         builtin->maxFragmentUniformVectors                                      = 16;
126         builtin->maxVertexOutputVectors                                         = 16;
127         builtin->maxFragmentInputVectors                                        = 15;
128         builtin->minProgramTexelOffset                                          = -8;
129         builtin->maxProgramTexelOffset                                          = 7;
130         builtin->maxClipDistances                                                       = 8;
131         builtin->maxComputeWorkGroupCountX                                      = 65535;
132         builtin->maxComputeWorkGroupCountY                                      = 65535;
133         builtin->maxComputeWorkGroupCountZ                                      = 65535;
134         builtin->maxComputeWorkGroupSizeX                                       = 1024;
135         builtin->maxComputeWorkGroupSizeY                                       = 1024;
136         builtin->maxComputeWorkGroupSizeZ                                       = 64;
137         builtin->maxComputeUniformComponents                            = 1024;
138         builtin->maxComputeTextureImageUnits                            = 16;
139         builtin->maxComputeImageUniforms                                        = 8;
140         builtin->maxComputeAtomicCounters                                       = 8;
141         builtin->maxComputeAtomicCounterBuffers                         = 1;
142         builtin->maxVaryingComponents                                           = 60;
143         builtin->maxVertexOutputComponents                                      = 64;
144         builtin->maxGeometryInputComponents                                     = 64;
145         builtin->maxGeometryOutputComponents                            = 128;
146         builtin->maxFragmentInputComponents                                     = 128;
147         builtin->maxImageUnits                                                          = 8;
148         builtin->maxCombinedImageUnitsAndFragmentOutputs        = 8;
149         builtin->maxCombinedShaderOutputResources                       = 8;
150         builtin->maxImageSamples                                                        = 0;
151         builtin->maxVertexImageUniforms                                         = 0;
152         builtin->maxTessControlImageUniforms                            = 0;
153         builtin->maxTessEvaluationImageUniforms                         = 0;
154         builtin->maxGeometryImageUniforms                                       = 0;
155         builtin->maxFragmentImageUniforms                                       = 8;
156         builtin->maxCombinedImageUniforms                                       = 8;
157         builtin->maxGeometryTextureImageUnits                           = 16;
158         builtin->maxGeometryOutputVertices                                      = 256;
159         builtin->maxGeometryTotalOutputComponents                       = 1024;
160         builtin->maxGeometryUniformComponents                           = 1024;
161         builtin->maxGeometryVaryingComponents                           = 64;
162         builtin->maxTessControlInputComponents                          = 128;
163         builtin->maxTessControlOutputComponents                         = 128;
164         builtin->maxTessControlTextureImageUnits                        = 16;
165         builtin->maxTessControlUniformComponents                        = 1024;
166         builtin->maxTessControlTotalOutputComponents            = 4096;
167         builtin->maxTessEvaluationInputComponents                       = 128;
168         builtin->maxTessEvaluationOutputComponents                      = 128;
169         builtin->maxTessEvaluationTextureImageUnits                     = 16;
170         builtin->maxTessEvaluationUniformComponents                     = 1024;
171         builtin->maxTessPatchComponents                                         = 120;
172         builtin->maxPatchVertices                                                       = 32;
173         builtin->maxTessGenLevel                                                        = 64;
174         builtin->maxViewports                                                           = 16;
175         builtin->maxVertexAtomicCounters                                        = 0;
176         builtin->maxTessControlAtomicCounters                           = 0;
177         builtin->maxTessEvaluationAtomicCounters                        = 0;
178         builtin->maxGeometryAtomicCounters                                      = 0;
179         builtin->maxFragmentAtomicCounters                                      = 8;
180         builtin->maxCombinedAtomicCounters                                      = 8;
181         builtin->maxAtomicCounterBindings                                       = 1;
182         builtin->maxVertexAtomicCounterBuffers                          = 0;
183         builtin->maxTessControlAtomicCounterBuffers                     = 0;
184         builtin->maxTessEvaluationAtomicCounterBuffers          = 0;
185         builtin->maxGeometryAtomicCounterBuffers                        = 0;
186         builtin->maxFragmentAtomicCounterBuffers                        = 1;
187         builtin->maxCombinedAtomicCounterBuffers                        = 1;
188         builtin->maxAtomicCounterBufferSize                                     = 16384;
189         builtin->maxTransformFeedbackBuffers                            = 4;
190         builtin->maxTransformFeedbackInterleavedComponents      = 64;
191         builtin->maxCullDistances                                                       = 8;
192         builtin->maxCombinedClipAndCullDistances                        = 8;
193         builtin->maxSamples                                                                     = 4;
194 };
195
196 } // anonymous
197
198 int getNumShaderStages (const glu::ProgramSources& program)
199 {
200         int numShaderStages = 0;
201
202         for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; ++shaderType)
203         {
204                 if (!program.sources[shaderType].empty())
205                         numShaderStages += 1;
206         }
207
208         return numShaderStages;
209 }
210
211 bool compileGlslToSpirV (const glu::ProgramSources& program, std::vector<deUint32>* dst, glu::ShaderProgramInfo* buildInfo)
212 {
213         TBuiltInResource        builtinRes;
214
215         if (getNumShaderStages(program) > 1)
216                 TCU_THROW(InternalError, "Linking multiple shader stages into a single SPIR-V binary is not supported");
217
218         prepareGlslang();
219         getDefaultBuiltInResources(&builtinRes);
220
221         // \note Compiles only first found shader
222         for (int shaderType = 0; shaderType < glu::SHADERTYPE_LAST; shaderType++)
223         {
224                 if (!program.sources[shaderType].empty())
225                 {
226                         const de::ScopedLock    compileLock                     (s_glslangLock);
227                         const std::string&              srcText                         = program.sources[shaderType][0];
228                         const char*                             srcPtrs[]                       = { srcText.c_str() };
229                         const int                               srcLengths[]            = { (int)srcText.size() };
230                         const EShLanguage               shaderStage                     = getGlslangStage(glu::ShaderType(shaderType));
231                         glslang::TShader                shader                          (shaderStage);
232                         glslang::TProgram               program;
233
234                         shader.setStrings(srcPtrs, DE_LENGTH_OF_ARRAY(srcPtrs));
235                         program.addShader(&shader);
236
237                         {
238                                 const deUint64  compileStartTime        = deGetMicroseconds();
239                                 const int               compileRes                      = shader.parse(&builtinRes, 110, false, (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules));
240                                 glu::ShaderInfo shaderBuildInfo;
241
242                                 shaderBuildInfo.type                    = (glu::ShaderType)shaderType;
243                                 shaderBuildInfo.source                  = srcText;
244                                 shaderBuildInfo.infoLog                 = shader.getInfoLog(); // \todo [2015-07-13 pyry] Include debug log?
245                                 shaderBuildInfo.compileTimeUs   = deGetMicroseconds()-compileStartTime;
246                                 shaderBuildInfo.compileOk               = (compileRes != 0);
247
248                                 buildInfo->shaders.push_back(shaderBuildInfo);
249                         }
250
251                         DE_ASSERT(buildInfo->shaders.size() == 1);
252                         if (buildInfo->shaders[0].compileOk)
253                         {
254                                 const deUint64  linkStartTime   = deGetMicroseconds();
255                                 const int               linkRes                 = program.link((EShMessages)(EShMsgSpvRules | EShMsgVulkanRules));
256
257                                 buildInfo->program.infoLog              = program.getInfoLog(); // \todo [2015-11-05 scygan] Include debug log?
258                                 buildInfo->program.linkOk               = (linkRes != 0);
259                                 buildInfo->program.linkTimeUs   = deGetMicroseconds()-linkStartTime;
260                         }
261
262                         if (buildInfo->program.linkOk)
263                         {
264                                 const glslang::TIntermediate* const     intermediate    = program.getIntermediate(shaderStage);
265                                 glslang::GlslangToSpv(*intermediate, *dst);
266                         }
267
268                         return buildInfo->program.linkOk;
269                 }
270         }
271
272         TCU_THROW(InternalError, "Can't compile empty program");
273 }
274
275 void stripSpirVDebugInfo (const size_t numSrcInstrs, const deUint32* srcInstrs, std::vector<deUint32>* dst)
276 {
277         spv::spirvbin_t remapper;
278
279         // glslang operates in-place
280         dst->resize(numSrcInstrs);
281         std::copy(srcInstrs, srcInstrs+numSrcInstrs, dst->begin());
282         remapper.remap(*dst, spv::spirvbin_base_t::STRIP);
283 }
284
285 #else // defined(DEQP_HAVE_GLSLANG)
286
287 bool compileGlslToSpirV (const glu::ProgramSources&, std::vector<deUint32>*, glu::ShaderProgramInfo*)
288 {
289         TCU_THROW(NotSupportedError, "GLSL to SPIR-V compilation not supported (DEQP_HAVE_GLSLANG not defined)");
290 }
291
292 void stripSpirVDebugInfo (const size_t, const deUint32*, std::vector<deUint32>*)
293 {
294         TCU_THROW(NotSupportedError, "SPIR-V stripping not supported (DEQP_HAVE_GLSLANG not defined)");
295 }
296
297 #endif // defined(DEQP_HAVE_GLSLANG)
298
299 } // vk