Merge remote-tracking branch 'aosp/master' into HEAD
[platform/upstream/VK-GL-CTS.git] / external / openglcts / modules / gl / gl4cGlSpirvTests.cpp
1 /*-------------------------------------------------------------------------
2  * OpenGL Conformance Test Suite
3  * -----------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group 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
22  */ /*-------------------------------------------------------------------*/
23
24 /**
25  */ /*!
26  * \file  gl4cGlSpirvTests.cpp
27  * \brief Conformance tests for the GL_ARB_gl_spirv functionality.
28  */ /*-------------------------------------------------------------------*/
29
30 #include "gl4cGlSpirvTests.hpp"
31 #include "deArrayUtil.hpp"
32 #include "deSingleton.h"
33 #include "deStringUtil.hpp"
34 #include "gluContextInfo.hpp"
35 #include "gluDefs.hpp"
36 #include "gluShaderProgram.hpp"
37 #include "gluStrUtil.hpp"
38 #include "glwEnums.hpp"
39 #include "glwFunctions.hpp"
40 #include "tcuRenderTarget.hpp"
41 #include "tcuResource.hpp"
42 #include "tcuTestLog.hpp"
43
44 #if defined DEQP_HAVE_GLSLANG
45 #include "SPIRV/GlslangToSpv.h"
46 #include "SPIRV/disassemble.h"
47 #include "SPIRV/doc.h"
48 #include "glslang/MachineIndependent/localintermediate.h"
49 #include "glslang/Public/ShaderLang.h"
50 #endif // DEQP_HAVE_GLSLANG
51
52 #if defined DEQP_HAVE_SPIRV_TOOLS
53 #include "spirv-tools/libspirv.hpp"
54 #include "spirv-tools/optimizer.hpp"
55 #endif // DEQP_HAVE_SPIRV_TOOLS
56
57 using namespace glu;
58 using namespace glw;
59
60 namespace gl4cts
61 {
62
63 namespace glslangUtils
64 {
65
66 #if defined DEQP_HAVE_GLSLANG
67
68 EShLanguage getGlslangStage(glu::ShaderType type)
69 {
70         static const EShLanguage stageMap[] = {
71                 EShLangVertex, EShLangFragment, EShLangGeometry, EShLangTessControl, EShLangTessEvaluation, EShLangCompute,
72         };
73
74         return de::getSizedArrayElement<glu::SHADERTYPE_LAST>(stageMap, type);
75 }
76
77 static volatile deSingletonState s_glslangInitState = DE_SINGLETON_STATE_NOT_INITIALIZED;
78
79 void initGlslang(void*)
80 {
81         // Main compiler
82         glslang::InitializeProcess();
83
84         // SPIR-V disassembly
85         spv::Parameterize();
86 }
87
88 void prepareGlslang(void)
89 {
90         deInitSingleton(&s_glslangInitState, initGlslang, DE_NULL);
91 }
92
93 void getDefaultLimits(TLimits* limits)
94 {
95         limits->nonInductiveForLoops                             = true;
96         limits->whileLoops                                                       = true;
97         limits->doWhileLoops                                             = true;
98         limits->generalUniformIndexing                           = true;
99         limits->generalAttributeMatrixVectorIndexing = true;
100         limits->generalVaryingIndexing                           = true;
101         limits->generalSamplerIndexing                           = true;
102         limits->generalVariableIndexing                          = true;
103         limits->generalConstantMatrixVectorIndexing  = true;
104 }
105
106 void getDefaultBuiltInResources(TBuiltInResource* builtin)
107 {
108         getDefaultLimits(&builtin->limits);
109
110         builtin->maxLights                                                                 = 32;
111         builtin->maxClipPlanes                                                     = 6;
112         builtin->maxTextureUnits                                                   = 32;
113         builtin->maxTextureCoords                                                  = 32;
114         builtin->maxVertexAttribs                                                  = 64;
115         builtin->maxVertexUniformComponents                                = 4096;
116         builtin->maxVaryingFloats                                                  = 64;
117         builtin->maxVertexTextureImageUnits                                = 32;
118         builtin->maxCombinedTextureImageUnits                      = 80;
119         builtin->maxTextureImageUnits                                      = 32;
120         builtin->maxFragmentUniformComponents                      = 4096;
121         builtin->maxDrawBuffers                                                    = 32;
122         builtin->maxVertexUniformVectors                                   = 128;
123         builtin->maxVaryingVectors                                                 = 8;
124         builtin->maxFragmentUniformVectors                                 = 16;
125         builtin->maxVertexOutputVectors                                    = 16;
126         builtin->maxFragmentInputVectors                                   = 15;
127         builtin->minProgramTexelOffset                                     = -8;
128         builtin->maxProgramTexelOffset                                     = 7;
129         builtin->maxClipDistances                                                  = 8;
130         builtin->maxComputeWorkGroupCountX                                 = 65535;
131         builtin->maxComputeWorkGroupCountY                                 = 65535;
132         builtin->maxComputeWorkGroupCountZ                                 = 65535;
133         builtin->maxComputeWorkGroupSizeX                                  = 1024;
134         builtin->maxComputeWorkGroupSizeY                                  = 1024;
135         builtin->maxComputeWorkGroupSizeZ                                  = 64;
136         builtin->maxComputeUniformComponents                       = 1024;
137         builtin->maxComputeTextureImageUnits                       = 16;
138         builtin->maxComputeImageUniforms                                   = 8;
139         builtin->maxComputeAtomicCounters                                  = 8;
140         builtin->maxComputeAtomicCounterBuffers                    = 1;
141         builtin->maxVaryingComponents                                      = 60;
142         builtin->maxVertexOutputComponents                                 = 64;
143         builtin->maxGeometryInputComponents                                = 64;
144         builtin->maxGeometryOutputComponents                       = 128;
145         builtin->maxFragmentInputComponents                                = 128;
146         builtin->maxImageUnits                                                     = 8;
147         builtin->maxCombinedImageUnitsAndFragmentOutputs   = 8;
148         builtin->maxCombinedShaderOutputResources                  = 8;
149         builtin->maxImageSamples                                                   = 0;
150         builtin->maxVertexImageUniforms                                    = 0;
151         builtin->maxTessControlImageUniforms                       = 0;
152         builtin->maxTessEvaluationImageUniforms                    = 0;
153         builtin->maxGeometryImageUniforms                                  = 0;
154         builtin->maxFragmentImageUniforms                                  = 8;
155         builtin->maxCombinedImageUniforms                                  = 8;
156         builtin->maxGeometryTextureImageUnits                      = 16;
157         builtin->maxGeometryOutputVertices                                 = 256;
158         builtin->maxGeometryTotalOutputComponents                  = 1024;
159         builtin->maxGeometryUniformComponents                      = 1024;
160         builtin->maxGeometryVaryingComponents                      = 64;
161         builtin->maxTessControlInputComponents                     = 128;
162         builtin->maxTessControlOutputComponents                    = 128;
163         builtin->maxTessControlTextureImageUnits                   = 16;
164         builtin->maxTessControlUniformComponents                   = 1024;
165         builtin->maxTessControlTotalOutputComponents       = 4096;
166         builtin->maxTessEvaluationInputComponents                  = 128;
167         builtin->maxTessEvaluationOutputComponents                 = 128;
168         builtin->maxTessEvaluationTextureImageUnits                = 16;
169         builtin->maxTessEvaluationUniformComponents                = 1024;
170         builtin->maxTessPatchComponents                                    = 120;
171         builtin->maxPatchVertices                                                  = 32;
172         builtin->maxTessGenLevel                                                   = 64;
173         builtin->maxViewports                                                      = 16;
174         builtin->maxVertexAtomicCounters                                   = 0;
175         builtin->maxTessControlAtomicCounters                      = 0;
176         builtin->maxTessEvaluationAtomicCounters                   = 0;
177         builtin->maxGeometryAtomicCounters                                 = 0;
178         builtin->maxFragmentAtomicCounters                                 = 8;
179         builtin->maxCombinedAtomicCounters                                 = 8;
180         builtin->maxAtomicCounterBindings                                  = 1;
181         builtin->maxVertexAtomicCounterBuffers                     = 0;
182         builtin->maxTessControlAtomicCounterBuffers                = 0;
183         builtin->maxTessEvaluationAtomicCounterBuffers   = 0;
184         builtin->maxGeometryAtomicCounterBuffers                   = 0;
185         builtin->maxFragmentAtomicCounterBuffers                   = 1;
186         builtin->maxCombinedAtomicCounterBuffers                   = 1;
187         builtin->maxAtomicCounterBufferSize                                = 16384;
188         builtin->maxTransformFeedbackBuffers                       = 4;
189         builtin->maxTransformFeedbackInterleavedComponents = 64;
190         builtin->maxCullDistances                                                  = 8;
191         builtin->maxCombinedClipAndCullDistances                   = 8;
192         builtin->maxSamples                                                                = 4;
193         builtin->maxMeshOutputVerticesNV                                   = 256;
194         builtin->maxMeshOutputPrimitivesNV                                 = 256;
195         builtin->maxMeshWorkGroupSizeX_NV                                  = 32;
196         builtin->maxMeshWorkGroupSizeY_NV                                  = 1;
197         builtin->maxMeshWorkGroupSizeZ_NV                                  = 1;
198         builtin->maxTaskWorkGroupSizeX_NV                                  = 32;
199         builtin->maxTaskWorkGroupSizeY_NV                                  = 1;
200         builtin->maxTaskWorkGroupSizeZ_NV                                  = 1;
201         builtin->maxMeshViewCountNV                                                = 4;
202 };
203
204 bool compileGlslToSpirV(tcu::TestLog& log, std::string source, glu::ShaderType type, ShaderBinaryDataType* dst)
205 {
206         TBuiltInResource builtinRes;
207
208         prepareGlslang();
209         getDefaultBuiltInResources(&builtinRes);
210
211         const EShLanguage shaderStage = getGlslangStage(type);
212
213         glslang::TShader  shader(shaderStage);
214         glslang::TProgram program;
215
216         const char* src[] = { source.c_str() };
217
218         shader.setStrings(src, 1);
219         program.addShader(&shader);
220
221         const int compileRes = shader.parse(&builtinRes, 100, false, EShMsgSpvRules);
222         if (compileRes != 0)
223         {
224                 const int linkRes = program.link(EShMsgSpvRules);
225
226                 if (linkRes != 0)
227                 {
228                         const glslang::TIntermediate* const intermediate = program.getIntermediate(shaderStage);
229                         glslang::GlslangToSpv(*intermediate, *dst);
230
231                         return true;
232                 }
233                 else
234                 {
235                         log << tcu::TestLog::Message << "Program linking error:\n"
236                                 << program.getInfoLog() << "\n"
237                                 << "Source:\n"
238                                 << source << "\n"
239                                 << tcu::TestLog::EndMessage;
240                 }
241         }
242         else
243         {
244                 log << tcu::TestLog::Message << "Shader compilation error:\n"
245                         << shader.getInfoLog() << "\n"
246                         << "Source:\n"
247                         << source << "\n"
248                         << tcu::TestLog::EndMessage;
249         }
250
251         return false;
252 }
253
254 #else // DEQP_HAVE_GLSLANG
255
256 bool compileGlslToSpirV(tcu::TestLog& log, std::string source, glu::ShaderType type, ShaderBinaryDataType* dst)
257 {
258         DE_UNREF(log);
259         DE_UNREF(source);
260         DE_UNREF(type);
261         DE_UNREF(dst);
262
263         TCU_THROW(InternalError, "Glslang not available.");
264
265         return false;
266 }
267
268 #endif // DEQP_HAVE_GLSLANG
269
270 #if defined DEQP_HAVE_SPIRV_TOOLS
271
272 void consumer(spv_message_level_t, const char*, const spv_position_t&, const char* m)
273 {
274         std::cerr << "error: " << m << std::endl;
275 }
276
277 void spirvAssemble(ShaderBinaryDataType& dst, const std::string& src)
278 {
279         spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
280
281         core.SetMessageConsumer(consumer);
282
283         if (!core.Assemble(src, &dst))
284                 TCU_THROW(InternalError, "Failed to assemble Spir-V source.");
285 }
286
287 void spirvDisassemble(std::string& dst, const ShaderBinaryDataType& src)
288 {
289         spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
290
291         core.SetMessageConsumer(consumer);
292
293         if (!core.Disassemble(src, &dst))
294                 TCU_THROW(InternalError, "Failed to disassemble Spir-V module.");
295 }
296
297 bool spirvValidate(ShaderBinaryDataType& dst, bool throwOnError)
298 {
299         spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
300
301         if (throwOnError)
302                 core.SetMessageConsumer(consumer);
303
304         if (!core.Validate(dst))
305         {
306                 if (throwOnError)
307                         TCU_THROW(InternalError, "Failed to validate Spir-V module.");
308                 return false;
309         }
310
311         return true;
312 }
313
314 #else //DEQP_HAVE_SPIRV_TOOLS
315
316 void spirvAssemble(ShaderBinaryDataType& dst, const std::string& src)
317 {
318         DE_UNREF(dst);
319         DE_UNREF(src);
320
321         TCU_THROW(InternalError, "Spirv-tools not available.");
322 }
323
324 void spirvDisassemble(std::string& dst, ShaderBinaryDataType& src)
325 {
326         DE_UNREF(dst);
327         DE_UNREF(src);
328
329         TCU_THROW(InternalError, "Spirv-tools not available.");
330 }
331
332 bool spirvValidate(ShaderBinaryDataType& dst, bool throwOnError)
333 {
334         DE_UNREF(dst);
335         DE_UNREF(throwOnError);
336
337         TCU_THROW(InternalError, "Spirv-tools not available.");
338 }
339
340 #endif // DEQP_HAVE_SPIRV_TOOLS
341
342 ShaderBinary makeSpirV(tcu::TestLog& log, ShaderSource source)
343 {
344         ShaderBinary binary;
345
346         if (!glslangUtils::compileGlslToSpirV(log, source.source, source.shaderType, &binary.binary))
347                 TCU_THROW(InternalError, "Failed to convert GLSL to Spir-V");
348
349         binary << source.shaderType << "main";
350
351         return binary;
352 }
353
354 /** Verifying if GLSL to SpirV mapping was performed correctly
355  *
356  * @param glslSource       GLSL shader template
357  * @param spirVSource      SpirV disassembled source
358  * @param mappings         Glsl to SpirV mappings vector
359  * @param anyOf            any occurence indicator
360  *
361  * @return true if GLSL code occurs as many times as all of SpirV code for each mapping if anyOf is false
362  *         or true if SpirV code occurs at least once if GLSL code found, false otherwise.
363  **/
364 bool verifyMappings(std::string glslSource, std::string spirVSource, SpirVMapping& mappings, bool anyOf)
365 {
366         std::vector<std::string> spirVSourceLines = de::splitString(spirVSource, '\n');
367
368         // Iterate through all glsl functions
369         for (SpirVMapping::iterator it = mappings.begin(); it != mappings.end(); it++)
370         {
371                 int glslCodeCount  = 0;
372                 int spirVCodeCount = 0;
373
374                 // To avoid finding functions with similar names (ie. "cos", "acos", "cosh")
375                 // add characteristic characters that delimits finding results
376                 std::string glslCode = it->first;
377
378                 // Count GLSL code occurrences in GLSL source
379                 size_t codePosition = glslSource.find(glslCode);
380                 while (codePosition != std::string::npos)
381                 {
382                         glslCodeCount++;
383                         codePosition = glslSource.find(glslCode, codePosition + 1);
384                 }
385
386                 if (glslCodeCount > 0)
387                 {
388                         // Count all SpirV code variants occurrences in SpirV source
389                         for (int s = 0; s < (signed)it->second.size(); ++s)
390                         {
391                                 std::vector<std::string> spirVCodes = de::splitString(it->second[s], ' ');
392
393                                 for (int v = 0; v < (signed)spirVSourceLines.size(); ++v)
394                                 {
395                                         std::vector<std::string> spirVLineCodes = de::splitString(spirVSourceLines[v], ' ');
396
397                                         bool matchAll = true;
398                                         for (int j = 0; j < (signed)spirVCodes.size(); ++j)
399                                         {
400                                                 bool match = false;
401                                                 for (int i = 0; i < (signed)spirVLineCodes.size(); ++i)
402                                                 {
403                                                         if (spirVLineCodes[i] == spirVCodes[j])
404                                                                 match = true;
405                                                 }
406
407                                                 matchAll = matchAll && match;
408                                         }
409
410                                         if (matchAll)
411                                                 spirVCodeCount++;
412                                 }
413                         }
414
415                         // Check if both counts match
416                         if (anyOf && (glslCodeCount > 0 && spirVCodeCount == 0))
417                                 return false;
418                         else if (!anyOf && glslCodeCount != spirVCodeCount)
419                                 return false;
420                 }
421         }
422
423         return true;
424 }
425
426 } // namespace glslangUtils
427
428 namespace commonUtils
429 {
430
431 void writeSpirV(const char* filename, ShaderBinary binary)
432 {
433         FILE* file = fopen(filename, "wb");
434         if (file)
435         {
436                 // As one binary could be associated with many shader objects it should be stored either a type of each shader
437                 // This will be extended in the future
438                 deUint8 count = (deUint8)binary.shaderTypes.size();
439                 fwrite((void*)&count, 1, 1, file);
440                 for (int i = 0; i < (signed)binary.shaderTypes.size(); ++i)
441                 {
442                         fwrite((void*)&binary.shaderTypes[i], 1, sizeof(ShaderType), file);
443
444                         if (count > 1)
445                         {
446                                 deUint8 strLen = (deUint8)binary.shaderEntryPoints[i].size();
447                                 fwrite((void*)&strLen, 1, 1, file);
448                                 fwrite((void*)binary.shaderEntryPoints[i].data(), 1, strLen, file);
449                         }
450                 }
451
452                 fwrite((void*)binary.binary.data(), 1, binary.binary.size() * 4, file);
453                 fclose(file);
454         }
455 }
456
457 ShaderBinary readSpirV(tcu::Resource* resource)
458 {
459         ShaderBinary binary;
460         if (!resource)
461                 return binary;
462
463         // As one binary could be associated with many shader objects it should be stored either a type of each shader
464         deUint8 count;
465         resource->read(&count, 1);
466         binary.shaderTypes.resize(count);
467         binary.shaderEntryPoints.resize(count);
468         for (int i = 0; i < (signed)binary.shaderTypes.size(); ++i)
469         {
470                 resource->read((deUint8*)&binary.shaderTypes[i], sizeof(ShaderType));
471
472                 if (count > 1)
473                 {
474                         deUint8 strLen;
475                         resource->read(&strLen, 1);
476
477                         binary.shaderEntryPoints[i].resize(strLen);
478                         resource->read((deUint8*)binary.shaderEntryPoints[i].data(), strLen);
479                 }
480                 else
481                         binary.shaderEntryPoints[i] = "main";
482         }
483
484         binary.binary.resize((resource->getSize() - resource->getPosition()) / sizeof(deUint32));
485         resource->read((deUint8*)binary.binary.data(), binary.binary.size() * sizeof(deUint32));
486
487         return binary;
488 }
489
490 /** Replace all occurance of <token> with <text> in <string>
491  *
492  * @param token           Token string
493  * @param text            String th at will be used as replacement for <token>
494  * @param string          String to work on
495  **/
496 void replaceToken(const GLchar* token, const GLchar* text, std::string& string)
497 {
498         const size_t text_length  = strlen(text);
499         const size_t token_length = strlen(token);
500
501         size_t token_position;
502         while ((token_position = string.find(token, 0)) != std::string::npos)
503         {
504                 string.replace(token_position, token_length, text, text_length);
505         }
506 }
507
508 bool compareUintColors(const GLuint inColor, const GLuint refColor, const int epsilon)
509 {
510         int r1 = (inColor & 0xFF);
511         int g1 = ((inColor >> 8) & 0xFF);
512         int b1 = ((inColor >> 16) & 0xFF);
513         int a1 = ((inColor >> 24) & 0xFF);
514
515         int r2 = (refColor & 0xFF);
516         int g2 = ((refColor >> 8) & 0xFF);
517         int b2 = ((refColor >> 16) & 0xFF);
518         int a2 = ((refColor >> 24) & 0xFF);
519
520         if (r1 >= r2 - epsilon && r1 <= r2 + epsilon && g1 >= g2 - epsilon && g1 <= g2 + epsilon && b1 >= b2 - epsilon &&
521                 b1 <= b2 + epsilon && a1 >= a2 - epsilon && a1 <= a2 + epsilon)
522         {
523                 return true;
524         }
525
526         return false;
527 }
528
529 void checkGlSpirvSupported(deqp::Context& m_context)
530 {
531         bool is_at_least_gl_46 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 6)));
532         bool is_arb_gl_spirv = m_context.getContextInfo().isExtensionSupported("GL_ARB_gl_spirv");
533
534         if ((!is_at_least_gl_46) && (!is_arb_gl_spirv))
535                 TCU_THROW(NotSupportedError, "GL_ARB_gl_spirv is not supported");
536 }
537 } // namespace commonUtils
538
539 /** Constructor.
540  *
541  *  @param context     Rendering context
542  *  @param name        Test name
543  *  @param description Test description
544  */
545 SpirvModulesPositiveTest::SpirvModulesPositiveTest(deqp::Context& context)
546         : TestCase(context, "spirv_modules_positive_test",
547                            "Test verifies if using SPIR-V modules for each shader stage works as expected")
548 {
549         /* Left blank intentionally */
550 }
551
552 /** Stub init method */
553 void SpirvModulesPositiveTest::init()
554 {
555         commonUtils::checkGlSpirvSupported(m_context);
556
557         m_vertex = "#version 450\n"
558                            "\n"
559                            "layout (location = 0) in vec3 position;\n"
560                            "\n"
561                            "layout (location = 1) out vec4 vColor;\n"
562                            "\n"
563                            "void main()\n"
564                            "{\n"
565                            "    gl_Position = vec4(position, 1.0);\n"
566                            "    vColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
567                            "}\n";
568
569         m_tesselationCtrl = "#version 450\n"
570                                                 "\n"
571                                                 "layout (vertices = 3) out;\n"
572                                                 "\n"
573                                                 "layout (location = 1) in vec4 vColor[];\n"
574                                                 "layout (location = 2) out vec4 tcColor[];\n"
575                                                 "\n"
576                                                 "void main()\n"
577                                                 "{\n"
578                                                 "    tcColor[gl_InvocationID] = vColor[gl_InvocationID];\n"
579                                                 "    tcColor[gl_InvocationID].r = 1.0;\n"
580                                                 "\n"
581                                                 "    if (gl_InvocationID == 0) {\n"
582                                                 "        gl_TessLevelOuter[0] = 1.0;\n"
583                                                 "        gl_TessLevelOuter[1] = 1.0;\n"
584                                                 "        gl_TessLevelOuter[2] = 1.0;\n"
585                                                 "        gl_TessLevelInner[0] = 1.0;\n"
586                                                 "    }\n"
587                                                 "\n"
588                                                 "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
589                                                 "}\n";
590
591         m_tesselationEval = "#version 450\n"
592                                                 "\n"
593                                                 "layout (triangles) in;\n"
594                                                 "\n"
595                                                 "layout (location = 2) in vec4 tcColor[];\n"
596                                                 "layout (location = 3) out vec4 teColor;\n"
597                                                 "\n"
598                                                 "void main()\n"
599                                                 "{\n"
600                                                 "    teColor = tcColor[0];\n"
601                                                 "    teColor.g = 1.0;\n"
602                                                 "\n"
603                                                 "    gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +\n"
604                                                 "                  gl_TessCoord.y * gl_in[1].gl_Position +\n"
605                                                 "                  gl_TessCoord.z * gl_in[2].gl_Position;\n"
606                                                 "}\n";
607
608         m_geometry = "#version 450\n"
609                                  "\n"
610                                  "layout (triangles) in;\n"
611                                  "layout (triangle_strip, max_vertices = 3) out;\n"
612                                  "\n"
613                                  "layout (location = 3) in vec4 teColor[];\n"
614                                  "layout (location = 4) out vec4 gColor;\n"
615                                  "\n"
616                                  "void main()\n"
617                                  "{\n"
618                                  "    gColor = teColor[0];\n"
619                                  "    gColor.b = 1.0;\n"
620                                  "\n"
621                                  "    for (int i = 0; i < 3; ++i) {\n"
622                                  "        gl_Position = gl_in[i].gl_Position;\n"
623                                  "        EmitVertex();\n"
624                                  "    }\n"
625                                  "    EndPrimitive();\n"
626                                  "}\n";
627
628         m_fragment = "#version 450\n"
629                                  "\n"
630                                  "layout (location = 4) in vec4 gColor;\n"
631                                  "layout (location = 0) out vec4 fColor;\n"
632                                  "\n"
633                                  "void main()\n"
634                                  "{\n"
635                                  "    fColor = gColor;\n"
636                                  "}\n";
637
638         const Functions& gl = m_context.getRenderContext().getFunctions();
639
640         gl.genTextures(1, &m_texture);
641         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
642         gl.bindTexture(GL_TEXTURE_2D, m_texture);
643         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
644         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32);
645         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
646
647         gl.genFramebuffers(1, &m_fbo);
648         GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
649         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
650         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
651         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
652         GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
653
654         gl.viewport(0, 0, 32, 32);
655         GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
656 }
657
658 /** Stub de-init method */
659 void SpirvModulesPositiveTest::deinit()
660 {
661         const Functions& gl = m_context.getRenderContext().getFunctions();
662
663         if (m_fbo)
664         {
665                 gl.deleteFramebuffers(1, &m_fbo);
666                 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
667         }
668         if (m_texture)
669         {
670                 gl.deleteTextures(1, &m_texture);
671                 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
672         }
673 }
674
675 /** Executes test iteration.
676  *
677  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
678  */
679 tcu::TestNode::IterateResult SpirvModulesPositiveTest::iterate()
680 {
681         const Functions& gl = m_context.getRenderContext().getFunctions();
682
683         const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
684
685         GLuint vao;
686         gl.genVertexArrays(1, &vao);
687         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
688         gl.bindVertexArray(vao);
689         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
690
691         GLuint vbo;
692         gl.genBuffers(1, &vbo);
693         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
694         gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
695         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
696
697         gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
698         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
699
700         enum Iterates
701         {
702                 ITERATE_GLSL,
703                 ITERATE_SPIRV,
704                 ITERATE_LAST
705         };
706
707         deUint32 outputs[ITERATE_LAST];
708         for (int it = ITERATE_GLSL; it < ITERATE_LAST; ++it)
709         {
710                 ShaderProgram* program = DE_NULL;
711                 if (it == ITERATE_GLSL)
712                 {
713                         ProgramSources sources;
714                         sources << VertexSource(m_vertex);
715                         sources << TessellationControlSource(m_tesselationCtrl);
716                         sources << TessellationEvaluationSource(m_tesselationEval);
717                         sources << GeometrySource(m_geometry);
718                         sources << FragmentSource(m_fragment);
719                         program = new ShaderProgram(gl, sources);
720                 }
721                 else if (it == ITERATE_SPIRV)
722                 {
723 #if defined                                     DEQP_HAVE_GLSLANG
724                         ProgramBinaries binaries;
725                         binaries << glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
726                         binaries << glslangUtils::makeSpirV(m_context.getTestContext().getLog(),
727                                                                                                 TessellationControlSource(m_tesselationCtrl));
728                         binaries << glslangUtils::makeSpirV(m_context.getTestContext().getLog(),
729                                                                                                 TessellationEvaluationSource(m_tesselationEval));
730                         binaries << glslangUtils::makeSpirV(m_context.getTestContext().getLog(), GeometrySource(m_geometry));
731                         binaries << glslangUtils::makeSpirV(m_context.getTestContext().getLog(), FragmentSource(m_fragment));
732                         program = new ShaderProgram(gl, binaries);
733 #else  // DEQP_HAVE_GLSLANG
734                         tcu::Archive&   archive = m_testCtx.getArchive();
735                         ProgramBinaries binaries;
736                         binaries << commonUtils::readSpirV(archive.getResource("spirv/modules_positive/vertex.nspv"));
737                         binaries << commonUtils::readSpirV(archive.getResource("spirv/modules_positive/tess_control.nspv"));
738                         binaries << commonUtils::readSpirV(archive.getResource("spirv/modules_positive/tess_evaluation.nspv"));
739                         binaries << commonUtils::readSpirV(archive.getResource("spirv/modules_positive/geometry.nspv"));
740                         binaries << commonUtils::readSpirV(archive.getResource("spirv/modules_positive/fragment.nspv"));
741                         program           = new ShaderProgram(gl, binaries);
742 #endif // DEQP_HAVE_GLSLANG
743                 }
744
745                 if (!program->isOk())
746                 {
747                         m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
748                                                            << "Vertex: " << program->getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
749                                                            << m_vertex << "\n"
750                                                            << "TesselationCtrl: " << program->getShaderInfo(SHADERTYPE_TESSELLATION_CONTROL).infoLog
751                                                            << "\n"
752                                                            << m_tesselationCtrl << "\n"
753                                                            << "TesselationEval: "
754                                                            << program->getShaderInfo(SHADERTYPE_TESSELLATION_EVALUATION).infoLog << "\n"
755                                                            << m_tesselationEval << "\n"
756                                                            << "Geometry: " << program->getShaderInfo(SHADERTYPE_GEOMETRY).infoLog << "\n"
757                                                            << m_geometry << "\n"
758                                                            << "Fragment: " << program->getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
759                                                            << m_fragment << "\n"
760                                                            << "Program: " << program->getProgramInfo().infoLog << tcu::TestLog::EndMessage;
761
762                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
763                         return STOP;
764                 }
765
766                 gl.useProgram(program->getProgram());
767                 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
768
769                 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
770                 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
771                 gl.clear(GL_COLOR_BUFFER_BIT);
772                 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
773
774                 gl.enableVertexAttribArray(0);
775                 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
776
777                 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
778                 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
779
780                 gl.patchParameteri(GL_PATCH_VERTICES, 3);
781                 gl.drawArrays(GL_PATCHES, 0, 3);
782                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
783
784                 gl.disableVertexAttribArray(0);
785                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
786
787                 gl.readPixels(16, 16, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&outputs[it]);
788                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
789
790                 if (program)
791                         delete program;
792         }
793
794         if (vbo)
795         {
796                 gl.deleteBuffers(1, &vbo);
797                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
798         }
799
800         if (vao)
801         {
802                 gl.deleteVertexArrays(1, &vao);
803                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
804         }
805
806         if ((outputs[ITERATE_GLSL] & outputs[ITERATE_SPIRV]) != 0xFFFFFFFF)
807         {
808                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
809                 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong output color read from framebuffer.\n"
810                                                    << "GLSL: " << outputs[ITERATE_GLSL] << ", SPIR-V: " << outputs[ITERATE_SPIRV]
811                                                    << "Expected: " << (deUint32)0xFFFFFFFF << tcu::TestLog::EndMessage;
812                 return STOP;
813         }
814
815         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
816         return STOP;
817 }
818
819 /** Constructor.
820  *
821  *  @param context     Rendering context
822  *  @param name        Test name
823  *  @param description Test description
824  */
825 SpirvShaderBinaryMultipleShaderObjectsTest::SpirvShaderBinaryMultipleShaderObjectsTest(deqp::Context& context)
826         : TestCase(context, "spirv_modules_shader_binary_multiple_shader_objects_test",
827                            "Test verifies if one binary module can be associated with multiple shader objects.")
828 {
829         /* Left blank intentionally */
830 }
831
832 /** Stub init method */
833 void SpirvShaderBinaryMultipleShaderObjectsTest::init()
834 {
835         commonUtils::checkGlSpirvSupported(m_context);
836
837         m_spirv = "OpCapability Shader\n"
838                           "%1 = OpExtInstImport \"GLSL.std.450\"\n"
839                           "OpMemoryModel Logical GLSL450\n"
840                           "OpEntryPoint Vertex %mainv \"mainv\" %_ %position %gl_VertexID %gl_InstanceID\n"
841                           "OpEntryPoint Fragment %mainf \"mainf\" %fColor\n"
842                           "OpSource GLSL 450\n"
843                           "OpName %mainv \"mainv\"\n"
844                           "OpName %mainf \"mainf\"\n"
845                           "OpName %gl_PerVertex \"gl_PerVertex\"\n"
846                           "OpMemberName %gl_PerVertex 0 \"gl_Position\"\n"
847                           "OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n"
848                           "OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n"
849                           "OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n"
850                           "OpName %_ \"\"\n"
851                           "OpName %position \"position\"\n"
852                           "OpName %gl_VertexID \"gl_VertexID\"\n"
853                           "OpName %gl_InstanceID \"gl_InstanceID\"\n"
854                           "OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
855                           "OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
856                           "OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
857                           "OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n"
858                           "OpDecorate %gl_PerVertex Block\n"
859                           "OpDecorate %position Location 0\n"
860                           "OpDecorate %gl_VertexID BuiltIn VertexId\n"
861                           "OpDecorate %gl_InstanceID BuiltIn InstanceId\n"
862                           "OpDecorate %fColor Location 0\n"
863                           "%void = OpTypeVoid\n"
864                           "%3 = OpTypeFunction %void\n"
865                           "%float = OpTypeFloat 32\n"
866                           "%v4float = OpTypeVector %float 4\n"
867                           "%uint = OpTypeInt 32 0\n"
868                           "%uint_1 = OpConstant %uint 1\n"
869                           "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n"
870                           "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n"
871                           "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
872                           "%_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
873                           "%int = OpTypeInt 32 1\n"
874                           "%int_0 = OpConstant %int 0\n"
875                           "%v3float = OpTypeVector %float 3\n"
876                           "%_ptr_Input_v3float = OpTypePointer Input %v3float\n"
877                           "%position = OpVariable %_ptr_Input_v3float Input\n"
878                           "%float_1 = OpConstant %float 1\n"
879                           "%_ptr_Output_v4float = OpTypePointer Output %v4float\n"
880                           "%_ptr_Input_int = OpTypePointer Input %int\n"
881                           "%gl_VertexID = OpVariable %_ptr_Input_int Input\n"
882                           "%gl_InstanceID = OpVariable %_ptr_Input_int Input\n"
883                           "%fColor = OpVariable %_ptr_Output_v4float Output\n"
884                           "%fVec4_1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1\n"
885                           "\n"
886                           "%mainv = OpFunction %void None %3\n"
887                           "%5 = OpLabel\n"
888                           "%19 = OpLoad %v3float %position\n"
889                           "%21 = OpCompositeExtract %float %19 0\n"
890                           "%22 = OpCompositeExtract %float %19 1\n"
891                           "%23 = OpCompositeExtract %float %19 2\n"
892                           "%24 = OpCompositeConstruct %v4float %21 %22 %23 %float_1\n"
893                           "%26 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n"
894                           "OpStore %26 %24\n"
895                           "OpReturn\n"
896                           "OpFunctionEnd\n"
897                           "\n"
898                           "%mainf = OpFunction %void None %3\n"
899                           "%32 = OpLabel\n"
900                           "OpStore %fColor %fVec4_1\n"
901                           "OpReturn\n"
902                           "OpFunctionEnd\n";
903 }
904
905 /** Stub init method */
906 void SpirvShaderBinaryMultipleShaderObjectsTest::deinit()
907 {
908 }
909
910 /** Executes test iteration.
911  *
912  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
913  */
914 tcu::TestNode::IterateResult SpirvShaderBinaryMultipleShaderObjectsTest::iterate()
915 {
916         const Functions& gl = m_context.getRenderContext().getFunctions();
917
918         const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
919
920         GLuint texture;
921         GLuint fbo;
922
923         gl.genTextures(1, &texture);
924         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
925         gl.bindTexture(GL_TEXTURE_2D, texture);
926         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
927         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32);
928         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
929
930         gl.genFramebuffers(1, &fbo);
931         GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
932         gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
933         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
934         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
935         GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
936
937         GLuint vao;
938         gl.genVertexArrays(1, &vao);
939         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
940         gl.bindVertexArray(vao);
941         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
942
943         GLuint vbo;
944         gl.genBuffers(1, &vbo);
945         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
946         gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
947         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
948
949         gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
950         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
951
952 #if defined DEQP_HAVE_SPIRV_TOOLS
953         ShaderBinary binary;
954         binary << SHADERTYPE_VERTEX << "mainv";
955         binary << SHADERTYPE_FRAGMENT << "mainf";
956
957         glslangUtils::spirvAssemble(binary.binary, m_spirv);
958         glslangUtils::spirvValidate(binary.binary, true);
959 #else  // DEQP_HAVE_SPIRV_TOOLS
960         tcu::Archive& archive = m_testCtx.getArchive();
961         ShaderBinary  binary  = commonUtils::readSpirV(
962                 archive.getResource("spirv/spirv_modules_shader_binary_multiple_shader_objects/binary.nspv"));
963 #endif // DEQP_HAVE_SPIRV_TOOLS
964
965         ProgramBinaries binaries;
966         binaries << binary;
967         ShaderProgram program(gl, binaries);
968
969         if (!program.isOk())
970         {
971                 m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
972                                                    << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
973                                                    << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
974                                                    << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
975
976                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
977                 return STOP;
978         }
979
980         gl.viewport(0, 0, 32, 32);
981         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
982
983         gl.useProgram(program.getProgram());
984         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
985
986         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
987         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
988         gl.clear(GL_COLOR_BUFFER_BIT);
989         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
990
991         gl.enableVertexAttribArray(0);
992         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
993
994         gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
995         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
996
997         gl.drawArrays(GL_TRIANGLE_STRIP, 0, 3);
998         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
999
1000         gl.disableVertexAttribArray(0);
1001         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
1002
1003         GLuint insidePixel;
1004         GLuint outsidePixel;
1005         gl.readPixels(16, 16, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&insidePixel);
1006         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
1007         gl.readPixels(2, 30, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&outsidePixel);
1008         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
1009
1010         if (vbo)
1011         {
1012                 gl.deleteBuffers(1, &vbo);
1013                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
1014         }
1015
1016         if (vao)
1017         {
1018                 gl.deleteVertexArrays(1, &vao);
1019                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
1020         }
1021
1022         if (fbo)
1023         {
1024                 gl.deleteFramebuffers(1, &fbo);
1025                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
1026         }
1027
1028         if (texture)
1029         {
1030                 gl.deleteTextures(1, &texture);
1031                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
1032         }
1033
1034         if (insidePixel == 0xFFFFFFFF && outsidePixel == 0xFF000000)
1035                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1036         else
1037         {
1038                 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong pixels color read.\n"
1039                                                    << "Expected (inside/outside): " << 0xFFFFFFFF << "/" << 0xFF000000 << "\n"
1040                                                    << "Read: " << insidePixel << "/" << outsidePixel << tcu::TestLog::EndMessage;
1041
1042                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1043         }
1044
1045         return STOP;
1046 }
1047
1048 /** Constructor.
1049  *
1050  *  @param context     Rendering context
1051  *  @param name        Test name
1052  *  @param description Test description
1053  */
1054 SpirvModulesStateQueriesTest::SpirvModulesStateQueriesTest(deqp::Context& context)
1055         : TestCase(context, "spirv_modules_state_queries_test",
1056                            "Test verifies if state queries for new features added by ARB_gl_spirv works as expected.")
1057 {
1058         /* Left blank intentionally */
1059 }
1060
1061 /** Stub init method */
1062 void SpirvModulesStateQueriesTest::init()
1063 {
1064         commonUtils::checkGlSpirvSupported(m_context);
1065
1066         m_vertex = "#version 450\n"
1067                            "\n"
1068                            "layout (location = 0) in vec4 position;\n"
1069                            "layout (location = 20) uniform vec4 extPosition;\n"
1070                            "layout (binding = 5) uniform ComponentsBlock\n"
1071                            "{\n"
1072                            "    vec4 c1;\n"
1073                            "    vec2 c2;\n"
1074                            "} components;\n"
1075                            "\n"
1076                            "void main()\n"
1077                            "{\n"
1078                            "    gl_Position = position + extPosition + components.c1 + vec4(components.c2, 0.0, 0.0);\n"
1079                            "}\n";
1080 }
1081
1082 /** Stub de-init method */
1083 void SpirvModulesStateQueriesTest::deinit()
1084 {
1085 }
1086
1087 /** Executes test iteration.
1088  *
1089  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1090  */
1091 tcu::TestNode::IterateResult SpirvModulesStateQueriesTest::iterate()
1092 {
1093         const Functions& gl = m_context.getRenderContext().getFunctions();
1094
1095         ProgramBinaries binaries;
1096         ShaderBinary    vertexBinary;
1097
1098 #if defined DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1099         {
1100                 vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
1101
1102                 // Disassemble Spir-V module
1103                 std::string output;
1104                 glslangUtils::spirvDisassemble(output, vertexBinary.binary);
1105
1106                 // Remove name reflection for defined variables
1107                 std::vector<std::string> lines = de::splitString(output, '\n');
1108                 std::string                              input;
1109                 for (int i = 0; i < (signed)lines.size(); ++i)
1110                 {
1111                         if (lines[i].find("OpName %position") != std::string::npos)
1112                                 continue;
1113                         if (lines[i].find("OpName %extPosition") != std::string::npos)
1114                                 continue;
1115                         if (lines[i].find("OpName %ComponentsBlock") != std::string::npos)
1116                                 continue;
1117                         if (lines[i].find("OpName %components") != std::string::npos)
1118                                 continue;
1119
1120                         input.append(lines[i] + "\n");
1121                 }
1122
1123                 // Assemble Spir-V module
1124                 vertexBinary.binary.clear();
1125                 glslangUtils::spirvAssemble(vertexBinary.binary, input);
1126                 glslangUtils::spirvValidate(vertexBinary.binary, true);
1127         }
1128 #else  // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1129         tcu::Archive& archive = m_testCtx.getArchive();
1130         vertexBinary              = commonUtils::readSpirV(archive.getResource("spirv/modules_state_queries/vertex.nspv"));
1131 #endif // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1132
1133         binaries << vertexBinary;
1134         ShaderProgram program(gl, binaries);
1135
1136         Shader* shader = program.getShader(SHADERTYPE_VERTEX);
1137
1138         // 1) Check compile status
1139         if (!program.getShaderInfo(SHADERTYPE_VERTEX).compileOk)
1140         {
1141                 m_testCtx.getLog() << tcu::TestLog::Message << "Check compile status failed.\n"
1142                                                    << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
1143                                                    << m_vertex << "\n"
1144                                                    << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
1145
1146                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1147                 return STOP;
1148         }
1149
1150         // 2) Check if SPIR_V_BINARY_ARB state is TRUE
1151         GLint shaderState;
1152         gl.getShaderiv(shader->getShader(), GL_SPIR_V_BINARY_ARB, &shaderState);
1153         GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
1154         if (shaderState != GL_TRUE)
1155         {
1156                 m_testCtx.getLog() << tcu::TestLog::Message << "SPIR_V_BINARY_ARB state set to FALSE. Expected TRUE."
1157                                                    << tcu::TestLog::EndMessage;
1158
1159                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1160                 return STOP;
1161         }
1162
1163         // 3) Check if queries for ACTIVE_ATTRIBUTE_MAX_LENGTH, ACTIVE_UNIFORM_MAX_LENGTH,
1164         //    ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH return value equal to 1, and
1165         //    TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH value equals to 0
1166         GLint programState[4];
1167         GLint expectedValues[4] = {1, 1, 0, 1};
1168         gl.getProgramiv(program.getProgram(), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &programState[0]);
1169         GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1170
1171         gl.getProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &programState[1]);
1172         GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1173
1174         // We expect 0 for GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH because the current program
1175         // doesn't activate transform feedback so there isn't any active varying.
1176         gl.getProgramiv(program.getProgram(), GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &programState[2]);
1177         GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1178
1179         gl.getProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &programState[3]);
1180         GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1181
1182         bool programStateResult = true;
1183         for (int i = 0; i < 4; ++i)
1184         {
1185                 if (programState[i] != expectedValues[i])
1186                 {
1187                         m_testCtx.getLog() << tcu::TestLog::Message << "Check max name length [" << i << "] failed. "
1188                                                           << "Expected: " << expectedValues[i] <<", Queried: "
1189                                                           << programState[i] << "\n"
1190                                                           << tcu::TestLog::EndMessage;
1191                         programStateResult = false;
1192                 }
1193         }
1194
1195         if (!programStateResult)
1196         {
1197                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1198                 return STOP;
1199         }
1200
1201         // 4) Check if ShaderSource command usage on Spir-V binary shader will change SPIR_V_BINARY_ARB state to FALSE
1202         const char* source = m_vertex.c_str();
1203         const int   length = m_vertex.length();
1204         gl.shaderSource(shader->getShader(), 1, &source, &length);
1205         GLU_EXPECT_NO_ERROR(gl.getError(), "shaderSource");
1206
1207         gl.getShaderiv(shader->getShader(), GL_SPIR_V_BINARY_ARB, &shaderState);
1208         GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
1209         if (shaderState != GL_FALSE)
1210         {
1211                 m_testCtx.getLog() << tcu::TestLog::Message << "SPIR_V_BINARY_ARB state set to TRUE. Expected FALSE."
1212                                                    << tcu::TestLog::EndMessage;
1213
1214                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1215                 return STOP;
1216         }
1217
1218         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1219         return STOP;
1220 }
1221
1222 /** Constructor.
1223  *
1224  *  @param context     Rendering context
1225  *  @param name        Test name
1226  *  @param description Test description
1227  */
1228 SpirvModulesErrorVerificationTest::SpirvModulesErrorVerificationTest(deqp::Context& context)
1229         : TestCase(context, "spirv_modules_error_verification_test",
1230                            "Test verifies if new features added by ARB_gl_spirv generate error messages as expected.")
1231 {
1232         /* Left blank intentionally */
1233 }
1234
1235 /** Stub init method */
1236 void SpirvModulesErrorVerificationTest::init()
1237 {
1238         commonUtils::checkGlSpirvSupported(m_context);
1239
1240         const Functions& gl = m_context.getRenderContext().getFunctions();
1241
1242         m_vertex = "#version 450\n"
1243                            "\n"
1244                            "layout (location = 0) in vec4 position;\n"
1245                            "\n"
1246                            "void main()\n"
1247                            "{\n"
1248                            "    gl_Position = position;\n"
1249                            "}\n";
1250
1251         m_glslShaderId = gl.createShader(GL_VERTEX_SHADER);
1252         GLU_EXPECT_NO_ERROR(gl.getError(), "createShader");
1253
1254         m_spirvShaderId = gl.createShader(GL_VERTEX_SHADER);
1255         GLU_EXPECT_NO_ERROR(gl.getError(), "createShader");
1256
1257         m_programId = gl.createProgram();
1258         GLU_EXPECT_NO_ERROR(gl.getError(), "createProgram");
1259
1260         gl.genTextures(1, &m_textureId);
1261         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
1262 }
1263
1264 /** Stub de-init method */
1265 void SpirvModulesErrorVerificationTest::deinit()
1266 {
1267         const Functions& gl = m_context.getRenderContext().getFunctions();
1268
1269         gl.deleteTextures(1, &m_textureId);
1270         GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
1271
1272         gl.deleteProgram(m_programId);
1273         GLU_EXPECT_NO_ERROR(gl.getError(), "deleteProgram");
1274
1275         gl.deleteShader(m_glslShaderId);
1276         GLU_EXPECT_NO_ERROR(gl.getError(), "deleteShader");
1277
1278         gl.deleteShader(m_spirvShaderId);
1279         GLU_EXPECT_NO_ERROR(gl.getError(), "deleteShader");
1280 }
1281
1282 /** Executes test iteration.
1283  *
1284  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1285  */
1286 tcu::TestNode::IterateResult SpirvModulesErrorVerificationTest::iterate()
1287 {
1288         const Functions& gl = m_context.getRenderContext().getFunctions();
1289
1290         const char* shaderSrc = m_vertex.c_str();
1291         const int   shaderLen = m_vertex.length();
1292
1293         ShaderBinary vertexBinary;
1294
1295 #if defined DEQP_HAVE_GLSLANG
1296         vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
1297 #else  // DEQP_HAVE_GLSLANG
1298         tcu::Archive& archive = m_testCtx.getArchive();
1299         vertexBinary              = commonUtils::readSpirV(archive.getResource("spirv/modules_error_verification/vertex.nspv"));
1300 #endif // DEQP_HAVE_GLSLANG
1301
1302         gl.shaderSource(m_glslShaderId, 1, &shaderSrc, &shaderLen);
1303         GLU_EXPECT_NO_ERROR(gl.getError(), "shaderSource");
1304
1305         gl.shaderBinary(1, &m_spirvShaderId, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, (GLvoid*)vertexBinary.binary.data(),
1306                                         vertexBinary.binary.size() * sizeof(deUint32));
1307         GLU_EXPECT_NO_ERROR(gl.getError(), "shaderBinary");
1308
1309         gl.attachShader(m_programId, m_spirvShaderId);
1310         GLU_EXPECT_NO_ERROR(gl.getError(), "attachShader");
1311
1312         GLint err;
1313
1314         // 1) Verify if CompileShader function used on shader with SPIR_V_BINARY_ARB state
1315         //    will result in generating INVALID_OPERATION error.
1316         gl.compileShader(m_spirvShaderId);
1317         err = gl.getError();
1318         if (err != GL_INVALID_OPERATION)
1319         {
1320                 m_testCtx.getLog()
1321                         << tcu::TestLog::Message
1322                         << "Unexpected error code generated by CompileShader [1]. Expected INVALID_OPERATION, generated: "
1323                         << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1324
1325                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1326                 return STOP;
1327         }
1328
1329         // 2) Verify if SpecializeShader function generate INVALID_VALUE error when
1330         //    <shader> is not the name of either a program or shader object.
1331         gl.specializeShader(0xFFFF, "main", 0, DE_NULL, DE_NULL);
1332         err = gl.getError();
1333         if (err != GL_INVALID_VALUE)
1334         {
1335                 m_testCtx.getLog()
1336                         << tcu::TestLog::Message
1337                         << "Unexpected error code generated by SpecializeShader [2]. Expected INVALID_VALUE, generated: "
1338                         << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1339
1340                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1341                 return STOP;
1342         }
1343
1344         // 3) Verify if SpecializeShader function generate INVALID_OPERATION error when
1345         //    <shader> is the name of a program object.
1346         gl.specializeShader(m_programId, "main", 0, DE_NULL, DE_NULL);
1347         err = gl.getError();
1348         if (err != GL_INVALID_OPERATION)
1349         {
1350                 m_testCtx.getLog()
1351                         << tcu::TestLog::Message
1352                         << "Unexpected error code generated by SpecializeShader [3]. Expected INVALID_OPERATION, generated: "
1353                         << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1354
1355                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1356                 return STOP;
1357         }
1358
1359         // 4) Verify if SpecializeShader function generate INVALID_OPERATION error when
1360         //    SPIR_V_BINARY_ARB state for <shader> is not TRUE.
1361         gl.specializeShader(m_glslShaderId, "main", 0, DE_NULL, DE_NULL);
1362         err = gl.getError();
1363         if (err != GL_INVALID_OPERATION)
1364         {
1365                 m_testCtx.getLog()
1366                         << tcu::TestLog::Message
1367                         << "Unexpected error code generated by SpecializeShader [4]. Expected INVALID_OPERATION, generated: "
1368                         << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1369
1370                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1371                 return STOP;
1372         }
1373
1374         // 5) Verify if SpecializeShader function generate INVALID_VALUE when <pEntryPoint>
1375         //    does not name a valid entry point for <shader>.
1376         gl.specializeShader(m_spirvShaderId, "entry", 0, DE_NULL, DE_NULL);
1377         err = gl.getError();
1378         if (err != GL_INVALID_VALUE)
1379         {
1380                 m_testCtx.getLog()
1381                         << tcu::TestLog::Message
1382                         << "Unexpected error code generated by SpecializeShader [5]. Expected INVALID_VALUE, generated: "
1383                         << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1384
1385                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1386                 return STOP;
1387         }
1388
1389         // 6) Verify if SpecializeShader function generate INVALID_VALUE when any element
1390         //    of <pConstantIndex> refers to a specialization constant that does not exist
1391         //    in the shader module contained in <shader>.
1392         const GLuint specID     = 10;
1393         const GLuint specValue = 10;
1394         gl.specializeShader(m_spirvShaderId, "main", 1, &specID, &specValue);
1395         err = gl.getError();
1396         if (err != GL_INVALID_VALUE)
1397         {
1398                 m_testCtx.getLog()
1399                         << tcu::TestLog::Message
1400                         << "Unexpected error code generated by SpecializeShader [6]. Expected INVALID_VALUE, generated: "
1401                         << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1402
1403                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1404                 return STOP;
1405         }
1406
1407         // 7) Verify if LinkProgram fail when one or more of the shader objects attached to
1408         //    <program> are not specialized.
1409         gl.linkProgram(m_programId);
1410         err = gl.getError();
1411         if (err == GL_NO_ERROR)
1412         {
1413                 GLint linkStatus;
1414                 gl.getProgramiv(m_programId, GL_LINK_STATUS, &linkStatus);
1415                 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1416
1417                 if (linkStatus != 0)
1418                 {
1419                         m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected result of LinkProgram [7]."
1420                                                            << tcu::TestLog::EndMessage;
1421
1422                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1423                         return STOP;
1424                 }
1425         }
1426
1427         // 8) Verify if SpecializeShader function generate INVALID_OPERATION error if the
1428         //    shader has already been specialized.
1429         gl.specializeShader(m_spirvShaderId, "main", 0, DE_NULL, DE_NULL);
1430         GLU_EXPECT_NO_ERROR(gl.getError(), "specializeShader");
1431
1432         gl.specializeShader(m_spirvShaderId, "main", 0, DE_NULL, DE_NULL);
1433         err = gl.getError();
1434         if (err != GL_INVALID_OPERATION)
1435         {
1436                 m_testCtx.getLog()
1437                         << tcu::TestLog::Message
1438                         << "Unexpected error code generated by SpecializeShader [8]. Expected INVALID_OPERATION, generated: "
1439                         << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1440
1441                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1442                 return STOP;
1443         }
1444
1445         // 9) Verify if LinkProgram fail when not all of shaders attached to <program> have
1446         //    the same value for the SPIR_V_BINARY_ARB state.
1447         gl.compileShader(m_glslShaderId);
1448         GLU_EXPECT_NO_ERROR(gl.getError(), "compileShader");
1449
1450         gl.attachShader(m_programId, m_glslShaderId);
1451         GLU_EXPECT_NO_ERROR(gl.getError(), "attachShader");
1452
1453         gl.linkProgram(m_programId);
1454         err = gl.getError();
1455         if (err == GL_NO_ERROR)
1456         {
1457                 GLint linkStatus;
1458                 gl.getProgramiv(m_programId, GL_LINK_STATUS, &linkStatus);
1459                 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1460
1461                 if (linkStatus != 0)
1462                 {
1463                         m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected result of LinkProgram [9]."
1464                                                            << tcu::TestLog::EndMessage;
1465
1466                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1467                         return STOP;
1468                 }
1469         }
1470
1471         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1472         return STOP;
1473 }
1474
1475 /** Constructor.
1476  *
1477  *  @param context     Rendering context
1478  *  @param name        Test name
1479  *  @param description Test description
1480  */
1481 SpirvGlslToSpirVEnableTest::SpirvGlslToSpirVEnableTest(deqp::Context& context)
1482         : TestCase(context, "spirv_glsl_to_spirv_enable_test", "Test verifies if glsl supports Spir-V features.")
1483 {
1484         /* Left blank intentionally */
1485 }
1486
1487 /** Stub init method */
1488 void SpirvGlslToSpirVEnableTest::init()
1489 {
1490         commonUtils::checkGlSpirvSupported(m_context);
1491
1492         m_vertex = "#version 450\n"
1493                            "\n"
1494                            "#ifdef GL_SPIRV\n"
1495                            "  layout (location = 0) in vec4 enabled;\n"
1496                            "#else\n"
1497                            "  layout (location = 0) in vec4 notEnabled;\n"
1498                            "#endif // GL_SPIRV\n"
1499                            "\n"
1500                            "void main()\n"
1501                            "{\n"
1502                            "    gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n"
1503                            "}\n";
1504 }
1505
1506 /** Stub de-init method */
1507 void SpirvGlslToSpirVEnableTest::deinit()
1508 {
1509 }
1510
1511 /** Executes test iteration.
1512  *
1513  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1514  */
1515 tcu::TestNode::IterateResult SpirvGlslToSpirVEnableTest::iterate()
1516 {
1517
1518 #if defined DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1519         {
1520                 const Functions& gl = m_context.getRenderContext().getFunctions();
1521
1522                 ProgramBinaries binaries;
1523                 ShaderBinary    vertexBinary =
1524                         glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
1525                 binaries << vertexBinary;
1526                 ShaderProgram spirvProgram(gl, binaries);
1527
1528                 std::string spirvSource;
1529                 glslangUtils::spirvDisassemble(spirvSource, vertexBinary.binary);
1530
1531                 if (spirvSource.find("OpName %enabled") == std::string::npos)
1532                 {
1533                         m_testCtx.getLog() << tcu::TestLog::Message << "GL_SPIRV not defined. Spir-V source:\n"
1534                                                            << spirvSource.c_str() << tcu::TestLog::EndMessage;
1535
1536                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1537                         return STOP;
1538                 }
1539
1540                 if (!spirvProgram.isOk())
1541                 {
1542                         m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed. Source:\n"
1543                                                            << spirvSource.c_str() << "InfoLog:\n"
1544                                                            << spirvProgram.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
1545                                                            << tcu::TestLog::EndMessage;
1546
1547                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1548                         return STOP;
1549                 }
1550
1551                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1552         }
1553 #else // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1554
1555         TCU_THROW(InternalError, "Either glslang or spirv-tools not available.");
1556
1557 #endif // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1558
1559         return STOP;
1560 }
1561
1562 enum EShaderTemplate
1563 {
1564         COMPUTE_TEMPLATE,
1565         TESSCTRL_TEMPLATE,
1566         GEOMETRY_TEMPLATE,
1567         FRAGMENT_TEMPLATE
1568 };
1569
1570 struct FunctionMapping
1571 {
1572         EShaderTemplate shaderTemplate;
1573         std::string             glslFunc;
1574         std::string             glslArgs;
1575         std::string             spirVFunc;
1576
1577         FunctionMapping() : shaderTemplate(COMPUTE_TEMPLATE), glslFunc(""), glslArgs(""), spirVFunc("")
1578         {
1579         }
1580
1581         FunctionMapping(EShaderTemplate shaderTemplate_, std::string glslFunc_, std::string glslArgs_,
1582                                         std::string spirVFunc_)
1583                 : shaderTemplate(shaderTemplate_), glslFunc(glslFunc_), glslArgs(glslArgs_), spirVFunc(spirVFunc_)
1584         {
1585         }
1586 };
1587
1588 /** Constructor.
1589  *
1590  *  @param context     Rendering context
1591  *  @param name        Test name
1592  *  @param description Test description
1593  */
1594 SpirvGlslToSpirVBuiltInFunctionsTest::SpirvGlslToSpirVBuiltInFunctionsTest(deqp::Context& context)
1595         : TestCase(context, "spirv_glsl_to_spirv_builtin_functions_test",
1596                            "Test verifies if GLSL built-in functions are supported by Spir-V.")
1597 {
1598         /* Left blank intentionally */
1599 }
1600
1601 /** Stub init method */
1602 void SpirvGlslToSpirVBuiltInFunctionsTest::init()
1603 {
1604         commonUtils::checkGlSpirvSupported(m_context);
1605
1606         initMappings();
1607
1608         m_commonVertex = "#version 450\n"
1609                                          "\n"
1610                                          "layout (location = 0) in vec3 position;\n"
1611                                          "layout (location = 1) out vec2 texCoord;\n"
1612                                          "\n"
1613                                          "void main()\n"
1614                                          "{\n"
1615                                          "    texCoord = vec2(0.0, 0.0);\n"
1616                                          "    gl_Position = vec4(position, 1.0);\n"
1617                                          "}\n";
1618
1619         m_commonTessEval = "#version 450\n"
1620                                            "\n"
1621                                            "layout (triangles) in;\n"
1622                                            "\n"
1623                                            "void main()\n"
1624                                            "{\n"
1625                                            "    gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +\n"
1626                                            "                  gl_TessCoord.y * gl_in[1].gl_Position +\n"
1627                                            "                  gl_TessCoord.z * gl_in[2].gl_Position;\n"
1628                                            "}\n";
1629
1630         m_sources.clear();
1631
1632         // Angle Trigonometry
1633         m_sources.push_back(ComputeSource("#version 450\n"
1634                                                                           "\n"
1635                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1636                                                                           "\n"
1637                                                                           "void main()\n"
1638                                                                           "{\n"
1639                                                                           "    float tmp0 = 0.5;\n"
1640                                                                           "    float value;\n"
1641                                                                           "    value = radians(tmp0) +\n"
1642                                                                           "            degrees(tmp0) +\n"
1643                                                                           "            sin(tmp0) +\n"
1644                                                                           "            cos(tmp0) +\n"
1645                                                                           "            tan(tmp0) +\n"
1646                                                                           "            asin(tmp0) +\n"
1647                                                                           "            acos(tmp0) +\n"
1648                                                                           "            atan(tmp0) +\n"
1649                                                                           "            atan(tmp0) +\n"
1650                                                                           "            sinh(tmp0) +\n"
1651                                                                           "            cosh(tmp0) +\n"
1652                                                                           "            tanh(tmp0) +\n"
1653                                                                           "            asinh(tmp0) +\n"
1654                                                                           "            acosh(tmp0) +\n"
1655                                                                           "            atanh(tmp0);\n"
1656                                                                           "}\n"));
1657
1658         // To avoid duplicated mappings create additional shaders for specific functions
1659         const std::string strAnlgeVariants = "#version 450\n"
1660                                                                                  "\n"
1661                                                                                  "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1662                                                                                  "\n"
1663                                                                                  "void main()\n"
1664                                                                                  "{\n"
1665                                                                                  "    float tmp0 = 0.5;\n"
1666                                                                                  "    float value = <ATANGENT>;\n"
1667                                                                                  "}\n";
1668         std::string strATan  = strAnlgeVariants;
1669         std::string strATan2 = strAnlgeVariants;
1670         commonUtils::replaceToken("<ATANGENT>", "atan(tmp0, tmp0)", strATan);
1671         commonUtils::replaceToken("<ATANGENT>", "atan(tmp0)", strATan2);
1672
1673         m_sources.push_back(ComputeSource(strATan));
1674         m_sources.push_back(ComputeSource(strATan2));
1675
1676         // Exponential
1677         m_sources.push_back(ComputeSource("#version 450\n"
1678                                                                           "\n"
1679                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1680                                                                           "\n"
1681                                                                           "void main()\n"
1682                                                                           "{\n"
1683                                                                           "    float tmp0;\n"
1684                                                                           "    float tmp1;\n"
1685                                                                           "    float value;\n"
1686                                                                           "    value = pow(tmp1, tmp0) +\n"
1687                                                                           "            exp(tmp0) +\n"
1688                                                                           "            log(tmp1) +\n"
1689                                                                           "            exp2(tmp0) +\n"
1690                                                                           "            log2(tmp1) +\n"
1691                                                                           "            sqrt(tmp1) +\n"
1692                                                                           "            inversesqrt(tmp1);\n"
1693                                                                           "}\n"));
1694
1695         // Common (without bit operations)
1696         m_sources.push_back(ComputeSource("#version 450\n"
1697                                                                           "\n"
1698                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1699                                                                           "\n"
1700                                                                           "void main()\n"
1701                                                                           "{\n"
1702                                                                           "    float value;\n"
1703                                                                           "    float outval;\n"
1704                                                                           "    float fpval = 0.5;\n"
1705                                                                           "    float fnval = -0.5;\n"
1706                                                                           "    int ival = 0x43800000;\n"
1707                                                                           "    uint uival= 0xC3800000;\n"
1708                                                                           "    value = abs(fnval) +\n"
1709                                                                           "            sign(fpval) +\n"
1710                                                                           "            floor(fpval) +\n"
1711                                                                           "            trunc(fpval) +\n"
1712                                                                           "            round(fpval) +\n"
1713                                                                           "            roundEven(fpval) +\n"
1714                                                                           "            ceil(fpval) +\n"
1715                                                                           "            fract(fpval) +\n"
1716                                                                           "            mod(fpval, 2.0) +\n"
1717                                                                           "            modf(fpval, outval) +\n"
1718                                                                           "            min(fpval, 0.2) +\n"
1719                                                                           "            max(fpval, 0.2) +\n"
1720                                                                           "            clamp(fpval, 0.8, 2.0) +\n"
1721                                                                           "            mix(fnval, fpval, 0.5) +\n"
1722                                                                           "            step(1.0, fpval) +\n"
1723                                                                           "            smoothstep(0.0, 1.0, fpval) +\n"
1724                                                                           "            float( isnan(fpval)) +\n"
1725                                                                           "            float( isinf(fpval)) +\n"
1726                                                                           "            fma(fpval, 1.0, fnval) +\n"
1727                                                                           "            frexp(4.0, ival) +\n"
1728                                                                           "            ldexp(4.0, ival);\n"
1729                                                                           "}\n"));
1730
1731         // To avoid duplicated mappings create additional shaders for specific functions
1732         const std::string strBitsOpsVariants = "#version 450\n"
1733                                                                                    "\n"
1734                                                                                    "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1735                                                                                    "\n"
1736                                                                                    "void main()\n"
1737                                                                                    "{\n"
1738                                                                                    "    float value;\n"
1739                                                                                    "    int ival = 0x43800000;\n"
1740                                                                                    "    uint uval = 0x43800000;\n"
1741                                                                                    "    value = <BITS_TO_FLOAT>;\n"
1742                                                                                    "}\n";
1743         std::string strIntBits  = strBitsOpsVariants;
1744         std::string strUIntBits = strBitsOpsVariants;
1745         commonUtils::replaceToken("<BITS_TO_FLOAT>", "intBitsToFloat(ival)", strIntBits);
1746         commonUtils::replaceToken("<BITS_TO_FLOAT>", "uintBitsToFloat(uval)", strUIntBits);
1747
1748         m_sources.push_back(ComputeSource(strIntBits));
1749         m_sources.push_back(ComputeSource(strUIntBits));
1750
1751         // Float Pack Unpack
1752         m_sources.push_back(ComputeSource("#version 450\n"
1753                                                                           "\n"
1754                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1755                                                                           "\n"
1756                                                                           "void main()\n"
1757                                                                           "{\n"
1758                                                                           "    vec2 v2val = vec2(0.1, 0.2);\n"
1759                                                                           "    vec4 v4val = vec4(0.1, 0.2, 0.3, 0.4);\n"
1760                                                                           "    uint uival1 = packUnorm2x16(v2val);\n"
1761                                                                           "    uint uival2 = packSnorm2x16(v2val);\n"
1762                                                                           "    uint uival3 = packUnorm4x8(v4val);\n"
1763                                                                           "    uint uival4 = packSnorm4x8(v4val);\n"
1764                                                                           "    v2val = unpackUnorm2x16(uival1);\n"
1765                                                                           "    v2val = unpackSnorm2x16(uival2);\n"
1766                                                                           "    v4val = unpackUnorm4x8(uival3);\n"
1767                                                                           "    v4val = unpackSnorm4x8(uival4);\n"
1768                                                                           "    uvec2 uv2val = uvec2(10, 20);\n"
1769                                                                           "    double dval = packDouble2x32(uv2val);\n"
1770                                                                           "    uv2val = unpackDouble2x32(dval);\n"
1771                                                                           "    uint uival5 = packHalf2x16(v2val);\n"
1772                                                                           "    v2val = unpackHalf2x16(uival5);\n"
1773                                                                           "}\n"));
1774
1775         // Geometric
1776         m_sources.push_back(ComputeSource("#version 450\n"
1777                                                                           "\n"
1778                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1779                                                                           "\n"
1780                                                                           "void main()\n"
1781                                                                           "{\n"
1782                                                                           "    vec3 v3val1 = vec3(0.1, 0.5, 1.0);\n"
1783                                                                           "    vec3 v3val2 = vec3(0.5, 0.3, 0.9);\n"
1784                                                                           "    vec3 v3val3 = vec3(1.0, 0.0, 0.0);\n"
1785                                                                           "    float fval = length(v3val1) +\n"
1786                                                                           "                 distance(v3val1, v3val2) +\n"
1787                                                                           "                 dot(v3val1, v3val2);\n"
1788                                                                           "    vec3 crossp = cross(v3val1, v3val2);\n"
1789                                                                           "    vec3 norm = normalize(crossp);\n"
1790                                                                           "    vec3 facef = faceforward(v3val1, v3val2, v3val3);\n"
1791                                                                           "    vec3 refl = reflect(v3val1, v3val2);\n"
1792                                                                           "    float eta = 0.1;\n"
1793                                                                           "    vec3 refr = refract(v3val1, v3val2, eta);"
1794                                                                           "}\n"));
1795
1796         // Matrix
1797         m_sources.push_back(ComputeSource("#version 450\n"
1798                                                                           "\n"
1799                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1800                                                                           "\n"
1801                                                                           "void main()\n"
1802                                                                           "{\n"
1803                                                                           "    mat2 m2val1 = mat2(\n"
1804                                                                           "        0.1, 0.5,\n"
1805                                                                           "        0.2, 0.4\n"
1806                                                                           "    );\n"
1807                                                                           "    mat2 m2val2 = mat2(\n"
1808                                                                           "        0.8, 0.2,\n"
1809                                                                           "        0.9, 0.1\n"
1810                                                                           "    );\n"
1811                                                                           "    vec2 v2val1 = vec2(0.3, 0.4);\n"
1812                                                                           "    vec2 v2val2 = vec2(0.5, 0.6);\n"
1813                                                                           "\n"
1814                                                                           "    mat2 m2comp = matrixCompMult(m2val1, m2val2);\n"
1815                                                                           "    mat2 m2outerp = outerProduct(v2val1, v2val2);\n"
1816                                                                           "    mat2 m2trans = transpose(m2val1);\n"
1817                                                                           "    float fdet = determinant(m2val2);\n"
1818                                                                           "    mat2 m2inv = inverse(m2trans);\n"
1819                                                                           "}\n"));
1820
1821         // Vector Relational
1822         m_sources.push_back(ComputeSource("#version 450\n"
1823                                                                           "\n"
1824                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1825                                                                           "\n"
1826                                                                           "void main()\n"
1827                                                                           "{\n"
1828                                                                           "    vec2 v2val1 = vec2(0.5, 0.2);\n"
1829                                                                           "    vec2 v2val2 = vec2(0.1, 0.8);\n"
1830                                                                           "    bvec2 bv2val1 = lessThan(v2val1, v2val2);\n"
1831                                                                           "    bvec2 bv2val2 = lessThanEqual(v2val1, v2val2);\n"
1832                                                                           "    bvec2 bv2val3 = greaterThan(v2val1, v2val2);\n"
1833                                                                           "    bvec2 bv2val4 = greaterThanEqual(v2val1, v2val2);\n"
1834                                                                           "    bvec2 bv2val5 = equal(v2val1, v2val2);\n"
1835                                                                           "    bvec2 bv2val6 = notEqual(v2val1, v2val2);\n"
1836                                                                           "    bool bval1 = any(bv2val1);\n"
1837                                                                           "    bool bval2 = all(bv2val1);\n"
1838                                                                           "    bvec2 bv2val7 = not(bv2val1);\n"
1839                                                                           "}\n"));
1840
1841         // Integer
1842         m_sources.push_back(ComputeSource("#version 450\n"
1843                                                                           "\n"
1844                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1845                                                                           "\n"
1846                                                                           "void main()\n"
1847                                                                           "{\n"
1848                                                                           "    int ival = 0;\n"
1849                                                                           "    uint uival = 200;\n"
1850                                                                           "    uint uivalRet1;\n"
1851                                                                           "    uint uivalRet2;\n"
1852                                                                           "    uivalRet2 = uaddCarry(uival, 0xFFFFFFFF, uivalRet1);\n"
1853                                                                           "    uivalRet2 = usubBorrow(uival, 0xFFFFFFFF, uivalRet1);\n"
1854                                                                           "    umulExtended(uival, 0xFFFFFFFF, uivalRet1, uivalRet2);\n"
1855                                                                           "    uivalRet1 = bitfieldExtract(uival, 3, 8);\n"
1856                                                                           "    uivalRet1 = bitfieldInsert(uival, 0xFFFFFFFF, 3, 8);\n"
1857                                                                           "    uivalRet1 = bitfieldReverse(uival);\n"
1858                                                                           "    ival = bitCount(uival);\n"
1859                                                                           "    ival = findLSB(uival);\n"
1860                                                                           "    ival = findMSB(uival);\n"
1861                                                                           "}\n"));
1862
1863         // Texture
1864         m_sources.push_back(
1865                 FragmentSource("#version 450\n"
1866                                            "\n"
1867                                            "layout (location = 0) out vec4 fragColor;\n"
1868                                            "\n"
1869                                            "layout (location = 1) uniform sampler2D tex2D;\n"
1870                                            "layout (location = 2) uniform sampler2DMS tex2DMS;\n"
1871                                            "\n"
1872                                            "void main()\n"
1873                                            "{\n"
1874                                            "    ivec2 iv2size = textureSize(tex2D, 0);\n"
1875                                            "    vec2 v2lod = textureQueryLod(tex2D, vec2(0.0));\n"
1876                                            "    int ilev = textureQueryLevels(tex2D);\n"
1877                                            "    int isamp = textureSamples(tex2DMS);\n"
1878                                            "    vec4 v4pix = textureLod(tex2D, vec2(0.0), 0.0) +\n"
1879                                            "                 textureOffset(tex2D, vec2(0.0), ivec2(2)) +\n"
1880                                            "                 texelFetch(tex2D, ivec2(2), 0) +\n"
1881                                            "                 texelFetchOffset(tex2D, ivec2(2), 0, ivec2(2)) +\n"
1882                                            "                 textureProjOffset(tex2D, vec3(0.0), ivec2(2)) +\n"
1883                                            "                 textureLodOffset(tex2D, vec2(0.0), 0.0, ivec2(2)) +\n"
1884                                            "                 textureProjLod(tex2D, vec3(0.0), 0.0) +\n"
1885                                            "                 textureProjLodOffset(tex2D, vec3(0.0), 0.0, ivec2(2)) +\n"
1886                                            "                 textureGrad(tex2D, vec2(0.0), vec2(0.2), vec2(0.5)) +\n"
1887                                            "                 textureGradOffset(tex2D, vec2(0.0), vec2(0.2), vec2(0.5), ivec2(2)) +\n"
1888                                            "                 textureProjGrad(tex2D, vec3(0.0), vec2(0.2), vec2(0.5)) +\n"
1889                                            "                 textureProjGradOffset(tex2D, vec3(0.0), vec2(0.2), vec2(0.5), ivec2(2)) +\n"
1890                                            "                 textureGatherOffset(tex2D, vec2(0.0), ivec2(2), 0);\n"
1891                                            "    fragColor = vec4(0.0);\n"
1892                                            "}\n"));
1893
1894         // To avoid duplicated mappings create additional shaders for specific functions
1895         const std::string strTextureVariants = "#version 450\n"
1896                                                                                    "\n"
1897                                                                                    "layout (location = 0) out vec4 fragColor;\n"
1898                                                                                    "\n"
1899                                                                                    "layout (location = 1) uniform sampler2D tex2D;\n"
1900                                                                                    "\n"
1901                                                                                    "void main()\n"
1902                                                                                    "{\n"
1903                                                                                    "    fragColor = <TEXTURE>;\n"
1904                                                                                    "}\n";
1905         std::string strTexture           = strTextureVariants;
1906         std::string strTextureProj   = strTextureVariants;
1907         std::string strTextureGather = strTextureVariants;
1908         commonUtils::replaceToken("<TEXTURE>", "texture(tex2D, vec2(0.0))", strTexture);
1909         commonUtils::replaceToken("<TEXTURE>", "textureProj(tex2D, vec3(0.0))", strTextureProj);
1910         commonUtils::replaceToken("<TEXTURE>", "textureGather(tex2D, vec2(0.0), 0)", strTextureGather);
1911
1912         m_sources.push_back(FragmentSource(strTexture));
1913         m_sources.push_back(FragmentSource(strTextureProj));
1914         m_sources.push_back(FragmentSource(strTextureGather));
1915
1916         // Atomic Counter
1917         m_sources.push_back(ComputeSource("#version 450\n"
1918                                                                           "\n"
1919                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1920                                                                           "\n"
1921                                                                           "layout (binding = 0) uniform atomic_uint auival;\n"
1922                                                                           "\n"
1923                                                                           "void main()\n"
1924                                                                           "{\n"
1925                                                                           "    uint uival = atomicCounterIncrement(auival) +\n"
1926                                                                           "                 atomicCounterDecrement(auival) +\n"
1927                                                                           "                 atomicCounter(auival);\n"
1928                                                                           "}\n"));
1929
1930         // Atomic Memory
1931         m_sources.push_back(ComputeSource("#version 450\n"
1932                                                                           "\n"
1933                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1934                                                                           "\n"
1935                                                                           "shared uint uishared;\n"
1936                                                                           "\n"
1937                                                                           "void main()\n"
1938                                                                           "{\n"
1939                                                                           "    uint uival2 = 5;\n"
1940                                                                           "    uint uivalRet = atomicAdd(uishared, uival2) +\n"
1941                                                                           "                    atomicMin(uishared, uival2) +\n"
1942                                                                           "                    atomicMax(uishared, uival2) +\n"
1943                                                                           "                    atomicAnd(uishared, uival2) +\n"
1944                                                                           "                    atomicOr(uishared, uival2) +\n"
1945                                                                           "                    atomicXor(uishared, uival2) +\n"
1946                                                                           "                    atomicExchange(uishared, uival2) +\n"
1947                                                                           "                    atomicCompSwap(uishared, uishared, uival2);\n"
1948                                                                           "}\n"));
1949
1950         // Image
1951         m_sources.push_back(ComputeSource("#version 450\n"
1952                                                                           "\n"
1953                                                                           "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1954                                                                           "\n"
1955                                                                           "layout (location = 1, rgba8ui) uniform readonly uimage2D rimg2D;\n"
1956                                                                           "layout (location = 2, rgba8ui) uniform readonly uimage2DMS rimg2DMS;\n"
1957                                                                           "layout (location = 3, rgba8ui) uniform writeonly uimage2D wimg2D;\n"
1958                                                                           "layout (location = 4, r32ui) uniform uimage2D aimg2D;\n"
1959                                                                           "\n"
1960                                                                           "void main()\n"
1961                                                                           "{\n"
1962                                                                           "    ivec2 size = imageSize(rimg2D);\n"
1963                                                                           "    int samp = imageSamples(rimg2DMS);\n"
1964                                                                           "    uvec4 v4pix = imageLoad(rimg2D, ivec2(0));\n"
1965                                                                           "    imageStore(wimg2D, ivec2(0), uvec4(255));\n"
1966                                                                           "    uint uivalRet = imageAtomicAdd(aimg2D, ivec2(0), 1) +\n"
1967                                                                           "                    imageAtomicMin(aimg2D, ivec2(0), 1) +\n"
1968                                                                           "                    imageAtomicMax(aimg2D, ivec2(0), 1) +\n"
1969                                                                           "                    imageAtomicAnd(aimg2D, ivec2(0), 1) +\n"
1970                                                                           "                    imageAtomicOr(aimg2D, ivec2(0), 1) +\n"
1971                                                                           "                    imageAtomicXor(aimg2D, ivec2(0), 1) +\n"
1972                                                                           "                    imageAtomicExchange(aimg2D, ivec2(0), 1) +\n"
1973                                                                           "                    imageAtomicCompSwap(aimg2D, ivec2(0), 1, 2);\n"
1974                                                                           "}\n"));
1975
1976         // Fragment Processing
1977         m_sources.push_back(FragmentSource("#version 450\n"
1978                                                                            "\n"
1979                                                                            "layout (location = 0) out vec4 fragColor;\n"
1980                                                                            "layout (location = 1) in vec2 texCoord;\n"
1981                                                                            "\n"
1982                                                                            "void main()\n"
1983                                                                            "{\n"
1984                                                                            "    vec2 p = vec2(0.0);\n"
1985                                                                            "    vec2 dx = dFdx(p);\n"
1986                                                                            "    vec2 dy = dFdy(p);\n"
1987                                                                            "    dx = dFdxFine(p);\n"
1988                                                                            "    dy = dFdyFine(p);\n"
1989                                                                            "    dx = dFdxCoarse(p);\n"
1990                                                                            "    dy = dFdyCoarse(p);\n"
1991                                                                            "    vec2 fw = fwidth(p);\n"
1992                                                                            "    fw = fwidthFine(p);\n"
1993                                                                            "    fw = fwidthCoarse(p);\n"
1994                                                                            "    vec2 interp = interpolateAtCentroid(texCoord) +\n"
1995                                                                            "                  interpolateAtSample(texCoord, 0) +\n"
1996                                                                            "                  interpolateAtOffset(texCoord, vec2(0.0));\n"
1997                                                                            "    fragColor = vec4(1.0);\n"
1998                                                                            "}\n"));
1999
2000         // To avoid duplicated mappings create additional shaders for specific functions
2001         const std::string strEmitVariants = "#version 450\n"
2002                                                                                 "\n"
2003                                                                                 "layout (points) in;\n"
2004                                                                                 "layout (points, max_vertices = 3) out;\n"
2005                                                                                 "\n"
2006                                                                                 "void main()\n"
2007                                                                                 "{\n"
2008                                                                                 "    gl_Position = vec4(0.0);\n"
2009                                                                                 "    <EMIT>;\n"
2010                                                                                 "    <END>;\n"
2011                                                                                 "}\n";
2012         std::string strEmit               = strEmitVariants;
2013         std::string strEmitStream = strEmitVariants;
2014         commonUtils::replaceToken("<EMIT>", "EmitVertex()", strEmit);
2015         commonUtils::replaceToken("<EMIT>", "EmitStreamVertex(0)", strEmitStream);
2016         commonUtils::replaceToken("<END>", "EndPrimitive()", strEmit);
2017         commonUtils::replaceToken("<END>", "EndStreamPrimitive(0)", strEmitStream);
2018
2019         m_sources.push_back(GeometrySource(strEmit));
2020         m_sources.push_back(GeometrySource(strEmitStream));
2021
2022         // Shader Invocation Control
2023         m_sources.push_back(
2024                 TessellationControlSource("#version 450\n"
2025                                                                   "\n"
2026                                                                   "layout (vertices = 3) out;\n"
2027                                                                   "\n"
2028                                                                   "void main()\n"
2029                                                                   "{\n"
2030                                                                   "    barrier();\n"
2031                                                                   "\n"
2032                                                                   "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2033                                                                   "}\n"));
2034
2035         // Shared Memory Control
2036         // To avoid duplicated mappings create additional shaders for specific functions
2037         const std::string strMemoryBarrierSource = "#version 450\n"
2038                                                                                            "\n"
2039                                                                                            "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2040                                                                                            "\n"
2041                                                                                            "void main()\n"
2042                                                                                            "{\n"
2043                                                                                            "    <MEMORY_BARRIER>;\n"
2044                                                                                            "}\n";
2045         std::string strMemoryBarrier                      = strMemoryBarrierSource;
2046         std::string strMemoryBarrierAtomicCounter = strMemoryBarrierSource;
2047         std::string strMemoryBarrierBuffer                = strMemoryBarrierSource;
2048         std::string strMemoryBarrierShared                = strMemoryBarrierSource;
2049         std::string strMemoryBarrierImage                 = strMemoryBarrierSource;
2050         std::string strGroupMemoryBarrier                 = strMemoryBarrierSource;
2051         commonUtils::replaceToken("<MEMORY_BARRIER>", "memoryBarrier()", strMemoryBarrier);
2052         commonUtils::replaceToken("<MEMORY_BARRIER>", "memoryBarrierAtomicCounter()", strMemoryBarrierAtomicCounter);
2053         commonUtils::replaceToken("<MEMORY_BARRIER>", "memoryBarrierBuffer()", strMemoryBarrierBuffer);
2054         commonUtils::replaceToken("<MEMORY_BARRIER>", "memoryBarrierShared()", strMemoryBarrierShared);
2055         commonUtils::replaceToken("<MEMORY_BARRIER>", "memoryBarrierImage()", strMemoryBarrierImage);
2056         commonUtils::replaceToken("<MEMORY_BARRIER>", "groupMemoryBarrier()", strGroupMemoryBarrier);
2057
2058         m_sources.push_back(ComputeSource(strMemoryBarrier));
2059         m_sources.push_back(ComputeSource(strMemoryBarrierAtomicCounter));
2060         m_sources.push_back(ComputeSource(strMemoryBarrierBuffer));
2061         m_sources.push_back(ComputeSource(strMemoryBarrierShared));
2062         m_sources.push_back(ComputeSource(strMemoryBarrierImage));
2063         m_sources.push_back(ComputeSource(strGroupMemoryBarrier));
2064 }
2065
2066 /** Stub de-init method */
2067 void SpirvGlslToSpirVBuiltInFunctionsTest::deinit()
2068 {
2069 }
2070
2071 /** Executes test iteration.
2072  *
2073  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2074  */
2075 tcu::TestNode::IterateResult SpirvGlslToSpirVBuiltInFunctionsTest::iterate()
2076 {
2077         const Functions& gl = m_context.getRenderContext().getFunctions();
2078
2079         for (int i = 0; i < (signed)m_sources.size(); ++i)
2080         {
2081                 ShaderSource shaderSource = m_sources[i];
2082
2083                 ProgramSources  sources;
2084                 ProgramBinaries binaries;
2085
2086                 if (shaderSource.shaderType != glu::SHADERTYPE_COMPUTE)
2087                 {
2088                         ShaderSource vertexSource(glu::SHADERTYPE_VERTEX, m_commonVertex);
2089
2090                         sources << vertexSource;
2091                         ShaderBinary vertexBinary;
2092 #if defined                              DEQP_HAVE_GLSLANG
2093                         vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), vertexSource);
2094 #else  // DEQP_HAVE_GLSLANG
2095                         tcu::Archive& archive = m_testCtx.getArchive();
2096                         vertexBinary =
2097                                 commonUtils::readSpirV(archive.getResource("spirv/glsl_to_spirv_builtin_functions/common_vertex.nspv"));
2098 #endif //DEQP_HAVE_GLSLANG
2099                         binaries << vertexBinary;
2100                 }
2101
2102                 sources << shaderSource;
2103                 ShaderBinary shaderBinary;
2104                 std::string  spirvSource;
2105
2106 #if defined DEQP_HAVE_GLSLANG
2107                 shaderBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), shaderSource);
2108 #else  // DEQP_HAVE_GLSLANG
2109                 {
2110                         std::stringstream ss;
2111                         ss << "spirv/glsl_to_spirv_builtin_functions/binary_" << i << ".nspv";
2112
2113                         tcu::Archive& archive = m_testCtx.getArchive();
2114                         shaderBinary              = commonUtils::readSpirV(archive.getResource(ss.str().c_str()));
2115                 }
2116 #endif // DEQP_HAVE_GLSLANG
2117
2118 #if defined DEQP_HAVE_SPIRV_TOOLS
2119                 {
2120                         glslangUtils::spirvDisassemble(spirvSource, shaderBinary.binary);
2121
2122                         if (!glslangUtils::verifyMappings(shaderSource.source, spirvSource, m_mappings, false))
2123                         {
2124                                 m_testCtx.getLog() << tcu::TestLog::Message << "Mappings for shader failed.\n"
2125                                                                    << "GLSL source:\n"
2126                                                                    << shaderSource.source.c_str() << "\n"
2127                                                                    << "SpirV source:\n"
2128                                                                    << spirvSource.c_str() << tcu::TestLog::EndMessage;
2129
2130                                 TCU_THROW(InternalError, "Mappings for shader failed.");
2131                         }
2132                 }
2133 #else  // DEQP_HAVE_SPIRV_TOOLS
2134                 spirvSource                               = "Could not disassemble Spir-V module. SPIRV-TOOLS not available.";
2135 #endif // DEQP_HAVE_SPIRV_TOOLS
2136
2137                 binaries << shaderBinary;
2138
2139                 if (shaderSource.shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)
2140                 {
2141                         ShaderSource tessEvalSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, m_commonTessEval);
2142
2143                         sources << tessEvalSource;
2144                         ShaderBinary tessEvalBinary;
2145 #if defined                              DEQP_HAVE_GLSLANG
2146                         tessEvalBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), tessEvalSource);
2147 #else  // DEQP_HAVE_GLSLANG
2148                         tcu::Archive& archive = m_testCtx.getArchive();
2149                         tessEvalBinary            = commonUtils::readSpirV(
2150                                 archive.getResource("spirv/glsl_to_spirv_builtin_functions/common_tesseval.nspv"));
2151 #endif // DEQP_HAVE_GLSLANG
2152                         binaries << tessEvalBinary;
2153                 }
2154
2155                 ShaderProgram glslProgram(gl, sources);
2156                 if (!glslProgram.isOk())
2157                 {
2158                         m_testCtx.getLog() << tcu::TestLog::Message << "GLSL shader compilation failed. Source:\n"
2159                                                            << shaderSource.source.c_str() << "InfoLog:\n"
2160                                                            << glslProgram.getShaderInfo(shaderSource.shaderType).infoLog << "\n"
2161                                                            << tcu::TestLog::EndMessage;
2162
2163                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2164                         return STOP;
2165                 }
2166
2167                 ShaderProgram spirvProgram(gl, binaries);
2168                 if (!spirvProgram.isOk())
2169                 {
2170                         m_testCtx.getLog() << tcu::TestLog::Message << "SpirV shader compilation failed. Source:\n"
2171                                                            << spirvSource.c_str() << "InfoLog:\n"
2172                                                            << spirvProgram.getShaderInfo(shaderSource.shaderType).infoLog << "\n"
2173                                                            << tcu::TestLog::EndMessage;
2174
2175                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2176                         return STOP;
2177                 }
2178         }
2179
2180         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2181         return STOP;
2182 }
2183
2184 /** Mappings init method */
2185 void SpirvGlslToSpirVBuiltInFunctionsTest::initMappings()
2186 {
2187         m_mappings.clear();
2188         m_mappings["radians"].push_back("OpExtInst Radians");
2189         m_mappings["degrees"].push_back("OpExtInst Degrees");
2190         m_mappings["sin"].push_back("OpExtInst Sin");
2191         m_mappings["cos"].push_back("OpExtInst Cos");
2192         m_mappings["tan"].push_back("OpExtInst Tan");
2193         m_mappings["asin"].push_back("OpExtInst Asin");
2194         m_mappings["acos"].push_back("OpExtInst Acos");
2195         m_mappings["atan"].push_back("OpExtInst Atan2");
2196         m_mappings["atan"].push_back("OpExtInst Atan");
2197         m_mappings["sinh"].push_back("OpExtInst Sinh");
2198         m_mappings["cosh"].push_back("OpExtInst Cosh");
2199         m_mappings["tanh"].push_back("OpExtInst Tanh");
2200         m_mappings["asinh"].push_back("OpExtInst Asinh");
2201         m_mappings["acosh"].push_back("OpExtInst Acosh");
2202         m_mappings["atanh"].push_back("OpExtInst Atanh");
2203         m_mappings["pow"].push_back("OpExtInst Pow");
2204         m_mappings["exp"].push_back("OpExtInst Exp");
2205         m_mappings["log"].push_back("OpExtInst Log");
2206         m_mappings["exp2"].push_back("OpExtInst Exp2");
2207         m_mappings["log2"].push_back("OpExtInst Log2");
2208         m_mappings["sqrt"].push_back("OpExtInst Sqrt");
2209         m_mappings["inversesqrt"].push_back("OpExtInst InverseSqrt");
2210         m_mappings["abs"].push_back("OpExtInst FAbs");
2211         m_mappings["sign"].push_back("OpExtInst FSign");
2212         m_mappings["floor"].push_back("OpExtInst Floor");
2213         m_mappings["trunc"].push_back("OpExtInst Trunc");
2214         m_mappings["round"].push_back("OpExtInst Round");
2215         m_mappings["roundEven"].push_back("OpExtInst RoundEven");
2216         m_mappings["ceil"].push_back("OpExtInst Ceil");
2217         m_mappings["fract"].push_back("OpExtInst Fract");
2218         m_mappings["mod"].push_back("OpFMod");
2219         m_mappings["modf"].push_back("OpExtInst Modf");
2220         m_mappings["min"].push_back("OpExtInst FMin");
2221         m_mappings["max"].push_back("OpExtInst FMax");
2222         m_mappings["clamp"].push_back("OpExtInst FClamp");
2223         m_mappings["mix"].push_back("OpExtInst FMix");
2224         m_mappings["step"].push_back("OpExtInst Step");
2225         m_mappings["smoothstep"].push_back("OpExtInst SmoothStep");
2226         m_mappings["intBitsToFloat"].push_back("OpBitcast");
2227         m_mappings["uintBitsToFloat"].push_back("OpBitcast");
2228         m_mappings["isnan"].push_back("OpIsNan");
2229         m_mappings["isinf"].push_back("OpIsInf");
2230         m_mappings["fma"].push_back("OpExtInst Fma");
2231         m_mappings["frexp"].push_back("OpExtInst FrexpStruct");
2232         m_mappings["ldexp"].push_back("OpExtInst Ldexp");
2233         m_mappings["packUnorm2x16"].push_back("OpExtInst PackUnorm2x16");
2234         m_mappings["packSnorm2x16"].push_back("OpExtInst PackSnorm2x16");
2235         m_mappings["packUnorm4x8"].push_back("OpExtInst PackUnorm4x8");
2236         m_mappings["packSnorm4x8"].push_back("OpExtInst PackSnorm4x8");
2237         m_mappings["unpackUnorm2x16"].push_back("OpExtInst UnpackUnorm2x16");
2238         m_mappings["unpackSnorm2x16"].push_back("OpExtInst UnpackSnorm2x16");
2239         m_mappings["unpackUnorm4x8"].push_back("OpExtInst UnpackUnorm4x8");
2240         m_mappings["unpackSnorm4x8"].push_back("OpExtInst UnpackSnorm4x8");
2241         m_mappings["packDouble2x32"].push_back("OpExtInst PackDouble2x32");
2242         m_mappings["unpackDouble2x32"].push_back("OpExtInst UnpackDouble2x32");
2243         m_mappings["packHalf2x16"].push_back("OpExtInst PackHalf2x16");
2244         m_mappings["unpackHalf2x16"].push_back("OpExtInst UnpackHalf2x16");
2245         m_mappings["length"].push_back("OpExtInst Length");
2246         m_mappings["distance"].push_back("OpExtInst Distance");
2247         m_mappings["dot"].push_back("OpDot");
2248         m_mappings["cross"].push_back("OpExtInst Cross");
2249         m_mappings["normalize"].push_back("OpExtInst Normalize");
2250         m_mappings["faceforward"].push_back("OpExtInst FaceForward");
2251         m_mappings["reflect"].push_back("OpExtInst Reflect");
2252         m_mappings["refract"].push_back("OpExtInst Refract");
2253         // This one could not be mapped as Spir-V equivalent need more steps
2254         // m_mappings["matrixCompMult"].push_back("");
2255         m_mappings["outerProduct"].push_back("OpOuterProduct");
2256         m_mappings["transpose"].push_back("OpTranspose");
2257         m_mappings["determinant"].push_back("OpExtInst Determinant");
2258         m_mappings["inverse"].push_back("OpExtInst MatrixInverse");
2259         m_mappings["lessThan"].push_back("OpFOrdLessThan");
2260         m_mappings["lessThanEqual"].push_back("OpFOrdLessThanEqual");
2261         m_mappings["greaterThan"].push_back("OpFOrdGreaterThan");
2262         m_mappings["greaterThanEqual"].push_back("OpFOrdGreaterThanEqual");
2263         m_mappings["equal"].push_back("OpFOrdEqual");
2264         m_mappings["notEqual"].push_back("OpFOrdNotEqual");
2265         m_mappings["any"].push_back("OpAny");
2266         m_mappings["all"].push_back("OpAll");
2267         m_mappings["not"].push_back("OpLogicalNot");
2268         m_mappings["uaddCarry"].push_back("OpIAddCarry");
2269         m_mappings["usubBorrow"].push_back("OpISubBorrow");
2270         m_mappings["umulExtended"].push_back("OpUMulExtended");
2271         m_mappings["bitfieldExtract"].push_back("OpBitFieldUExtract");
2272         m_mappings["bitfieldInsert"].push_back("OpBitFieldInsert");
2273         m_mappings["bitfieldReverse"].push_back("OpBitReverse");
2274         m_mappings["bitCount"].push_back("OpBitCount");
2275         m_mappings["findLSB"].push_back("OpExtInst FindILsb");
2276         m_mappings["findMSB"].push_back("OpExtInst FindUMsb");
2277         m_mappings["textureSize"].push_back("OpImageQuerySizeLod");
2278         m_mappings["textureQueryLod"].push_back("OpImageQueryLod");
2279         m_mappings["textureQueryLevels"].push_back("OpImageQueryLevels");
2280         m_mappings["textureSamples"].push_back("OpImageQuerySamples");
2281         m_mappings["texture"].push_back("OpImageSampleImplicitLod");
2282         m_mappings["textureProj"].push_back("OpImageSampleProjImplicitLod");
2283         m_mappings["textureLod"].push_back("OpImageSampleExplicitLod Lod");
2284         m_mappings["textureOffset"].push_back("OpImageSampleImplicitLod ConstOffset");
2285         m_mappings["texelFetch"].push_back("OpImageFetch Lod");
2286         m_mappings["texelFetchOffset"].push_back("OpImageFetch Lod|ConstOffset");
2287         m_mappings["textureProjOffset"].push_back("OpImageSampleProjImplicitLod ConstOffset");
2288         m_mappings["textureLodOffset"].push_back("OpImageSampleExplicitLod Lod|ConstOffset");
2289         m_mappings["textureProjLod"].push_back("OpImageSampleProjExplicitLod Lod");
2290         m_mappings["textureProjLodOffset"].push_back("OpImageSampleProjExplicitLod Lod|ConstOffset");
2291         m_mappings["textureGrad"].push_back("OpImageSampleExplicitLod Grad");
2292         m_mappings["textureGradOffset"].push_back("OpImageSampleExplicitLod Grad|ConstOffset");
2293         m_mappings["textureProjGrad"].push_back("OpImageSampleProjExplicitLod Grad");
2294         m_mappings["textureProjGradOffset"].push_back("OpImageSampleProjExplicitLod Grad|ConstOffset");
2295         m_mappings["textureGather"].push_back("OpImageGather");
2296         m_mappings["textureGatherOffset"].push_back("OpImageGather ConstOffset");
2297         m_mappings["atomicCounterIncrement"].push_back("OpAtomicIIncrement");
2298         m_mappings["atomicCounterDecrement"].push_back("OpAtomicIDecrement");
2299         m_mappings["atomicCounter"].push_back("OpAtomicLoad");
2300         m_mappings["atomicAdd"].push_back("OpAtomicIAdd");
2301         m_mappings["atomicMin"].push_back("OpAtomicUMin");
2302         m_mappings["atomicMax"].push_back("OpAtomicUMax");
2303         m_mappings["atomicAnd"].push_back("OpAtomicAnd");
2304         m_mappings["atomicOr"].push_back("OpAtomicOr");
2305         m_mappings["atomicXor"].push_back("OpAtomicXor");
2306         m_mappings["atomicExchange"].push_back("OpAtomicExchange");
2307         m_mappings["atomicCompSwap"].push_back("OpAtomicCompareExchange");
2308         m_mappings["imageSize"].push_back("OpImageQuerySize");
2309         m_mappings["imageSamples"].push_back("OpImageQuerySamples");
2310         m_mappings["imageLoad"].push_back("OpImageRead");
2311         m_mappings["imageStore"].push_back("OpImageWrite");
2312         m_mappings["imageAtomicAdd"].push_back("OpAtomicIAdd");
2313         m_mappings["imageAtomicMin"].push_back("OpAtomicUMin");
2314         m_mappings["imageAtomicMax"].push_back("OpAtomicUMax");
2315         m_mappings["imageAtomicAnd"].push_back("OpAtomicAnd");
2316         m_mappings["imageAtomicOr"].push_back("OpAtomicOr");
2317         m_mappings["imageAtomicXor"].push_back("OpAtomicXor");
2318         m_mappings["imageAtomicExchange"].push_back("OpAtomicExchange");
2319         m_mappings["imageAtomicCompSwap"].push_back("OpAtomicCompareExchange");
2320         m_mappings["dFdx"].push_back("OpDPdx");
2321         m_mappings["dFdy"].push_back("OpDPdy");
2322         m_mappings["dFdxFine"].push_back("OpDPdxFine");
2323         m_mappings["dFdyFine"].push_back("OpDPdyFine");
2324         m_mappings["dFdxCoarse"].push_back("OpDPdxCoarse");
2325         m_mappings["dFdyCoarse"].push_back("OpDPdyCoarse");
2326         m_mappings["fwidth"].push_back("OpFwidth");
2327         m_mappings["fwidthFine"].push_back("OpFwidthFine");
2328         m_mappings["fwidthCoarse"].push_back("OpFwidthCoarse");
2329         m_mappings["interpolateAtCentroid"].push_back("OpExtInst InterpolateAtCentroid");
2330         m_mappings["interpolateAtSample"].push_back("OpExtInst InterpolateAtSample");
2331         m_mappings["interpolateAtOffset"].push_back("OpExtInst InterpolateAtOffset");
2332         m_mappings["EmitStreamVertex"].push_back("OpEmitStreamVertex");
2333         m_mappings["EndStreamPrimitive"].push_back("OpEndStreamPrimitive");
2334         m_mappings["EmitVertex"].push_back("OpEmitVertex");
2335         m_mappings["EndPrimitive"].push_back("OpEndPrimitive");
2336         m_mappings["barrier"].push_back("OpControlBarrier");
2337         m_mappings["memoryBarrier"].push_back("OpMemoryBarrier");
2338         m_mappings["memoryBarrierAtomicCounter"].push_back("OpMemoryBarrier");
2339         m_mappings["memoryBarrierBuffer"].push_back("OpMemoryBarrier");
2340         m_mappings["memoryBarrierShared"].push_back("OpMemoryBarrier");
2341         m_mappings["memoryBarrierImage"].push_back("OpMemoryBarrier");
2342         m_mappings["groupMemoryBarrier"].push_back("OpMemoryBarrier");
2343
2344         // Add a space prefix and parenthesis sufix to avoid searching for similar names
2345         SpirVMapping               tempMappings;
2346         SpirVMapping::iterator it;
2347         for (it = m_mappings.begin(); it != m_mappings.end(); ++it)
2348         {
2349                 tempMappings[std::string(" ") + it->first + "("] = it->second;
2350         }
2351
2352         m_mappings = tempMappings;
2353 }
2354
2355 /** Constructor.
2356  *
2357  *  @param context     Rendering context
2358  *  @param name        Test name
2359  *  @param description Test description
2360  */
2361 SpirvGlslToSpirVSpecializationConstantsTest::SpirvGlslToSpirVSpecializationConstantsTest(deqp::Context& context)
2362         : TestCase(context, "spirv_glsl_to_spirv_specialization_constants_test",
2363                            "Test verifies if constant specialization feature works as expected.")
2364 {
2365         /* Left blank intentionally */
2366 }
2367
2368 /** Stub init method */
2369 void SpirvGlslToSpirVSpecializationConstantsTest::init()
2370 {
2371         commonUtils::checkGlSpirvSupported(m_context);
2372
2373         const Functions& gl = m_context.getRenderContext().getFunctions();
2374
2375         m_vertex = "#version 450\n"
2376                            "\n"
2377                            "layout (location = 0) in vec3 position;\n"
2378                            "\n"
2379                            "void main()\n"
2380                            "{\n"
2381                            "    gl_Position = vec4(position, 1.0);\n"
2382                            "}\n";
2383
2384         m_fragment = "#version 450\n"
2385                                  "\n"
2386                                  "layout (constant_id = 10) const int red = 255;\n"
2387                                  "\n"
2388                                  "layout (location = 0) out vec4 fragColor;\n"
2389                                  "\n"
2390                                  "void main()\n"
2391                                  "{\n"
2392                                  "    fragColor = vec4(float(red) / 255, 0.0, 1.0, 1.0);\n"
2393                                  "}\n";
2394
2395         gl.genTextures(1, &m_texture);
2396         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
2397         gl.bindTexture(GL_TEXTURE_2D, m_texture);
2398         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
2399         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32);
2400         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
2401
2402         gl.genFramebuffers(1, &m_fbo);
2403         GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
2404         gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
2405         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
2406         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
2407         GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
2408
2409         gl.viewport(0, 0, 32, 32);
2410         GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
2411 }
2412
2413 /** Stub de-init method */
2414 void SpirvGlslToSpirVSpecializationConstantsTest::deinit()
2415 {
2416         const Functions& gl = m_context.getRenderContext().getFunctions();
2417
2418         if (m_fbo)
2419         {
2420                 gl.deleteFramebuffers(1, &m_fbo);
2421                 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
2422         }
2423         if (m_texture)
2424         {
2425                 gl.deleteTextures(1, &m_texture);
2426                 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
2427         }
2428 }
2429
2430 /** Executes test iteration.
2431  *
2432  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2433  */
2434 tcu::TestNode::IterateResult SpirvGlslToSpirVSpecializationConstantsTest::iterate()
2435 {
2436         const Functions& gl = m_context.getRenderContext().getFunctions();
2437
2438         const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
2439
2440         GLuint vao;
2441         gl.genVertexArrays(1, &vao);
2442         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
2443         gl.bindVertexArray(vao);
2444         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
2445
2446         GLuint vbo;
2447         gl.genBuffers(1, &vbo);
2448         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
2449         gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
2450         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
2451
2452         gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
2453         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
2454
2455         ShaderBinary vertexBinary;
2456         ShaderBinary fragmentBinary;
2457 #if defined              DEQP_HAVE_GLSLANG
2458         {
2459                 vertexBinary   = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
2460                 fragmentBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), FragmentSource(m_fragment));
2461         }
2462 #else  // DEQP_HAVE_GLSLANG
2463         {
2464                 tcu::Archive& archive = m_testCtx.getArchive();
2465                 vertexBinary =
2466                         commonUtils::readSpirV(archive.getResource("spirv/glsl_to_spirv_specialization_constants/vertex.nspv"));
2467                 fragmentBinary =
2468                         commonUtils::readSpirV(archive.getResource("spirv/glsl_to_spirv_specialization_constants/fragment.nspv"));
2469         }
2470 #endif // DEQP_HAVE_GLSLANG
2471         fragmentBinary << SpecializationData(10, 128);
2472
2473         ProgramBinaries binaries;
2474         binaries << vertexBinary;
2475         binaries << fragmentBinary;
2476         ShaderProgram spirvProgram(gl, binaries);
2477
2478         if (!spirvProgram.isOk())
2479         {
2480                 m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed.\n"
2481                                                    << "Vertex:\n"
2482                                                    << m_vertex.c_str() << "Fragment:\n"
2483                                                    << m_fragment.c_str() << "InfoLog:\n"
2484                                                    << spirvProgram.getShaderInfo(SHADERTYPE_VERTEX).infoLog << tcu::TestLog::EndMessage;
2485
2486                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2487                 return STOP;
2488         }
2489
2490         gl.useProgram(spirvProgram.getProgram());
2491         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2492
2493         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
2494         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
2495         gl.clear(GL_COLOR_BUFFER_BIT);
2496         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
2497
2498         gl.enableVertexAttribArray(0);
2499         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
2500
2501         gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2502         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
2503
2504         gl.drawArrays(GL_TRIANGLES, 0, 3);
2505         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
2506
2507         gl.disableVertexAttribArray(0);
2508         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
2509
2510         GLuint output;
2511
2512         gl.readPixels(16, 16, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&output);
2513         GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
2514
2515         if (output != 0xFFFF0080)
2516         {
2517                 m_testCtx.getLog() << tcu::TestLog::Message
2518                                                    << "Color value read from framebuffer is wrong. Expected: " << 0xFFFF0080
2519                                                    << ", Read: " << output << tcu::TestLog::EndMessage;
2520
2521                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2522                 return STOP;
2523         }
2524
2525         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2526         return STOP;
2527 }
2528
2529 /** Constructor.
2530  *
2531  *  @param context     Rendering context
2532  *  @param name        Test name
2533  *  @param description Test description
2534  */
2535 SpirvValidationBuiltInVariableDecorationsTest::SpirvValidationBuiltInVariableDecorationsTest(deqp::Context& context)
2536         : TestCase(context, "spirv_validation_builtin_variable_decorations_test",
2537                            "Test verifies if Spir-V built in variable decorations works as expected.")
2538 {
2539         /* Left blank intentionally */
2540 }
2541
2542 /** Stub init method */
2543 void SpirvValidationBuiltInVariableDecorationsTest::init()
2544 {
2545         commonUtils::checkGlSpirvSupported(m_context);
2546
2547         m_compute = "#version 450\n"
2548                                 "\n"
2549                                 "layout (local_size_x = 1, local_size_y = 2, local_size_z = 1) in;\n"
2550                                 "\n"
2551                                 "layout (location = 0, rgba8ui) uniform uimage2D img0;\n"
2552                                 "layout (location = 1, rgba8ui) uniform uimage2D img1;\n"
2553                                 "layout (location = 2, rgba8ui) uniform uimage2D img2;\n"
2554                                 "layout (location = 3, rgba8ui) uniform uimage2D img3;\n"
2555                                 "layout (location = 4, rgba8ui) uniform uimage2D img4;\n"
2556                                 "\n"
2557                                 "void main()\n"
2558                                 "{\n"
2559                                 "    ivec3 point = ivec3(gl_GlobalInvocationID);\n"
2560                                 "    uvec3 color0 = uvec3(gl_NumWorkGroups);\n"
2561                                 "    uvec3 color1 = uvec3(gl_WorkGroupSize);\n"
2562                                 "    uvec3 color2 = uvec3(gl_WorkGroupID);\n"
2563                                 "    uvec3 color3 = uvec3(gl_LocalInvocationID);\n"
2564                                 "    uvec3 color4 = uvec3(gl_LocalInvocationIndex);\n"
2565                                 "    imageStore(img0, point.xy, uvec4(color0, 0xFF));\n"
2566                                 "    imageStore(img1, point.xy, uvec4(color1, 0xFF));\n"
2567                                 "    imageStore(img2, point.xy, uvec4(color2, 0xFF));\n"
2568                                 "    imageStore(img3, point.xy, uvec4(color3, 0xFF));\n"
2569                                 "    imageStore(img4, point.xy, uvec4(color4, 0xFF));\n"
2570                                 "    memoryBarrier();\n"
2571                                 "}\n";
2572
2573         m_vertex = "#version 450\n"
2574                            "\n"
2575                            "layout (location = 0) in vec3 position;\n"
2576                            "\n"
2577                            "layout (location = 1) out vec4 vColor;\n"
2578                            "\n"
2579                            "void main()\n"
2580                            "{\n"
2581                            "    gl_PointSize = 10.0f;\n"
2582                            "    gl_Position = vec4(position.x, position.y + 0.3 * gl_InstanceID, position.z, 1.0);\n"
2583                            "    gl_ClipDistance[0] = <CLIP_DISTANCE>;\n"
2584                            "    gl_CullDistance[0] = <CULL_DISTANCE>;\n"
2585                            "    vColor = <VERTEX_COLOR>;\n"
2586                            "}\n";
2587
2588         m_tesselationCtrl = "#version 450\n"
2589                                                 "\n"
2590                                                 "layout (vertices = 3) out;\n"
2591                                                 "\n"
2592                                                 "layout (location = 1) in vec4 vColor[];\n"
2593                                                 "layout (location = 2) out vec4 tcColor[];\n"
2594                                                 "\n"
2595                                                 "void main()\n"
2596                                                 "{\n"
2597                                                 "    tcColor[gl_InvocationID] = vColor[gl_InvocationID];\n"
2598                                                 "    tcColor[gl_InvocationID].r = float(gl_PatchVerticesIn) / 3;\n"
2599                                                 "\n"
2600                                                 "    if (gl_InvocationID == 0) {\n"
2601                                                 "        gl_TessLevelOuter[0] = 1.0;\n"
2602                                                 "        gl_TessLevelOuter[1] = 1.0;\n"
2603                                                 "        gl_TessLevelOuter[2] = 1.0;\n"
2604                                                 "        gl_TessLevelInner[0] = 1.0;\n"
2605                                                 "    }\n"
2606                                                 "\n"
2607                                                 "    gl_out[gl_InvocationID].gl_ClipDistance[0] = gl_in[gl_InvocationID].gl_ClipDistance[0];\n"
2608                                                 "    gl_out[gl_InvocationID].gl_CullDistance[0] = gl_in[gl_InvocationID].gl_CullDistance[0];\n"
2609                                                 "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2610                                                 "}\n";
2611
2612         m_tesselationEval = "#version 450\n"
2613                                                 "\n"
2614                                                 "layout (triangles) in;\n"
2615                                                 "\n"
2616                                                 "layout (location = 2) in vec4 tcColor[];\n"
2617                                                 "layout (location = 3) out vec4 teColor;\n"
2618                                                 "\n"
2619                                                 "void main()\n"
2620                                                 "{\n"
2621                                                 "    teColor = tcColor[0];\n"
2622                                                 "\n"
2623                                                 "    gl_ClipDistance[0] = gl_in[0].gl_ClipDistance[0];\n"
2624                                                 "    gl_CullDistance[0] = gl_in[0].gl_CullDistance[0];\n"
2625                                                 "    gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +\n"
2626                                                 "                  gl_TessCoord.y * gl_in[1].gl_Position +\n"
2627                                                 "                  gl_TessCoord.z * gl_in[2].gl_Position;\n"
2628                                                 "}\n";
2629
2630         m_geometry = "#version 450\n"
2631                                  "\n"
2632                                  "layout (triangles) in;\n"
2633                                  "layout (triangle_strip, max_vertices = 3) out;\n"
2634                                  "\n"
2635                                  "layout (location = 3) in vec4 teColor[];\n"
2636                                  "layout (location = 4) out vec4 gColor;\n"
2637                                  "\n"
2638                                  "void main()\n"
2639                                  "{\n"
2640                                  "    gColor = teColor[0];\n"
2641                                  "    gColor.b = float(gl_PrimitiveIDIn);\n"
2642                                  "\n"
2643                                  "    gl_Layer = 1;\n"
2644                                  "    gl_ViewportIndex = 1;\n"
2645                                  "\n"
2646                                  "    for (int i = 0; i < 3; ++i) {\n"
2647                                  "        gl_ClipDistance[0] = gl_in[i].gl_ClipDistance[0];\n"
2648                                  "        gl_CullDistance[0] = gl_in[i].gl_CullDistance[0];\n"
2649                                  "        gl_Position = gl_in[i].gl_Position;\n"
2650                                  "        EmitVertex();\n"
2651                                  "    }\n"
2652                                  "    EndPrimitive();\n"
2653                                  "}\n";
2654
2655         m_fragment = "#version 450\n"
2656                                  "\n"
2657                                  "layout (location = <INPUT_LOCATION>) in vec4 <INPUT_NAME>;\n"
2658                                  "layout (location = 0) out vec4 fColor;\n"
2659                                  "\n"
2660                                  "void main()\n"
2661                                  "{\n"
2662                                  "    vec4 color = <INPUT_NAME>;\n"
2663                                  "    <ADDITIONAL_CODE>\n"
2664                                  "    fColor = color;\n"
2665                                  "}\n";
2666
2667         ValidationStruct validationCompute(&SpirvValidationBuiltInVariableDecorationsTest::validComputeFunc);
2668         validationCompute.shaders.push_back(ComputeSource(m_compute));
2669         m_validations.push_back(validationCompute);
2670
2671         std::string clipNegativeVertex   = m_vertex;
2672         std::string clipNegativeFragment = m_fragment;
2673         commonUtils::replaceToken("<CLIP_DISTANCE>", "-1.0", clipNegativeVertex);
2674         commonUtils::replaceToken("<CULL_DISTANCE>", "1.0", clipNegativeVertex);
2675         commonUtils::replaceToken("<VERTEX_COLOR>", "vec4(1.0, 1.0, 1.0, 1.0)", clipNegativeVertex);
2676         commonUtils::replaceToken("<INPUT_LOCATION>", "1", clipNegativeFragment);
2677         commonUtils::replaceToken("<INPUT_NAME>", "vColor", clipNegativeFragment);
2678         commonUtils::replaceToken("<ADDITIONAL_CODE>", "", clipNegativeFragment);
2679         ValidationStruct validationClipNegative(&SpirvValidationBuiltInVariableDecorationsTest::validPerVertexFragFunc);
2680         validationClipNegative.shaders.push_back(VertexSource(clipNegativeVertex));
2681         validationClipNegative.shaders.push_back(FragmentSource(clipNegativeFragment));
2682         validationClipNegative.outputs.push_back(ValidationOutputStruct(32, 32, 0xFF000000));
2683         m_validations.push_back(validationClipNegative);
2684
2685         std::string perVertexFragVertex   = m_vertex;
2686         std::string perVertexFragFragment = m_fragment;
2687         std::string fragCode                      = "vec4 coord = gl_FragCoord;\n"
2688                                                    "color = vec4(0.0, coord.s / 64, coord.t / 64, 1.0);\n";
2689         commonUtils::replaceToken("<CLIP_DISTANCE>", "1.0", perVertexFragVertex);
2690         commonUtils::replaceToken("<CULL_DISTANCE>", "1.0", perVertexFragVertex);
2691         commonUtils::replaceToken("<VERTEX_COLOR>", "vec4(1.0, 1.0, 1.0, 1.0)", perVertexFragVertex);
2692         commonUtils::replaceToken("<INPUT_LOCATION>", "1", perVertexFragFragment);
2693         commonUtils::replaceToken("<INPUT_NAME>", "vColor", perVertexFragFragment);
2694         commonUtils::replaceToken("<ADDITIONAL_CODE>", fragCode.c_str(), perVertexFragFragment);
2695         ValidationStruct validationFrag(&SpirvValidationBuiltInVariableDecorationsTest::validPerVertexFragFunc);
2696         validationFrag.shaders.push_back(VertexSource(perVertexFragVertex));
2697         validationFrag.shaders.push_back(FragmentSource(perVertexFragFragment));
2698         validationFrag.outputs.push_back(ValidationOutputStruct(32, 32, 0xFF7F7F00));
2699         m_validations.push_back(validationFrag);
2700
2701         std::string perVertexPointVertex   = m_vertex;
2702         std::string perVertexPointFragment = m_fragment;
2703         std::string pointCode                      = "vec2 coord = gl_PointCoord;\n"
2704                                                         "color.b = coord.s * coord.t;\n";
2705         commonUtils::replaceToken("<CLIP_DISTANCE>", "1.0", perVertexPointVertex);
2706         commonUtils::replaceToken("<CULL_DISTANCE>", "1.0", perVertexPointVertex);
2707         commonUtils::replaceToken("<VERTEX_COLOR>", "vec4(float(gl_VertexID) / 3, 0.0, 0.0, 1.0)", perVertexPointVertex);
2708         commonUtils::replaceToken("<INPUT_LOCATION>", "1", perVertexPointFragment);
2709         commonUtils::replaceToken("<INPUT_NAME>", "vColor", perVertexPointFragment);
2710         commonUtils::replaceToken("<ADDITIONAL_CODE>", pointCode.c_str(), perVertexPointFragment);
2711         ValidationStruct validationPoint(&SpirvValidationBuiltInVariableDecorationsTest::validPerVertexPointFunc);
2712         validationPoint.shaders.push_back(VertexSource(perVertexPointVertex));
2713         validationPoint.shaders.push_back(FragmentSource(perVertexPointFragment));
2714         validationPoint.outputs.push_back(ValidationOutputStruct(64, 64, 0xFF3F0055));
2715         validationPoint.outputs.push_back(ValidationOutputStruct(45, 45, 0xFF3F0000));
2716         validationPoint.outputs.push_back(ValidationOutputStruct(83, 83, 0xFF3F00AA));
2717         m_validations.push_back(validationPoint);
2718
2719         std::string tessGeomVertex   = m_vertex;
2720         std::string tessGeomFragment = m_fragment;
2721         commonUtils::replaceToken("<CLIP_DISTANCE>", "1.0", tessGeomVertex);
2722         commonUtils::replaceToken("<CULL_DISTANCE>", "1.0", tessGeomVertex);
2723         commonUtils::replaceToken("<VERTEX_COLOR>", "vec4(1.0, 1.0, 1.0, 1.0)", tessGeomVertex);
2724         commonUtils::replaceToken("<INPUT_LOCATION>", "4", tessGeomFragment);
2725         commonUtils::replaceToken("<INPUT_NAME>", "gColor", tessGeomFragment);
2726         commonUtils::replaceToken("<ADDITIONAL_CODE>", "", tessGeomFragment);
2727         ValidationStruct validationTessGeom(&SpirvValidationBuiltInVariableDecorationsTest::validTesselationGeometryFunc);
2728         validationTessGeom.shaders.push_back(VertexSource(tessGeomVertex));
2729         validationTessGeom.shaders.push_back(TessellationControlSource(m_tesselationCtrl));
2730         validationTessGeom.shaders.push_back(TessellationEvaluationSource(m_tesselationEval));
2731         validationTessGeom.shaders.push_back(GeometrySource(m_geometry));
2732         validationTessGeom.shaders.push_back(FragmentSource(tessGeomFragment));
2733         validationTessGeom.outputs.push_back(ValidationOutputStruct(48, 32, 1, 0xFF00FFFF));
2734         m_validations.push_back(validationTessGeom);
2735
2736         std::string multisampleVertex   = m_vertex;
2737         std::string multisampleFragment = m_fragment;
2738         std::string samplingCode                = "if (gl_SampleID == 0)\n"
2739                                                            "{\n"
2740                                                            "   vec2 sampPos = gl_SamplePosition;\n"
2741                                                            "    color = vec4(1.0, sampPos.x, sampPos.y, 1.0);\n"
2742                                                            "}\n"
2743                                                            "else\n"
2744                                                            "{\n"
2745                                                            "    color = vec4(0.0, 1.0, 0.0, 1.0);\n"
2746                                                            "}\n"
2747                                                            "gl_SampleMask[0] = 0x02;";
2748         commonUtils::replaceToken("<CLIP_DISTANCE>", "1.0", multisampleVertex);
2749         commonUtils::replaceToken("<CULL_DISTANCE>", "1.0", multisampleVertex);
2750         commonUtils::replaceToken("<VERTEX_COLOR>", "vec4(1.0, 1.0, 1.0, 1.0)", multisampleVertex);
2751         commonUtils::replaceToken("<INPUT_LOCATION>", "1", multisampleFragment);
2752         commonUtils::replaceToken("<INPUT_NAME>", "vColor", multisampleFragment);
2753         commonUtils::replaceToken("<ADDITIONAL_CODE>", samplingCode.c_str(), multisampleFragment);
2754         ValidationStruct validationMultisample(&SpirvValidationBuiltInVariableDecorationsTest::validMultiSamplingFunc);
2755         validationMultisample.shaders.push_back(VertexSource(multisampleVertex));
2756         validationMultisample.shaders.push_back(FragmentSource(multisampleFragment));
2757         validationMultisample.outputs.push_back(ValidationOutputStruct(16, 16, 0xFF00BC00));
2758         m_validations.push_back(validationMultisample);
2759
2760         m_mappings["gl_NumWorkGroups"].push_back("BuiltIn NumWorkgroups");
2761         m_mappings["gl_WorkGroupSize"].push_back("BuiltIn WorkgroupSize");
2762         m_mappings["gl_WorkGroupID"].push_back("BuiltIn WorkgroupId");
2763         m_mappings["gl_LocalInvocationID"].push_back("BuiltIn LocalInvocationId");
2764         m_mappings["gl_GlobalInvocationID"].push_back("BuiltIn GlobalInvocationId");
2765         m_mappings["gl_LocalInvocationIndex"].push_back("BuiltIn LocalInvocationIndex");
2766         m_mappings["gl_VertexID"].push_back("BuiltIn VertexId");
2767         m_mappings["gl_InstanceID"].push_back("BuiltIn InstanceId");
2768         m_mappings["gl_Position"].push_back("BuiltIn Position");
2769         m_mappings["gl_PointSize"].push_back("BuiltIn PointSize");
2770         m_mappings["gl_ClipDistance"].push_back("BuiltIn ClipDistance");
2771         m_mappings["gl_CullDistance"].push_back("BuiltIn CullDistance");
2772         m_mappings["gl_PrimitiveIDIn"].push_back("BuiltIn PrimitiveId");
2773         m_mappings["gl_InvocationID"].push_back("BuiltIn InvocationId");
2774         m_mappings["gl_Layer"].push_back("BuiltIn Layer");
2775         m_mappings["gl_ViewportIndex"].push_back("BuiltIn ViewportIndex");
2776         m_mappings["gl_PatchVerticesIn"].push_back("BuiltIn PatchVertices");
2777         m_mappings["gl_TessLevelOuter"].push_back("BuiltIn TessLevelOuter");
2778         m_mappings["gl_TessLevelInner"].push_back("BuiltIn TessLevelInner");
2779         m_mappings["gl_TessCoord"].push_back("BuiltIn TessCoord");
2780         m_mappings["gl_FragCoord"].push_back("BuiltIn FragCoord");
2781         m_mappings["gl_FrontFacing"].push_back("BuiltIn FrontFacing");
2782         m_mappings["gl_PointCoord"].push_back("BuiltIn PointCoord");
2783         m_mappings["gl_SampleId"].push_back("BuiltIn SampleId");
2784         m_mappings["gl_SamplePosition"].push_back("BuiltIn SamplePosition");
2785         m_mappings["gl_SampleMask"].push_back("BuiltIn SampleMask");
2786 }
2787
2788 /** Stub de-init method */
2789 void SpirvValidationBuiltInVariableDecorationsTest::deinit()
2790 {
2791 }
2792
2793 /** Executes test iteration.
2794  *
2795  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2796  */
2797 tcu::TestNode::IterateResult SpirvValidationBuiltInVariableDecorationsTest::iterate()
2798 {
2799         const Functions& gl = m_context.getRenderContext().getFunctions();
2800
2801         GLuint vao;
2802         gl.genVertexArrays(1, &vao);
2803         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
2804         gl.bindVertexArray(vao);
2805         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
2806
2807         GLuint vbo;
2808         gl.genBuffers(1, &vbo);
2809         GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
2810         gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
2811         GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
2812
2813         enum Iterates
2814         {
2815                 ITERATE_GLSL,
2816                 ITERATE_SPIRV,
2817                 ITERATE_LAST
2818         };
2819
2820         bool result = true;
2821
2822         for (int v = 0; v < (signed)m_validations.size(); ++v)
2823         {
2824                 for (int it = ITERATE_GLSL; it < ITERATE_LAST; ++it)
2825                 {
2826                         ShaderProgram* program = DE_NULL;
2827                         if (it == ITERATE_GLSL)
2828                         {
2829                                 ProgramSources sources;
2830                                 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2831                                         sources << m_validations[v].shaders[s];
2832
2833                                 program = new ShaderProgram(gl, sources);
2834                         }
2835                         else if (it == ITERATE_SPIRV)
2836                         {
2837                                 std::vector<ShaderBinary> binariesVec;
2838
2839 #if defined                                             DEQP_HAVE_GLSLANG
2840                                 ProgramBinaries binaries;
2841                                 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2842                                 {
2843                                         ShaderBinary shaderBinary =
2844                                                 glslangUtils::makeSpirV(m_context.getTestContext().getLog(), m_validations[v].shaders[s]);
2845                                         binariesVec.push_back(shaderBinary);
2846                                         binaries << shaderBinary;
2847                                 }
2848 #else  // DEQP_HAVE_GLSLANG
2849                                 tcu::Archive&   archive = m_testCtx.getArchive();
2850                                 ProgramBinaries binaries;
2851                                 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2852                                 {
2853                                         std::stringstream ss;
2854                                         ss << "spirv/spirv_validation_builtin_variable_decorations/shader_" << v << "_" << s << ".nspv";
2855
2856                                         ShaderBinary shaderBinary = commonUtils::readSpirV(archive.getResource(ss.str().c_str()));
2857                                         binariesVec.push_back(shaderBinary);
2858                                         binaries << shaderBinary;
2859                                 }
2860 #endif // DEQP_HAVE_GLSLANG
2861                                 program = new ShaderProgram(gl, binaries);
2862
2863 #if defined                                     DEQP_HAVE_SPIRV_TOOLS
2864                                 std::string spirvSource;
2865
2866                                 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2867                                 {
2868                                         ShaderSource shaderSource = m_validations[v].shaders[s];
2869
2870                                         glslangUtils::spirvDisassemble(spirvSource, binariesVec[s].binary);
2871
2872                                         if (!glslangUtils::verifyMappings(shaderSource.source, spirvSource, m_mappings, true))
2873                                         {
2874                                                 m_testCtx.getLog() << tcu::TestLog::Message << "Mappings for shader failed.\n"
2875                                                                                    << "GLSL source:\n"
2876                                                                                    << shaderSource.source.c_str() << "\n"
2877                                                                                    << "SpirV source:\n"
2878                                                                                    << spirvSource.c_str() << tcu::TestLog::EndMessage;
2879
2880                                                 TCU_THROW(InternalError, "Mappings for shader failed.");
2881                                         }
2882                                 }
2883 #endif // DEQP_HAVE_SPIRV_TOOLS
2884                         }
2885
2886                         if (!program->isOk())
2887                         {
2888                                 std::stringstream message;
2889                                 message << "Shader build failed.\n";
2890
2891                                 if (program->hasShader(SHADERTYPE_COMPUTE))
2892                                         message << "ComputeInfo: " << program->getShaderInfo(SHADERTYPE_COMPUTE).infoLog << "\n"
2893                                                         << "ComputeSource: " << program->getShader(SHADERTYPE_COMPUTE)->getSource() << "\n";
2894                                 if (program->hasShader(SHADERTYPE_VERTEX))
2895                                         message << "VertexInfo: " << program->getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
2896                                                         << "VertexSource: " << program->getShader(SHADERTYPE_VERTEX)->getSource() << "\n";
2897                                 if (program->hasShader(SHADERTYPE_TESSELLATION_CONTROL))
2898                                         message << "TesselationCtrlInfo: "
2899                                                         << program->getShaderInfo(SHADERTYPE_TESSELLATION_CONTROL).infoLog << "\n"
2900                                                         << "TesselationCtrlSource: "
2901                                                         << program->getShader(SHADERTYPE_TESSELLATION_CONTROL)->getSource() << "\n";
2902                                 if (program->hasShader(SHADERTYPE_TESSELLATION_EVALUATION))
2903                                         message << "TesselationEvalInfo: "
2904                                                         << program->getShaderInfo(SHADERTYPE_TESSELLATION_EVALUATION).infoLog << "\n"
2905                                                         << "TesselationEvalSource: "
2906                                                         << program->getShader(SHADERTYPE_TESSELLATION_EVALUATION)->getSource() << "\n";
2907                                 if (program->hasShader(SHADERTYPE_GEOMETRY))
2908                                         message << "GeometryInfo: " << program->getShaderInfo(SHADERTYPE_GEOMETRY).infoLog << "\n"
2909                                                         << "GeometrySource: " << program->getShader(SHADERTYPE_GEOMETRY)->getSource() << "\n";
2910                                 if (program->hasShader(SHADERTYPE_FRAGMENT))
2911                                         message << "FragmentInfo: " << program->getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
2912                                                         << "FragmentSource: " << program->getShader(SHADERTYPE_FRAGMENT)->getSource() << "\n";
2913
2914                                 message << "ProgramInfo: " << program->getProgramInfo().infoLog;
2915
2916                                 m_testCtx.getLog() << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
2917
2918                                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2919                                 return STOP;
2920                         }
2921
2922                         gl.useProgram(program->getProgram());
2923                         GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2924
2925                         ValidationFuncPtr funcPtr = m_validations[v].validationFuncPtr;
2926                         result                                    = (this->*funcPtr)(m_validations[v].outputs);
2927
2928                         if (program)
2929                                 delete program;
2930
2931                         if (!result)
2932                         {
2933                                 m_testCtx.getLog() << tcu::TestLog::Message << "Validation " << v << " failed!"
2934                                                                    << tcu::TestLog::EndMessage;
2935
2936                                 break;
2937                         }
2938                 }
2939         }
2940
2941         if (vbo)
2942         {
2943                 gl.deleteBuffers(1, &vbo);
2944                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
2945         }
2946
2947         if (vao)
2948         {
2949                 gl.deleteVertexArrays(1, &vao);
2950                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
2951         }
2952
2953         if (result)
2954                 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2955         else
2956                 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2957         return STOP;
2958 }
2959
2960 bool SpirvValidationBuiltInVariableDecorationsTest::validComputeFunc(ValidationOutputVec& outputs)
2961 {
2962         DE_UNREF(outputs);
2963
2964         const Functions& gl = m_context.getRenderContext().getFunctions();
2965
2966         GLuint textures[5];
2967
2968         gl.genTextures(5, textures);
2969         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
2970         for (int i = 0; i < 5; ++i)
2971         {
2972                 gl.bindTexture(GL_TEXTURE_2D, textures[i]);
2973                 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
2974                 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8UI, 4, 4);
2975                 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
2976         }
2977
2978         gl.bindImageTexture(0, textures[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI);
2979         GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture");
2980         gl.bindImageTexture(1, textures[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI);
2981         GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture");
2982         gl.bindImageTexture(2, textures[2], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI);
2983         GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture");
2984         gl.bindImageTexture(3, textures[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI);
2985         GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture");
2986         gl.bindImageTexture(4, textures[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI);
2987         GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture");
2988         gl.uniform1i(0, 0);
2989         GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2990         gl.uniform1i(1, 1);
2991         GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2992         gl.uniform1i(2, 2);
2993         GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2994         gl.uniform1i(3, 3);
2995         GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2996         gl.uniform1i(4, 4);
2997         GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2998         gl.dispatchCompute(4, 2, 1);
2999         GLU_EXPECT_NO_ERROR(gl.getError(), "dispatchCompute");
3000
3001         gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3002         GLU_EXPECT_NO_ERROR(gl.getError(), "memoryBarrier");
3003
3004         std::vector<GLubyte> expectedResults[5];
3005         for (int i = 0; i < 5; ++i)
3006         {
3007                 for (int y = 0; y < 4; ++y)
3008                 {
3009                         for (int x = 0; x < 4; ++x)
3010                         {
3011                                 //"uvec3 color0 = uvec3(gl_NumWorkGroups);"
3012                                 if (i == 0)
3013                                 {
3014                                         expectedResults[i].push_back(4);
3015                                         expectedResults[i].push_back(2);
3016                                         expectedResults[i].push_back(1);
3017                                         expectedResults[i].push_back(0xFF);
3018                                 }
3019                                 //"uvec3 color1 = uvec3(gl_WorkGroupSize);"
3020                                 else if (i == 1)
3021                                 {
3022                                         expectedResults[i].push_back(1);
3023                                         expectedResults[i].push_back(2);
3024                                         expectedResults[i].push_back(1);
3025                                         expectedResults[i].push_back(0xFF);
3026                                 }
3027                                 //"uvec3 color2 = uvec3(gl_WorkGroupID);"
3028                                 else if (i == 2)
3029                                 {
3030                                         expectedResults[i].push_back(x);
3031                                         expectedResults[i].push_back(y / 2);
3032                                         expectedResults[i].push_back(0);
3033                                         expectedResults[i].push_back(0xFF);
3034                                 }
3035                                 //"uvec3 color3 = uvec3(gl_LocalInvocationID);"
3036                                 else if (i == 3)
3037                                 {
3038                                         expectedResults[i].push_back(0);
3039                                         expectedResults[i].push_back(y % 2);
3040                                         expectedResults[i].push_back(0);
3041                                         expectedResults[i].push_back(0xFF);
3042                                 }
3043                                 //"uvec3 color4 = uvec3(gl_LocalInvocationIndex);"
3044                                 else if (i == 4)
3045                                 {
3046                                         expectedResults[i].push_back(y % 2);
3047                                         expectedResults[i].push_back(y % 2);
3048                                         expectedResults[i].push_back(y % 2);
3049                                         expectedResults[i].push_back(0xFF);
3050                                 }
3051                         }
3052                 }
3053         }
3054
3055         bool result = true;
3056         for (int i = 0; i < 5; ++i)
3057         {
3058                 gl.bindTexture(GL_TEXTURE_2D, textures[i]);
3059                 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3060
3061                 std::vector<GLubyte> pixels;
3062                 pixels.resize(4 * 4 * 4);
3063                 gl.getTexImage(GL_TEXTURE_2D, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, (GLvoid*)pixels.data());
3064                 GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage");
3065
3066                 if (pixels != expectedResults[i])
3067                 {
3068                         m_testCtx.getLog() << tcu::TestLog::Message << "Invalid image computed [" << i << "]."
3069                                                            << tcu::TestLog::EndMessage;
3070
3071                         result = false;
3072                 }
3073         }
3074
3075         gl.deleteTextures(5, textures);
3076         GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3077
3078         return result;
3079 }
3080
3081 bool SpirvValidationBuiltInVariableDecorationsTest::validPerVertexFragFunc(ValidationOutputVec& outputs)
3082 {
3083         const Functions& gl = m_context.getRenderContext().getFunctions();
3084
3085         const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
3086
3087         GLuint texture;
3088         GLuint fbo;
3089
3090         gl.genTextures(1, &texture);
3091         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3092         gl.bindTexture(GL_TEXTURE_2D, texture);
3093         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3094         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 64, 64);
3095         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
3096
3097         gl.genFramebuffers(1, &fbo);
3098         GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
3099         gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3100         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3101         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3102         GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3103
3104         gl.viewport(0, 0, 64, 64);
3105         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3106
3107         gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3108         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3109
3110         gl.enable(GL_CLIP_DISTANCE0);
3111
3112         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3113         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
3114         gl.clear(GL_COLOR_BUFFER_BIT);
3115         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
3116
3117         gl.enableVertexAttribArray(0);
3118         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3119
3120         gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3121         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3122
3123         gl.drawArrays(GL_TRIANGLES, 0, 3);
3124         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3125
3126         gl.disableVertexAttribArray(0);
3127         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3128
3129         gl.disable(GL_CLIP_DISTANCE0);
3130
3131         bool result = true;
3132         for (int o = 0; o < (signed)outputs.size(); ++o)
3133         {
3134                 GLuint output;
3135                 gl.readPixels(outputs[o].x, outputs[o].y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&output);
3136                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
3137
3138                 if (!commonUtils::compareUintColors(output, outputs[o].value, 2))
3139                 {
3140                         m_testCtx.getLog() << tcu::TestLog::Message << "Invalid output color read at [" << (int)outputs[o].x << "/"
3141                                                            << (int)outputs[o].y << "]. Expected: " << outputs[o].value << ", "
3142                                                            << "Read: " << output << tcu::TestLog::EndMessage;
3143
3144                         result = false;
3145                 }
3146         }
3147
3148         if (fbo)
3149         {
3150                 gl.deleteFramebuffers(1, &fbo);
3151                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3152         }
3153
3154         if (texture)
3155         {
3156                 gl.deleteTextures(1, &texture);
3157                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3158         }
3159
3160         return result;
3161 }
3162
3163 bool SpirvValidationBuiltInVariableDecorationsTest::validPerVertexPointFunc(ValidationOutputVec& outputs)
3164 {
3165         const Functions& gl = m_context.getRenderContext().getFunctions();
3166
3167         const GLfloat vertices[] = { -0.3f, -0.3f, 0.0f, 0.0f, -0.3f, 0.0f, 0.3f, -0.3f, 0.0f };
3168
3169         GLuint texture;
3170         GLuint fbo;
3171
3172         gl.genTextures(1, &texture);
3173         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3174         gl.bindTexture(GL_TEXTURE_2D, texture);
3175         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3176         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 128, 128);
3177         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
3178
3179         gl.genFramebuffers(1, &fbo);
3180         GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
3181         gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3182         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3183         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3184         GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3185
3186         gl.viewport(0, 0, 128, 128);
3187         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3188
3189         gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3190         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3191
3192         gl.enable(GL_CLIP_DISTANCE0);
3193         gl.enable(GL_PROGRAM_POINT_SIZE);
3194
3195         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3196         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
3197         gl.clear(GL_COLOR_BUFFER_BIT);
3198         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
3199
3200         gl.enableVertexAttribArray(0);
3201         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3202
3203         gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3204         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3205
3206         gl.drawArraysInstanced(GL_POINTS, 0, 3, 3);
3207         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3208
3209         gl.disableVertexAttribArray(0);
3210         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3211
3212         gl.disable(GL_PROGRAM_POINT_SIZE);
3213         gl.disable(GL_CLIP_DISTANCE0);
3214
3215         bool result = true;
3216         for (int o = 0; o < (signed)outputs.size(); ++o)
3217         {
3218                 GLuint output;
3219                 gl.readPixels(outputs[o].x, outputs[o].y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&output);
3220                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
3221
3222                 if (!commonUtils::compareUintColors(output, outputs[o].value, 2))
3223                 {
3224                         m_testCtx.getLog() << tcu::TestLog::Message << "Invalid output color read at [" << (int)outputs[o].x << "/"
3225                                                            << (int)outputs[o].y << "]. Expected: " << outputs[o].value << ", "
3226                                                            << "Read: " << output << tcu::TestLog::EndMessage;
3227
3228                         result = false;
3229                 }
3230         }
3231
3232         if (fbo)
3233         {
3234                 gl.deleteFramebuffers(1, &fbo);
3235                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3236         }
3237
3238         if (texture)
3239         {
3240                 gl.deleteTextures(1, &texture);
3241                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3242         }
3243
3244         return result;
3245 }
3246
3247 bool SpirvValidationBuiltInVariableDecorationsTest::validTesselationGeometryFunc(ValidationOutputVec& outputs)
3248 {
3249         const Functions& gl = m_context.getRenderContext().getFunctions();
3250
3251         const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
3252
3253         GLuint texture;
3254         GLuint fbo;
3255
3256         gl.genTextures(1, &texture);
3257         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3258         gl.bindTexture(GL_TEXTURE_2D_ARRAY, texture);
3259         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3260         gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 64, 64, 2);
3261         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
3262
3263         gl.genFramebuffers(1, &fbo);
3264         GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
3265         gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3266         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3267         gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
3268         GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3269
3270         gl.viewportIndexedf(0, 0.0f, 0.0f, 32.0f, 64.0f);
3271         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewportIndexed");
3272
3273         gl.viewportIndexedf(1, 32.0f, 0.0f, 32.0f, 64.0f);
3274         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewportIndexed");
3275
3276         gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3277         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3278
3279         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3280         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
3281         gl.clear(GL_COLOR_BUFFER_BIT);
3282         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
3283
3284         gl.enableVertexAttribArray(0);
3285         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3286
3287         gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3288         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3289
3290         gl.patchParameteri(GL_PATCH_VERTICES, 3);
3291         gl.drawArrays(GL_PATCHES, 0, 3);
3292         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3293
3294         gl.disableVertexAttribArray(0);
3295         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3296
3297         gl.viewport(0, 0, 128, 64);
3298         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3299
3300         std::vector<GLuint> pixels;
3301         pixels.resize(64 * 64 * 2);
3302         gl.getTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)pixels.data());
3303         GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage");
3304
3305         bool result = true;
3306         for (int o = 0; o < (signed)outputs.size(); ++o)
3307         {
3308                 GLuint output = pixels[(outputs[o].x + outputs[o].y * 64) + outputs[o].z * 64 * 64];
3309
3310                 if (!commonUtils::compareUintColors(output, outputs[o].value, 2))
3311                 {
3312                         m_testCtx.getLog() << tcu::TestLog::Message << "Invalid output color read at [" << (int)outputs[o].x << "/"
3313                                                            << (int)outputs[o].y << "/" << (int)outputs[o].z << "]. Expected: " << outputs[o].value
3314                                                            << ", "
3315                                                            << "Read: " << output << tcu::TestLog::EndMessage;
3316
3317                         result = false;
3318                 }
3319         }
3320
3321         if (fbo)
3322         {
3323                 gl.deleteFramebuffers(1, &fbo);
3324                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3325         }
3326
3327         if (texture)
3328         {
3329                 gl.deleteTextures(1, &texture);
3330                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3331         }
3332
3333         return result;
3334 }
3335
3336 bool SpirvValidationBuiltInVariableDecorationsTest::validMultiSamplingFunc(ValidationOutputVec& outputs)
3337 {
3338         const Functions& gl = m_context.getRenderContext().getFunctions();
3339
3340         const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
3341
3342         GLuint textureMS;
3343         GLuint texture;
3344         GLuint fboMS;
3345         GLuint fbo;
3346
3347         gl.genTextures(1, &textureMS);
3348         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3349         gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureMS);
3350         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3351         gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 32, 32, GL_TRUE);
3352         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2DMultisample");
3353
3354         gl.genTextures(1, &texture);
3355         GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3356         gl.bindTexture(GL_TEXTURE_2D, texture);
3357         GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3358         gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32);
3359         GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
3360
3361         gl.genFramebuffers(1, &fboMS);
3362         GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
3363         gl.bindFramebuffer(GL_FRAMEBUFFER, fboMS);
3364         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3365         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureMS, 0);
3366         GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3367
3368         gl.genFramebuffers(1, &fbo);
3369         GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
3370         gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3371         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3372         gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3373         GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3374
3375         gl.bindFramebuffer(GL_FRAMEBUFFER, fboMS);
3376         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3377
3378         gl.viewport(0, 0, 32, 32);
3379         GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3380
3381         gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3382         GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3383
3384         gl.enable(GL_CLIP_DISTANCE0);
3385
3386         gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3387         GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
3388         gl.clear(GL_COLOR_BUFFER_BIT);
3389         GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
3390
3391         gl.enableVertexAttribArray(0);
3392         GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3393
3394         gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3395         GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3396
3397         gl.drawArrays(GL_TRIANGLES, 0, 3);
3398         GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3399
3400         gl.disableVertexAttribArray(0);
3401         GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3402
3403         gl.disable(GL_CLIP_DISTANCE0);
3404
3405         gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fboMS);
3406         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3407         gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3408         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3409
3410         gl.blitFramebuffer(0, 0, 32, 32, 0, 0, 32, 32, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3411         GLU_EXPECT_NO_ERROR(gl.getError(), "blitFramebuffer");
3412
3413         gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3414         GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3415
3416         const int epsilon = 2;
3417         bool result = true;
3418         for (int o = 0; o < (signed)outputs.size(); ++o)
3419         {
3420                 GLuint output;
3421                 gl.readPixels(outputs[o].x, outputs[o].y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&output);
3422                 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
3423
3424                 // The fragment shader for this case is rendering to a 2-sample FBO discarding
3425                 // sample 0 and rendering 100% green to sample 1, so we expect a green output.
3426                 // However, because sample locations may not be the same across implementations,
3427                 // and that can influence their weights during the multisample resolve,
3428                 // we can only check that there has to be some green in the output (since we know
3429                 // that we have a green sample being selected) and that the level of green is not
3430                 // 100% (since we know that pixel coverage is not 100% because we are
3431                 // discarding one of the samples).
3432
3433                 int r1  = (output & 0xFF);
3434                 int g1  = ((output >> 8) & 0xFF);
3435                 int b1  = ((output >> 16) & 0xFF);
3436                 int a1  = ((output >> 24) & 0xFF);
3437
3438                 int r2  = (outputs[o].value & 0xFF);
3439                 int b2  = ((outputs[o].value >> 16) & 0xFF);
3440                 int a2  = ((outputs[o].value >> 24) & 0xFF);
3441
3442                 if (r1 < r2 - epsilon || r1 > r2 + epsilon ||
3443                     g1 == 0x00 || g1 == 0xFF ||
3444                     b1 < b2 - epsilon || b1 > b2 + epsilon ||
3445                     a1 < a2 - epsilon || a1 > a2 + epsilon)
3446                 {
3447                         m_testCtx.getLog() << tcu::TestLog::Message << "Invalid output color read at [" << (int)outputs[o].x << "/"
3448                                                            << (int)outputs[o].y << "]. Expected 0xff00xx00, with xx anything but ff or 00. "
3449                                                            << "Read: " << std::hex << output << tcu::TestLog::EndMessage;
3450
3451                         result = false;
3452                 }
3453         }
3454
3455         if (fboMS)
3456         {
3457                 gl.deleteFramebuffers(1, &fboMS);
3458                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3459         }
3460
3461         if (fbo)
3462         {
3463                 gl.deleteFramebuffers(1, &fbo);
3464                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3465         }
3466
3467         if (textureMS)
3468         {
3469                 gl.deleteTextures(1, &texture);
3470                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3471         }
3472
3473         if (texture)
3474         {
3475                 gl.deleteTextures(1, &texture);
3476                 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3477         }
3478
3479         return result;
3480 }
3481
3482 /** Constructor.
3483  *
3484  *  @param context     Rendering context
3485  *  @param name        Test name
3486  *  @param description Test description
3487  */
3488 SpirvValidationCapabilitiesTest::SpirvValidationCapabilitiesTest(deqp::Context& context)
3489         : TestCase(context, "spirv_validation_capabilities_test", "Test verifies if Spir-V capabilities works as expected.")
3490 {
3491         /* Left blank intentionally */
3492 }
3493
3494 /** Stub init method */
3495 void SpirvValidationCapabilitiesTest::init()
3496 {
3497         ShaderStage computeStage;
3498         computeStage.source = ComputeSource("#version 450\n"
3499                                                                                 "\n"
3500                                                                                 "layout (local_size_x = 1, local_size_y = 2, local_size_z = 1) in;\n"
3501                                                                                 "\n"
3502                                                                                 "layout (location = 0, rgba8) uniform image2DMS img0;\n"
3503                                                                                 "layout (location = 1, rgba8) uniform image2DMSArray img1;\n"
3504                                                                                 "layout (location = 2, rgba8) uniform image2DRect img2;\n"
3505                                                                                 "layout (location = 3, rgba8) uniform imageCube img3;\n"
3506                                                                                 "layout (location = 4, rgba8) uniform imageCubeArray img4;\n"
3507                                                                                 "layout (location = 5, rgba8) uniform imageBuffer img5;\n"
3508                                                                                 "layout (location = 6, rgba8) uniform image2D img6;\n"
3509                                                                                 "layout (location = 7, rgba8) uniform image1D img7;\n"
3510                                                                                 "layout (location = 8) uniform writeonly image1D img8;\n"
3511                                                                                 "layout (location = 9, rg32f) uniform image1D img9;\n"
3512                                                                                 "layout (location = 10) uniform sampler2DRect img10;\n"
3513                                                                                 "layout (location = 11) uniform samplerCubeArray img11;\n"
3514                                                                                 "layout (location = 12) uniform samplerBuffer img12;\n"
3515                                                                                 "layout (location = 13) uniform sampler1D img13;\n"
3516                                                                                 "layout (location = 14) uniform sampler2D img14;\n"
3517                                                                                 "\n"
3518                                                                                 "layout (binding = 0) uniform atomic_uint atCounter;\n"
3519                                                                                 "\n"
3520                                                                                 "void main()\n"
3521                                                                                 "{\n"
3522                                                                                 "    ivec2 size = imageSize(img6);\n"
3523                                                                                 "    ivec3 point = ivec3(gl_GlobalInvocationID);\n"
3524                                                                                 "    imageStore(img0, point.xy, 0, vec4(0));\n"
3525                                                                                 "    imageStore(img1, point, 0, vec4(0));\n"
3526                                                                                 "    imageStore(img2, point.xy, vec4(0));\n"
3527                                                                                 "    imageStore(img3, point, vec4(0));\n"
3528                                                                                 "    imageStore(img4, point, vec4(0));\n"
3529                                                                                 "    imageStore(img5, point.x, vec4(0));\n"
3530                                                                                 "    imageStore(img6, point.xy, vec4(0));\n"
3531                                                                                 "    imageStore(img7, point.x, vec4(0));\n"
3532                                                                                 "    imageStore(img8, point.x, vec4(0));\n"
3533                                                                                 "\n"
3534                                                                                 "    vec3 coord = vec3(0);\n"
3535                                                                                 "    ivec2 offset = ivec2(gl_GlobalInvocationID.xy);\n"
3536                                                                                 "    vec4 color;\n"
3537                                                                                 "    color = textureGather(img10, coord.xy);\n"
3538                                                                                 "    color = textureGather(img11, vec4(0));\n"
3539                                                                                 "    color = texelFetch(img12, point.x);\n"
3540                                                                                 "    color = textureGatherOffset(img14, coord.xy, offset);\n"
3541                                                                                 "    memoryBarrier();\n"
3542                                                                                 "}\n");
3543
3544         computeStage.caps.push_back("Shader");
3545         computeStage.caps.push_back("SampledRect Shader");
3546         computeStage.caps.push_back("SampledCubeArray Shader");
3547         computeStage.caps.push_back("SampledBuffer Shader");
3548         computeStage.caps.push_back("Sampled1D");
3549         computeStage.caps.push_back("ImageRect SampledRect Shader");
3550         computeStage.caps.push_back("Image1D Sampled1D");
3551         computeStage.caps.push_back("ImageCubeArray SampledCubeArray Shader");
3552         computeStage.caps.push_back("ImageBuffer SampledBuffer");
3553         computeStage.caps.push_back("ImageMSArray Shader");
3554         computeStage.caps.push_back("ImageQuery Shader");
3555         computeStage.caps.push_back("ImageGatherExtended Shader");
3556         computeStage.caps.push_back("StorageImageExtendedFormats Shader");
3557         computeStage.caps.push_back("StorageImageWriteWithoutFormat Shader");
3558         computeStage.caps.push_back("AtomicStorage Shader");
3559
3560         ShaderStage vertexStage;
3561         vertexStage.source = VertexSource("#version 450\n"
3562                                                                           "\n"
3563                                                                           "layout (location = 0) in vec3 position;\n"
3564                                                                           "layout (location = 1) in mat4 projMatrix;\n"
3565                                                                           "\n"
3566                                                                           "layout (location = 2, xfb_buffer = 0) out float xfbVal;\n"
3567                                                                           "layout (location = 3) out vec2 texCoord;\n"
3568                                                                           "\n"
3569                                                                           "void main()\n"
3570                                                                           "{\n"
3571                                                                           "    double dval = double(position.x);\n"
3572                                                                           "    gl_Position = vec4(position, 1.0) * projMatrix;\n"
3573                                                                           "    gl_ClipDistance[0] = 0.0;\n"
3574                                                                           "    gl_CullDistance[0] = 0.0;\n"
3575                                                                           "\n"
3576                                                                           "    xfbVal = 1.0;\n"
3577                                                                           "    texCoord = vec2(0, 0);\n"
3578                                                                           "}\n");
3579
3580         vertexStage.caps.push_back("Matrix");
3581         vertexStage.caps.push_back("Shader Matrix");
3582         vertexStage.caps.push_back("Float64");
3583         vertexStage.caps.push_back("ClipDistance Shader");
3584         vertexStage.caps.push_back("CullDistance Shader");
3585         vertexStage.caps.push_back("TransformFeedback Shader");
3586
3587         ShaderStage tessCtrlStage;
3588         tessCtrlStage.source =
3589                 TessellationControlSource("#version 450\n"
3590                                                                   "\n"
3591                                                                   "layout (vertices = 3) out;\n"
3592                                                                   "\n"
3593                                                                   "void main()\n"
3594                                                                   "{\n"
3595                                                                   "    if (gl_InvocationID == 0) {\n"
3596                                                                   "        gl_TessLevelOuter[0] = 1.0;\n"
3597                                                                   "        gl_TessLevelOuter[1] = 1.0;\n"
3598                                                                   "        gl_TessLevelOuter[2] = 1.0;\n"
3599                                                                   "        gl_TessLevelInner[0] = 1.0;\n"
3600                                                                   "    }\n"
3601                                                                   "\n"
3602                                                                   "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
3603                                                                   "    gl_out[gl_InvocationID].gl_PointSize = gl_in[gl_InvocationID].gl_PointSize;\n"
3604                                                                   "}\n");
3605
3606         tessCtrlStage.caps.push_back("Tessellation Shader");
3607         tessCtrlStage.caps.push_back("TessellationPointSize Tessellation");
3608
3609         ShaderStage tessEvalStage;
3610         tessEvalStage.source = TessellationEvaluationSource("#version 450\n"
3611                                                                                                                 "\n"
3612                                                                                                                 "layout (triangles) in;\n"
3613                                                                                                                 "\n"
3614                                                                                                                 "void main()\n"
3615                                                                                                                 "{\n"
3616                                                                                                                 "    gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +\n"
3617                                                                                                                 "                  gl_TessCoord.y * gl_in[1].gl_Position +\n"
3618                                                                                                                 "                  gl_TessCoord.z * gl_in[2].gl_Position;\n"
3619                                                                                                                 "}\n");
3620
3621         ShaderStage geometryStage;
3622         geometryStage.source = GeometrySource("#version 450\n"
3623                                                                                   "\n"
3624                                                                                   "layout (triangles) in;\n"
3625                                                                                   "layout (triangle_strip, max_vertices = 3) out;\n"
3626                                                                                   "\n"
3627                                                                                   "void main()\n"
3628                                                                                   "{\n"
3629                                                                                   "    gl_ViewportIndex = 0;\n"
3630                                                                                   "    for (int i = 0; i < 3; ++i) {\n"
3631                                                                                   "        gl_Position = gl_in[i].gl_Position;\n"
3632                                                                                   "        gl_PointSize = gl_in[i].gl_PointSize;\n"
3633                                                                                   "        EmitStreamVertex(0);\n"
3634                                                                                   "    }\n"
3635                                                                                   "    EndStreamPrimitive(0);\n"
3636                                                                                   "}\n");
3637
3638         geometryStage.caps.push_back("Geometry Shader");
3639         geometryStage.caps.push_back("GeometryPointSize Geometry");
3640         geometryStage.caps.push_back("GeometryStreams Geometry");
3641         geometryStage.caps.push_back("MultiViewport Geometry");
3642
3643         ShaderStage fragmentStage;
3644         fragmentStage.source = FragmentSource("#version 450\n"
3645                                                                                   "\n"
3646                                                                                   "layout (location = 3) in vec2 texCoord;\n"
3647                                                                                   "\n"
3648                                                                                   "layout (location = 0) out vec4 fColor;\n"
3649                                                                                   "\n"
3650                                                                                   "layout (location = 1) uniform sampler2D tex;\n"
3651                                                                                   "\n"
3652                                                                                   "void main()\n"
3653                                                                                   "{\n"
3654                                                                                   "    vec2 p = vec2(gl_SampleID);\n"
3655                                                                                   "    vec2 dx = dFdxFine(p);\n"
3656                                                                                   "\n"
3657                                                                                   "    interpolateAtCentroid(texCoord);"
3658                                                                                   "\n"
3659                                                                                   "    fColor = vec4(1.0);\n"
3660                                                                                   "}\n");
3661
3662         fragmentStage.caps.push_back("Shader");
3663         fragmentStage.caps.push_back("DerivativeControl Shader");
3664         fragmentStage.caps.push_back("SampleRateShading");
3665         fragmentStage.caps.push_back("InterpolationFunction");
3666
3667         ShaderStage dynamicIndexingStage;
3668         dynamicIndexingStage.source = ComputeSource("#version 450\n"
3669                                                                                                 "\n"
3670                                                                                                 "layout (location = 0) uniform sampler2D uniSamp[10];\n"
3671                                                                                                 "layout (location = 10, rgba8) uniform image2D uniImg[10];\n"
3672                                                                                                 "layout (binding = 5) uniform UniData\n"
3673                                                                                                 "{\n"
3674                                                                                                 "   int a[10];\n"
3675                                                                                                 "} uniBuff[10];\n"
3676                                                                                                 "layout (binding = 5) buffer StorageData\n"
3677                                                                                                 "{\n"
3678                                                                                                 "   int a[10];\n"
3679                                                                                                 "} storageBuff[10];\n"
3680                                                                                                 "\n"
3681                                                                                                 "void main()\n"
3682                                                                                                 "{\n"
3683                                                                                                 "    vec2 coord = vec2(0.0);\n"
3684                                                                                                 "    ivec2 point = ivec2(0);\n"
3685                                                                                                 "\n"
3686                                                                                                 "    int ret = 0;\n"
3687                                                                                                 "    for (int i = 0; i < 10; ++i)"
3688                                                                                                 "    {\n"
3689                                                                                                 "        ret = ret + uniBuff[i].a[i] + storageBuff[i].a[i];\n"
3690                                                                                                 "        textureGather(uniSamp[i], coord);\n"
3691                                                                                                 "        imageLoad(uniImg[i], point);\n"
3692                                                                                                 "    }\n"
3693                                                                                                 "    memoryBarrier();\n"
3694                                                                                                 "}\n");
3695
3696         dynamicIndexingStage.caps.push_back("UniformBufferArrayDynamicIndexing");
3697         dynamicIndexingStage.caps.push_back("SampledImageArrayDynamicIndexing");
3698         dynamicIndexingStage.caps.push_back("StorageBufferArrayDynamicIndexing");
3699         dynamicIndexingStage.caps.push_back("StorageImageArrayDynamicIndexing");
3700
3701         Pipeline computePipeline;
3702         computePipeline.push_back(computeStage);
3703
3704         Pipeline standardPipeline;
3705         standardPipeline.push_back(vertexStage);
3706         standardPipeline.push_back(tessCtrlStage);
3707         standardPipeline.push_back(tessEvalStage);
3708         standardPipeline.push_back(geometryStage);
3709         standardPipeline.push_back(fragmentStage);
3710
3711         Pipeline dynamicIndexingPipeline;
3712         dynamicIndexingPipeline.push_back(dynamicIndexingStage);
3713
3714         m_pipelines.push_back(computePipeline);
3715         m_pipelines.push_back(standardPipeline);
3716         m_pipelines.push_back(dynamicIndexingPipeline);
3717
3718         if (m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_int64"))
3719         {
3720                 ShaderStage computeStageExt("GL_ARB_gpu_shader_int64");
3721                 computeStageExt.source = ComputeSource("#version 450\n"
3722                                                                                            "\n"
3723                                                                                            "#extension GL_ARB_gpu_shader_int64 : require\n"
3724                                                                                            "\n"
3725                                                                                            "void main()\n"
3726                                                                                            "{\n"
3727                                                                                            "    int64_t ival = int64_t(gl_GlobalInvocationID.x);\n"
3728                                                                                            "}\n");
3729                 computeStageExt.caps.push_back("Int64");
3730
3731                 Pipeline extPipeline;
3732                 extPipeline.push_back(computeStageExt);
3733
3734                 m_pipelines.push_back(extPipeline);
3735         }
3736
3737         if (m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
3738         {
3739                 {
3740                         ShaderStage computeStageExt("GL_ARB_sparse_texture2");
3741                         computeStageExt.source = ComputeSource("#version 450\n"
3742                                                                                                 "\n"
3743                                                                                                 "#extension GL_ARB_sparse_texture2 : require\n"
3744                                                                                                 "\n"
3745                                                                                                 "layout (location = 0) uniform sampler2D tex;\n"
3746                                                                                                 "\n"
3747                                                                                                 "void main()\n"
3748                                                                                                 "{\n"
3749                                                                                                 "    vec2 p = vec2(0.0);\n"
3750                                                                                                 "\n"
3751                                                                                                 "    vec4 spCol;\n"
3752                                                                                                 "    sparseTextureARB(tex, p, spCol);\n"
3753                                                                                                 "}\n");
3754
3755                         computeStageExt.caps.push_back("SparseResidency");
3756
3757                         Pipeline extPipeline;
3758                         extPipeline.push_back(computeStageExt);
3759
3760                         m_pipelines.push_back(extPipeline);
3761                 }
3762
3763                 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture_clamp"))
3764                 {
3765                         ShaderStage vertexStageExt("GL_ARB_sparse_texture_clamp_vert");
3766                         vertexStageExt.source = VertexSource("#version 450\n"
3767                                                                                                 "\n"
3768                                                                                                 "layout (location = 0) in vec4 pos;\n"
3769                                                                                                 "\n"
3770                                                                                                 "void main()\n"
3771                                                                                                 "{\n"
3772                                                                                                 "    gl_Position = pos;\n"
3773                                                                                                 "}\n");
3774
3775                         ShaderStage fragmentStageExt("GL_ARB_sparse_texture_clamp_frag");
3776                         fragmentStageExt.source = FragmentSource("#version 450\n"
3777                                                                                                          "\n"
3778                                                                                                          "#extension GL_ARB_sparse_texture2 : require\n"
3779                                                                                                          "#extension GL_ARB_sparse_texture_clamp : require\n"
3780                                                                                                          "\n"
3781                                                                                                          "uniform sampler2D tex;\n"
3782                                                                                                          "\n"
3783                                                                                                          "layout (location = 0) out vec4 spCol;\n"
3784                                                                                                          "\n"
3785                                                                                                          "void main()\n"
3786                                                                                                          "{\n"
3787                                                                                                          "    vec2 p = vec2(0.0);\n"
3788                                                                                                          "\n"
3789                                                                                                          "    sparseTextureClampARB(tex, p, 0.5, spCol);\n"
3790                                                                                                          "}\n");
3791
3792                         fragmentStageExt.caps.push_back("MinLod");
3793
3794                         Pipeline extPipeline;
3795                         extPipeline.push_back(vertexStageExt);
3796                         extPipeline.push_back(fragmentStageExt);
3797
3798                         m_pipelines.push_back(extPipeline);
3799                 }
3800         }
3801
3802         if (m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_image_load_formatted"))
3803         {
3804                 ShaderStage computeStageExt("GL_EXT_shader_image_load_formatted");
3805                 computeStageExt.source = ComputeSource("#version 450\n"
3806                                                                                            "\n"
3807                                                                                            "#extension GL_EXT_shader_image_load_formatted : require\n"
3808                                                                                            "\n"
3809                                                                                            "layout (location = 0) uniform image2D img;\n"
3810                                                                                            "\n"
3811                                                                                            "void main()\n"
3812                                                                                            "{\n"
3813                                                                                            "    ivec3 point = ivec3(gl_GlobalInvocationID);\n"
3814                                                                                            "    vec4 color = imageLoad(img, point.xy);\n"
3815                                                                                            "}\n");
3816
3817                 computeStageExt.caps.push_back("StorageImageReadWithoutFormat");
3818
3819                 Pipeline extPipeline;
3820                 extPipeline.push_back(computeStageExt);
3821
3822                 m_pipelines.push_back(extPipeline);
3823         }
3824 }
3825
3826 /** Stub de-init method */
3827 void SpirvValidationCapabilitiesTest::deinit()
3828 {
3829 }
3830
3831 /** Executes test iteration.
3832  *
3833  *  @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
3834  */
3835 tcu::TestNode::IterateResult SpirvValidationCapabilitiesTest::iterate()
3836 {
3837         const Functions& gl = m_context.getRenderContext().getFunctions();
3838
3839         for (int p = 0; p < (signed)m_pipelines.size(); ++p)
3840         {
3841                 ProgramBinaries programBinaries;
3842
3843                 Pipeline& pipeline = m_pipelines[p];
3844                 for (int s = 0; s < (signed)pipeline.size(); ++s)
3845                 {
3846                         ShaderStage& stage = pipeline[s];
3847 #if defined                              DEQP_HAVE_GLSLANG
3848                         stage.binary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), stage.source);
3849                         std::stringstream ssw;
3850                         if (stage.name.empty())
3851                                 ssw << "gl_cts/data/spirv/spirv_validation_capabilities/binary_p" << p << "s" << s << ".nspv";
3852                         else
3853                                 ssw << "gl_cts/data/spirv/spirv_validation_capabilities/" << stage.name << ".nspv";
3854                         commonUtils::writeSpirV(ssw.str().c_str(), stage.binary);
3855 #else  // DEQP_HAVE_GLSLANG
3856                         tcu::Archive&    archive = m_testCtx.getArchive();
3857                         std::stringstream ss;
3858                         if (stage.name.empty())
3859                                 ss << "spirv/spirv_validation_capabilities/binary_p" << p << "s" << s << ".nspv";
3860                         else
3861                                 ss << "spirv/spirv_validation_capabilities/" << stage.name << ".nspv";
3862                         stage.binary = commonUtils::readSpirV(archive.getResource(ss.str().c_str()));
3863 #endif // DEQP_HAVE_GLSLANG
3864                         programBinaries << stage.binary;
3865                 }
3866
3867                 ShaderProgram program(gl, programBinaries);
3868                 if (!program.isOk())
3869                 {
3870                         std::stringstream ssLog;
3871
3872                         ssLog << "Program build failed [" << p << "].\n";
3873                         if (program.hasShader(SHADERTYPE_COMPUTE))
3874                                 ssLog << "Compute: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog << "\n";
3875                         if (program.hasShader(SHADERTYPE_VERTEX))
3876                                 ssLog << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n";
3877                         if (program.hasShader(SHADERTYPE_TESSELLATION_CONTROL))
3878                                 ssLog << "TessellationCtrl: " << program.getShaderInfo(SHADERTYPE_TESSELLATION_CONTROL).infoLog << "\n";
3879                         if (program.hasShader(SHADERTYPE_TESSELLATION_EVALUATION))
3880                                 ssLog << "TessellationEval: " << program.getShaderInfo(SHADERTYPE_TESSELLATION_EVALUATION).infoLog
3881                                           << "\n";
3882                         if (program.hasShader(SHADERTYPE_GEOMETRY))
3883                                 ssLog << "Geometry: " << program.getShaderInfo(SHADERTYPE_GEOMETRY).infoLog << "\n";
3884                         if (program.hasShader(SHADERTYPE_FRAGMENT))
3885                                 ssLog << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n";
3886                         ssLog << "Program: " << program.getProgramInfo().infoLog;
3887
3888                         m_testCtx.getLog() << tcu::TestLog::Message << ssLog.str() << tcu::TestLog::EndMessage;
3889
3890                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3891                         return STOP;
3892                 }
3893
3894 #if defined DEQP_HAVE_SPIRV_TOOLS
3895                 for (int s = 0; s < (signed)pipeline.size(); ++s)
3896                 {
3897                         ShaderStage  stage  = pipeline[s];
3898                         ShaderBinary binary = stage.binary;
3899
3900                         std::string spirVSource;
3901                         glslangUtils::spirvDisassemble(spirVSource, binary.binary);
3902
3903                         for (int c = 0; c < (signed)stage.caps.size(); ++c)
3904                         {
3905                                 std::string spirVSourceCut;
3906                                 int                     foundCount = spirVCapabilityCutOff(spirVSource, spirVSourceCut, stage.caps, c);
3907
3908                                 if (foundCount == 0)
3909                                 {
3910                                         m_testCtx.getLog()
3911                                                 << tcu::TestLog::Message << "OpCapability (" << stage.caps[c] << ") [" << p << "/" << s
3912                                                 << "].\n"
3913                                                 << "Neither capability nor capabilities that depends on this capability has been found."
3914                                                 << tcu::TestLog::EndMessage;
3915                                 }
3916                                 else
3917                                 {
3918                                         // Assemble and validate cut off SpirV source
3919                                         glslangUtils::spirvAssemble(binary.binary, spirVSourceCut);
3920                                         if (glslangUtils::spirvValidate(binary.binary, false))
3921                                         {
3922                                                 m_testCtx.getLog() << tcu::TestLog::Message << "OpCapability (" << stage.caps[c] << ") [" << p
3923                                                                                    << "/" << s << "].\n"
3924                                                                                    << "Validation passed without corresponding OpCapability declared."
3925                                                                                    << tcu::TestLog::EndMessage;
3926                                         }
3927                                 }
3928                         }
3929                 }
3930 #endif // DEQP_HAVE_SPIRV_TOOLS
3931         }
3932
3933         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3934         return STOP;
3935 }
3936
3937 int SpirvValidationCapabilitiesTest::spirVCapabilityCutOff(std::string spirVSrcInput, std::string& spirVSrcOutput,
3938                                                                                                                    CapabilitiesVec& capabilities, int& currentCapability)
3939 {
3940         std::vector<std::string> current = de::splitString(capabilities[currentCapability], ' ');
3941
3942         CapabilitiesVec toDisable;
3943         toDisable.push_back(current[0]);
3944
3945         // Search for capabilities that depends on current one as it should be removed either
3946         for (int cr = 0; cr < (signed)capabilities.size(); ++cr)
3947         {
3948                 std::vector<std::string> split = de::splitString(capabilities[cr], ' ');
3949
3950                 if (split[0] == current[0])
3951                         continue;
3952
3953                 for (int s = 1; s < (signed)split.size(); ++s)
3954                 {
3955                         if (split[s] == current[0])
3956                                 toDisable.push_back(split[0]);
3957                 }
3958         }
3959
3960         // Disable current capability and capabilities that depends on it
3961         int foundCount = 0;
3962         spirVSrcOutput = spirVSrcInput;
3963         for (int d = 0; d < (signed)toDisable.size(); ++d)
3964         {
3965                 std::string searchString = std::string("OpCapability ") + toDisable[d];
3966
3967                 size_t pos = spirVSrcOutput.find(searchString);
3968
3969                 if (pos != std::string::npos)
3970                 {
3971                         foundCount++;
3972                         spirVSrcOutput.erase(pos, searchString.length());
3973                 }
3974         }
3975
3976         return foundCount;
3977 }
3978
3979 /** Constructor.
3980  *
3981  *  @param context Rendering context.
3982  */
3983 GlSpirvTests::GlSpirvTests(deqp::Context& context)
3984         : TestCaseGroup(context, "gl_spirv", "Verify conformance of ARB_gl_spirv implementation")
3985 {
3986 }
3987
3988 /** Initializes the test group contents. */
3989 void GlSpirvTests::init()
3990 {
3991         addChild(new SpirvModulesPositiveTest(m_context));
3992         addChild(new SpirvShaderBinaryMultipleShaderObjectsTest(m_context));
3993         addChild(new SpirvModulesStateQueriesTest(m_context));
3994         addChild(new SpirvModulesErrorVerificationTest(m_context));
3995         addChild(new SpirvGlslToSpirVEnableTest(m_context));
3996         addChild(new SpirvGlslToSpirVBuiltInFunctionsTest(m_context));
3997         addChild(new SpirvGlslToSpirVSpecializationConstantsTest(m_context));
3998         addChild(new SpirvValidationBuiltInVariableDecorationsTest(m_context));
3999         addChild(new SpirvValidationCapabilitiesTest(m_context));
4000 }
4001
4002 } /* gl4cts namespace */