1 /*-------------------------------------------------------------------------
2 * OpenGL Conformance Test Suite
3 * -----------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 */ /*-------------------------------------------------------------------*/
26 * \file gl4cGlSpirvTests.cpp
27 * \brief Conformance tests for the GL_ARB_gl_spirv functionality.
28 */ /*-------------------------------------------------------------------*/
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"
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
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
63 namespace glslangUtils
66 #if defined DEQP_HAVE_GLSLANG
68 EShLanguage getGlslangStage(glu::ShaderType type)
70 static const EShLanguage stageMap[] = {
71 EShLangVertex, EShLangFragment, EShLangGeometry, EShLangTessControl, EShLangTessEvaluation, EShLangCompute,
74 return de::getSizedArrayElement<glu::SHADERTYPE_LAST>(stageMap, type);
77 static volatile deSingletonState s_glslangInitState = DE_SINGLETON_STATE_NOT_INITIALIZED;
79 void initGlslang(void*)
82 glslang::InitializeProcess();
88 void prepareGlslang(void)
90 deInitSingleton(&s_glslangInitState, initGlslang, DE_NULL);
93 void getDefaultLimits(TLimits* limits)
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;
106 void getDefaultBuiltInResources(TBuiltInResource* builtin)
108 getDefaultLimits(&builtin->limits);
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;
204 bool compileGlslToSpirV(tcu::TestLog& log, std::string source, glu::ShaderType type, ShaderBinaryDataType* dst)
206 TBuiltInResource builtinRes;
209 getDefaultBuiltInResources(&builtinRes);
211 const EShLanguage shaderStage = getGlslangStage(type);
213 glslang::TShader shader(shaderStage);
214 glslang::TProgram program;
216 const char* src[] = { source.c_str() };
218 shader.setStrings(src, 1);
219 program.addShader(&shader);
221 const int compileRes = shader.parse(&builtinRes, 100, false, EShMsgSpvRules);
224 const int linkRes = program.link(EShMsgSpvRules);
228 const glslang::TIntermediate* const intermediate = program.getIntermediate(shaderStage);
229 glslang::GlslangToSpv(*intermediate, *dst);
235 log << tcu::TestLog::Message << "Program linking error:\n"
236 << program.getInfoLog() << "\n"
239 << tcu::TestLog::EndMessage;
244 log << tcu::TestLog::Message << "Shader compilation error:\n"
245 << shader.getInfoLog() << "\n"
248 << tcu::TestLog::EndMessage;
254 #else // DEQP_HAVE_GLSLANG
256 bool compileGlslToSpirV(tcu::TestLog& log, std::string source, glu::ShaderType type, ShaderBinaryDataType* dst)
263 TCU_THROW(InternalError, "Glslang not available.");
268 #endif // DEQP_HAVE_GLSLANG
270 #if defined DEQP_HAVE_SPIRV_TOOLS
272 void consumer(spv_message_level_t, const char*, const spv_position_t&, const char* m)
274 std::cerr << "error: " << m << std::endl;
277 void spirvAssemble(ShaderBinaryDataType& dst, const std::string& src)
279 spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
281 core.SetMessageConsumer(consumer);
283 if (!core.Assemble(src, &dst))
284 TCU_THROW(InternalError, "Failed to assemble Spir-V source.");
287 void spirvDisassemble(std::string& dst, const ShaderBinaryDataType& src)
289 spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
291 core.SetMessageConsumer(consumer);
293 if (!core.Disassemble(src, &dst))
294 TCU_THROW(InternalError, "Failed to disassemble Spir-V module.");
297 bool spirvValidate(ShaderBinaryDataType& dst, bool throwOnError)
299 spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
302 core.SetMessageConsumer(consumer);
304 if (!core.Validate(dst))
307 TCU_THROW(InternalError, "Failed to validate Spir-V module.");
314 #else //DEQP_HAVE_SPIRV_TOOLS
316 void spirvAssemble(ShaderBinaryDataType& dst, const std::string& src)
321 TCU_THROW(InternalError, "Spirv-tools not available.");
324 void spirvDisassemble(std::string& dst, ShaderBinaryDataType& src)
329 TCU_THROW(InternalError, "Spirv-tools not available.");
332 bool spirvValidate(ShaderBinaryDataType& dst, bool throwOnError)
335 DE_UNREF(throwOnError);
337 TCU_THROW(InternalError, "Spirv-tools not available.");
340 #endif // DEQP_HAVE_SPIRV_TOOLS
342 ShaderBinary makeSpirV(tcu::TestLog& log, ShaderSource source)
346 if (!glslangUtils::compileGlslToSpirV(log, source.source, source.shaderType, &binary.binary))
347 TCU_THROW(InternalError, "Failed to convert GLSL to Spir-V");
349 binary << source.shaderType << "main";
354 /** Verifying if GLSL to SpirV mapping was performed correctly
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
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.
364 bool verifyMappings(std::string glslSource, std::string spirVSource, SpirVMapping& mappings, bool anyOf)
366 std::vector<std::string> spirVSourceLines = de::splitString(spirVSource, '\n');
368 // Iterate through all glsl functions
369 for (SpirVMapping::iterator it = mappings.begin(); it != mappings.end(); it++)
371 int glslCodeCount = 0;
372 int spirVCodeCount = 0;
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;
378 // Count GLSL code occurrences in GLSL source
379 size_t codePosition = glslSource.find(glslCode);
380 while (codePosition != std::string::npos)
383 codePosition = glslSource.find(glslCode, codePosition + 1);
386 if (glslCodeCount > 0)
388 // Count all SpirV code variants occurrences in SpirV source
389 for (int s = 0; s < (signed)it->second.size(); ++s)
391 std::vector<std::string> spirVCodes = de::splitString(it->second[s], ' ');
393 for (int v = 0; v < (signed)spirVSourceLines.size(); ++v)
395 std::vector<std::string> spirVLineCodes = de::splitString(spirVSourceLines[v], ' ');
397 bool matchAll = true;
398 for (int j = 0; j < (signed)spirVCodes.size(); ++j)
401 for (int i = 0; i < (signed)spirVLineCodes.size(); ++i)
403 if (spirVLineCodes[i] == spirVCodes[j])
407 matchAll = matchAll && match;
415 // Check if both counts match
416 if (anyOf && (glslCodeCount > 0 && spirVCodeCount == 0))
418 else if (!anyOf && glslCodeCount != spirVCodeCount)
426 } // namespace glslangUtils
428 namespace commonUtils
431 void writeSpirV(const char* filename, ShaderBinary binary)
433 FILE* file = fopen(filename, "wb");
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)
442 fwrite((void*)&binary.shaderTypes[i], 1, sizeof(ShaderType), file);
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);
452 fwrite((void*)binary.binary.data(), 1, binary.binary.size() * 4, file);
457 ShaderBinary readSpirV(tcu::Resource* resource)
463 // As one binary could be associated with many shader objects it should be stored either a type of each shader
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)
470 resource->read((deUint8*)&binary.shaderTypes[i], sizeof(ShaderType));
475 resource->read(&strLen, 1);
477 binary.shaderEntryPoints[i].resize(strLen);
478 resource->read((deUint8*)binary.shaderEntryPoints[i].data(), strLen);
481 binary.shaderEntryPoints[i] = "main";
484 binary.binary.resize((resource->getSize() - resource->getPosition()) / sizeof(deUint32));
485 resource->read((deUint8*)binary.binary.data(), binary.binary.size() * sizeof(deUint32));
490 /** Replace all occurance of <token> with <text> in <string>
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
496 void replaceToken(const GLchar* token, const GLchar* text, std::string& string)
498 const size_t text_length = strlen(text);
499 const size_t token_length = strlen(token);
501 size_t token_position;
502 while ((token_position = string.find(token, 0)) != std::string::npos)
504 string.replace(token_position, token_length, text, text_length);
508 bool compareUintColors(const GLuint inColor, const GLuint refColor, const int epsilon)
510 int r1 = (inColor & 0xFF);
511 int g1 = ((inColor >> 8) & 0xFF);
512 int b1 = ((inColor >> 16) & 0xFF);
513 int a1 = ((inColor >> 24) & 0xFF);
515 int r2 = (refColor & 0xFF);
516 int g2 = ((refColor >> 8) & 0xFF);
517 int b2 = ((refColor >> 16) & 0xFF);
518 int a2 = ((refColor >> 24) & 0xFF);
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)
529 void checkGlSpirvSupported(deqp::Context& m_context)
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");
534 if ((!is_at_least_gl_46) && (!is_arb_gl_spirv))
535 TCU_THROW(NotSupportedError, "GL_ARB_gl_spirv is not supported");
537 } // namespace commonUtils
541 * @param context Rendering context
542 * @param name Test name
543 * @param description Test description
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")
549 /* Left blank intentionally */
552 /** Stub init method */
553 void SpirvModulesPositiveTest::init()
555 commonUtils::checkGlSpirvSupported(m_context);
557 m_vertex = "#version 450\n"
559 "layout (location = 0) in vec3 position;\n"
561 "layout (location = 1) out vec4 vColor;\n"
565 " gl_Position = vec4(position, 1.0);\n"
566 " vColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
569 m_tesselationCtrl = "#version 450\n"
571 "layout (vertices = 3) out;\n"
573 "layout (location = 1) in vec4 vColor[];\n"
574 "layout (location = 2) out vec4 tcColor[];\n"
578 " tcColor[gl_InvocationID] = vColor[gl_InvocationID];\n"
579 " tcColor[gl_InvocationID].r = 1.0;\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"
588 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
591 m_tesselationEval = "#version 450\n"
593 "layout (triangles) in;\n"
595 "layout (location = 2) in vec4 tcColor[];\n"
596 "layout (location = 3) out vec4 teColor;\n"
600 " teColor = tcColor[0];\n"
601 " teColor.g = 1.0;\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"
608 m_geometry = "#version 450\n"
610 "layout (triangles) in;\n"
611 "layout (triangle_strip, max_vertices = 3) out;\n"
613 "layout (location = 3) in vec4 teColor[];\n"
614 "layout (location = 4) out vec4 gColor;\n"
618 " gColor = teColor[0];\n"
621 " for (int i = 0; i < 3; ++i) {\n"
622 " gl_Position = gl_in[i].gl_Position;\n"
628 m_fragment = "#version 450\n"
630 "layout (location = 4) in vec4 gColor;\n"
631 "layout (location = 0) out vec4 fColor;\n"
635 " fColor = gColor;\n"
638 const Functions& gl = m_context.getRenderContext().getFunctions();
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");
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");
654 gl.viewport(0, 0, 32, 32);
655 GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
658 /** Stub de-init method */
659 void SpirvModulesPositiveTest::deinit()
661 const Functions& gl = m_context.getRenderContext().getFunctions();
665 gl.deleteFramebuffers(1, &m_fbo);
666 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
670 gl.deleteTextures(1, &m_texture);
671 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
675 /** Executes test iteration.
677 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
679 tcu::TestNode::IterateResult SpirvModulesPositiveTest::iterate()
681 const Functions& gl = m_context.getRenderContext().getFunctions();
683 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
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");
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");
697 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
698 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
707 deUint32 outputs[ITERATE_LAST];
708 for (int it = ITERATE_GLSL; it < ITERATE_LAST; ++it)
710 ShaderProgram* program = DE_NULL;
711 if (it == ITERATE_GLSL)
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);
721 else if (it == ITERATE_SPIRV)
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
745 if (!program->isOk())
747 m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
748 << "Vertex: " << program->getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
750 << "TesselationCtrl: " << program->getShaderInfo(SHADERTYPE_TESSELLATION_CONTROL).infoLog
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;
762 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
766 gl.useProgram(program->getProgram());
767 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
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");
774 gl.enableVertexAttribArray(0);
775 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
777 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
778 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
780 gl.patchParameteri(GL_PATCH_VERTICES, 3);
781 gl.drawArrays(GL_PATCHES, 0, 3);
782 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
784 gl.disableVertexAttribArray(0);
785 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
787 gl.readPixels(16, 16, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&outputs[it]);
788 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
796 gl.deleteBuffers(1, &vbo);
797 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
802 gl.deleteVertexArrays(1, &vao);
803 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
806 if ((outputs[ITERATE_GLSL] & outputs[ITERATE_SPIRV]) != 0xFFFFFFFF)
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;
815 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
821 * @param context Rendering context
822 * @param name Test name
823 * @param description Test description
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.")
829 /* Left blank intentionally */
832 /** Stub init method */
833 void SpirvShaderBinaryMultipleShaderObjectsTest::init()
835 commonUtils::checkGlSpirvSupported(m_context);
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"
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"
887 "%mainv = OpFunction %void None %3\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"
899 "%mainf = OpFunction %void None %3\n"
901 "OpStore %fColor %fVec4_1\n"
906 /** Stub init method */
907 void SpirvShaderBinaryMultipleShaderObjectsTest::deinit()
911 /** Executes test iteration.
913 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
915 tcu::TestNode::IterateResult SpirvShaderBinaryMultipleShaderObjectsTest::iterate()
917 const Functions& gl = m_context.getRenderContext().getFunctions();
919 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
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");
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");
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");
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");
950 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
951 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
953 #if defined DEQP_HAVE_SPIRV_TOOLS
955 binary << SHADERTYPE_VERTEX << "mainv";
956 binary << SHADERTYPE_FRAGMENT << "mainf";
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
966 ProgramBinaries binaries;
968 ShaderProgram program(gl, binaries);
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;
977 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
981 gl.viewport(0, 0, 32, 32);
982 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
984 gl.useProgram(program.getProgram());
985 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
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");
992 gl.enableVertexAttribArray(0);
993 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
995 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
996 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
998 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 3);
999 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
1001 gl.disableVertexAttribArray(0);
1002 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
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");
1013 gl.deleteBuffers(1, &vbo);
1014 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
1019 gl.deleteVertexArrays(1, &vao);
1020 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
1025 gl.deleteFramebuffers(1, &fbo);
1026 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
1031 gl.deleteTextures(1, &texture);
1032 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
1035 if (insidePixel == 0xFFFFFFFF && outsidePixel == 0xFF000000)
1036 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
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;
1043 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1051 * @param context Rendering context
1052 * @param name Test name
1053 * @param description Test description
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.")
1059 /* Left blank intentionally */
1062 /** Stub init method */
1063 void SpirvModulesStateQueriesTest::init()
1065 commonUtils::checkGlSpirvSupported(m_context);
1067 m_vertex = "#version 450\n"
1069 "layout (location = 0) in vec4 position;\n"
1070 "layout (location = 20) uniform vec4 extPosition;\n"
1071 "layout (binding = 5) uniform ComponentsBlock\n"
1079 " gl_Position = position + extPosition + components.c1 + vec4(components.c2, 0.0, 0.0);\n"
1083 /** Stub de-init method */
1084 void SpirvModulesStateQueriesTest::deinit()
1088 /** Executes test iteration.
1090 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1092 tcu::TestNode::IterateResult SpirvModulesStateQueriesTest::iterate()
1094 const Functions& gl = m_context.getRenderContext().getFunctions();
1096 ProgramBinaries binaries;
1097 ShaderBinary vertexBinary;
1099 #if defined DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1101 vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
1103 // Disassemble Spir-V module
1105 glslangUtils::spirvDisassemble(output, vertexBinary.binary);
1107 // Remove name reflection for defined variables
1108 std::vector<std::string> lines = de::splitString(output, '\n');
1110 for (int i = 0; i < (signed)lines.size(); ++i)
1112 if (lines[i].find("OpName %position") != std::string::npos)
1114 if (lines[i].find("OpName %extPosition") != std::string::npos)
1116 if (lines[i].find("OpName %ComponentsBlock") != std::string::npos)
1118 if (lines[i].find("OpName %components") != std::string::npos)
1121 input.append(lines[i] + "\n");
1124 // Assemble Spir-V module
1125 vertexBinary.binary.clear();
1126 glslangUtils::spirvAssemble(vertexBinary.binary, input);
1127 glslangUtils::spirvValidate(vertexBinary.binary, true);
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
1134 binaries << vertexBinary;
1135 ShaderProgram program(gl, binaries);
1137 Shader* shader = program.getShader(SHADERTYPE_VERTEX);
1139 // 1) Check compile status
1140 if (!program.getShaderInfo(SHADERTYPE_VERTEX).compileOk)
1142 m_testCtx.getLog() << tcu::TestLog::Message << "Check compile status failed.\n"
1143 << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
1145 << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
1147 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1151 // 2) Check if SPIR_V_BINARY_ARB state is TRUE
1153 gl.getShaderiv(shader->getShader(), GL_SPIR_V_BINARY_ARB, &shaderState);
1154 GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
1155 if (shaderState != GL_TRUE)
1157 m_testCtx.getLog() << tcu::TestLog::Message << "SPIR_V_BINARY_ARB state set to FALSE. Expected TRUE."
1158 << tcu::TestLog::EndMessage;
1160 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
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");
1172 gl.getProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &programState[1]);
1173 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
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");
1180 gl.getProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &programState[3]);
1181 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1183 bool programStateResult = true;
1184 for (int i = 0; i < 4; ++i)
1186 if (programState[i] != expectedValues[i])
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;
1196 if (!programStateResult)
1198 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
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");
1208 gl.getShaderiv(shader->getShader(), GL_SPIR_V_BINARY_ARB, &shaderState);
1209 GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
1210 if (shaderState != GL_FALSE)
1212 m_testCtx.getLog() << tcu::TestLog::Message << "SPIR_V_BINARY_ARB state set to TRUE. Expected FALSE."
1213 << tcu::TestLog::EndMessage;
1215 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1219 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1225 * @param context Rendering context
1226 * @param name Test name
1227 * @param description Test description
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.")
1233 /* Left blank intentionally */
1236 /** Stub init method */
1237 void SpirvModulesErrorVerificationTest::init()
1239 commonUtils::checkGlSpirvSupported(m_context);
1241 const Functions& gl = m_context.getRenderContext().getFunctions();
1243 m_vertex = "#version 450\n"
1245 "layout (location = 0) in vec4 position;\n"
1249 " gl_Position = position;\n"
1252 m_glslShaderId = gl.createShader(GL_VERTEX_SHADER);
1253 GLU_EXPECT_NO_ERROR(gl.getError(), "createShader");
1255 m_spirvShaderId = gl.createShader(GL_VERTEX_SHADER);
1256 GLU_EXPECT_NO_ERROR(gl.getError(), "createShader");
1258 m_programId = gl.createProgram();
1259 GLU_EXPECT_NO_ERROR(gl.getError(), "createProgram");
1261 gl.genTextures(1, &m_textureId);
1262 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
1265 /** Stub de-init method */
1266 void SpirvModulesErrorVerificationTest::deinit()
1268 const Functions& gl = m_context.getRenderContext().getFunctions();
1270 gl.deleteTextures(1, &m_textureId);
1271 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
1273 gl.deleteProgram(m_programId);
1274 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteProgram");
1276 gl.deleteShader(m_glslShaderId);
1277 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteShader");
1279 gl.deleteShader(m_spirvShaderId);
1280 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteShader");
1283 /** Executes test iteration.
1285 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1287 tcu::TestNode::IterateResult SpirvModulesErrorVerificationTest::iterate()
1289 const Functions& gl = m_context.getRenderContext().getFunctions();
1291 const char* shaderSrc = m_vertex.c_str();
1292 const int shaderLen = m_vertex.length();
1294 ShaderBinary vertexBinary;
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
1303 gl.shaderSource(m_glslShaderId, 1, &shaderSrc, &shaderLen);
1304 GLU_EXPECT_NO_ERROR(gl.getError(), "shaderSource");
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");
1310 gl.attachShader(m_programId, m_spirvShaderId);
1311 GLU_EXPECT_NO_ERROR(gl.getError(), "attachShader");
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)
1322 << tcu::TestLog::Message
1323 << "Unexpected error code generated by CompileShader [1]. Expected INVALID_OPERATION, generated: "
1324 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1326 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
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)
1337 << tcu::TestLog::Message
1338 << "Unexpected error code generated by SpecializeShader [2]. Expected INVALID_VALUE, generated: "
1339 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1341 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
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)
1352 << tcu::TestLog::Message
1353 << "Unexpected error code generated by SpecializeShader [3]. Expected INVALID_OPERATION, generated: "
1354 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1356 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
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)
1367 << tcu::TestLog::Message
1368 << "Unexpected error code generated by SpecializeShader [4]. Expected INVALID_OPERATION, generated: "
1369 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1371 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
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)
1382 << tcu::TestLog::Message
1383 << "Unexpected error code generated by SpecializeShader [5]. Expected INVALID_VALUE, generated: "
1384 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1386 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
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)
1400 << tcu::TestLog::Message
1401 << "Unexpected error code generated by SpecializeShader [6]. Expected INVALID_VALUE, generated: "
1402 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1404 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
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)
1415 gl.getProgramiv(m_programId, GL_LINK_STATUS, &linkStatus);
1416 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1418 if (linkStatus != 0)
1420 m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected result of LinkProgram [7]."
1421 << tcu::TestLog::EndMessage;
1423 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
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");
1433 gl.specializeShader(m_spirvShaderId, "main", 0, DE_NULL, DE_NULL);
1434 err = gl.getError();
1435 if (err != GL_INVALID_OPERATION)
1438 << tcu::TestLog::Message
1439 << "Unexpected error code generated by SpecializeShader [8]. Expected INVALID_OPERATION, generated: "
1440 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1442 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
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");
1451 gl.attachShader(m_programId, m_glslShaderId);
1452 GLU_EXPECT_NO_ERROR(gl.getError(), "attachShader");
1454 gl.linkProgram(m_programId);
1455 err = gl.getError();
1456 if (err == GL_NO_ERROR)
1459 gl.getProgramiv(m_programId, GL_LINK_STATUS, &linkStatus);
1460 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1462 if (linkStatus != 0)
1464 m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected result of LinkProgram [9]."
1465 << tcu::TestLog::EndMessage;
1467 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1472 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1478 * @param context Rendering context
1479 * @param name Test name
1480 * @param description Test description
1482 SpirvGlslToSpirVEnableTest::SpirvGlslToSpirVEnableTest(deqp::Context& context)
1483 : TestCase(context, "spirv_glsl_to_spirv_enable_test", "Test verifies if glsl supports Spir-V features.")
1485 /* Left blank intentionally */
1488 /** Stub init method */
1489 void SpirvGlslToSpirVEnableTest::init()
1491 commonUtils::checkGlSpirvSupported(m_context);
1493 m_vertex = "#version 450\n"
1496 " layout (location = 0) in vec4 enabled;\n"
1498 " layout (location = 0) in vec4 notEnabled;\n"
1499 "#endif // GL_SPIRV\n"
1503 " gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n"
1507 /** Stub de-init method */
1508 void SpirvGlslToSpirVEnableTest::deinit()
1512 /** Executes test iteration.
1514 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1516 tcu::TestNode::IterateResult SpirvGlslToSpirVEnableTest::iterate()
1519 #if defined DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1521 const Functions& gl = m_context.getRenderContext().getFunctions();
1523 ProgramBinaries binaries;
1524 ShaderBinary vertexBinary =
1525 glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
1526 binaries << vertexBinary;
1527 ShaderProgram spirvProgram(gl, binaries);
1529 std::string spirvSource;
1530 glslangUtils::spirvDisassemble(spirvSource, vertexBinary.binary);
1532 if (spirvSource.find("OpName %enabled") == std::string::npos)
1534 m_testCtx.getLog() << tcu::TestLog::Message << "GL_SPIRV not defined. Spir-V source:\n"
1535 << spirvSource.c_str() << tcu::TestLog::EndMessage;
1537 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1541 if (!spirvProgram.isOk())
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;
1548 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1552 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1554 #else // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1556 TCU_THROW(InternalError, "Either glslang or spirv-tools not available.");
1558 #endif // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1563 enum EShaderTemplate
1571 struct FunctionMapping
1573 EShaderTemplate shaderTemplate;
1574 std::string glslFunc;
1575 std::string glslArgs;
1576 std::string spirVFunc;
1578 FunctionMapping() : shaderTemplate(COMPUTE_TEMPLATE), glslFunc(""), glslArgs(""), spirVFunc("")
1582 FunctionMapping(EShaderTemplate shaderTemplate_, std::string glslFunc_, std::string glslArgs_,
1583 std::string spirVFunc_)
1584 : shaderTemplate(shaderTemplate_), glslFunc(glslFunc_), glslArgs(glslArgs_), spirVFunc(spirVFunc_)
1591 * @param context Rendering context
1592 * @param name Test name
1593 * @param description Test description
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.")
1599 /* Left blank intentionally */
1602 /** Stub init method */
1603 void SpirvGlslToSpirVBuiltInFunctionsTest::init()
1605 commonUtils::checkGlSpirvSupported(m_context);
1609 m_commonVertex = "#version 450\n"
1611 "layout (location = 0) in vec3 position;\n"
1612 "layout (location = 1) out vec2 texCoord;\n"
1616 " texCoord = vec2(0.0, 0.0);\n"
1617 " gl_Position = vec4(position, 1.0);\n"
1620 m_commonTessEval = "#version 450\n"
1622 "layout (triangles) in;\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"
1633 // Angle Trigonometry
1634 m_sources.push_back(ComputeSource("#version 450\n"
1636 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1640 " float tmp0 = 0.5;\n"
1642 " value = radians(tmp0) +\n"
1643 " degrees(tmp0) +\n"
1659 // To avoid duplicated mappings create additional shaders for specific functions
1660 const std::string strAnlgeVariants = "#version 450\n"
1662 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1666 " float tmp0 = 0.5;\n"
1667 " float value = <ATANGENT>;\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);
1674 m_sources.push_back(ComputeSource(strATan));
1675 m_sources.push_back(ComputeSource(strATan2));
1678 m_sources.push_back(ComputeSource("#version 450\n"
1680 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1687 " value = pow(tmp1, tmp0) +\n"
1693 " inversesqrt(tmp1);\n"
1696 // Common (without bit operations)
1697 m_sources.push_back(ComputeSource("#version 450\n"
1699 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\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"
1714 " roundEven(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"
1732 // To avoid duplicated mappings create additional shaders for specific functions
1733 const std::string strBitsOpsVariants = "#version 450\n"
1735 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1740 " int ival = 0x43800000;\n"
1741 " uint uval = 0x43800000;\n"
1742 " value = <BITS_TO_FLOAT>;\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);
1749 m_sources.push_back(ComputeSource(strIntBits));
1750 m_sources.push_back(ComputeSource(strUIntBits));
1752 // Float Pack Unpack
1753 m_sources.push_back(ComputeSource("#version 450\n"
1755 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\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"
1777 m_sources.push_back(ComputeSource("#version 450\n"
1779 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\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);"
1798 m_sources.push_back(ComputeSource("#version 450\n"
1800 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1804 " mat2 m2val1 = mat2(\n"
1808 " mat2 m2val2 = mat2(\n"
1812 " vec2 v2val1 = vec2(0.3, 0.4);\n"
1813 " vec2 v2val2 = vec2(0.5, 0.6);\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"
1822 // Vector Relational
1823 m_sources.push_back(ComputeSource("#version 450\n"
1825 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\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"
1843 m_sources.push_back(ComputeSource("#version 450\n"
1845 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\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"
1865 m_sources.push_back(
1866 FragmentSource("#version 450\n"
1868 "layout (location = 0) out vec4 fragColor;\n"
1870 "layout (location = 1) uniform sampler2D tex2D;\n"
1871 "layout (location = 2) uniform sampler2DMS tex2DMS;\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"
1895 // To avoid duplicated mappings create additional shaders for specific functions
1896 const std::string strTextureVariants = "#version 450\n"
1898 "layout (location = 0) out vec4 fragColor;\n"
1900 "layout (location = 1) uniform sampler2D tex2D;\n"
1904 " fragColor = <TEXTURE>;\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);
1913 m_sources.push_back(FragmentSource(strTexture));
1914 m_sources.push_back(FragmentSource(strTextureProj));
1915 m_sources.push_back(FragmentSource(strTextureGather));
1918 m_sources.push_back(ComputeSource("#version 450\n"
1920 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1922 "layout (binding = 0) uniform atomic_uint auival;\n"
1926 " uint uival = atomicCounterIncrement(auival) +\n"
1927 " atomicCounterDecrement(auival) +\n"
1928 " atomicCounter(auival);\n"
1932 m_sources.push_back(ComputeSource("#version 450\n"
1934 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1936 "shared uint uishared;\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"
1952 m_sources.push_back(ComputeSource("#version 450\n"
1954 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\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"
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"
1977 // Fragment Processing
1978 m_sources.push_back(FragmentSource("#version 450\n"
1980 "layout (location = 0) out vec4 fragColor;\n"
1981 "layout (location = 1) in vec2 texCoord;\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"
2001 // To avoid duplicated mappings create additional shaders for specific functions
2002 const std::string strEmitVariants = "#version 450\n"
2004 "layout (points) in;\n"
2005 "layout (points, max_vertices = 3) out;\n"
2009 " gl_Position = vec4(0.0);\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);
2020 m_sources.push_back(GeometrySource(strEmit));
2021 m_sources.push_back(GeometrySource(strEmitStream));
2023 // Shader Invocation Control
2024 m_sources.push_back(
2025 TessellationControlSource("#version 450\n"
2027 "layout (vertices = 3) out;\n"
2033 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2036 // Shared Memory Control
2037 // To avoid duplicated mappings create additional shaders for specific functions
2038 const std::string strMemoryBarrierSource = "#version 450\n"
2040 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2044 " <MEMORY_BARRIER>;\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);
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));
2067 /** Stub de-init method */
2068 void SpirvGlslToSpirVBuiltInFunctionsTest::deinit()
2072 /** Executes test iteration.
2074 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2076 tcu::TestNode::IterateResult SpirvGlslToSpirVBuiltInFunctionsTest::iterate()
2078 const Functions& gl = m_context.getRenderContext().getFunctions();
2080 for (int i = 0; i < (signed)m_sources.size(); ++i)
2082 ShaderSource shaderSource = m_sources[i];
2084 ProgramSources sources;
2085 ProgramBinaries binaries;
2087 if (shaderSource.shaderType != glu::SHADERTYPE_COMPUTE)
2089 ShaderSource vertexSource(glu::SHADERTYPE_VERTEX, m_commonVertex);
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();
2098 commonUtils::readSpirV(archive.getResource("spirv/glsl_to_spirv_builtin_functions/common_vertex.nspv"));
2099 #endif //DEQP_HAVE_GLSLANG
2100 binaries << vertexBinary;
2103 sources << shaderSource;
2104 ShaderBinary shaderBinary;
2105 std::string spirvSource;
2107 #if defined DEQP_HAVE_GLSLANG
2108 shaderBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), shaderSource);
2109 #else // DEQP_HAVE_GLSLANG
2111 std::stringstream ss;
2112 ss << "spirv/glsl_to_spirv_builtin_functions/binary_" << i << ".nspv";
2114 tcu::Archive& archive = m_testCtx.getArchive();
2115 shaderBinary = commonUtils::readSpirV(archive.getResource(ss.str().c_str()));
2117 #endif // DEQP_HAVE_GLSLANG
2119 #if defined DEQP_HAVE_SPIRV_TOOLS
2121 glslangUtils::spirvDisassemble(spirvSource, shaderBinary.binary);
2123 if (!glslangUtils::verifyMappings(shaderSource.source, spirvSource, m_mappings, false))
2125 m_testCtx.getLog() << tcu::TestLog::Message << "Mappings for shader failed.\n"
2127 << shaderSource.source.c_str() << "\n"
2128 << "SpirV source:\n"
2129 << spirvSource.c_str() << tcu::TestLog::EndMessage;
2131 TCU_THROW(InternalError, "Mappings for shader failed.");
2134 #else // DEQP_HAVE_SPIRV_TOOLS
2135 spirvSource = "Could not disassemble Spir-V module. SPIRV-TOOLS not available.";
2136 #endif // DEQP_HAVE_SPIRV_TOOLS
2138 binaries << shaderBinary;
2140 if (shaderSource.shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)
2142 ShaderSource tessEvalSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, m_commonTessEval);
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;
2156 ShaderProgram glslProgram(gl, sources);
2157 if (!glslProgram.isOk())
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;
2164 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2168 ShaderProgram spirvProgram(gl, binaries);
2169 if (!spirvProgram.isOk())
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;
2176 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2181 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2185 /** Mappings init method */
2186 void SpirvGlslToSpirVBuiltInFunctionsTest::initMappings()
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");
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)
2350 tempMappings[std::string(" ") + it->first + "("] = it->second;
2353 m_mappings = tempMappings;
2358 * @param context Rendering context
2359 * @param name Test name
2360 * @param description Test description
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.")
2366 /* Left blank intentionally */
2369 /** Stub init method */
2370 void SpirvGlslToSpirVSpecializationConstantsTest::init()
2372 commonUtils::checkGlSpirvSupported(m_context);
2374 const Functions& gl = m_context.getRenderContext().getFunctions();
2376 m_vertex = "#version 450\n"
2378 "layout (location = 0) in vec3 position;\n"
2382 " gl_Position = vec4(position, 1.0);\n"
2385 m_fragment = "#version 450\n"
2387 "layout (constant_id = 10) const int red = 255;\n"
2389 "layout (location = 0) out vec4 fragColor;\n"
2393 " fragColor = vec4(float(red) / 255, 0.0, 1.0, 1.0);\n"
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");
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");
2410 gl.viewport(0, 0, 32, 32);
2411 GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
2414 /** Stub de-init method */
2415 void SpirvGlslToSpirVSpecializationConstantsTest::deinit()
2417 const Functions& gl = m_context.getRenderContext().getFunctions();
2421 gl.deleteFramebuffers(1, &m_fbo);
2422 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
2426 gl.deleteTextures(1, &m_texture);
2427 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
2431 /** Executes test iteration.
2433 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2435 tcu::TestNode::IterateResult SpirvGlslToSpirVSpecializationConstantsTest::iterate()
2437 const Functions& gl = m_context.getRenderContext().getFunctions();
2439 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
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");
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");
2453 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
2454 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
2456 ShaderBinary vertexBinary;
2457 ShaderBinary fragmentBinary;
2458 #if defined DEQP_HAVE_GLSLANG
2460 vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
2461 fragmentBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), FragmentSource(m_fragment));
2463 #else // DEQP_HAVE_GLSLANG
2465 tcu::Archive& archive = m_testCtx.getArchive();
2467 commonUtils::readSpirV(archive.getResource("spirv/glsl_to_spirv_specialization_constants/vertex.nspv"));
2469 commonUtils::readSpirV(archive.getResource("spirv/glsl_to_spirv_specialization_constants/fragment.nspv"));
2471 #endif // DEQP_HAVE_GLSLANG
2472 fragmentBinary << SpecializationData(10, 128);
2474 ProgramBinaries binaries;
2475 binaries << vertexBinary;
2476 binaries << fragmentBinary;
2477 ShaderProgram spirvProgram(gl, binaries);
2479 if (!spirvProgram.isOk())
2481 m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed.\n"
2483 << m_vertex.c_str() << "Fragment:\n"
2484 << m_fragment.c_str() << "InfoLog:\n"
2485 << spirvProgram.getShaderInfo(SHADERTYPE_VERTEX).infoLog << tcu::TestLog::EndMessage;
2487 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2491 gl.useProgram(spirvProgram.getProgram());
2492 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
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");
2499 gl.enableVertexAttribArray(0);
2500 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
2502 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2503 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
2505 gl.drawArrays(GL_TRIANGLES, 0, 3);
2506 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
2508 gl.disableVertexAttribArray(0);
2509 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
2513 gl.readPixels(16, 16, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&output);
2514 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
2516 if (output != 0xFFFF0080)
2518 m_testCtx.getLog() << tcu::TestLog::Message
2519 << "Color value read from framebuffer is wrong. Expected: " << 0xFFFF0080
2520 << ", Read: " << output << tcu::TestLog::EndMessage;
2522 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2526 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2532 * @param context Rendering context
2533 * @param name Test name
2534 * @param description Test description
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.")
2540 /* Left blank intentionally */
2543 /** Stub init method */
2544 void SpirvValidationBuiltInVariableDecorationsTest::init()
2546 commonUtils::checkGlSpirvSupported(m_context);
2548 m_compute = "#version 450\n"
2550 "layout (local_size_x = 1, local_size_y = 2, local_size_z = 1) in;\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"
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"
2574 m_vertex = "#version 450\n"
2576 "layout (location = 0) in vec3 position;\n"
2578 "layout (location = 1) out vec4 vColor;\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"
2589 m_tesselationCtrl = "#version 450\n"
2591 "layout (vertices = 3) out;\n"
2593 "layout (location = 1) in vec4 vColor[];\n"
2594 "layout (location = 2) out vec4 tcColor[];\n"
2598 " tcColor[gl_InvocationID] = vColor[gl_InvocationID];\n"
2599 " tcColor[gl_InvocationID].r = float(gl_PatchVerticesIn) / 3;\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"
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"
2613 m_tesselationEval = "#version 450\n"
2615 "layout (triangles) in;\n"
2617 "layout (location = 2) in vec4 tcColor[];\n"
2618 "layout (location = 3) out vec4 teColor;\n"
2622 " teColor = tcColor[0];\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"
2631 m_geometry = "#version 450\n"
2633 "layout (triangles) in;\n"
2634 "layout (triangle_strip, max_vertices = 3) out;\n"
2636 "layout (location = 3) in vec4 teColor[];\n"
2637 "layout (location = 4) out vec4 gColor;\n"
2641 " gColor = teColor[0];\n"
2642 " gColor.b = float(gl_PrimitiveIDIn);\n"
2645 " gl_ViewportIndex = 1;\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"
2653 " EndPrimitive();\n"
2656 m_fragment = "#version 450\n"
2658 "layout (location = <INPUT_LOCATION>) in vec4 <INPUT_NAME>;\n"
2659 "layout (location = 0) out vec4 fColor;\n"
2663 " vec4 color = <INPUT_NAME>;\n"
2664 " <ADDITIONAL_CODE>\n"
2665 " fColor = color;\n"
2668 ValidationStruct validationCompute(&SpirvValidationBuiltInVariableDecorationsTest::validComputeFunc);
2669 validationCompute.shaders.push_back(ComputeSource(m_compute));
2670 m_validations.push_back(validationCompute);
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);
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);
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);
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);
2737 std::string multisampleVertex = m_vertex;
2738 std::string multisampleFragment = m_fragment;
2739 std::string samplingCode = "if (gl_SampleID == 0)\n"
2741 " vec2 sampPos = gl_SamplePosition;\n"
2742 " color = vec4(1.0, sampPos.x, sampPos.y, 1.0);\n"
2746 " color = vec4(0.0, 1.0, 0.0, 1.0);\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);
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");
2789 /** Stub de-init method */
2790 void SpirvValidationBuiltInVariableDecorationsTest::deinit()
2794 /** Executes test iteration.
2796 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2798 tcu::TestNode::IterateResult SpirvValidationBuiltInVariableDecorationsTest::iterate()
2800 const Functions& gl = m_context.getRenderContext().getFunctions();
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");
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");
2823 for (int v = 0; v < (signed)m_validations.size(); ++v)
2825 for (int it = ITERATE_GLSL; it < ITERATE_LAST; ++it)
2827 ShaderProgram* program = DE_NULL;
2828 if (it == ITERATE_GLSL)
2830 ProgramSources sources;
2831 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2832 sources << m_validations[v].shaders[s];
2834 program = new ShaderProgram(gl, sources);
2836 else if (it == ITERATE_SPIRV)
2838 std::vector<ShaderBinary> binariesVec;
2840 #if defined DEQP_HAVE_GLSLANG
2841 ProgramBinaries binaries;
2842 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2844 ShaderBinary shaderBinary =
2845 glslangUtils::makeSpirV(m_context.getTestContext().getLog(), m_validations[v].shaders[s]);
2846 binariesVec.push_back(shaderBinary);
2847 binaries << shaderBinary;
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)
2854 std::stringstream ss;
2855 ss << "spirv/spirv_validation_builtin_variable_decorations/shader_" << v << "_" << s << ".nspv";
2857 ShaderBinary shaderBinary = commonUtils::readSpirV(archive.getResource(ss.str().c_str()));
2858 binariesVec.push_back(shaderBinary);
2859 binaries << shaderBinary;
2861 #endif // DEQP_HAVE_GLSLANG
2862 program = new ShaderProgram(gl, binaries);
2864 #if defined DEQP_HAVE_SPIRV_TOOLS
2865 std::string spirvSource;
2867 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2869 ShaderSource shaderSource = m_validations[v].shaders[s];
2871 glslangUtils::spirvDisassemble(spirvSource, binariesVec[s].binary);
2873 if (!glslangUtils::verifyMappings(shaderSource.source, spirvSource, m_mappings, true))
2875 m_testCtx.getLog() << tcu::TestLog::Message << "Mappings for shader failed.\n"
2877 << shaderSource.source.c_str() << "\n"
2878 << "SpirV source:\n"
2879 << spirvSource.c_str() << tcu::TestLog::EndMessage;
2881 TCU_THROW(InternalError, "Mappings for shader failed.");
2884 #endif // DEQP_HAVE_SPIRV_TOOLS
2887 if (!program->isOk())
2889 std::stringstream message;
2890 message << "Shader build failed.\n";
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";
2915 message << "ProgramInfo: " << program->getProgramInfo().infoLog;
2917 m_testCtx.getLog() << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
2919 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2923 gl.useProgram(program->getProgram());
2924 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2926 ValidationFuncPtr funcPtr = m_validations[v].validationFuncPtr;
2927 result = (this->*funcPtr)(m_validations[v].outputs);
2934 m_testCtx.getLog() << tcu::TestLog::Message << "Validation " << v << " failed!"
2935 << tcu::TestLog::EndMessage;
2944 gl.deleteBuffers(1, &vbo);
2945 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
2950 gl.deleteVertexArrays(1, &vao);
2951 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
2955 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2957 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2961 bool SpirvValidationBuiltInVariableDecorationsTest::validComputeFunc(ValidationOutputVec& outputs)
2965 const Functions& gl = m_context.getRenderContext().getFunctions();
2969 gl.genTextures(5, textures);
2970 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
2971 for (int i = 0; i < 5; ++i)
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");
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");
2990 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2992 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2994 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2996 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2998 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2999 gl.dispatchCompute(4, 2, 1);
3000 GLU_EXPECT_NO_ERROR(gl.getError(), "dispatchCompute");
3002 gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3003 GLU_EXPECT_NO_ERROR(gl.getError(), "memoryBarrier");
3005 std::vector<GLubyte> expectedResults[5];
3006 for (int i = 0; i < 5; ++i)
3008 for (int y = 0; y < 4; ++y)
3010 for (int x = 0; x < 4; ++x)
3012 //"uvec3 color0 = uvec3(gl_NumWorkGroups);"
3015 expectedResults[i].push_back(4);
3016 expectedResults[i].push_back(2);
3017 expectedResults[i].push_back(1);
3018 expectedResults[i].push_back(0xFF);
3020 //"uvec3 color1 = uvec3(gl_WorkGroupSize);"
3023 expectedResults[i].push_back(1);
3024 expectedResults[i].push_back(2);
3025 expectedResults[i].push_back(1);
3026 expectedResults[i].push_back(0xFF);
3028 //"uvec3 color2 = uvec3(gl_WorkGroupID);"
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);
3036 //"uvec3 color3 = uvec3(gl_LocalInvocationID);"
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);
3044 //"uvec3 color4 = uvec3(gl_LocalInvocationIndex);"
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);
3057 for (int i = 0; i < 5; ++i)
3059 gl.bindTexture(GL_TEXTURE_2D, textures[i]);
3060 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
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");
3067 if (pixels != expectedResults[i])
3069 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid image computed [" << i << "]."
3070 << tcu::TestLog::EndMessage;
3076 gl.deleteTextures(5, textures);
3077 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3082 bool SpirvValidationBuiltInVariableDecorationsTest::validPerVertexFragFunc(ValidationOutputVec& outputs)
3084 const Functions& gl = m_context.getRenderContext().getFunctions();
3086 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
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");
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");
3105 gl.viewport(0, 0, 64, 64);
3106 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3108 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3109 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3111 gl.enable(GL_CLIP_DISTANCE0);
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");
3118 gl.enableVertexAttribArray(0);
3119 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3121 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3122 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3124 gl.drawArrays(GL_TRIANGLES, 0, 3);
3125 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3127 gl.disableVertexAttribArray(0);
3128 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3130 gl.disable(GL_CLIP_DISTANCE0);
3133 for (int o = 0; o < (signed)outputs.size(); ++o)
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");
3139 if (!commonUtils::compareUintColors(output, outputs[o].value, 2))
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;
3151 gl.deleteFramebuffers(1, &fbo);
3152 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3157 gl.deleteTextures(1, &texture);
3158 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3164 bool SpirvValidationBuiltInVariableDecorationsTest::validPerVertexPointFunc(ValidationOutputVec& outputs)
3166 const Functions& gl = m_context.getRenderContext().getFunctions();
3168 const GLfloat vertices[] = { -0.3f, -0.3f, 0.0f, 0.0f, -0.3f, 0.0f, 0.3f, -0.3f, 0.0f };
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");
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");
3187 gl.viewport(0, 0, 128, 128);
3188 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3190 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3191 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3193 gl.enable(GL_CLIP_DISTANCE0);
3194 gl.enable(GL_PROGRAM_POINT_SIZE);
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");
3201 gl.enableVertexAttribArray(0);
3202 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3204 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3205 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3207 gl.drawArraysInstanced(GL_POINTS, 0, 3, 3);
3208 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3210 gl.disableVertexAttribArray(0);
3211 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3213 gl.disable(GL_PROGRAM_POINT_SIZE);
3214 gl.disable(GL_CLIP_DISTANCE0);
3217 for (int o = 0; o < (signed)outputs.size(); ++o)
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");
3223 if (!commonUtils::compareUintColors(output, outputs[o].value, 2))
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;
3235 gl.deleteFramebuffers(1, &fbo);
3236 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3241 gl.deleteTextures(1, &texture);
3242 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3248 bool SpirvValidationBuiltInVariableDecorationsTest::validTesselationGeometryFunc(ValidationOutputVec& outputs)
3250 const Functions& gl = m_context.getRenderContext().getFunctions();
3252 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
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");
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");
3271 gl.viewportIndexedf(0, 0.0f, 0.0f, 32.0f, 64.0f);
3272 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewportIndexed");
3274 gl.viewportIndexedf(1, 32.0f, 0.0f, 32.0f, 64.0f);
3275 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewportIndexed");
3277 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3278 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
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");
3285 gl.enableVertexAttribArray(0);
3286 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3288 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3289 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3291 gl.patchParameteri(GL_PATCH_VERTICES, 3);
3292 gl.drawArrays(GL_PATCHES, 0, 3);
3293 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3295 gl.disableVertexAttribArray(0);
3296 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3298 gl.viewport(0, 0, 128, 64);
3299 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
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");
3307 for (int o = 0; o < (signed)outputs.size(); ++o)
3309 GLuint output = pixels[(outputs[o].x + outputs[o].y * 64) + outputs[o].z * 64 * 64];
3311 if (!commonUtils::compareUintColors(output, outputs[o].value, 2))
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
3316 << "Read: " << output << tcu::TestLog::EndMessage;
3324 gl.deleteFramebuffers(1, &fbo);
3325 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3330 gl.deleteTextures(1, &texture);
3331 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3337 bool SpirvValidationBuiltInVariableDecorationsTest::validMultiSamplingFunc(ValidationOutputVec& outputs)
3339 const Functions& gl = m_context.getRenderContext().getFunctions();
3341 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
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");
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");
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");
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");
3376 gl.bindFramebuffer(GL_FRAMEBUFFER, fboMS);
3377 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3379 gl.viewport(0, 0, 32, 32);
3380 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3382 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3383 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3385 gl.enable(GL_CLIP_DISTANCE0);
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");
3392 gl.enableVertexAttribArray(0);
3393 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3395 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3396 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3398 gl.drawArrays(GL_TRIANGLES, 0, 3);
3399 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3401 gl.disableVertexAttribArray(0);
3402 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3404 gl.disable(GL_CLIP_DISTANCE0);
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");
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");
3414 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3415 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3417 const int epsilon = 2;
3419 for (int o = 0; o < (signed)outputs.size(); ++o)
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");
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).
3434 int r1 = (output & 0xFF);
3435 int g1 = ((output >> 8) & 0xFF);
3436 int b1 = ((output >> 16) & 0xFF);
3437 int a1 = ((output >> 24) & 0xFF);
3439 int r2 = (outputs[o].value & 0xFF);
3440 int b2 = ((outputs[o].value >> 16) & 0xFF);
3441 int a2 = ((outputs[o].value >> 24) & 0xFF);
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)
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;
3458 gl.deleteFramebuffers(1, &fboMS);
3459 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3464 gl.deleteFramebuffers(1, &fbo);
3465 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3470 gl.deleteTextures(1, &texture);
3471 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3476 gl.deleteTextures(1, &texture);
3477 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3485 * @param context Rendering context
3486 * @param name Test name
3487 * @param description Test description
3489 SpirvValidationCapabilitiesTest::SpirvValidationCapabilitiesTest(deqp::Context& context)
3490 : TestCase(context, "spirv_validation_capabilities_test", "Test verifies if Spir-V capabilities works as expected.")
3492 /* Left blank intentionally */
3495 /** Stub init method */
3496 void SpirvValidationCapabilitiesTest::init()
3498 ShaderStage computeStage;
3499 computeStage.source = ComputeSource("#version 450\n"
3501 "layout (local_size_x = 1, local_size_y = 2, local_size_z = 1) in;\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"
3519 "layout (binding = 0) uniform atomic_uint atCounter;\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"
3535 " vec3 coord = vec3(0);\n"
3536 " ivec2 offset = ivec2(gl_GlobalInvocationID.xy);\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"
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");
3561 ShaderStage vertexStage;
3562 vertexStage.source = VertexSource("#version 450\n"
3564 "layout (location = 0) in vec3 position;\n"
3565 "layout (location = 1) in mat4 projMatrix;\n"
3567 "layout (location = 2, xfb_buffer = 0) out float xfbVal;\n"
3568 "layout (location = 3) out vec2 texCoord;\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"
3578 " texCoord = vec2(0, 0);\n"
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");
3588 ShaderStage tessCtrlStage;
3589 tessCtrlStage.source =
3590 TessellationControlSource("#version 450\n"
3592 "layout (vertices = 3) out;\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"
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"
3607 tessCtrlStage.caps.push_back("Tessellation Shader");
3608 tessCtrlStage.caps.push_back("TessellationPointSize Tessellation");
3610 ShaderStage tessEvalStage;
3611 tessEvalStage.source = TessellationEvaluationSource("#version 450\n"
3613 "layout (triangles) in;\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"
3622 ShaderStage geometryStage;
3623 geometryStage.source = GeometrySource("#version 450\n"
3625 "layout (triangles) in;\n"
3626 "layout (triangle_strip, max_vertices = 3) out;\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"
3636 " EndStreamPrimitive(0);\n"
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");
3644 ShaderStage fragmentStage;
3645 fragmentStage.source = FragmentSource("#version 450\n"
3647 "layout (location = 3) in vec2 texCoord;\n"
3649 "layout (location = 0) out vec4 fColor;\n"
3651 "layout (location = 1) uniform sampler2D tex;\n"
3655 " vec2 p = vec2(gl_SampleID);\n"
3656 " vec2 dx = dFdxFine(p);\n"
3658 " interpolateAtCentroid(texCoord);"
3660 " fColor = vec4(1.0);\n"
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");
3668 ShaderStage dynamicIndexingStage;
3669 dynamicIndexingStage.source = ComputeSource("#version 450\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"
3677 "layout (binding = 5) buffer StorageData\n"
3680 "} storageBuff[10];\n"
3684 " vec2 coord = vec2(0.0);\n"
3685 " ivec2 point = ivec2(0);\n"
3688 " for (int i = 0; i < 10; ++i)"
3690 " ret = ret + uniBuff[i].a[i] + storageBuff[i].a[i];\n"
3691 " textureGather(uniSamp[i], coord);\n"
3692 " imageLoad(uniImg[i], point);\n"
3694 " memoryBarrier();\n"
3697 dynamicIndexingStage.caps.push_back("UniformBufferArrayDynamicIndexing");
3698 dynamicIndexingStage.caps.push_back("SampledImageArrayDynamicIndexing");
3699 dynamicIndexingStage.caps.push_back("StorageBufferArrayDynamicIndexing");
3700 dynamicIndexingStage.caps.push_back("StorageImageArrayDynamicIndexing");
3702 Pipeline computePipeline;
3703 computePipeline.push_back(computeStage);
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);
3712 Pipeline dynamicIndexingPipeline;
3713 dynamicIndexingPipeline.push_back(dynamicIndexingStage);
3715 m_pipelines.push_back(computePipeline);
3716 m_pipelines.push_back(standardPipeline);
3717 m_pipelines.push_back(dynamicIndexingPipeline);
3719 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_int64"))
3721 ShaderStage computeStageExt("GL_ARB_gpu_shader_int64");
3722 computeStageExt.source = ComputeSource("#version 450\n"
3724 "#extension GL_ARB_gpu_shader_int64 : require\n"
3728 " int64_t ival = int64_t(gl_GlobalInvocationID.x);\n"
3730 computeStageExt.caps.push_back("Int64");
3732 Pipeline extPipeline;
3733 extPipeline.push_back(computeStageExt);
3735 m_pipelines.push_back(extPipeline);
3738 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
3741 ShaderStage computeStageExt("GL_ARB_sparse_texture2");
3742 computeStageExt.source = ComputeSource("#version 450\n"
3744 "#extension GL_ARB_sparse_texture2 : require\n"
3746 "layout (location = 0) uniform sampler2D tex;\n"
3750 " vec2 p = vec2(0.0);\n"
3753 " sparseTextureARB(tex, p, spCol);\n"
3756 computeStageExt.caps.push_back("SparseResidency");
3758 Pipeline extPipeline;
3759 extPipeline.push_back(computeStageExt);
3761 m_pipelines.push_back(extPipeline);
3764 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture_clamp"))
3766 ShaderStage vertexStageExt("GL_ARB_sparse_texture_clamp_vert");
3767 vertexStageExt.source = VertexSource("#version 450\n"
3769 "layout (location = 0) in vec4 pos;\n"
3773 " gl_Position = pos;\n"
3776 ShaderStage fragmentStageExt("GL_ARB_sparse_texture_clamp_frag");
3777 fragmentStageExt.source = FragmentSource("#version 450\n"
3779 "#extension GL_ARB_sparse_texture2 : require\n"
3780 "#extension GL_ARB_sparse_texture_clamp : require\n"
3782 "uniform sampler2D tex;\n"
3784 "layout (location = 0) out vec4 spCol;\n"
3788 " vec2 p = vec2(0.0);\n"
3790 " sparseTextureClampARB(tex, p, 0.5, spCol);\n"
3793 fragmentStageExt.caps.push_back("MinLod");
3795 Pipeline extPipeline;
3796 extPipeline.push_back(vertexStageExt);
3797 extPipeline.push_back(fragmentStageExt);
3799 m_pipelines.push_back(extPipeline);
3803 if (m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_image_load_formatted"))
3805 ShaderStage computeStageExt("GL_EXT_shader_image_load_formatted");
3806 computeStageExt.source = ComputeSource("#version 450\n"
3808 "#extension GL_EXT_shader_image_load_formatted : require\n"
3810 "layout (location = 0) uniform image2D img;\n"
3814 " ivec3 point = ivec3(gl_GlobalInvocationID);\n"
3815 " vec4 color = imageLoad(img, point.xy);\n"
3818 computeStageExt.caps.push_back("StorageImageReadWithoutFormat");
3820 Pipeline extPipeline;
3821 extPipeline.push_back(computeStageExt);
3823 m_pipelines.push_back(extPipeline);
3827 /** Stub de-init method */
3828 void SpirvValidationCapabilitiesTest::deinit()
3832 /** Executes test iteration.
3834 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
3836 tcu::TestNode::IterateResult SpirvValidationCapabilitiesTest::iterate()
3838 const Functions& gl = m_context.getRenderContext().getFunctions();
3840 for (int p = 0; p < (signed)m_pipelines.size(); ++p)
3842 ProgramBinaries programBinaries;
3844 Pipeline& pipeline = m_pipelines[p];
3845 for (int s = 0; s < (signed)pipeline.size(); ++s)
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";
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";
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;
3868 ShaderProgram program(gl, programBinaries);
3869 if (!program.isOk())
3871 std::stringstream ssLog;
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
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;
3889 m_testCtx.getLog() << tcu::TestLog::Message << ssLog.str() << tcu::TestLog::EndMessage;
3891 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3895 #if defined DEQP_HAVE_SPIRV_TOOLS
3896 for (int s = 0; s < (signed)pipeline.size(); ++s)
3898 ShaderStage stage = pipeline[s];
3899 ShaderBinary binary = stage.binary;
3901 std::string spirVSource;
3902 glslangUtils::spirvDisassemble(spirVSource, binary.binary);
3904 for (int c = 0; c < (signed)stage.caps.size(); ++c)
3906 std::string spirVSourceCut;
3907 int foundCount = spirVCapabilityCutOff(spirVSource, spirVSourceCut, stage.caps, c);
3909 if (foundCount == 0)
3912 << tcu::TestLog::Message << "OpCapability (" << stage.caps[c] << ") [" << p << "/" << s
3914 << "Neither capability nor capabilities that depends on this capability has been found."
3915 << tcu::TestLog::EndMessage;
3919 // Assemble and validate cut off SpirV source
3920 glslangUtils::spirvAssemble(binary.binary, spirVSourceCut);
3921 if (glslangUtils::spirvValidate(binary.binary, false))
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;
3931 #endif // DEQP_HAVE_SPIRV_TOOLS
3934 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3938 int SpirvValidationCapabilitiesTest::spirVCapabilityCutOff(std::string spirVSrcInput, std::string& spirVSrcOutput,
3939 CapabilitiesVec& capabilities, int& currentCapability)
3941 std::vector<std::string> current = de::splitString(capabilities[currentCapability], ' ');
3943 CapabilitiesVec toDisable;
3944 toDisable.push_back(current[0]);
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)
3949 std::vector<std::string> split = de::splitString(capabilities[cr], ' ');
3951 if (split[0] == current[0])
3954 for (int s = 1; s < (signed)split.size(); ++s)
3956 if (split[s] == current[0])
3957 toDisable.push_back(split[0]);
3961 // Disable current capability and capabilities that depends on it
3963 spirVSrcOutput = spirVSrcInput;
3964 for (int d = 0; d < (signed)toDisable.size(); ++d)
3966 std::string searchString = std::string("OpCapability ") + toDisable[d];
3968 size_t pos = spirVSrcOutput.find(searchString);
3970 if (pos != std::string::npos)
3973 spirVSrcOutput.erase(pos, searchString.length());
3982 * @param context Rendering context.
3984 GlSpirvTests::GlSpirvTests(deqp::Context& context)
3985 : TestCaseGroup(context, "gl_spirv", "Verify conformance of ARB_gl_spirv implementation")
3989 /** Initializes the test group contents. */
3990 void GlSpirvTests::init()
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));
4003 } /* gl4cts namespace */