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