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 "OpSource GLSL 450\n"
843 "OpName %mainv \"mainv\"\n"
844 "OpName %mainf \"mainf\"\n"
845 "OpName %gl_PerVertex \"gl_PerVertex\"\n"
846 "OpMemberName %gl_PerVertex 0 \"gl_Position\"\n"
847 "OpMemberName %gl_PerVertex 1 \"gl_PointSize\"\n"
848 "OpMemberName %gl_PerVertex 2 \"gl_ClipDistance\"\n"
849 "OpMemberName %gl_PerVertex 3 \"gl_CullDistance\"\n"
851 "OpName %position \"position\"\n"
852 "OpName %gl_VertexID \"gl_VertexID\"\n"
853 "OpName %gl_InstanceID \"gl_InstanceID\"\n"
854 "OpMemberDecorate %gl_PerVertex 0 BuiltIn Position\n"
855 "OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize\n"
856 "OpMemberDecorate %gl_PerVertex 2 BuiltIn ClipDistance\n"
857 "OpMemberDecorate %gl_PerVertex 3 BuiltIn CullDistance\n"
858 "OpDecorate %gl_PerVertex Block\n"
859 "OpDecorate %position Location 0\n"
860 "OpDecorate %gl_VertexID BuiltIn VertexId\n"
861 "OpDecorate %gl_InstanceID BuiltIn InstanceId\n"
862 "OpDecorate %fColor Location 0\n"
863 "%void = OpTypeVoid\n"
864 "%3 = OpTypeFunction %void\n"
865 "%float = OpTypeFloat 32\n"
866 "%v4float = OpTypeVector %float 4\n"
867 "%uint = OpTypeInt 32 0\n"
868 "%uint_1 = OpConstant %uint 1\n"
869 "%_arr_float_uint_1 = OpTypeArray %float %uint_1\n"
870 "%gl_PerVertex = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1\n"
871 "%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex\n"
872 "%_ = OpVariable %_ptr_Output_gl_PerVertex Output\n"
873 "%int = OpTypeInt 32 1\n"
874 "%int_0 = OpConstant %int 0\n"
875 "%v3float = OpTypeVector %float 3\n"
876 "%_ptr_Input_v3float = OpTypePointer Input %v3float\n"
877 "%position = OpVariable %_ptr_Input_v3float Input\n"
878 "%float_1 = OpConstant %float 1\n"
879 "%_ptr_Output_v4float = OpTypePointer Output %v4float\n"
880 "%_ptr_Input_int = OpTypePointer Input %int\n"
881 "%gl_VertexID = OpVariable %_ptr_Input_int Input\n"
882 "%gl_InstanceID = OpVariable %_ptr_Input_int Input\n"
883 "%fColor = OpVariable %_ptr_Output_v4float Output\n"
884 "%fVec4_1 = OpConstantComposite %v4float %float_1 %float_1 %float_1 %float_1\n"
886 "%mainv = OpFunction %void None %3\n"
888 "%19 = OpLoad %v3float %position\n"
889 "%21 = OpCompositeExtract %float %19 0\n"
890 "%22 = OpCompositeExtract %float %19 1\n"
891 "%23 = OpCompositeExtract %float %19 2\n"
892 "%24 = OpCompositeConstruct %v4float %21 %22 %23 %float_1\n"
893 "%26 = OpAccessChain %_ptr_Output_v4float %_ %int_0\n"
898 "%mainf = OpFunction %void None %3\n"
900 "OpStore %fColor %fVec4_1\n"
905 /** Stub init method */
906 void SpirvShaderBinaryMultipleShaderObjectsTest::deinit()
910 /** Executes test iteration.
912 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
914 tcu::TestNode::IterateResult SpirvShaderBinaryMultipleShaderObjectsTest::iterate()
916 const Functions& gl = m_context.getRenderContext().getFunctions();
918 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
923 gl.genTextures(1, &texture);
924 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
925 gl.bindTexture(GL_TEXTURE_2D, texture);
926 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
927 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32);
928 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
930 gl.genFramebuffers(1, &fbo);
931 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
932 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
933 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
934 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
935 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
938 gl.genVertexArrays(1, &vao);
939 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
940 gl.bindVertexArray(vao);
941 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
944 gl.genBuffers(1, &vbo);
945 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
946 gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
947 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
949 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
950 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
952 #if defined DEQP_HAVE_SPIRV_TOOLS
954 binary << SHADERTYPE_VERTEX << "mainv";
955 binary << SHADERTYPE_FRAGMENT << "mainf";
957 glslangUtils::spirvAssemble(binary.binary, m_spirv);
958 glslangUtils::spirvValidate(binary.binary, true);
959 #else // DEQP_HAVE_SPIRV_TOOLS
960 tcu::Archive& archive = m_testCtx.getArchive();
961 ShaderBinary binary = commonUtils::readSpirV(
962 archive.getResource("spirv/spirv_modules_shader_binary_multiple_shader_objects/binary.nspv"));
963 #endif // DEQP_HAVE_SPIRV_TOOLS
965 ProgramBinaries binaries;
967 ShaderProgram program(gl, binaries);
971 m_testCtx.getLog() << tcu::TestLog::Message << "Shader build failed.\n"
972 << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
973 << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
974 << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
976 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
980 gl.viewport(0, 0, 32, 32);
981 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
983 gl.useProgram(program.getProgram());
984 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
986 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
987 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
988 gl.clear(GL_COLOR_BUFFER_BIT);
989 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
991 gl.enableVertexAttribArray(0);
992 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
994 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
995 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
997 gl.drawArrays(GL_TRIANGLE_STRIP, 0, 3);
998 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
1000 gl.disableVertexAttribArray(0);
1001 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
1004 GLuint outsidePixel;
1005 gl.readPixels(16, 16, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&insidePixel);
1006 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
1007 gl.readPixels(2, 30, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&outsidePixel);
1008 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
1012 gl.deleteBuffers(1, &vbo);
1013 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
1018 gl.deleteVertexArrays(1, &vao);
1019 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
1024 gl.deleteFramebuffers(1, &fbo);
1025 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
1030 gl.deleteTextures(1, &texture);
1031 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
1034 if (insidePixel == 0xFFFFFFFF && outsidePixel == 0xFF000000)
1035 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1038 m_testCtx.getLog() << tcu::TestLog::Message << "Wrong pixels color read.\n"
1039 << "Expected (inside/outside): " << 0xFFFFFFFF << "/" << 0xFF000000 << "\n"
1040 << "Read: " << insidePixel << "/" << outsidePixel << tcu::TestLog::EndMessage;
1042 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1050 * @param context Rendering context
1051 * @param name Test name
1052 * @param description Test description
1054 SpirvModulesStateQueriesTest::SpirvModulesStateQueriesTest(deqp::Context& context)
1055 : TestCase(context, "spirv_modules_state_queries_test",
1056 "Test verifies if state queries for new features added by ARB_gl_spirv works as expected.")
1058 /* Left blank intentionally */
1061 /** Stub init method */
1062 void SpirvModulesStateQueriesTest::init()
1064 commonUtils::checkGlSpirvSupported(m_context);
1066 m_vertex = "#version 450\n"
1068 "layout (location = 0) in vec4 position;\n"
1069 "layout (location = 20) uniform vec4 extPosition;\n"
1070 "layout (binding = 5) uniform ComponentsBlock\n"
1078 " gl_Position = position + extPosition + components.c1 + vec4(components.c2, 0.0, 0.0);\n"
1082 /** Stub de-init method */
1083 void SpirvModulesStateQueriesTest::deinit()
1087 /** Executes test iteration.
1089 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1091 tcu::TestNode::IterateResult SpirvModulesStateQueriesTest::iterate()
1093 const Functions& gl = m_context.getRenderContext().getFunctions();
1095 ProgramBinaries binaries;
1096 ShaderBinary vertexBinary;
1098 #if defined DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1100 vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
1102 // Disassemble Spir-V module
1104 glslangUtils::spirvDisassemble(output, vertexBinary.binary);
1106 // Remove name reflection for defined variables
1107 std::vector<std::string> lines = de::splitString(output, '\n');
1109 for (int i = 0; i < (signed)lines.size(); ++i)
1111 if (lines[i].find("OpName %position") != std::string::npos)
1113 if (lines[i].find("OpName %extPosition") != std::string::npos)
1115 if (lines[i].find("OpName %ComponentsBlock") != std::string::npos)
1117 if (lines[i].find("OpName %components") != std::string::npos)
1120 input.append(lines[i] + "\n");
1123 // Assemble Spir-V module
1124 vertexBinary.binary.clear();
1125 glslangUtils::spirvAssemble(vertexBinary.binary, input);
1126 glslangUtils::spirvValidate(vertexBinary.binary, true);
1128 #else // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1129 tcu::Archive& archive = m_testCtx.getArchive();
1130 vertexBinary = commonUtils::readSpirV(archive.getResource("spirv/modules_state_queries/vertex.nspv"));
1131 #endif // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1133 binaries << vertexBinary;
1134 ShaderProgram program(gl, binaries);
1136 Shader* shader = program.getShader(SHADERTYPE_VERTEX);
1138 // 1) Check compile status
1139 if (!program.getShaderInfo(SHADERTYPE_VERTEX).compileOk)
1141 m_testCtx.getLog() << tcu::TestLog::Message << "Check compile status failed.\n"
1142 << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
1144 << "Program: " << program.getProgramInfo().infoLog << tcu::TestLog::EndMessage;
1146 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1150 // 2) Check if SPIR_V_BINARY_ARB state is TRUE
1152 gl.getShaderiv(shader->getShader(), GL_SPIR_V_BINARY_ARB, &shaderState);
1153 GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
1154 if (shaderState != GL_TRUE)
1156 m_testCtx.getLog() << tcu::TestLog::Message << "SPIR_V_BINARY_ARB state set to FALSE. Expected TRUE."
1157 << tcu::TestLog::EndMessage;
1159 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1163 // 3) Check if queries for ACTIVE_ATTRIBUTE_MAX_LENGTH, ACTIVE_UNIFORM_MAX_LENGTH,
1164 // ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH return value equal to 1, and
1165 // TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH value equals to 0
1166 GLint programState[4];
1167 GLint expectedValues[4] = {1, 1, 0, 1};
1168 gl.getProgramiv(program.getProgram(), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &programState[0]);
1169 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1171 gl.getProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &programState[1]);
1172 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1174 // We expect 0 for GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH because the current program
1175 // doesn't activate transform feedback so there isn't any active varying.
1176 gl.getProgramiv(program.getProgram(), GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH, &programState[2]);
1177 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1179 gl.getProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &programState[3]);
1180 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1182 bool programStateResult = true;
1183 for (int i = 0; i < 4; ++i)
1185 if (programState[i] != expectedValues[i])
1187 m_testCtx.getLog() << tcu::TestLog::Message << "Check max name length [" << i << "] failed. "
1188 << "Expected: " << expectedValues[i] <<", Queried: "
1189 << programState[i] << "\n"
1190 << tcu::TestLog::EndMessage;
1191 programStateResult = false;
1195 if (!programStateResult)
1197 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1201 // 4) Check if ShaderSource command usage on Spir-V binary shader will change SPIR_V_BINARY_ARB state to FALSE
1202 const char* source = m_vertex.c_str();
1203 const int length = m_vertex.length();
1204 gl.shaderSource(shader->getShader(), 1, &source, &length);
1205 GLU_EXPECT_NO_ERROR(gl.getError(), "shaderSource");
1207 gl.getShaderiv(shader->getShader(), GL_SPIR_V_BINARY_ARB, &shaderState);
1208 GLU_EXPECT_NO_ERROR(gl.getError(), "getShaderiv");
1209 if (shaderState != GL_FALSE)
1211 m_testCtx.getLog() << tcu::TestLog::Message << "SPIR_V_BINARY_ARB state set to TRUE. Expected FALSE."
1212 << tcu::TestLog::EndMessage;
1214 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1218 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1224 * @param context Rendering context
1225 * @param name Test name
1226 * @param description Test description
1228 SpirvModulesErrorVerificationTest::SpirvModulesErrorVerificationTest(deqp::Context& context)
1229 : TestCase(context, "spirv_modules_error_verification_test",
1230 "Test verifies if new features added by ARB_gl_spirv generate error messages as expected.")
1232 /* Left blank intentionally */
1235 /** Stub init method */
1236 void SpirvModulesErrorVerificationTest::init()
1238 commonUtils::checkGlSpirvSupported(m_context);
1240 const Functions& gl = m_context.getRenderContext().getFunctions();
1242 m_vertex = "#version 450\n"
1244 "layout (location = 0) in vec4 position;\n"
1248 " gl_Position = position;\n"
1251 m_glslShaderId = gl.createShader(GL_VERTEX_SHADER);
1252 GLU_EXPECT_NO_ERROR(gl.getError(), "createShader");
1254 m_spirvShaderId = gl.createShader(GL_VERTEX_SHADER);
1255 GLU_EXPECT_NO_ERROR(gl.getError(), "createShader");
1257 m_programId = gl.createProgram();
1258 GLU_EXPECT_NO_ERROR(gl.getError(), "createProgram");
1260 gl.genTextures(1, &m_textureId);
1261 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
1264 /** Stub de-init method */
1265 void SpirvModulesErrorVerificationTest::deinit()
1267 const Functions& gl = m_context.getRenderContext().getFunctions();
1269 gl.deleteTextures(1, &m_textureId);
1270 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
1272 gl.deleteProgram(m_programId);
1273 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteProgram");
1275 gl.deleteShader(m_glslShaderId);
1276 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteShader");
1278 gl.deleteShader(m_spirvShaderId);
1279 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteShader");
1282 /** Executes test iteration.
1284 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1286 tcu::TestNode::IterateResult SpirvModulesErrorVerificationTest::iterate()
1288 const Functions& gl = m_context.getRenderContext().getFunctions();
1290 const char* shaderSrc = m_vertex.c_str();
1291 const int shaderLen = m_vertex.length();
1293 ShaderBinary vertexBinary;
1295 #if defined DEQP_HAVE_GLSLANG
1296 vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
1297 #else // DEQP_HAVE_GLSLANG
1298 tcu::Archive& archive = m_testCtx.getArchive();
1299 vertexBinary = commonUtils::readSpirV(archive.getResource("spirv/modules_error_verification/vertex.nspv"));
1300 #endif // DEQP_HAVE_GLSLANG
1302 gl.shaderSource(m_glslShaderId, 1, &shaderSrc, &shaderLen);
1303 GLU_EXPECT_NO_ERROR(gl.getError(), "shaderSource");
1305 gl.shaderBinary(1, &m_spirvShaderId, GL_SHADER_BINARY_FORMAT_SPIR_V_ARB, (GLvoid*)vertexBinary.binary.data(),
1306 vertexBinary.binary.size() * sizeof(deUint32));
1307 GLU_EXPECT_NO_ERROR(gl.getError(), "shaderBinary");
1309 gl.attachShader(m_programId, m_spirvShaderId);
1310 GLU_EXPECT_NO_ERROR(gl.getError(), "attachShader");
1314 // 1) Verify if CompileShader function used on shader with SPIR_V_BINARY_ARB state
1315 // will result in generating INVALID_OPERATION error.
1316 gl.compileShader(m_spirvShaderId);
1317 err = gl.getError();
1318 if (err != GL_INVALID_OPERATION)
1321 << tcu::TestLog::Message
1322 << "Unexpected error code generated by CompileShader [1]. Expected INVALID_OPERATION, generated: "
1323 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1325 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1329 // 2) Verify if SpecializeShader function generate INVALID_VALUE error when
1330 // <shader> is not the name of either a program or shader object.
1331 gl.specializeShader(0xFFFF, "main", 0, DE_NULL, DE_NULL);
1332 err = gl.getError();
1333 if (err != GL_INVALID_VALUE)
1336 << tcu::TestLog::Message
1337 << "Unexpected error code generated by SpecializeShader [2]. Expected INVALID_VALUE, generated: "
1338 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1340 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1344 // 3) Verify if SpecializeShader function generate INVALID_OPERATION error when
1345 // <shader> is the name of a program object.
1346 gl.specializeShader(m_programId, "main", 0, DE_NULL, DE_NULL);
1347 err = gl.getError();
1348 if (err != GL_INVALID_OPERATION)
1351 << tcu::TestLog::Message
1352 << "Unexpected error code generated by SpecializeShader [3]. Expected INVALID_OPERATION, generated: "
1353 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1355 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1359 // 4) Verify if SpecializeShader function generate INVALID_OPERATION error when
1360 // SPIR_V_BINARY_ARB state for <shader> is not TRUE.
1361 gl.specializeShader(m_glslShaderId, "main", 0, DE_NULL, DE_NULL);
1362 err = gl.getError();
1363 if (err != GL_INVALID_OPERATION)
1366 << tcu::TestLog::Message
1367 << "Unexpected error code generated by SpecializeShader [4]. Expected INVALID_OPERATION, generated: "
1368 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1370 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1374 // 5) Verify if SpecializeShader function generate INVALID_VALUE when <pEntryPoint>
1375 // does not name a valid entry point for <shader>.
1376 gl.specializeShader(m_spirvShaderId, "entry", 0, DE_NULL, DE_NULL);
1377 err = gl.getError();
1378 if (err != GL_INVALID_VALUE)
1381 << tcu::TestLog::Message
1382 << "Unexpected error code generated by SpecializeShader [5]. Expected INVALID_VALUE, generated: "
1383 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1385 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1389 // 6) Verify if SpecializeShader function generate INVALID_VALUE when any element
1390 // of <pConstantIndex> refers to a specialization constant that does not exist
1391 // in the shader module contained in <shader>.
1392 const GLuint specID = 10;
1393 const GLuint specValue = 10;
1394 gl.specializeShader(m_spirvShaderId, "main", 1, &specID, &specValue);
1395 err = gl.getError();
1396 if (err != GL_INVALID_VALUE)
1399 << tcu::TestLog::Message
1400 << "Unexpected error code generated by SpecializeShader [6]. Expected INVALID_VALUE, generated: "
1401 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1403 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1407 // 7) Verify if LinkProgram fail when one or more of the shader objects attached to
1408 // <program> are not specialized.
1409 gl.linkProgram(m_programId);
1410 err = gl.getError();
1411 if (err == GL_NO_ERROR)
1414 gl.getProgramiv(m_programId, GL_LINK_STATUS, &linkStatus);
1415 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1417 if (linkStatus != 0)
1419 m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected result of LinkProgram [7]."
1420 << tcu::TestLog::EndMessage;
1422 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1427 // 8) Verify if SpecializeShader function generate INVALID_OPERATION error if the
1428 // shader has already been specialized.
1429 gl.specializeShader(m_spirvShaderId, "main", 0, DE_NULL, DE_NULL);
1430 GLU_EXPECT_NO_ERROR(gl.getError(), "specializeShader");
1432 gl.specializeShader(m_spirvShaderId, "main", 0, DE_NULL, DE_NULL);
1433 err = gl.getError();
1434 if (err != GL_INVALID_OPERATION)
1437 << tcu::TestLog::Message
1438 << "Unexpected error code generated by SpecializeShader [8]. Expected INVALID_OPERATION, generated: "
1439 << glu::getErrorName(err) << tcu::TestLog::EndMessage;
1441 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1445 // 9) Verify if LinkProgram fail when not all of shaders attached to <program> have
1446 // the same value for the SPIR_V_BINARY_ARB state.
1447 gl.compileShader(m_glslShaderId);
1448 GLU_EXPECT_NO_ERROR(gl.getError(), "compileShader");
1450 gl.attachShader(m_programId, m_glslShaderId);
1451 GLU_EXPECT_NO_ERROR(gl.getError(), "attachShader");
1453 gl.linkProgram(m_programId);
1454 err = gl.getError();
1455 if (err == GL_NO_ERROR)
1458 gl.getProgramiv(m_programId, GL_LINK_STATUS, &linkStatus);
1459 GLU_EXPECT_NO_ERROR(gl.getError(), "getProgramiv");
1461 if (linkStatus != 0)
1463 m_testCtx.getLog() << tcu::TestLog::Message << "Unexpected result of LinkProgram [9]."
1464 << tcu::TestLog::EndMessage;
1466 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1471 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1477 * @param context Rendering context
1478 * @param name Test name
1479 * @param description Test description
1481 SpirvGlslToSpirVEnableTest::SpirvGlslToSpirVEnableTest(deqp::Context& context)
1482 : TestCase(context, "spirv_glsl_to_spirv_enable_test", "Test verifies if glsl supports Spir-V features.")
1484 /* Left blank intentionally */
1487 /** Stub init method */
1488 void SpirvGlslToSpirVEnableTest::init()
1490 commonUtils::checkGlSpirvSupported(m_context);
1492 m_vertex = "#version 450\n"
1495 " layout (location = 0) in vec4 enabled;\n"
1497 " layout (location = 0) in vec4 notEnabled;\n"
1498 "#endif // GL_SPIRV\n"
1502 " gl_Position = vec4(0.0, 0.0, 0.0, 0.0);\n"
1506 /** Stub de-init method */
1507 void SpirvGlslToSpirVEnableTest::deinit()
1511 /** Executes test iteration.
1513 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
1515 tcu::TestNode::IterateResult SpirvGlslToSpirVEnableTest::iterate()
1518 #if defined DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1520 const Functions& gl = m_context.getRenderContext().getFunctions();
1522 ProgramBinaries binaries;
1523 ShaderBinary vertexBinary =
1524 glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
1525 binaries << vertexBinary;
1526 ShaderProgram spirvProgram(gl, binaries);
1528 std::string spirvSource;
1529 glslangUtils::spirvDisassemble(spirvSource, vertexBinary.binary);
1531 if (spirvSource.find("OpName %enabled") == std::string::npos)
1533 m_testCtx.getLog() << tcu::TestLog::Message << "GL_SPIRV not defined. Spir-V source:\n"
1534 << spirvSource.c_str() << tcu::TestLog::EndMessage;
1536 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1540 if (!spirvProgram.isOk())
1542 m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed. Source:\n"
1543 << spirvSource.c_str() << "InfoLog:\n"
1544 << spirvProgram.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
1545 << tcu::TestLog::EndMessage;
1547 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1551 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1553 #else // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1555 TCU_THROW(InternalError, "Either glslang or spirv-tools not available.");
1557 #endif // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
1562 enum EShaderTemplate
1570 struct FunctionMapping
1572 EShaderTemplate shaderTemplate;
1573 std::string glslFunc;
1574 std::string glslArgs;
1575 std::string spirVFunc;
1577 FunctionMapping() : shaderTemplate(COMPUTE_TEMPLATE), glslFunc(""), glslArgs(""), spirVFunc("")
1581 FunctionMapping(EShaderTemplate shaderTemplate_, std::string glslFunc_, std::string glslArgs_,
1582 std::string spirVFunc_)
1583 : shaderTemplate(shaderTemplate_), glslFunc(glslFunc_), glslArgs(glslArgs_), spirVFunc(spirVFunc_)
1590 * @param context Rendering context
1591 * @param name Test name
1592 * @param description Test description
1594 SpirvGlslToSpirVBuiltInFunctionsTest::SpirvGlslToSpirVBuiltInFunctionsTest(deqp::Context& context)
1595 : TestCase(context, "spirv_glsl_to_spirv_builtin_functions_test",
1596 "Test verifies if GLSL built-in functions are supported by Spir-V.")
1598 /* Left blank intentionally */
1601 /** Stub init method */
1602 void SpirvGlslToSpirVBuiltInFunctionsTest::init()
1604 commonUtils::checkGlSpirvSupported(m_context);
1608 m_commonVertex = "#version 450\n"
1610 "layout (location = 0) in vec3 position;\n"
1611 "layout (location = 1) out vec2 texCoord;\n"
1615 " texCoord = vec2(0.0, 0.0);\n"
1616 " gl_Position = vec4(position, 1.0);\n"
1619 m_commonTessEval = "#version 450\n"
1621 "layout (triangles) in;\n"
1625 " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +\n"
1626 " gl_TessCoord.y * gl_in[1].gl_Position +\n"
1627 " gl_TessCoord.z * gl_in[2].gl_Position;\n"
1632 // Angle Trigonometry
1633 m_sources.push_back(ComputeSource("#version 450\n"
1635 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1639 " float tmp0 = 0.5;\n"
1641 " value = radians(tmp0) +\n"
1642 " degrees(tmp0) +\n"
1658 // To avoid duplicated mappings create additional shaders for specific functions
1659 const std::string strAnlgeVariants = "#version 450\n"
1661 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1665 " float tmp0 = 0.5;\n"
1666 " float value = <ATANGENT>;\n"
1668 std::string strATan = strAnlgeVariants;
1669 std::string strATan2 = strAnlgeVariants;
1670 commonUtils::replaceToken("<ATANGENT>", "atan(tmp0, tmp0)", strATan);
1671 commonUtils::replaceToken("<ATANGENT>", "atan(tmp0)", strATan2);
1673 m_sources.push_back(ComputeSource(strATan));
1674 m_sources.push_back(ComputeSource(strATan2));
1677 m_sources.push_back(ComputeSource("#version 450\n"
1679 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1686 " value = pow(tmp1, tmp0) +\n"
1692 " inversesqrt(tmp1);\n"
1695 // Common (without bit operations)
1696 m_sources.push_back(ComputeSource("#version 450\n"
1698 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1704 " float fpval = 0.5;\n"
1705 " float fnval = -0.5;\n"
1706 " int ival = 0x43800000;\n"
1707 " uint uival= 0xC3800000;\n"
1708 " value = abs(fnval) +\n"
1713 " roundEven(fpval) +\n"
1716 " mod(fpval, 2.0) +\n"
1717 " modf(fpval, outval) +\n"
1718 " min(fpval, 0.2) +\n"
1719 " max(fpval, 0.2) +\n"
1720 " clamp(fpval, 0.8, 2.0) +\n"
1721 " mix(fnval, fpval, 0.5) +\n"
1722 " step(1.0, fpval) +\n"
1723 " smoothstep(0.0, 1.0, fpval) +\n"
1724 " float( isnan(fpval)) +\n"
1725 " float( isinf(fpval)) +\n"
1726 " fma(fpval, 1.0, fnval) +\n"
1727 " frexp(4.0, ival) +\n"
1728 " ldexp(4.0, ival);\n"
1731 // To avoid duplicated mappings create additional shaders for specific functions
1732 const std::string strBitsOpsVariants = "#version 450\n"
1734 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1739 " int ival = 0x43800000;\n"
1740 " uint uval = 0x43800000;\n"
1741 " value = <BITS_TO_FLOAT>;\n"
1743 std::string strIntBits = strBitsOpsVariants;
1744 std::string strUIntBits = strBitsOpsVariants;
1745 commonUtils::replaceToken("<BITS_TO_FLOAT>", "intBitsToFloat(ival)", strIntBits);
1746 commonUtils::replaceToken("<BITS_TO_FLOAT>", "uintBitsToFloat(uval)", strUIntBits);
1748 m_sources.push_back(ComputeSource(strIntBits));
1749 m_sources.push_back(ComputeSource(strUIntBits));
1751 // Float Pack Unpack
1752 m_sources.push_back(ComputeSource("#version 450\n"
1754 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1758 " vec2 v2val = vec2(0.1, 0.2);\n"
1759 " vec4 v4val = vec4(0.1, 0.2, 0.3, 0.4);\n"
1760 " uint uival1 = packUnorm2x16(v2val);\n"
1761 " uint uival2 = packSnorm2x16(v2val);\n"
1762 " uint uival3 = packUnorm4x8(v4val);\n"
1763 " uint uival4 = packSnorm4x8(v4val);\n"
1764 " v2val = unpackUnorm2x16(uival1);\n"
1765 " v2val = unpackSnorm2x16(uival2);\n"
1766 " v4val = unpackUnorm4x8(uival3);\n"
1767 " v4val = unpackSnorm4x8(uival4);\n"
1768 " uvec2 uv2val = uvec2(10, 20);\n"
1769 " double dval = packDouble2x32(uv2val);\n"
1770 " uv2val = unpackDouble2x32(dval);\n"
1771 " uint uival5 = packHalf2x16(v2val);\n"
1772 " v2val = unpackHalf2x16(uival5);\n"
1776 m_sources.push_back(ComputeSource("#version 450\n"
1778 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1782 " vec3 v3val1 = vec3(0.1, 0.5, 1.0);\n"
1783 " vec3 v3val2 = vec3(0.5, 0.3, 0.9);\n"
1784 " vec3 v3val3 = vec3(1.0, 0.0, 0.0);\n"
1785 " float fval = length(v3val1) +\n"
1786 " distance(v3val1, v3val2) +\n"
1787 " dot(v3val1, v3val2);\n"
1788 " vec3 crossp = cross(v3val1, v3val2);\n"
1789 " vec3 norm = normalize(crossp);\n"
1790 " vec3 facef = faceforward(v3val1, v3val2, v3val3);\n"
1791 " vec3 refl = reflect(v3val1, v3val2);\n"
1792 " float eta = 0.1;\n"
1793 " vec3 refr = refract(v3val1, v3val2, eta);"
1797 m_sources.push_back(ComputeSource("#version 450\n"
1799 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1803 " mat2 m2val1 = mat2(\n"
1807 " mat2 m2val2 = mat2(\n"
1811 " vec2 v2val1 = vec2(0.3, 0.4);\n"
1812 " vec2 v2val2 = vec2(0.5, 0.6);\n"
1814 " mat2 m2comp = matrixCompMult(m2val1, m2val2);\n"
1815 " mat2 m2outerp = outerProduct(v2val1, v2val2);\n"
1816 " mat2 m2trans = transpose(m2val1);\n"
1817 " float fdet = determinant(m2val2);\n"
1818 " mat2 m2inv = inverse(m2trans);\n"
1821 // Vector Relational
1822 m_sources.push_back(ComputeSource("#version 450\n"
1824 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1828 " vec2 v2val1 = vec2(0.5, 0.2);\n"
1829 " vec2 v2val2 = vec2(0.1, 0.8);\n"
1830 " bvec2 bv2val1 = lessThan(v2val1, v2val2);\n"
1831 " bvec2 bv2val2 = lessThanEqual(v2val1, v2val2);\n"
1832 " bvec2 bv2val3 = greaterThan(v2val1, v2val2);\n"
1833 " bvec2 bv2val4 = greaterThanEqual(v2val1, v2val2);\n"
1834 " bvec2 bv2val5 = equal(v2val1, v2val2);\n"
1835 " bvec2 bv2val6 = notEqual(v2val1, v2val2);\n"
1836 " bool bval1 = any(bv2val1);\n"
1837 " bool bval2 = all(bv2val1);\n"
1838 " bvec2 bv2val7 = not(bv2val1);\n"
1842 m_sources.push_back(ComputeSource("#version 450\n"
1844 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1849 " uint uival = 200;\n"
1850 " uint uivalRet1;\n"
1851 " uint uivalRet2;\n"
1852 " uivalRet2 = uaddCarry(uival, 0xFFFFFFFF, uivalRet1);\n"
1853 " uivalRet2 = usubBorrow(uival, 0xFFFFFFFF, uivalRet1);\n"
1854 " umulExtended(uival, 0xFFFFFFFF, uivalRet1, uivalRet2);\n"
1855 " uivalRet1 = bitfieldExtract(uival, 3, 8);\n"
1856 " uivalRet1 = bitfieldInsert(uival, 0xFFFFFFFF, 3, 8);\n"
1857 " uivalRet1 = bitfieldReverse(uival);\n"
1858 " ival = bitCount(uival);\n"
1859 " ival = findLSB(uival);\n"
1860 " ival = findMSB(uival);\n"
1864 m_sources.push_back(
1865 FragmentSource("#version 450\n"
1867 "layout (location = 0) out vec4 fragColor;\n"
1869 "layout (location = 1) uniform sampler2D tex2D;\n"
1870 "layout (location = 2) uniform sampler2DMS tex2DMS;\n"
1874 " ivec2 iv2size = textureSize(tex2D, 0);\n"
1875 " vec2 v2lod = textureQueryLod(tex2D, vec2(0.0));\n"
1876 " int ilev = textureQueryLevels(tex2D);\n"
1877 " int isamp = textureSamples(tex2DMS);\n"
1878 " vec4 v4pix = textureLod(tex2D, vec2(0.0), 0.0) +\n"
1879 " textureOffset(tex2D, vec2(0.0), ivec2(2)) +\n"
1880 " texelFetch(tex2D, ivec2(2), 0) +\n"
1881 " texelFetchOffset(tex2D, ivec2(2), 0, ivec2(2)) +\n"
1882 " textureProjOffset(tex2D, vec3(0.0), ivec2(2)) +\n"
1883 " textureLodOffset(tex2D, vec2(0.0), 0.0, ivec2(2)) +\n"
1884 " textureProjLod(tex2D, vec3(0.0), 0.0) +\n"
1885 " textureProjLodOffset(tex2D, vec3(0.0), 0.0, ivec2(2)) +\n"
1886 " textureGrad(tex2D, vec2(0.0), vec2(0.2), vec2(0.5)) +\n"
1887 " textureGradOffset(tex2D, vec2(0.0), vec2(0.2), vec2(0.5), ivec2(2)) +\n"
1888 " textureProjGrad(tex2D, vec3(0.0), vec2(0.2), vec2(0.5)) +\n"
1889 " textureProjGradOffset(tex2D, vec3(0.0), vec2(0.2), vec2(0.5), ivec2(2)) +\n"
1890 " textureGatherOffset(tex2D, vec2(0.0), ivec2(2), 0);\n"
1891 " fragColor = vec4(0.0);\n"
1894 // To avoid duplicated mappings create additional shaders for specific functions
1895 const std::string strTextureVariants = "#version 450\n"
1897 "layout (location = 0) out vec4 fragColor;\n"
1899 "layout (location = 1) uniform sampler2D tex2D;\n"
1903 " fragColor = <TEXTURE>;\n"
1905 std::string strTexture = strTextureVariants;
1906 std::string strTextureProj = strTextureVariants;
1907 std::string strTextureGather = strTextureVariants;
1908 commonUtils::replaceToken("<TEXTURE>", "texture(tex2D, vec2(0.0))", strTexture);
1909 commonUtils::replaceToken("<TEXTURE>", "textureProj(tex2D, vec3(0.0))", strTextureProj);
1910 commonUtils::replaceToken("<TEXTURE>", "textureGather(tex2D, vec2(0.0), 0)", strTextureGather);
1912 m_sources.push_back(FragmentSource(strTexture));
1913 m_sources.push_back(FragmentSource(strTextureProj));
1914 m_sources.push_back(FragmentSource(strTextureGather));
1917 m_sources.push_back(ComputeSource("#version 450\n"
1919 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1921 "layout (binding = 0) uniform atomic_uint auival;\n"
1925 " uint uival = atomicCounterIncrement(auival) +\n"
1926 " atomicCounterDecrement(auival) +\n"
1927 " atomicCounter(auival);\n"
1931 m_sources.push_back(ComputeSource("#version 450\n"
1933 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1935 "shared uint uishared;\n"
1939 " uint uival2 = 5;\n"
1940 " uint uivalRet = atomicAdd(uishared, uival2) +\n"
1941 " atomicMin(uishared, uival2) +\n"
1942 " atomicMax(uishared, uival2) +\n"
1943 " atomicAnd(uishared, uival2) +\n"
1944 " atomicOr(uishared, uival2) +\n"
1945 " atomicXor(uishared, uival2) +\n"
1946 " atomicExchange(uishared, uival2) +\n"
1947 " atomicCompSwap(uishared, uishared, uival2);\n"
1951 m_sources.push_back(ComputeSource("#version 450\n"
1953 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
1955 "layout (location = 1, rgba8ui) uniform readonly uimage2D rimg2D;\n"
1956 "layout (location = 2, rgba8ui) uniform readonly uimage2DMS rimg2DMS;\n"
1957 "layout (location = 3, rgba8ui) uniform writeonly uimage2D wimg2D;\n"
1958 "layout (location = 4, r32ui) uniform uimage2D aimg2D;\n"
1962 " ivec2 size = imageSize(rimg2D);\n"
1963 " int samp = imageSamples(rimg2DMS);\n"
1964 " uvec4 v4pix = imageLoad(rimg2D, ivec2(0));\n"
1965 " imageStore(wimg2D, ivec2(0), uvec4(255));\n"
1966 " uint uivalRet = imageAtomicAdd(aimg2D, ivec2(0), 1) +\n"
1967 " imageAtomicMin(aimg2D, ivec2(0), 1) +\n"
1968 " imageAtomicMax(aimg2D, ivec2(0), 1) +\n"
1969 " imageAtomicAnd(aimg2D, ivec2(0), 1) +\n"
1970 " imageAtomicOr(aimg2D, ivec2(0), 1) +\n"
1971 " imageAtomicXor(aimg2D, ivec2(0), 1) +\n"
1972 " imageAtomicExchange(aimg2D, ivec2(0), 1) +\n"
1973 " imageAtomicCompSwap(aimg2D, ivec2(0), 1, 2);\n"
1976 // Fragment Processing
1977 m_sources.push_back(FragmentSource("#version 450\n"
1979 "layout (location = 0) out vec4 fragColor;\n"
1980 "layout (location = 1) in vec2 texCoord;\n"
1984 " vec2 p = vec2(0.0);\n"
1985 " vec2 dx = dFdx(p);\n"
1986 " vec2 dy = dFdy(p);\n"
1987 " dx = dFdxFine(p);\n"
1988 " dy = dFdyFine(p);\n"
1989 " dx = dFdxCoarse(p);\n"
1990 " dy = dFdyCoarse(p);\n"
1991 " vec2 fw = fwidth(p);\n"
1992 " fw = fwidthFine(p);\n"
1993 " fw = fwidthCoarse(p);\n"
1994 " vec2 interp = interpolateAtCentroid(texCoord) +\n"
1995 " interpolateAtSample(texCoord, 0) +\n"
1996 " interpolateAtOffset(texCoord, vec2(0.0));\n"
1997 " fragColor = vec4(1.0);\n"
2000 // To avoid duplicated mappings create additional shaders for specific functions
2001 const std::string strEmitVariants = "#version 450\n"
2003 "layout (points) in;\n"
2004 "layout (points, max_vertices = 3) out;\n"
2008 " gl_Position = vec4(0.0);\n"
2012 std::string strEmit = strEmitVariants;
2013 std::string strEmitStream = strEmitVariants;
2014 commonUtils::replaceToken("<EMIT>", "EmitVertex()", strEmit);
2015 commonUtils::replaceToken("<EMIT>", "EmitStreamVertex(0)", strEmitStream);
2016 commonUtils::replaceToken("<END>", "EndPrimitive()", strEmit);
2017 commonUtils::replaceToken("<END>", "EndStreamPrimitive(0)", strEmitStream);
2019 m_sources.push_back(GeometrySource(strEmit));
2020 m_sources.push_back(GeometrySource(strEmitStream));
2022 // Shader Invocation Control
2023 m_sources.push_back(
2024 TessellationControlSource("#version 450\n"
2026 "layout (vertices = 3) out;\n"
2032 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2035 // Shared Memory Control
2036 // To avoid duplicated mappings create additional shaders for specific functions
2037 const std::string strMemoryBarrierSource = "#version 450\n"
2039 "layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2043 " <MEMORY_BARRIER>;\n"
2045 std::string strMemoryBarrier = strMemoryBarrierSource;
2046 std::string strMemoryBarrierAtomicCounter = strMemoryBarrierSource;
2047 std::string strMemoryBarrierBuffer = strMemoryBarrierSource;
2048 std::string strMemoryBarrierShared = strMemoryBarrierSource;
2049 std::string strMemoryBarrierImage = strMemoryBarrierSource;
2050 std::string strGroupMemoryBarrier = strMemoryBarrierSource;
2051 commonUtils::replaceToken("<MEMORY_BARRIER>", "memoryBarrier()", strMemoryBarrier);
2052 commonUtils::replaceToken("<MEMORY_BARRIER>", "memoryBarrierAtomicCounter()", strMemoryBarrierAtomicCounter);
2053 commonUtils::replaceToken("<MEMORY_BARRIER>", "memoryBarrierBuffer()", strMemoryBarrierBuffer);
2054 commonUtils::replaceToken("<MEMORY_BARRIER>", "memoryBarrierShared()", strMemoryBarrierShared);
2055 commonUtils::replaceToken("<MEMORY_BARRIER>", "memoryBarrierImage()", strMemoryBarrierImage);
2056 commonUtils::replaceToken("<MEMORY_BARRIER>", "groupMemoryBarrier()", strGroupMemoryBarrier);
2058 m_sources.push_back(ComputeSource(strMemoryBarrier));
2059 m_sources.push_back(ComputeSource(strMemoryBarrierAtomicCounter));
2060 m_sources.push_back(ComputeSource(strMemoryBarrierBuffer));
2061 m_sources.push_back(ComputeSource(strMemoryBarrierShared));
2062 m_sources.push_back(ComputeSource(strMemoryBarrierImage));
2063 m_sources.push_back(ComputeSource(strGroupMemoryBarrier));
2066 /** Stub de-init method */
2067 void SpirvGlslToSpirVBuiltInFunctionsTest::deinit()
2071 /** Executes test iteration.
2073 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2075 tcu::TestNode::IterateResult SpirvGlslToSpirVBuiltInFunctionsTest::iterate()
2077 const Functions& gl = m_context.getRenderContext().getFunctions();
2079 for (int i = 0; i < (signed)m_sources.size(); ++i)
2081 ShaderSource shaderSource = m_sources[i];
2083 ProgramSources sources;
2084 ProgramBinaries binaries;
2086 if (shaderSource.shaderType != glu::SHADERTYPE_COMPUTE)
2088 ShaderSource vertexSource(glu::SHADERTYPE_VERTEX, m_commonVertex);
2090 sources << vertexSource;
2091 ShaderBinary vertexBinary;
2092 #if defined DEQP_HAVE_GLSLANG
2093 vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), vertexSource);
2094 #else // DEQP_HAVE_GLSLANG
2095 tcu::Archive& archive = m_testCtx.getArchive();
2097 commonUtils::readSpirV(archive.getResource("spirv/glsl_to_spirv_builtin_functions/common_vertex.nspv"));
2098 #endif //DEQP_HAVE_GLSLANG
2099 binaries << vertexBinary;
2102 sources << shaderSource;
2103 ShaderBinary shaderBinary;
2104 std::string spirvSource;
2106 #if defined DEQP_HAVE_GLSLANG
2107 shaderBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), shaderSource);
2108 #else // DEQP_HAVE_GLSLANG
2110 std::stringstream ss;
2111 ss << "spirv/glsl_to_spirv_builtin_functions/binary_" << i << ".nspv";
2113 tcu::Archive& archive = m_testCtx.getArchive();
2114 shaderBinary = commonUtils::readSpirV(archive.getResource(ss.str().c_str()));
2116 #endif // DEQP_HAVE_GLSLANG
2118 #if defined DEQP_HAVE_SPIRV_TOOLS
2120 glslangUtils::spirvDisassemble(spirvSource, shaderBinary.binary);
2122 if (!glslangUtils::verifyMappings(shaderSource.source, spirvSource, m_mappings, false))
2124 m_testCtx.getLog() << tcu::TestLog::Message << "Mappings for shader failed.\n"
2126 << shaderSource.source.c_str() << "\n"
2127 << "SpirV source:\n"
2128 << spirvSource.c_str() << tcu::TestLog::EndMessage;
2130 TCU_THROW(InternalError, "Mappings for shader failed.");
2133 #else // DEQP_HAVE_SPIRV_TOOLS
2134 spirvSource = "Could not disassemble Spir-V module. SPIRV-TOOLS not available.";
2135 #endif // DEQP_HAVE_SPIRV_TOOLS
2137 binaries << shaderBinary;
2139 if (shaderSource.shaderType == glu::SHADERTYPE_TESSELLATION_CONTROL)
2141 ShaderSource tessEvalSource(glu::SHADERTYPE_TESSELLATION_EVALUATION, m_commonTessEval);
2143 sources << tessEvalSource;
2144 ShaderBinary tessEvalBinary;
2145 #if defined DEQP_HAVE_GLSLANG
2146 tessEvalBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), tessEvalSource);
2147 #else // DEQP_HAVE_GLSLANG
2148 tcu::Archive& archive = m_testCtx.getArchive();
2149 tessEvalBinary = commonUtils::readSpirV(
2150 archive.getResource("spirv/glsl_to_spirv_builtin_functions/common_tesseval.nspv"));
2151 #endif // DEQP_HAVE_GLSLANG
2152 binaries << tessEvalBinary;
2155 ShaderProgram glslProgram(gl, sources);
2156 if (!glslProgram.isOk())
2158 m_testCtx.getLog() << tcu::TestLog::Message << "GLSL shader compilation failed. Source:\n"
2159 << shaderSource.source.c_str() << "InfoLog:\n"
2160 << glslProgram.getShaderInfo(shaderSource.shaderType).infoLog << "\n"
2161 << tcu::TestLog::EndMessage;
2163 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2167 ShaderProgram spirvProgram(gl, binaries);
2168 if (!spirvProgram.isOk())
2170 m_testCtx.getLog() << tcu::TestLog::Message << "SpirV shader compilation failed. Source:\n"
2171 << spirvSource.c_str() << "InfoLog:\n"
2172 << spirvProgram.getShaderInfo(shaderSource.shaderType).infoLog << "\n"
2173 << tcu::TestLog::EndMessage;
2175 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2180 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2184 /** Mappings init method */
2185 void SpirvGlslToSpirVBuiltInFunctionsTest::initMappings()
2188 m_mappings["radians"].push_back("OpExtInst Radians");
2189 m_mappings["degrees"].push_back("OpExtInst Degrees");
2190 m_mappings["sin"].push_back("OpExtInst Sin");
2191 m_mappings["cos"].push_back("OpExtInst Cos");
2192 m_mappings["tan"].push_back("OpExtInst Tan");
2193 m_mappings["asin"].push_back("OpExtInst Asin");
2194 m_mappings["acos"].push_back("OpExtInst Acos");
2195 m_mappings["atan"].push_back("OpExtInst Atan2");
2196 m_mappings["atan"].push_back("OpExtInst Atan");
2197 m_mappings["sinh"].push_back("OpExtInst Sinh");
2198 m_mappings["cosh"].push_back("OpExtInst Cosh");
2199 m_mappings["tanh"].push_back("OpExtInst Tanh");
2200 m_mappings["asinh"].push_back("OpExtInst Asinh");
2201 m_mappings["acosh"].push_back("OpExtInst Acosh");
2202 m_mappings["atanh"].push_back("OpExtInst Atanh");
2203 m_mappings["pow"].push_back("OpExtInst Pow");
2204 m_mappings["exp"].push_back("OpExtInst Exp");
2205 m_mappings["log"].push_back("OpExtInst Log");
2206 m_mappings["exp2"].push_back("OpExtInst Exp2");
2207 m_mappings["log2"].push_back("OpExtInst Log2");
2208 m_mappings["sqrt"].push_back("OpExtInst Sqrt");
2209 m_mappings["inversesqrt"].push_back("OpExtInst InverseSqrt");
2210 m_mappings["abs"].push_back("OpExtInst FAbs");
2211 m_mappings["sign"].push_back("OpExtInst FSign");
2212 m_mappings["floor"].push_back("OpExtInst Floor");
2213 m_mappings["trunc"].push_back("OpExtInst Trunc");
2214 m_mappings["round"].push_back("OpExtInst Round");
2215 m_mappings["roundEven"].push_back("OpExtInst RoundEven");
2216 m_mappings["ceil"].push_back("OpExtInst Ceil");
2217 m_mappings["fract"].push_back("OpExtInst Fract");
2218 m_mappings["mod"].push_back("OpFMod");
2219 m_mappings["modf"].push_back("OpExtInst Modf");
2220 m_mappings["min"].push_back("OpExtInst FMin");
2221 m_mappings["max"].push_back("OpExtInst FMax");
2222 m_mappings["clamp"].push_back("OpExtInst FClamp");
2223 m_mappings["mix"].push_back("OpExtInst FMix");
2224 m_mappings["step"].push_back("OpExtInst Step");
2225 m_mappings["smoothstep"].push_back("OpExtInst SmoothStep");
2226 m_mappings["intBitsToFloat"].push_back("OpBitcast");
2227 m_mappings["uintBitsToFloat"].push_back("OpBitcast");
2228 m_mappings["isnan"].push_back("OpIsNan");
2229 m_mappings["isinf"].push_back("OpIsInf");
2230 m_mappings["fma"].push_back("OpExtInst Fma");
2231 m_mappings["frexp"].push_back("OpExtInst FrexpStruct");
2232 m_mappings["ldexp"].push_back("OpExtInst Ldexp");
2233 m_mappings["packUnorm2x16"].push_back("OpExtInst PackUnorm2x16");
2234 m_mappings["packSnorm2x16"].push_back("OpExtInst PackSnorm2x16");
2235 m_mappings["packUnorm4x8"].push_back("OpExtInst PackUnorm4x8");
2236 m_mappings["packSnorm4x8"].push_back("OpExtInst PackSnorm4x8");
2237 m_mappings["unpackUnorm2x16"].push_back("OpExtInst UnpackUnorm2x16");
2238 m_mappings["unpackSnorm2x16"].push_back("OpExtInst UnpackSnorm2x16");
2239 m_mappings["unpackUnorm4x8"].push_back("OpExtInst UnpackUnorm4x8");
2240 m_mappings["unpackSnorm4x8"].push_back("OpExtInst UnpackSnorm4x8");
2241 m_mappings["packDouble2x32"].push_back("OpExtInst PackDouble2x32");
2242 m_mappings["unpackDouble2x32"].push_back("OpExtInst UnpackDouble2x32");
2243 m_mappings["packHalf2x16"].push_back("OpExtInst PackHalf2x16");
2244 m_mappings["unpackHalf2x16"].push_back("OpExtInst UnpackHalf2x16");
2245 m_mappings["length"].push_back("OpExtInst Length");
2246 m_mappings["distance"].push_back("OpExtInst Distance");
2247 m_mappings["dot"].push_back("OpDot");
2248 m_mappings["cross"].push_back("OpExtInst Cross");
2249 m_mappings["normalize"].push_back("OpExtInst Normalize");
2250 m_mappings["faceforward"].push_back("OpExtInst FaceForward");
2251 m_mappings["reflect"].push_back("OpExtInst Reflect");
2252 m_mappings["refract"].push_back("OpExtInst Refract");
2253 // This one could not be mapped as Spir-V equivalent need more steps
2254 // m_mappings["matrixCompMult"].push_back("");
2255 m_mappings["outerProduct"].push_back("OpOuterProduct");
2256 m_mappings["transpose"].push_back("OpTranspose");
2257 m_mappings["determinant"].push_back("OpExtInst Determinant");
2258 m_mappings["inverse"].push_back("OpExtInst MatrixInverse");
2259 m_mappings["lessThan"].push_back("OpFOrdLessThan");
2260 m_mappings["lessThanEqual"].push_back("OpFOrdLessThanEqual");
2261 m_mappings["greaterThan"].push_back("OpFOrdGreaterThan");
2262 m_mappings["greaterThanEqual"].push_back("OpFOrdGreaterThanEqual");
2263 m_mappings["equal"].push_back("OpFOrdEqual");
2264 m_mappings["notEqual"].push_back("OpFOrdNotEqual");
2265 m_mappings["any"].push_back("OpAny");
2266 m_mappings["all"].push_back("OpAll");
2267 m_mappings["not"].push_back("OpLogicalNot");
2268 m_mappings["uaddCarry"].push_back("OpIAddCarry");
2269 m_mappings["usubBorrow"].push_back("OpISubBorrow");
2270 m_mappings["umulExtended"].push_back("OpUMulExtended");
2271 m_mappings["bitfieldExtract"].push_back("OpBitFieldUExtract");
2272 m_mappings["bitfieldInsert"].push_back("OpBitFieldInsert");
2273 m_mappings["bitfieldReverse"].push_back("OpBitReverse");
2274 m_mappings["bitCount"].push_back("OpBitCount");
2275 m_mappings["findLSB"].push_back("OpExtInst FindILsb");
2276 m_mappings["findMSB"].push_back("OpExtInst FindUMsb");
2277 m_mappings["textureSize"].push_back("OpImageQuerySizeLod");
2278 m_mappings["textureQueryLod"].push_back("OpImageQueryLod");
2279 m_mappings["textureQueryLevels"].push_back("OpImageQueryLevels");
2280 m_mappings["textureSamples"].push_back("OpImageQuerySamples");
2281 m_mappings["texture"].push_back("OpImageSampleImplicitLod");
2282 m_mappings["textureProj"].push_back("OpImageSampleProjImplicitLod");
2283 m_mappings["textureLod"].push_back("OpImageSampleExplicitLod Lod");
2284 m_mappings["textureOffset"].push_back("OpImageSampleImplicitLod ConstOffset");
2285 m_mappings["texelFetch"].push_back("OpImageFetch Lod");
2286 m_mappings["texelFetchOffset"].push_back("OpImageFetch Lod|ConstOffset");
2287 m_mappings["textureProjOffset"].push_back("OpImageSampleProjImplicitLod ConstOffset");
2288 m_mappings["textureLodOffset"].push_back("OpImageSampleExplicitLod Lod|ConstOffset");
2289 m_mappings["textureProjLod"].push_back("OpImageSampleProjExplicitLod Lod");
2290 m_mappings["textureProjLodOffset"].push_back("OpImageSampleProjExplicitLod Lod|ConstOffset");
2291 m_mappings["textureGrad"].push_back("OpImageSampleExplicitLod Grad");
2292 m_mappings["textureGradOffset"].push_back("OpImageSampleExplicitLod Grad|ConstOffset");
2293 m_mappings["textureProjGrad"].push_back("OpImageSampleProjExplicitLod Grad");
2294 m_mappings["textureProjGradOffset"].push_back("OpImageSampleProjExplicitLod Grad|ConstOffset");
2295 m_mappings["textureGather"].push_back("OpImageGather");
2296 m_mappings["textureGatherOffset"].push_back("OpImageGather ConstOffset");
2297 m_mappings["atomicCounterIncrement"].push_back("OpAtomicIIncrement");
2298 m_mappings["atomicCounterDecrement"].push_back("OpAtomicIDecrement");
2299 m_mappings["atomicCounter"].push_back("OpAtomicLoad");
2300 m_mappings["atomicAdd"].push_back("OpAtomicIAdd");
2301 m_mappings["atomicMin"].push_back("OpAtomicUMin");
2302 m_mappings["atomicMax"].push_back("OpAtomicUMax");
2303 m_mappings["atomicAnd"].push_back("OpAtomicAnd");
2304 m_mappings["atomicOr"].push_back("OpAtomicOr");
2305 m_mappings["atomicXor"].push_back("OpAtomicXor");
2306 m_mappings["atomicExchange"].push_back("OpAtomicExchange");
2307 m_mappings["atomicCompSwap"].push_back("OpAtomicCompareExchange");
2308 m_mappings["imageSize"].push_back("OpImageQuerySize");
2309 m_mappings["imageSamples"].push_back("OpImageQuerySamples");
2310 m_mappings["imageLoad"].push_back("OpImageRead");
2311 m_mappings["imageStore"].push_back("OpImageWrite");
2312 m_mappings["imageAtomicAdd"].push_back("OpAtomicIAdd");
2313 m_mappings["imageAtomicMin"].push_back("OpAtomicUMin");
2314 m_mappings["imageAtomicMax"].push_back("OpAtomicUMax");
2315 m_mappings["imageAtomicAnd"].push_back("OpAtomicAnd");
2316 m_mappings["imageAtomicOr"].push_back("OpAtomicOr");
2317 m_mappings["imageAtomicXor"].push_back("OpAtomicXor");
2318 m_mappings["imageAtomicExchange"].push_back("OpAtomicExchange");
2319 m_mappings["imageAtomicCompSwap"].push_back("OpAtomicCompareExchange");
2320 m_mappings["dFdx"].push_back("OpDPdx");
2321 m_mappings["dFdy"].push_back("OpDPdy");
2322 m_mappings["dFdxFine"].push_back("OpDPdxFine");
2323 m_mappings["dFdyFine"].push_back("OpDPdyFine");
2324 m_mappings["dFdxCoarse"].push_back("OpDPdxCoarse");
2325 m_mappings["dFdyCoarse"].push_back("OpDPdyCoarse");
2326 m_mappings["fwidth"].push_back("OpFwidth");
2327 m_mappings["fwidthFine"].push_back("OpFwidthFine");
2328 m_mappings["fwidthCoarse"].push_back("OpFwidthCoarse");
2329 m_mappings["interpolateAtCentroid"].push_back("OpExtInst InterpolateAtCentroid");
2330 m_mappings["interpolateAtSample"].push_back("OpExtInst InterpolateAtSample");
2331 m_mappings["interpolateAtOffset"].push_back("OpExtInst InterpolateAtOffset");
2332 m_mappings["EmitStreamVertex"].push_back("OpEmitStreamVertex");
2333 m_mappings["EndStreamPrimitive"].push_back("OpEndStreamPrimitive");
2334 m_mappings["EmitVertex"].push_back("OpEmitVertex");
2335 m_mappings["EndPrimitive"].push_back("OpEndPrimitive");
2336 m_mappings["barrier"].push_back("OpControlBarrier");
2337 m_mappings["memoryBarrier"].push_back("OpMemoryBarrier");
2338 m_mappings["memoryBarrierAtomicCounter"].push_back("OpMemoryBarrier");
2339 m_mappings["memoryBarrierBuffer"].push_back("OpMemoryBarrier");
2340 m_mappings["memoryBarrierShared"].push_back("OpMemoryBarrier");
2341 m_mappings["memoryBarrierImage"].push_back("OpMemoryBarrier");
2342 m_mappings["groupMemoryBarrier"].push_back("OpMemoryBarrier");
2344 // Add a space prefix and parenthesis sufix to avoid searching for similar names
2345 SpirVMapping tempMappings;
2346 SpirVMapping::iterator it;
2347 for (it = m_mappings.begin(); it != m_mappings.end(); ++it)
2349 tempMappings[std::string(" ") + it->first + "("] = it->second;
2352 m_mappings = tempMappings;
2357 * @param context Rendering context
2358 * @param name Test name
2359 * @param description Test description
2361 SpirvGlslToSpirVSpecializationConstantsTest::SpirvGlslToSpirVSpecializationConstantsTest(deqp::Context& context)
2362 : TestCase(context, "spirv_glsl_to_spirv_specialization_constants_test",
2363 "Test verifies if constant specialization feature works as expected.")
2365 /* Left blank intentionally */
2368 /** Stub init method */
2369 void SpirvGlslToSpirVSpecializationConstantsTest::init()
2371 commonUtils::checkGlSpirvSupported(m_context);
2373 const Functions& gl = m_context.getRenderContext().getFunctions();
2375 m_vertex = "#version 450\n"
2377 "layout (location = 0) in vec3 position;\n"
2381 " gl_Position = vec4(position, 1.0);\n"
2384 m_fragment = "#version 450\n"
2386 "layout (constant_id = 10) const int red = 255;\n"
2388 "layout (location = 0) out vec4 fragColor;\n"
2392 " fragColor = vec4(float(red) / 255, 0.0, 1.0, 1.0);\n"
2395 gl.genTextures(1, &m_texture);
2396 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
2397 gl.bindTexture(GL_TEXTURE_2D, m_texture);
2398 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
2399 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32);
2400 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
2402 gl.genFramebuffers(1, &m_fbo);
2403 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
2404 gl.bindFramebuffer(GL_FRAMEBUFFER, m_fbo);
2405 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
2406 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0);
2407 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
2409 gl.viewport(0, 0, 32, 32);
2410 GLU_EXPECT_NO_ERROR(gl.getError(), "viewport");
2413 /** Stub de-init method */
2414 void SpirvGlslToSpirVSpecializationConstantsTest::deinit()
2416 const Functions& gl = m_context.getRenderContext().getFunctions();
2420 gl.deleteFramebuffers(1, &m_fbo);
2421 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteFramebuffers");
2425 gl.deleteTextures(1, &m_texture);
2426 GLU_EXPECT_NO_ERROR(gl.getError(), "deleteTextures");
2430 /** Executes test iteration.
2432 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2434 tcu::TestNode::IterateResult SpirvGlslToSpirVSpecializationConstantsTest::iterate()
2436 const Functions& gl = m_context.getRenderContext().getFunctions();
2438 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
2441 gl.genVertexArrays(1, &vao);
2442 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
2443 gl.bindVertexArray(vao);
2444 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
2447 gl.genBuffers(1, &vbo);
2448 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
2449 gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
2450 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
2452 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
2453 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
2455 ShaderBinary vertexBinary;
2456 ShaderBinary fragmentBinary;
2457 #if defined DEQP_HAVE_GLSLANG
2459 vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
2460 fragmentBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), FragmentSource(m_fragment));
2462 #else // DEQP_HAVE_GLSLANG
2464 tcu::Archive& archive = m_testCtx.getArchive();
2466 commonUtils::readSpirV(archive.getResource("spirv/glsl_to_spirv_specialization_constants/vertex.nspv"));
2468 commonUtils::readSpirV(archive.getResource("spirv/glsl_to_spirv_specialization_constants/fragment.nspv"));
2470 #endif // DEQP_HAVE_GLSLANG
2471 fragmentBinary << SpecializationData(10, 128);
2473 ProgramBinaries binaries;
2474 binaries << vertexBinary;
2475 binaries << fragmentBinary;
2476 ShaderProgram spirvProgram(gl, binaries);
2478 if (!spirvProgram.isOk())
2480 m_testCtx.getLog() << tcu::TestLog::Message << "Shader compilation failed.\n"
2482 << m_vertex.c_str() << "Fragment:\n"
2483 << m_fragment.c_str() << "InfoLog:\n"
2484 << spirvProgram.getShaderInfo(SHADERTYPE_VERTEX).infoLog << tcu::TestLog::EndMessage;
2486 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2490 gl.useProgram(spirvProgram.getProgram());
2491 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2493 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
2494 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
2495 gl.clear(GL_COLOR_BUFFER_BIT);
2496 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
2498 gl.enableVertexAttribArray(0);
2499 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
2501 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
2502 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
2504 gl.drawArrays(GL_TRIANGLES, 0, 3);
2505 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
2507 gl.disableVertexAttribArray(0);
2508 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
2512 gl.readPixels(16, 16, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&output);
2513 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
2515 if (output != 0xFFFF0080)
2517 m_testCtx.getLog() << tcu::TestLog::Message
2518 << "Color value read from framebuffer is wrong. Expected: " << 0xFFFF0080
2519 << ", Read: " << output << tcu::TestLog::EndMessage;
2521 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2525 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2531 * @param context Rendering context
2532 * @param name Test name
2533 * @param description Test description
2535 SpirvValidationBuiltInVariableDecorationsTest::SpirvValidationBuiltInVariableDecorationsTest(deqp::Context& context)
2536 : TestCase(context, "spirv_validation_builtin_variable_decorations_test",
2537 "Test verifies if Spir-V built in variable decorations works as expected.")
2539 /* Left blank intentionally */
2542 /** Stub init method */
2543 void SpirvValidationBuiltInVariableDecorationsTest::init()
2545 commonUtils::checkGlSpirvSupported(m_context);
2547 m_compute = "#version 450\n"
2549 "layout (local_size_x = 1, local_size_y = 2, local_size_z = 1) in;\n"
2551 "layout (location = 0, rgba8ui) uniform uimage2D img0;\n"
2552 "layout (location = 1, rgba8ui) uniform uimage2D img1;\n"
2553 "layout (location = 2, rgba8ui) uniform uimage2D img2;\n"
2554 "layout (location = 3, rgba8ui) uniform uimage2D img3;\n"
2555 "layout (location = 4, rgba8ui) uniform uimage2D img4;\n"
2559 " ivec3 point = ivec3(gl_GlobalInvocationID);\n"
2560 " uvec3 color0 = uvec3(gl_NumWorkGroups);\n"
2561 " uvec3 color1 = uvec3(gl_WorkGroupSize);\n"
2562 " uvec3 color2 = uvec3(gl_WorkGroupID);\n"
2563 " uvec3 color3 = uvec3(gl_LocalInvocationID);\n"
2564 " uvec3 color4 = uvec3(gl_LocalInvocationIndex);\n"
2565 " imageStore(img0, point.xy, uvec4(color0, 0xFF));\n"
2566 " imageStore(img1, point.xy, uvec4(color1, 0xFF));\n"
2567 " imageStore(img2, point.xy, uvec4(color2, 0xFF));\n"
2568 " imageStore(img3, point.xy, uvec4(color3, 0xFF));\n"
2569 " imageStore(img4, point.xy, uvec4(color4, 0xFF));\n"
2570 " memoryBarrier();\n"
2573 m_vertex = "#version 450\n"
2575 "layout (location = 0) in vec3 position;\n"
2577 "layout (location = 1) out vec4 vColor;\n"
2581 " gl_PointSize = 10.0f;\n"
2582 " gl_Position = vec4(position.x, position.y + 0.3 * gl_InstanceID, position.z, 1.0);\n"
2583 " gl_ClipDistance[0] = <CLIP_DISTANCE>;\n"
2584 " gl_CullDistance[0] = <CULL_DISTANCE>;\n"
2585 " vColor = <VERTEX_COLOR>;\n"
2588 m_tesselationCtrl = "#version 450\n"
2590 "layout (vertices = 3) out;\n"
2592 "layout (location = 1) in vec4 vColor[];\n"
2593 "layout (location = 2) out vec4 tcColor[];\n"
2597 " tcColor[gl_InvocationID] = vColor[gl_InvocationID];\n"
2598 " tcColor[gl_InvocationID].r = float(gl_PatchVerticesIn) / 3;\n"
2600 " if (gl_InvocationID == 0) {\n"
2601 " gl_TessLevelOuter[0] = 1.0;\n"
2602 " gl_TessLevelOuter[1] = 1.0;\n"
2603 " gl_TessLevelOuter[2] = 1.0;\n"
2604 " gl_TessLevelInner[0] = 1.0;\n"
2607 " gl_out[gl_InvocationID].gl_ClipDistance[0] = gl_in[gl_InvocationID].gl_ClipDistance[0];\n"
2608 " gl_out[gl_InvocationID].gl_CullDistance[0] = gl_in[gl_InvocationID].gl_CullDistance[0];\n"
2609 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
2612 m_tesselationEval = "#version 450\n"
2614 "layout (triangles) in;\n"
2616 "layout (location = 2) in vec4 tcColor[];\n"
2617 "layout (location = 3) out vec4 teColor;\n"
2621 " teColor = tcColor[0];\n"
2623 " gl_ClipDistance[0] = gl_in[0].gl_ClipDistance[0];\n"
2624 " gl_CullDistance[0] = gl_in[0].gl_CullDistance[0];\n"
2625 " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +\n"
2626 " gl_TessCoord.y * gl_in[1].gl_Position +\n"
2627 " gl_TessCoord.z * gl_in[2].gl_Position;\n"
2630 m_geometry = "#version 450\n"
2632 "layout (triangles) in;\n"
2633 "layout (triangle_strip, max_vertices = 3) out;\n"
2635 "layout (location = 3) in vec4 teColor[];\n"
2636 "layout (location = 4) out vec4 gColor;\n"
2640 " gColor = teColor[0];\n"
2641 " gColor.b = float(gl_PrimitiveIDIn);\n"
2644 " gl_ViewportIndex = 1;\n"
2646 " for (int i = 0; i < 3; ++i) {\n"
2647 " gl_ClipDistance[0] = gl_in[i].gl_ClipDistance[0];\n"
2648 " gl_CullDistance[0] = gl_in[i].gl_CullDistance[0];\n"
2649 " gl_Position = gl_in[i].gl_Position;\n"
2652 " EndPrimitive();\n"
2655 m_fragment = "#version 450\n"
2657 "layout (location = <INPUT_LOCATION>) in vec4 <INPUT_NAME>;\n"
2658 "layout (location = 0) out vec4 fColor;\n"
2662 " vec4 color = <INPUT_NAME>;\n"
2663 " <ADDITIONAL_CODE>\n"
2664 " fColor = color;\n"
2667 ValidationStruct validationCompute(&SpirvValidationBuiltInVariableDecorationsTest::validComputeFunc);
2668 validationCompute.shaders.push_back(ComputeSource(m_compute));
2669 m_validations.push_back(validationCompute);
2671 std::string clipNegativeVertex = m_vertex;
2672 std::string clipNegativeFragment = m_fragment;
2673 commonUtils::replaceToken("<CLIP_DISTANCE>", "-1.0", clipNegativeVertex);
2674 commonUtils::replaceToken("<CULL_DISTANCE>", "1.0", clipNegativeVertex);
2675 commonUtils::replaceToken("<VERTEX_COLOR>", "vec4(1.0, 1.0, 1.0, 1.0)", clipNegativeVertex);
2676 commonUtils::replaceToken("<INPUT_LOCATION>", "1", clipNegativeFragment);
2677 commonUtils::replaceToken("<INPUT_NAME>", "vColor", clipNegativeFragment);
2678 commonUtils::replaceToken("<ADDITIONAL_CODE>", "", clipNegativeFragment);
2679 ValidationStruct validationClipNegative(&SpirvValidationBuiltInVariableDecorationsTest::validPerVertexFragFunc);
2680 validationClipNegative.shaders.push_back(VertexSource(clipNegativeVertex));
2681 validationClipNegative.shaders.push_back(FragmentSource(clipNegativeFragment));
2682 validationClipNegative.outputs.push_back(ValidationOutputStruct(32, 32, 0xFF000000));
2683 m_validations.push_back(validationClipNegative);
2685 std::string perVertexFragVertex = m_vertex;
2686 std::string perVertexFragFragment = m_fragment;
2687 std::string fragCode = "vec4 coord = gl_FragCoord;\n"
2688 "color = vec4(0.0, coord.s / 64, coord.t / 64, 1.0);\n";
2689 commonUtils::replaceToken("<CLIP_DISTANCE>", "1.0", perVertexFragVertex);
2690 commonUtils::replaceToken("<CULL_DISTANCE>", "1.0", perVertexFragVertex);
2691 commonUtils::replaceToken("<VERTEX_COLOR>", "vec4(1.0, 1.0, 1.0, 1.0)", perVertexFragVertex);
2692 commonUtils::replaceToken("<INPUT_LOCATION>", "1", perVertexFragFragment);
2693 commonUtils::replaceToken("<INPUT_NAME>", "vColor", perVertexFragFragment);
2694 commonUtils::replaceToken("<ADDITIONAL_CODE>", fragCode.c_str(), perVertexFragFragment);
2695 ValidationStruct validationFrag(&SpirvValidationBuiltInVariableDecorationsTest::validPerVertexFragFunc);
2696 validationFrag.shaders.push_back(VertexSource(perVertexFragVertex));
2697 validationFrag.shaders.push_back(FragmentSource(perVertexFragFragment));
2698 validationFrag.outputs.push_back(ValidationOutputStruct(32, 32, 0xFF7F7F00));
2699 m_validations.push_back(validationFrag);
2701 std::string perVertexPointVertex = m_vertex;
2702 std::string perVertexPointFragment = m_fragment;
2703 std::string pointCode = "vec2 coord = gl_PointCoord;\n"
2704 "color.b = coord.s * coord.t;\n";
2705 commonUtils::replaceToken("<CLIP_DISTANCE>", "1.0", perVertexPointVertex);
2706 commonUtils::replaceToken("<CULL_DISTANCE>", "1.0", perVertexPointVertex);
2707 commonUtils::replaceToken("<VERTEX_COLOR>", "vec4(float(gl_VertexID) / 3, 0.0, 0.0, 1.0)", perVertexPointVertex);
2708 commonUtils::replaceToken("<INPUT_LOCATION>", "1", perVertexPointFragment);
2709 commonUtils::replaceToken("<INPUT_NAME>", "vColor", perVertexPointFragment);
2710 commonUtils::replaceToken("<ADDITIONAL_CODE>", pointCode.c_str(), perVertexPointFragment);
2711 ValidationStruct validationPoint(&SpirvValidationBuiltInVariableDecorationsTest::validPerVertexPointFunc);
2712 validationPoint.shaders.push_back(VertexSource(perVertexPointVertex));
2713 validationPoint.shaders.push_back(FragmentSource(perVertexPointFragment));
2714 validationPoint.outputs.push_back(ValidationOutputStruct(64, 64, 0xFF3F0055));
2715 validationPoint.outputs.push_back(ValidationOutputStruct(45, 45, 0xFF3F0000));
2716 validationPoint.outputs.push_back(ValidationOutputStruct(83, 83, 0xFF3F00AA));
2717 m_validations.push_back(validationPoint);
2719 std::string tessGeomVertex = m_vertex;
2720 std::string tessGeomFragment = m_fragment;
2721 commonUtils::replaceToken("<CLIP_DISTANCE>", "1.0", tessGeomVertex);
2722 commonUtils::replaceToken("<CULL_DISTANCE>", "1.0", tessGeomVertex);
2723 commonUtils::replaceToken("<VERTEX_COLOR>", "vec4(1.0, 1.0, 1.0, 1.0)", tessGeomVertex);
2724 commonUtils::replaceToken("<INPUT_LOCATION>", "4", tessGeomFragment);
2725 commonUtils::replaceToken("<INPUT_NAME>", "gColor", tessGeomFragment);
2726 commonUtils::replaceToken("<ADDITIONAL_CODE>", "", tessGeomFragment);
2727 ValidationStruct validationTessGeom(&SpirvValidationBuiltInVariableDecorationsTest::validTesselationGeometryFunc);
2728 validationTessGeom.shaders.push_back(VertexSource(tessGeomVertex));
2729 validationTessGeom.shaders.push_back(TessellationControlSource(m_tesselationCtrl));
2730 validationTessGeom.shaders.push_back(TessellationEvaluationSource(m_tesselationEval));
2731 validationTessGeom.shaders.push_back(GeometrySource(m_geometry));
2732 validationTessGeom.shaders.push_back(FragmentSource(tessGeomFragment));
2733 validationTessGeom.outputs.push_back(ValidationOutputStruct(48, 32, 1, 0xFF00FFFF));
2734 m_validations.push_back(validationTessGeom);
2736 std::string multisampleVertex = m_vertex;
2737 std::string multisampleFragment = m_fragment;
2738 std::string samplingCode = "if (gl_SampleID == 0)\n"
2740 " vec2 sampPos = gl_SamplePosition;\n"
2741 " color = vec4(1.0, sampPos.x, sampPos.y, 1.0);\n"
2745 " color = vec4(0.0, 1.0, 0.0, 1.0);\n"
2747 "gl_SampleMask[0] = 0x02;";
2748 commonUtils::replaceToken("<CLIP_DISTANCE>", "1.0", multisampleVertex);
2749 commonUtils::replaceToken("<CULL_DISTANCE>", "1.0", multisampleVertex);
2750 commonUtils::replaceToken("<VERTEX_COLOR>", "vec4(1.0, 1.0, 1.0, 1.0)", multisampleVertex);
2751 commonUtils::replaceToken("<INPUT_LOCATION>", "1", multisampleFragment);
2752 commonUtils::replaceToken("<INPUT_NAME>", "vColor", multisampleFragment);
2753 commonUtils::replaceToken("<ADDITIONAL_CODE>", samplingCode.c_str(), multisampleFragment);
2754 ValidationStruct validationMultisample(&SpirvValidationBuiltInVariableDecorationsTest::validMultiSamplingFunc);
2755 validationMultisample.shaders.push_back(VertexSource(multisampleVertex));
2756 validationMultisample.shaders.push_back(FragmentSource(multisampleFragment));
2757 validationMultisample.outputs.push_back(ValidationOutputStruct(16, 16, 0xFF00BC00));
2758 m_validations.push_back(validationMultisample);
2760 m_mappings["gl_NumWorkGroups"].push_back("BuiltIn NumWorkgroups");
2761 m_mappings["gl_WorkGroupSize"].push_back("BuiltIn WorkgroupSize");
2762 m_mappings["gl_WorkGroupID"].push_back("BuiltIn WorkgroupId");
2763 m_mappings["gl_LocalInvocationID"].push_back("BuiltIn LocalInvocationId");
2764 m_mappings["gl_GlobalInvocationID"].push_back("BuiltIn GlobalInvocationId");
2765 m_mappings["gl_LocalInvocationIndex"].push_back("BuiltIn LocalInvocationIndex");
2766 m_mappings["gl_VertexID"].push_back("BuiltIn VertexId");
2767 m_mappings["gl_InstanceID"].push_back("BuiltIn InstanceId");
2768 m_mappings["gl_Position"].push_back("BuiltIn Position");
2769 m_mappings["gl_PointSize"].push_back("BuiltIn PointSize");
2770 m_mappings["gl_ClipDistance"].push_back("BuiltIn ClipDistance");
2771 m_mappings["gl_CullDistance"].push_back("BuiltIn CullDistance");
2772 m_mappings["gl_PrimitiveIDIn"].push_back("BuiltIn PrimitiveId");
2773 m_mappings["gl_InvocationID"].push_back("BuiltIn InvocationId");
2774 m_mappings["gl_Layer"].push_back("BuiltIn Layer");
2775 m_mappings["gl_ViewportIndex"].push_back("BuiltIn ViewportIndex");
2776 m_mappings["gl_PatchVerticesIn"].push_back("BuiltIn PatchVertices");
2777 m_mappings["gl_TessLevelOuter"].push_back("BuiltIn TessLevelOuter");
2778 m_mappings["gl_TessLevelInner"].push_back("BuiltIn TessLevelInner");
2779 m_mappings["gl_TessCoord"].push_back("BuiltIn TessCoord");
2780 m_mappings["gl_FragCoord"].push_back("BuiltIn FragCoord");
2781 m_mappings["gl_FrontFacing"].push_back("BuiltIn FrontFacing");
2782 m_mappings["gl_PointCoord"].push_back("BuiltIn PointCoord");
2783 m_mappings["gl_SampleId"].push_back("BuiltIn SampleId");
2784 m_mappings["gl_SamplePosition"].push_back("BuiltIn SamplePosition");
2785 m_mappings["gl_SampleMask"].push_back("BuiltIn SampleMask");
2788 /** Stub de-init method */
2789 void SpirvValidationBuiltInVariableDecorationsTest::deinit()
2793 /** Executes test iteration.
2795 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
2797 tcu::TestNode::IterateResult SpirvValidationBuiltInVariableDecorationsTest::iterate()
2799 const Functions& gl = m_context.getRenderContext().getFunctions();
2802 gl.genVertexArrays(1, &vao);
2803 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenVertexArrays");
2804 gl.bindVertexArray(vao);
2805 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindVertexArray");
2808 gl.genBuffers(1, &vbo);
2809 GLU_EXPECT_NO_ERROR(gl.getError(), "glGenBuffers");
2810 gl.bindBuffer(GL_ARRAY_BUFFER, vbo);
2811 GLU_EXPECT_NO_ERROR(gl.getError(), "glBindBuffer");
2822 for (int v = 0; v < (signed)m_validations.size(); ++v)
2824 for (int it = ITERATE_GLSL; it < ITERATE_LAST; ++it)
2826 ShaderProgram* program = DE_NULL;
2827 if (it == ITERATE_GLSL)
2829 ProgramSources sources;
2830 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2831 sources << m_validations[v].shaders[s];
2833 program = new ShaderProgram(gl, sources);
2835 else if (it == ITERATE_SPIRV)
2837 std::vector<ShaderBinary> binariesVec;
2839 #if defined DEQP_HAVE_GLSLANG
2840 ProgramBinaries binaries;
2841 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2843 ShaderBinary shaderBinary =
2844 glslangUtils::makeSpirV(m_context.getTestContext().getLog(), m_validations[v].shaders[s]);
2845 binariesVec.push_back(shaderBinary);
2846 binaries << shaderBinary;
2848 #else // DEQP_HAVE_GLSLANG
2849 tcu::Archive& archive = m_testCtx.getArchive();
2850 ProgramBinaries binaries;
2851 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2853 std::stringstream ss;
2854 ss << "spirv/spirv_validation_builtin_variable_decorations/shader_" << v << "_" << s << ".nspv";
2856 ShaderBinary shaderBinary = commonUtils::readSpirV(archive.getResource(ss.str().c_str()));
2857 binariesVec.push_back(shaderBinary);
2858 binaries << shaderBinary;
2860 #endif // DEQP_HAVE_GLSLANG
2861 program = new ShaderProgram(gl, binaries);
2863 #if defined DEQP_HAVE_SPIRV_TOOLS
2864 std::string spirvSource;
2866 for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
2868 ShaderSource shaderSource = m_validations[v].shaders[s];
2870 glslangUtils::spirvDisassemble(spirvSource, binariesVec[s].binary);
2872 if (!glslangUtils::verifyMappings(shaderSource.source, spirvSource, m_mappings, true))
2874 m_testCtx.getLog() << tcu::TestLog::Message << "Mappings for shader failed.\n"
2876 << shaderSource.source.c_str() << "\n"
2877 << "SpirV source:\n"
2878 << spirvSource.c_str() << tcu::TestLog::EndMessage;
2880 TCU_THROW(InternalError, "Mappings for shader failed.");
2883 #endif // DEQP_HAVE_SPIRV_TOOLS
2886 if (!program->isOk())
2888 std::stringstream message;
2889 message << "Shader build failed.\n";
2891 if (program->hasShader(SHADERTYPE_COMPUTE))
2892 message << "ComputeInfo: " << program->getShaderInfo(SHADERTYPE_COMPUTE).infoLog << "\n"
2893 << "ComputeSource: " << program->getShader(SHADERTYPE_COMPUTE)->getSource() << "\n";
2894 if (program->hasShader(SHADERTYPE_VERTEX))
2895 message << "VertexInfo: " << program->getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n"
2896 << "VertexSource: " << program->getShader(SHADERTYPE_VERTEX)->getSource() << "\n";
2897 if (program->hasShader(SHADERTYPE_TESSELLATION_CONTROL))
2898 message << "TesselationCtrlInfo: "
2899 << program->getShaderInfo(SHADERTYPE_TESSELLATION_CONTROL).infoLog << "\n"
2900 << "TesselationCtrlSource: "
2901 << program->getShader(SHADERTYPE_TESSELLATION_CONTROL)->getSource() << "\n";
2902 if (program->hasShader(SHADERTYPE_TESSELLATION_EVALUATION))
2903 message << "TesselationEvalInfo: "
2904 << program->getShaderInfo(SHADERTYPE_TESSELLATION_EVALUATION).infoLog << "\n"
2905 << "TesselationEvalSource: "
2906 << program->getShader(SHADERTYPE_TESSELLATION_EVALUATION)->getSource() << "\n";
2907 if (program->hasShader(SHADERTYPE_GEOMETRY))
2908 message << "GeometryInfo: " << program->getShaderInfo(SHADERTYPE_GEOMETRY).infoLog << "\n"
2909 << "GeometrySource: " << program->getShader(SHADERTYPE_GEOMETRY)->getSource() << "\n";
2910 if (program->hasShader(SHADERTYPE_FRAGMENT))
2911 message << "FragmentInfo: " << program->getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n"
2912 << "FragmentSource: " << program->getShader(SHADERTYPE_FRAGMENT)->getSource() << "\n";
2914 message << "ProgramInfo: " << program->getProgramInfo().infoLog;
2916 m_testCtx.getLog() << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
2918 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2922 gl.useProgram(program->getProgram());
2923 GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram");
2925 ValidationFuncPtr funcPtr = m_validations[v].validationFuncPtr;
2926 result = (this->*funcPtr)(m_validations[v].outputs);
2933 m_testCtx.getLog() << tcu::TestLog::Message << "Validation " << v << " failed!"
2934 << tcu::TestLog::EndMessage;
2943 gl.deleteBuffers(1, &vbo);
2944 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteBuffers");
2949 gl.deleteVertexArrays(1, &vao);
2950 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteVertexArrays");
2954 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
2956 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
2960 bool SpirvValidationBuiltInVariableDecorationsTest::validComputeFunc(ValidationOutputVec& outputs)
2964 const Functions& gl = m_context.getRenderContext().getFunctions();
2968 gl.genTextures(5, textures);
2969 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
2970 for (int i = 0; i < 5; ++i)
2972 gl.bindTexture(GL_TEXTURE_2D, textures[i]);
2973 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
2974 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8UI, 4, 4);
2975 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
2978 gl.bindImageTexture(0, textures[0], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI);
2979 GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture");
2980 gl.bindImageTexture(1, textures[1], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI);
2981 GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture");
2982 gl.bindImageTexture(2, textures[2], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI);
2983 GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture");
2984 gl.bindImageTexture(3, textures[3], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI);
2985 GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture");
2986 gl.bindImageTexture(4, textures[4], 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8UI);
2987 GLU_EXPECT_NO_ERROR(gl.getError(), "bindImageTexture");
2989 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2991 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2993 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2995 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2997 GLU_EXPECT_NO_ERROR(gl.getError(), "uniform1i");
2998 gl.dispatchCompute(4, 2, 1);
2999 GLU_EXPECT_NO_ERROR(gl.getError(), "dispatchCompute");
3001 gl.memoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
3002 GLU_EXPECT_NO_ERROR(gl.getError(), "memoryBarrier");
3004 std::vector<GLubyte> expectedResults[5];
3005 for (int i = 0; i < 5; ++i)
3007 for (int y = 0; y < 4; ++y)
3009 for (int x = 0; x < 4; ++x)
3011 //"uvec3 color0 = uvec3(gl_NumWorkGroups);"
3014 expectedResults[i].push_back(4);
3015 expectedResults[i].push_back(2);
3016 expectedResults[i].push_back(1);
3017 expectedResults[i].push_back(0xFF);
3019 //"uvec3 color1 = uvec3(gl_WorkGroupSize);"
3022 expectedResults[i].push_back(1);
3023 expectedResults[i].push_back(2);
3024 expectedResults[i].push_back(1);
3025 expectedResults[i].push_back(0xFF);
3027 //"uvec3 color2 = uvec3(gl_WorkGroupID);"
3030 expectedResults[i].push_back(x);
3031 expectedResults[i].push_back(y / 2);
3032 expectedResults[i].push_back(0);
3033 expectedResults[i].push_back(0xFF);
3035 //"uvec3 color3 = uvec3(gl_LocalInvocationID);"
3038 expectedResults[i].push_back(0);
3039 expectedResults[i].push_back(y % 2);
3040 expectedResults[i].push_back(0);
3041 expectedResults[i].push_back(0xFF);
3043 //"uvec3 color4 = uvec3(gl_LocalInvocationIndex);"
3046 expectedResults[i].push_back(y % 2);
3047 expectedResults[i].push_back(y % 2);
3048 expectedResults[i].push_back(y % 2);
3049 expectedResults[i].push_back(0xFF);
3056 for (int i = 0; i < 5; ++i)
3058 gl.bindTexture(GL_TEXTURE_2D, textures[i]);
3059 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3061 std::vector<GLubyte> pixels;
3062 pixels.resize(4 * 4 * 4);
3063 gl.getTexImage(GL_TEXTURE_2D, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, (GLvoid*)pixels.data());
3064 GLU_EXPECT_NO_ERROR(gl.getError(), "getTexImage");
3066 if (pixels != expectedResults[i])
3068 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid image computed [" << i << "]."
3069 << tcu::TestLog::EndMessage;
3075 gl.deleteTextures(5, textures);
3076 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3081 bool SpirvValidationBuiltInVariableDecorationsTest::validPerVertexFragFunc(ValidationOutputVec& outputs)
3083 const Functions& gl = m_context.getRenderContext().getFunctions();
3085 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
3090 gl.genTextures(1, &texture);
3091 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3092 gl.bindTexture(GL_TEXTURE_2D, texture);
3093 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3094 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 64, 64);
3095 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
3097 gl.genFramebuffers(1, &fbo);
3098 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
3099 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3100 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3101 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3102 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3104 gl.viewport(0, 0, 64, 64);
3105 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3107 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3108 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3110 gl.enable(GL_CLIP_DISTANCE0);
3112 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3113 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
3114 gl.clear(GL_COLOR_BUFFER_BIT);
3115 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
3117 gl.enableVertexAttribArray(0);
3118 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3120 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3121 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3123 gl.drawArrays(GL_TRIANGLES, 0, 3);
3124 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3126 gl.disableVertexAttribArray(0);
3127 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3129 gl.disable(GL_CLIP_DISTANCE0);
3132 for (int o = 0; o < (signed)outputs.size(); ++o)
3135 gl.readPixels(outputs[o].x, outputs[o].y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&output);
3136 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
3138 if (!commonUtils::compareUintColors(output, outputs[o].value, 2))
3140 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid output color read at [" << (int)outputs[o].x << "/"
3141 << (int)outputs[o].y << "]. Expected: " << outputs[o].value << ", "
3142 << "Read: " << output << tcu::TestLog::EndMessage;
3150 gl.deleteFramebuffers(1, &fbo);
3151 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3156 gl.deleteTextures(1, &texture);
3157 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3163 bool SpirvValidationBuiltInVariableDecorationsTest::validPerVertexPointFunc(ValidationOutputVec& outputs)
3165 const Functions& gl = m_context.getRenderContext().getFunctions();
3167 const GLfloat vertices[] = { -0.3f, -0.3f, 0.0f, 0.0f, -0.3f, 0.0f, 0.3f, -0.3f, 0.0f };
3172 gl.genTextures(1, &texture);
3173 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3174 gl.bindTexture(GL_TEXTURE_2D, texture);
3175 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3176 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 128, 128);
3177 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
3179 gl.genFramebuffers(1, &fbo);
3180 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
3181 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3182 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3183 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3184 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3186 gl.viewport(0, 0, 128, 128);
3187 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3189 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3190 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3192 gl.enable(GL_CLIP_DISTANCE0);
3193 gl.enable(GL_PROGRAM_POINT_SIZE);
3195 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3196 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
3197 gl.clear(GL_COLOR_BUFFER_BIT);
3198 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
3200 gl.enableVertexAttribArray(0);
3201 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3203 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3204 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3206 gl.drawArraysInstanced(GL_POINTS, 0, 3, 3);
3207 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3209 gl.disableVertexAttribArray(0);
3210 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3212 gl.disable(GL_PROGRAM_POINT_SIZE);
3213 gl.disable(GL_CLIP_DISTANCE0);
3216 for (int o = 0; o < (signed)outputs.size(); ++o)
3219 gl.readPixels(outputs[o].x, outputs[o].y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&output);
3220 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
3222 if (!commonUtils::compareUintColors(output, outputs[o].value, 2))
3224 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid output color read at [" << (int)outputs[o].x << "/"
3225 << (int)outputs[o].y << "]. Expected: " << outputs[o].value << ", "
3226 << "Read: " << output << tcu::TestLog::EndMessage;
3234 gl.deleteFramebuffers(1, &fbo);
3235 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3240 gl.deleteTextures(1, &texture);
3241 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3247 bool SpirvValidationBuiltInVariableDecorationsTest::validTesselationGeometryFunc(ValidationOutputVec& outputs)
3249 const Functions& gl = m_context.getRenderContext().getFunctions();
3251 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
3256 gl.genTextures(1, &texture);
3257 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3258 gl.bindTexture(GL_TEXTURE_2D_ARRAY, texture);
3259 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3260 gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 64, 64, 2);
3261 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
3263 gl.genFramebuffers(1, &fbo);
3264 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
3265 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3266 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3267 gl.framebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
3268 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3270 gl.viewportIndexedf(0, 0.0f, 0.0f, 32.0f, 64.0f);
3271 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewportIndexed");
3273 gl.viewportIndexedf(1, 32.0f, 0.0f, 32.0f, 64.0f);
3274 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewportIndexed");
3276 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3277 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3279 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3280 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
3281 gl.clear(GL_COLOR_BUFFER_BIT);
3282 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
3284 gl.enableVertexAttribArray(0);
3285 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3287 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3288 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3290 gl.patchParameteri(GL_PATCH_VERTICES, 3);
3291 gl.drawArrays(GL_PATCHES, 0, 3);
3292 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3294 gl.disableVertexAttribArray(0);
3295 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3297 gl.viewport(0, 0, 128, 64);
3298 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3300 std::vector<GLuint> pixels;
3301 pixels.resize(64 * 64 * 2);
3302 gl.getTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)pixels.data());
3303 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetTexImage");
3306 for (int o = 0; o < (signed)outputs.size(); ++o)
3308 GLuint output = pixels[(outputs[o].x + outputs[o].y * 64) + outputs[o].z * 64 * 64];
3310 if (!commonUtils::compareUintColors(output, outputs[o].value, 2))
3312 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid output color read at [" << (int)outputs[o].x << "/"
3313 << (int)outputs[o].y << "/" << (int)outputs[o].z << "]. Expected: " << outputs[o].value
3315 << "Read: " << output << tcu::TestLog::EndMessage;
3323 gl.deleteFramebuffers(1, &fbo);
3324 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3329 gl.deleteTextures(1, &texture);
3330 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3336 bool SpirvValidationBuiltInVariableDecorationsTest::validMultiSamplingFunc(ValidationOutputVec& outputs)
3338 const Functions& gl = m_context.getRenderContext().getFunctions();
3340 const GLfloat vertices[] = { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f };
3347 gl.genTextures(1, &textureMS);
3348 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3349 gl.bindTexture(GL_TEXTURE_2D_MULTISAMPLE, textureMS);
3350 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3351 gl.texStorage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, 2, GL_RGBA8, 32, 32, GL_TRUE);
3352 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2DMultisample");
3354 gl.genTextures(1, &texture);
3355 GLU_EXPECT_NO_ERROR(gl.getError(), "genTextures");
3356 gl.bindTexture(GL_TEXTURE_2D, texture);
3357 GLU_EXPECT_NO_ERROR(gl.getError(), "bindTexture");
3358 gl.texStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 32, 32);
3359 GLU_EXPECT_NO_ERROR(gl.getError(), "texStorage2D");
3361 gl.genFramebuffers(1, &fboMS);
3362 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
3363 gl.bindFramebuffer(GL_FRAMEBUFFER, fboMS);
3364 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3365 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, textureMS, 0);
3366 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3368 gl.genFramebuffers(1, &fbo);
3369 GLU_EXPECT_NO_ERROR(gl.getError(), "genFramenuffers");
3370 gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
3371 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3372 gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
3373 GLU_EXPECT_NO_ERROR(gl.getError(), "framebufferTexture2D");
3375 gl.bindFramebuffer(GL_FRAMEBUFFER, fboMS);
3376 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3378 gl.viewport(0, 0, 32, 32);
3379 GLU_EXPECT_NO_ERROR(gl.getError(), "glViewport");
3381 gl.bufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), (GLvoid*)vertices, GL_DYNAMIC_DRAW);
3382 GLU_EXPECT_NO_ERROR(gl.getError(), "glBufferData");
3384 gl.enable(GL_CLIP_DISTANCE0);
3386 gl.clearColor(0.0f, 0.0f, 0.0f, 1.0f);
3387 GLU_EXPECT_NO_ERROR(gl.getError(), "glClearColor");
3388 gl.clear(GL_COLOR_BUFFER_BIT);
3389 GLU_EXPECT_NO_ERROR(gl.getError(), "glClear");
3391 gl.enableVertexAttribArray(0);
3392 GLU_EXPECT_NO_ERROR(gl.getError(), "glEnableVertexAttribArray");
3394 gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, DE_NULL);
3395 GLU_EXPECT_NO_ERROR(gl.getError(), "glVertexAttribPointer");
3397 gl.drawArrays(GL_TRIANGLES, 0, 3);
3398 GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawArray");
3400 gl.disableVertexAttribArray(0);
3401 GLU_EXPECT_NO_ERROR(gl.getError(), "glDisableVertexAttribArray");
3403 gl.disable(GL_CLIP_DISTANCE0);
3405 gl.bindFramebuffer(GL_READ_FRAMEBUFFER, fboMS);
3406 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3407 gl.bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
3408 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3410 gl.blitFramebuffer(0, 0, 32, 32, 0, 0, 32, 32, GL_COLOR_BUFFER_BIT, GL_NEAREST);
3411 GLU_EXPECT_NO_ERROR(gl.getError(), "blitFramebuffer");
3413 gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
3414 GLU_EXPECT_NO_ERROR(gl.getError(), "bindFramebuffer");
3416 const int epsilon = 2;
3418 for (int o = 0; o < (signed)outputs.size(); ++o)
3421 gl.readPixels(outputs[o].x, outputs[o].y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)&output);
3422 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels");
3424 // The fragment shader for this case is rendering to a 2-sample FBO discarding
3425 // sample 0 and rendering 100% green to sample 1, so we expect a green output.
3426 // However, because sample locations may not be the same across implementations,
3427 // and that can influence their weights during the multisample resolve,
3428 // we can only check that there has to be some green in the output (since we know
3429 // that we have a green sample being selected) and that the level of green is not
3430 // 100% (since we know that pixel coverage is not 100% because we are
3431 // discarding one of the samples).
3433 int r1 = (output & 0xFF);
3434 int g1 = ((output >> 8) & 0xFF);
3435 int b1 = ((output >> 16) & 0xFF);
3436 int a1 = ((output >> 24) & 0xFF);
3438 int r2 = (outputs[o].value & 0xFF);
3439 int b2 = ((outputs[o].value >> 16) & 0xFF);
3440 int a2 = ((outputs[o].value >> 24) & 0xFF);
3442 if (r1 < r2 - epsilon || r1 > r2 + epsilon ||
3443 g1 == 0x00 || g1 == 0xFF ||
3444 b1 < b2 - epsilon || b1 > b2 + epsilon ||
3445 a1 < a2 - epsilon || a1 > a2 + epsilon)
3447 m_testCtx.getLog() << tcu::TestLog::Message << "Invalid output color read at [" << (int)outputs[o].x << "/"
3448 << (int)outputs[o].y << "]. Expected 0xff00xx00, with xx anything but ff or 00. "
3449 << "Read: " << std::hex << output << tcu::TestLog::EndMessage;
3457 gl.deleteFramebuffers(1, &fboMS);
3458 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3463 gl.deleteFramebuffers(1, &fbo);
3464 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteFramebuffers");
3469 gl.deleteTextures(1, &texture);
3470 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3475 gl.deleteTextures(1, &texture);
3476 GLU_EXPECT_NO_ERROR(gl.getError(), "glDeleteTextures");
3484 * @param context Rendering context
3485 * @param name Test name
3486 * @param description Test description
3488 SpirvValidationCapabilitiesTest::SpirvValidationCapabilitiesTest(deqp::Context& context)
3489 : TestCase(context, "spirv_validation_capabilities_test", "Test verifies if Spir-V capabilities works as expected.")
3491 /* Left blank intentionally */
3494 /** Stub init method */
3495 void SpirvValidationCapabilitiesTest::init()
3497 ShaderStage computeStage;
3498 computeStage.source = ComputeSource("#version 450\n"
3500 "layout (local_size_x = 1, local_size_y = 2, local_size_z = 1) in;\n"
3502 "layout (location = 0, rgba8) uniform image2DMS img0;\n"
3503 "layout (location = 1, rgba8) uniform image2DMSArray img1;\n"
3504 "layout (location = 2, rgba8) uniform image2DRect img2;\n"
3505 "layout (location = 3, rgba8) uniform imageCube img3;\n"
3506 "layout (location = 4, rgba8) uniform imageCubeArray img4;\n"
3507 "layout (location = 5, rgba8) uniform imageBuffer img5;\n"
3508 "layout (location = 6, rgba8) uniform image2D img6;\n"
3509 "layout (location = 7, rgba8) uniform image1D img7;\n"
3510 "layout (location = 8) uniform writeonly image1D img8;\n"
3511 "layout (location = 9, rg32f) uniform image1D img9;\n"
3512 "layout (location = 10) uniform sampler2DRect img10;\n"
3513 "layout (location = 11) uniform samplerCubeArray img11;\n"
3514 "layout (location = 12) uniform samplerBuffer img12;\n"
3515 "layout (location = 13) uniform sampler1D img13;\n"
3516 "layout (location = 14) uniform sampler2D img14;\n"
3518 "layout (binding = 0) uniform atomic_uint atCounter;\n"
3522 " ivec2 size = imageSize(img6);\n"
3523 " ivec3 point = ivec3(gl_GlobalInvocationID);\n"
3524 " imageStore(img0, point.xy, 0, vec4(0));\n"
3525 " imageStore(img1, point, 0, vec4(0));\n"
3526 " imageStore(img2, point.xy, vec4(0));\n"
3527 " imageStore(img3, point, vec4(0));\n"
3528 " imageStore(img4, point, vec4(0));\n"
3529 " imageStore(img5, point.x, vec4(0));\n"
3530 " imageStore(img6, point.xy, vec4(0));\n"
3531 " imageStore(img7, point.x, vec4(0));\n"
3532 " imageStore(img8, point.x, vec4(0));\n"
3534 " vec3 coord = vec3(0);\n"
3535 " ivec2 offset = ivec2(gl_GlobalInvocationID.xy);\n"
3537 " color = textureGather(img10, coord.xy);\n"
3538 " color = textureGather(img11, vec4(0));\n"
3539 " color = texelFetch(img12, point.x);\n"
3540 " color = textureGatherOffset(img14, coord.xy, offset);\n"
3541 " memoryBarrier();\n"
3544 computeStage.caps.push_back("Shader");
3545 computeStage.caps.push_back("SampledRect Shader");
3546 computeStage.caps.push_back("SampledCubeArray Shader");
3547 computeStage.caps.push_back("SampledBuffer Shader");
3548 computeStage.caps.push_back("Sampled1D");
3549 computeStage.caps.push_back("ImageRect SampledRect Shader");
3550 computeStage.caps.push_back("Image1D Sampled1D");
3551 computeStage.caps.push_back("ImageCubeArray SampledCubeArray Shader");
3552 computeStage.caps.push_back("ImageBuffer SampledBuffer");
3553 computeStage.caps.push_back("ImageMSArray Shader");
3554 computeStage.caps.push_back("ImageQuery Shader");
3555 computeStage.caps.push_back("ImageGatherExtended Shader");
3556 computeStage.caps.push_back("StorageImageExtendedFormats Shader");
3557 computeStage.caps.push_back("StorageImageWriteWithoutFormat Shader");
3558 computeStage.caps.push_back("AtomicStorage Shader");
3560 ShaderStage vertexStage;
3561 vertexStage.source = VertexSource("#version 450\n"
3563 "layout (location = 0) in vec3 position;\n"
3564 "layout (location = 1) in mat4 projMatrix;\n"
3566 "layout (location = 2, xfb_buffer = 0) out float xfbVal;\n"
3567 "layout (location = 3) out vec2 texCoord;\n"
3571 " double dval = double(position.x);\n"
3572 " gl_Position = vec4(position, 1.0) * projMatrix;\n"
3573 " gl_ClipDistance[0] = 0.0;\n"
3574 " gl_CullDistance[0] = 0.0;\n"
3577 " texCoord = vec2(0, 0);\n"
3580 vertexStage.caps.push_back("Matrix");
3581 vertexStage.caps.push_back("Shader Matrix");
3582 vertexStage.caps.push_back("Float64");
3583 vertexStage.caps.push_back("ClipDistance Shader");
3584 vertexStage.caps.push_back("CullDistance Shader");
3585 vertexStage.caps.push_back("TransformFeedback Shader");
3587 ShaderStage tessCtrlStage;
3588 tessCtrlStage.source =
3589 TessellationControlSource("#version 450\n"
3591 "layout (vertices = 3) out;\n"
3595 " if (gl_InvocationID == 0) {\n"
3596 " gl_TessLevelOuter[0] = 1.0;\n"
3597 " gl_TessLevelOuter[1] = 1.0;\n"
3598 " gl_TessLevelOuter[2] = 1.0;\n"
3599 " gl_TessLevelInner[0] = 1.0;\n"
3602 " gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
3603 " gl_out[gl_InvocationID].gl_PointSize = gl_in[gl_InvocationID].gl_PointSize;\n"
3606 tessCtrlStage.caps.push_back("Tessellation Shader");
3607 tessCtrlStage.caps.push_back("TessellationPointSize Tessellation");
3609 ShaderStage tessEvalStage;
3610 tessEvalStage.source = TessellationEvaluationSource("#version 450\n"
3612 "layout (triangles) in;\n"
3616 " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position +\n"
3617 " gl_TessCoord.y * gl_in[1].gl_Position +\n"
3618 " gl_TessCoord.z * gl_in[2].gl_Position;\n"
3621 ShaderStage geometryStage;
3622 geometryStage.source = GeometrySource("#version 450\n"
3624 "layout (triangles) in;\n"
3625 "layout (triangle_strip, max_vertices = 3) out;\n"
3629 " gl_ViewportIndex = 0;\n"
3630 " for (int i = 0; i < 3; ++i) {\n"
3631 " gl_Position = gl_in[i].gl_Position;\n"
3632 " gl_PointSize = gl_in[i].gl_PointSize;\n"
3633 " EmitStreamVertex(0);\n"
3635 " EndStreamPrimitive(0);\n"
3638 geometryStage.caps.push_back("Geometry Shader");
3639 geometryStage.caps.push_back("GeometryPointSize Geometry");
3640 geometryStage.caps.push_back("GeometryStreams Geometry");
3641 geometryStage.caps.push_back("MultiViewport Geometry");
3643 ShaderStage fragmentStage;
3644 fragmentStage.source = FragmentSource("#version 450\n"
3646 "layout (location = 3) in vec2 texCoord;\n"
3648 "layout (location = 0) out vec4 fColor;\n"
3650 "layout (location = 1) uniform sampler2D tex;\n"
3654 " vec2 p = vec2(gl_SampleID);\n"
3655 " vec2 dx = dFdxFine(p);\n"
3657 " interpolateAtCentroid(texCoord);"
3659 " fColor = vec4(1.0);\n"
3662 fragmentStage.caps.push_back("Shader");
3663 fragmentStage.caps.push_back("DerivativeControl Shader");
3664 fragmentStage.caps.push_back("SampleRateShading");
3665 fragmentStage.caps.push_back("InterpolationFunction");
3667 ShaderStage dynamicIndexingStage;
3668 dynamicIndexingStage.source = ComputeSource("#version 450\n"
3670 "layout (location = 0) uniform sampler2D uniSamp[10];\n"
3671 "layout (location = 10, rgba8) uniform image2D uniImg[10];\n"
3672 "layout (binding = 5) uniform UniData\n"
3676 "layout (binding = 5) buffer StorageData\n"
3679 "} storageBuff[10];\n"
3683 " vec2 coord = vec2(0.0);\n"
3684 " ivec2 point = ivec2(0);\n"
3687 " for (int i = 0; i < 10; ++i)"
3689 " ret = ret + uniBuff[i].a[i] + storageBuff[i].a[i];\n"
3690 " textureGather(uniSamp[i], coord);\n"
3691 " imageLoad(uniImg[i], point);\n"
3693 " memoryBarrier();\n"
3696 dynamicIndexingStage.caps.push_back("UniformBufferArrayDynamicIndexing");
3697 dynamicIndexingStage.caps.push_back("SampledImageArrayDynamicIndexing");
3698 dynamicIndexingStage.caps.push_back("StorageBufferArrayDynamicIndexing");
3699 dynamicIndexingStage.caps.push_back("StorageImageArrayDynamicIndexing");
3701 Pipeline computePipeline;
3702 computePipeline.push_back(computeStage);
3704 Pipeline standardPipeline;
3705 standardPipeline.push_back(vertexStage);
3706 standardPipeline.push_back(tessCtrlStage);
3707 standardPipeline.push_back(tessEvalStage);
3708 standardPipeline.push_back(geometryStage);
3709 standardPipeline.push_back(fragmentStage);
3711 Pipeline dynamicIndexingPipeline;
3712 dynamicIndexingPipeline.push_back(dynamicIndexingStage);
3714 m_pipelines.push_back(computePipeline);
3715 m_pipelines.push_back(standardPipeline);
3716 m_pipelines.push_back(dynamicIndexingPipeline);
3718 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_int64"))
3720 ShaderStage computeStageExt("GL_ARB_gpu_shader_int64");
3721 computeStageExt.source = ComputeSource("#version 450\n"
3723 "#extension GL_ARB_gpu_shader_int64 : require\n"
3727 " int64_t ival = int64_t(gl_GlobalInvocationID.x);\n"
3729 computeStageExt.caps.push_back("Int64");
3731 Pipeline extPipeline;
3732 extPipeline.push_back(computeStageExt);
3734 m_pipelines.push_back(extPipeline);
3737 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture2"))
3740 ShaderStage computeStageExt("GL_ARB_sparse_texture2");
3741 computeStageExt.source = ComputeSource("#version 450\n"
3743 "#extension GL_ARB_sparse_texture2 : require\n"
3745 "layout (location = 0) uniform sampler2D tex;\n"
3749 " vec2 p = vec2(0.0);\n"
3752 " sparseTextureARB(tex, p, spCol);\n"
3755 computeStageExt.caps.push_back("SparseResidency");
3757 Pipeline extPipeline;
3758 extPipeline.push_back(computeStageExt);
3760 m_pipelines.push_back(extPipeline);
3763 if (m_context.getContextInfo().isExtensionSupported("GL_ARB_sparse_texture_clamp"))
3765 ShaderStage vertexStageExt("GL_ARB_sparse_texture_clamp_vert");
3766 vertexStageExt.source = VertexSource("#version 450\n"
3768 "layout (location = 0) in vec4 pos;\n"
3772 " gl_Position = pos;\n"
3775 ShaderStage fragmentStageExt("GL_ARB_sparse_texture_clamp_frag");
3776 fragmentStageExt.source = FragmentSource("#version 450\n"
3778 "#extension GL_ARB_sparse_texture2 : require\n"
3779 "#extension GL_ARB_sparse_texture_clamp : require\n"
3781 "uniform sampler2D tex;\n"
3783 "layout (location = 0) out vec4 spCol;\n"
3787 " vec2 p = vec2(0.0);\n"
3789 " sparseTextureClampARB(tex, p, 0.5, spCol);\n"
3792 fragmentStageExt.caps.push_back("MinLod");
3794 Pipeline extPipeline;
3795 extPipeline.push_back(vertexStageExt);
3796 extPipeline.push_back(fragmentStageExt);
3798 m_pipelines.push_back(extPipeline);
3802 if (m_context.getContextInfo().isExtensionSupported("GL_EXT_shader_image_load_formatted"))
3804 ShaderStage computeStageExt("GL_EXT_shader_image_load_formatted");
3805 computeStageExt.source = ComputeSource("#version 450\n"
3807 "#extension GL_EXT_shader_image_load_formatted : require\n"
3809 "layout (location = 0) uniform image2D img;\n"
3813 " ivec3 point = ivec3(gl_GlobalInvocationID);\n"
3814 " vec4 color = imageLoad(img, point.xy);\n"
3817 computeStageExt.caps.push_back("StorageImageReadWithoutFormat");
3819 Pipeline extPipeline;
3820 extPipeline.push_back(computeStageExt);
3822 m_pipelines.push_back(extPipeline);
3826 /** Stub de-init method */
3827 void SpirvValidationCapabilitiesTest::deinit()
3831 /** Executes test iteration.
3833 * @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
3835 tcu::TestNode::IterateResult SpirvValidationCapabilitiesTest::iterate()
3837 const Functions& gl = m_context.getRenderContext().getFunctions();
3839 for (int p = 0; p < (signed)m_pipelines.size(); ++p)
3841 ProgramBinaries programBinaries;
3843 Pipeline& pipeline = m_pipelines[p];
3844 for (int s = 0; s < (signed)pipeline.size(); ++s)
3846 ShaderStage& stage = pipeline[s];
3847 #if defined DEQP_HAVE_GLSLANG
3848 stage.binary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), stage.source);
3849 std::stringstream ssw;
3850 if (stage.name.empty())
3851 ssw << "gl_cts/data/spirv/spirv_validation_capabilities/binary_p" << p << "s" << s << ".nspv";
3853 ssw << "gl_cts/data/spirv/spirv_validation_capabilities/" << stage.name << ".nspv";
3854 commonUtils::writeSpirV(ssw.str().c_str(), stage.binary);
3855 #else // DEQP_HAVE_GLSLANG
3856 tcu::Archive& archive = m_testCtx.getArchive();
3857 std::stringstream ss;
3858 if (stage.name.empty())
3859 ss << "spirv/spirv_validation_capabilities/binary_p" << p << "s" << s << ".nspv";
3861 ss << "spirv/spirv_validation_capabilities/" << stage.name << ".nspv";
3862 stage.binary = commonUtils::readSpirV(archive.getResource(ss.str().c_str()));
3863 #endif // DEQP_HAVE_GLSLANG
3864 programBinaries << stage.binary;
3867 ShaderProgram program(gl, programBinaries);
3868 if (!program.isOk())
3870 std::stringstream ssLog;
3872 ssLog << "Program build failed [" << p << "].\n";
3873 if (program.hasShader(SHADERTYPE_COMPUTE))
3874 ssLog << "Compute: " << program.getShaderInfo(SHADERTYPE_COMPUTE).infoLog << "\n";
3875 if (program.hasShader(SHADERTYPE_VERTEX))
3876 ssLog << "Vertex: " << program.getShaderInfo(SHADERTYPE_VERTEX).infoLog << "\n";
3877 if (program.hasShader(SHADERTYPE_TESSELLATION_CONTROL))
3878 ssLog << "TessellationCtrl: " << program.getShaderInfo(SHADERTYPE_TESSELLATION_CONTROL).infoLog << "\n";
3879 if (program.hasShader(SHADERTYPE_TESSELLATION_EVALUATION))
3880 ssLog << "TessellationEval: " << program.getShaderInfo(SHADERTYPE_TESSELLATION_EVALUATION).infoLog
3882 if (program.hasShader(SHADERTYPE_GEOMETRY))
3883 ssLog << "Geometry: " << program.getShaderInfo(SHADERTYPE_GEOMETRY).infoLog << "\n";
3884 if (program.hasShader(SHADERTYPE_FRAGMENT))
3885 ssLog << "Fragment: " << program.getShaderInfo(SHADERTYPE_FRAGMENT).infoLog << "\n";
3886 ssLog << "Program: " << program.getProgramInfo().infoLog;
3888 m_testCtx.getLog() << tcu::TestLog::Message << ssLog.str() << tcu::TestLog::EndMessage;
3890 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
3894 #if defined DEQP_HAVE_SPIRV_TOOLS
3895 for (int s = 0; s < (signed)pipeline.size(); ++s)
3897 ShaderStage stage = pipeline[s];
3898 ShaderBinary binary = stage.binary;
3900 std::string spirVSource;
3901 glslangUtils::spirvDisassemble(spirVSource, binary.binary);
3903 for (int c = 0; c < (signed)stage.caps.size(); ++c)
3905 std::string spirVSourceCut;
3906 int foundCount = spirVCapabilityCutOff(spirVSource, spirVSourceCut, stage.caps, c);
3908 if (foundCount == 0)
3911 << tcu::TestLog::Message << "OpCapability (" << stage.caps[c] << ") [" << p << "/" << s
3913 << "Neither capability nor capabilities that depends on this capability has been found."
3914 << tcu::TestLog::EndMessage;
3918 // Assemble and validate cut off SpirV source
3919 glslangUtils::spirvAssemble(binary.binary, spirVSourceCut);
3920 if (glslangUtils::spirvValidate(binary.binary, false))
3922 m_testCtx.getLog() << tcu::TestLog::Message << "OpCapability (" << stage.caps[c] << ") [" << p
3923 << "/" << s << "].\n"
3924 << "Validation passed without corresponding OpCapability declared."
3925 << tcu::TestLog::EndMessage;
3930 #endif // DEQP_HAVE_SPIRV_TOOLS
3933 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
3937 int SpirvValidationCapabilitiesTest::spirVCapabilityCutOff(std::string spirVSrcInput, std::string& spirVSrcOutput,
3938 CapabilitiesVec& capabilities, int& currentCapability)
3940 std::vector<std::string> current = de::splitString(capabilities[currentCapability], ' ');
3942 CapabilitiesVec toDisable;
3943 toDisable.push_back(current[0]);
3945 // Search for capabilities that depends on current one as it should be removed either
3946 for (int cr = 0; cr < (signed)capabilities.size(); ++cr)
3948 std::vector<std::string> split = de::splitString(capabilities[cr], ' ');
3950 if (split[0] == current[0])
3953 for (int s = 1; s < (signed)split.size(); ++s)
3955 if (split[s] == current[0])
3956 toDisable.push_back(split[0]);
3960 // Disable current capability and capabilities that depends on it
3962 spirVSrcOutput = spirVSrcInput;
3963 for (int d = 0; d < (signed)toDisable.size(); ++d)
3965 std::string searchString = std::string("OpCapability ") + toDisable[d];
3967 size_t pos = spirVSrcOutput.find(searchString);
3969 if (pos != std::string::npos)
3972 spirVSrcOutput.erase(pos, searchString.length());
3981 * @param context Rendering context.
3983 GlSpirvTests::GlSpirvTests(deqp::Context& context)
3984 : TestCaseGroup(context, "gl_spirv", "Verify conformance of ARB_gl_spirv implementation")
3988 /** Initializes the test group contents. */
3989 void GlSpirvTests::init()
3991 addChild(new SpirvModulesPositiveTest(m_context));
3992 addChild(new SpirvShaderBinaryMultipleShaderObjectsTest(m_context));
3993 addChild(new SpirvModulesStateQueriesTest(m_context));
3994 addChild(new SpirvModulesErrorVerificationTest(m_context));
3995 addChild(new SpirvGlslToSpirVEnableTest(m_context));
3996 addChild(new SpirvGlslToSpirVBuiltInFunctionsTest(m_context));
3997 addChild(new SpirvGlslToSpirVSpecializationConstantsTest(m_context));
3998 addChild(new SpirvValidationBuiltInVariableDecorationsTest(m_context));
3999 addChild(new SpirvValidationCapabilitiesTest(m_context));
4002 } /* gl4cts namespace */