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