--- /dev/null
+/*-------------------------------------------------------------------------
+ * OpenGL Conformance Test Suite
+ * -----------------------------
+ *
+ * Copyright (c) 2017-2019 The Khronos Group Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */ /*!
+ * \file glcSpirvUtils.cpp
+ * \brief Utility functions for using Glslang and Spirv-tools to work with
+ * SPIR-V shaders.
+ */ /*-------------------------------------------------------------------*/
+
+#include "glcSpirvUtils.hpp"
+#include "deArrayUtil.hpp"
+#include "deSingleton.h"
+#include "deStringUtil.hpp"
+#include "gluContextInfo.hpp"
+#include "tcuTestLog.hpp"
+
+#if defined DEQP_HAVE_GLSLANG
+#include "SPIRV/GlslangToSpv.h"
+#include "SPIRV/disassemble.h"
+#include "SPIRV/doc.h"
+#include "glslang/MachineIndependent/localintermediate.h"
+#include "glslang/Public/ShaderLang.h"
+#endif // DEQP_HAVE_GLSLANG
+
+#if defined DEQP_HAVE_SPIRV_TOOLS
+#include "spirv-tools/libspirv.hpp"
+#include "spirv-tools/optimizer.hpp"
+#endif // DEQP_HAVE_SPIRV_TOOLS
+
+namespace glc
+{
+
+namespace spirvUtils
+{
+
+void checkGlSpirvSupported(deqp::Context& m_context)
+{
+ bool is_at_least_gl_46 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 6)));
+ bool is_arb_gl_spirv = m_context.getContextInfo().isExtensionSupported("GL_ARB_gl_spirv");
+
+ if ((!is_at_least_gl_46) && (!is_arb_gl_spirv))
+ TCU_THROW(NotSupportedError, "GL_ARB_gl_spirv is not supported");
+}
+
+#if defined DEQP_HAVE_GLSLANG
+
+EShLanguage getGlslangStage(glu::ShaderType type)
+{
+ static const EShLanguage stageMap[] = {
+ EShLangVertex, EShLangFragment, EShLangGeometry, EShLangTessControl, EShLangTessEvaluation, EShLangCompute,
+ };
+
+ return de::getSizedArrayElement<glu::SHADERTYPE_LAST>(stageMap, type);
+}
+
+static volatile deSingletonState s_glslangInitState = DE_SINGLETON_STATE_NOT_INITIALIZED;
+
+void initGlslang(void*)
+{
+ // Main compiler
+ glslang::InitializeProcess();
+
+ // SPIR-V disassembly
+ spv::Parameterize();
+}
+
+void prepareGlslang(void)
+{
+ deInitSingleton(&s_glslangInitState, initGlslang, DE_NULL);
+}
+
+void getDefaultLimits(TLimits* limits)
+{
+ limits->nonInductiveForLoops = true;
+ limits->whileLoops = true;
+ limits->doWhileLoops = true;
+ limits->generalUniformIndexing = true;
+ limits->generalAttributeMatrixVectorIndexing = true;
+ limits->generalVaryingIndexing = true;
+ limits->generalSamplerIndexing = true;
+ limits->generalVariableIndexing = true;
+ limits->generalConstantMatrixVectorIndexing = true;
+}
+
+void getDefaultBuiltInResources(TBuiltInResource* builtin)
+{
+ getDefaultLimits(&builtin->limits);
+
+ builtin->maxLights = 32;
+ builtin->maxClipPlanes = 6;
+ builtin->maxTextureUnits = 32;
+ builtin->maxTextureCoords = 32;
+ builtin->maxVertexAttribs = 64;
+ builtin->maxVertexUniformComponents = 4096;
+ builtin->maxVaryingFloats = 64;
+ builtin->maxVertexTextureImageUnits = 32;
+ builtin->maxCombinedTextureImageUnits = 80;
+ builtin->maxTextureImageUnits = 32;
+ builtin->maxFragmentUniformComponents = 4096;
+ builtin->maxDrawBuffers = 32;
+ builtin->maxVertexUniformVectors = 128;
+ builtin->maxVaryingVectors = 8;
+ builtin->maxFragmentUniformVectors = 16;
+ builtin->maxVertexOutputVectors = 16;
+ builtin->maxFragmentInputVectors = 15;
+ builtin->minProgramTexelOffset = -8;
+ builtin->maxProgramTexelOffset = 7;
+ builtin->maxClipDistances = 8;
+ builtin->maxComputeWorkGroupCountX = 65535;
+ builtin->maxComputeWorkGroupCountY = 65535;
+ builtin->maxComputeWorkGroupCountZ = 65535;
+ builtin->maxComputeWorkGroupSizeX = 1024;
+ builtin->maxComputeWorkGroupSizeY = 1024;
+ builtin->maxComputeWorkGroupSizeZ = 64;
+ builtin->maxComputeUniformComponents = 1024;
+ builtin->maxComputeTextureImageUnits = 16;
+ builtin->maxComputeImageUniforms = 8;
+ builtin->maxComputeAtomicCounters = 8;
+ builtin->maxComputeAtomicCounterBuffers = 1;
+ builtin->maxVaryingComponents = 60;
+ builtin->maxVertexOutputComponents = 64;
+ builtin->maxGeometryInputComponents = 64;
+ builtin->maxGeometryOutputComponents = 128;
+ builtin->maxFragmentInputComponents = 128;
+ builtin->maxImageUnits = 8;
+ builtin->maxCombinedImageUnitsAndFragmentOutputs = 8;
+ builtin->maxCombinedShaderOutputResources = 8;
+ builtin->maxImageSamples = 0;
+ builtin->maxVertexImageUniforms = 0;
+ builtin->maxTessControlImageUniforms = 0;
+ builtin->maxTessEvaluationImageUniforms = 0;
+ builtin->maxGeometryImageUniforms = 0;
+ builtin->maxFragmentImageUniforms = 8;
+ builtin->maxCombinedImageUniforms = 8;
+ builtin->maxGeometryTextureImageUnits = 16;
+ builtin->maxGeometryOutputVertices = 256;
+ builtin->maxGeometryTotalOutputComponents = 1024;
+ builtin->maxGeometryUniformComponents = 1024;
+ builtin->maxGeometryVaryingComponents = 64;
+ builtin->maxTessControlInputComponents = 128;
+ builtin->maxTessControlOutputComponents = 128;
+ builtin->maxTessControlTextureImageUnits = 16;
+ builtin->maxTessControlUniformComponents = 1024;
+ builtin->maxTessControlTotalOutputComponents = 4096;
+ builtin->maxTessEvaluationInputComponents = 128;
+ builtin->maxTessEvaluationOutputComponents = 128;
+ builtin->maxTessEvaluationTextureImageUnits = 16;
+ builtin->maxTessEvaluationUniformComponents = 1024;
+ builtin->maxTessPatchComponents = 120;
+ builtin->maxPatchVertices = 32;
+ builtin->maxTessGenLevel = 64;
+ builtin->maxViewports = 16;
+ builtin->maxVertexAtomicCounters = 0;
+ builtin->maxTessControlAtomicCounters = 0;
+ builtin->maxTessEvaluationAtomicCounters = 0;
+ builtin->maxGeometryAtomicCounters = 0;
+ builtin->maxFragmentAtomicCounters = 8;
+ builtin->maxCombinedAtomicCounters = 8;
+ builtin->maxAtomicCounterBindings = 1;
+ builtin->maxVertexAtomicCounterBuffers = 0;
+ builtin->maxTessControlAtomicCounterBuffers = 0;
+ builtin->maxTessEvaluationAtomicCounterBuffers = 0;
+ builtin->maxGeometryAtomicCounterBuffers = 0;
+ builtin->maxFragmentAtomicCounterBuffers = 1;
+ builtin->maxCombinedAtomicCounterBuffers = 1;
+ builtin->maxAtomicCounterBufferSize = 16384;
+ builtin->maxTransformFeedbackBuffers = 4;
+ builtin->maxTransformFeedbackInterleavedComponents = 64;
+ builtin->maxCullDistances = 8;
+ builtin->maxCombinedClipAndCullDistances = 8;
+ builtin->maxSamples = 4;
+ builtin->maxMeshOutputVerticesNV = 256;
+ builtin->maxMeshOutputPrimitivesNV = 256;
+ builtin->maxMeshWorkGroupSizeX_NV = 32;
+ builtin->maxMeshWorkGroupSizeY_NV = 1;
+ builtin->maxMeshWorkGroupSizeZ_NV = 1;
+ builtin->maxTaskWorkGroupSizeX_NV = 32;
+ builtin->maxTaskWorkGroupSizeY_NV = 1;
+ builtin->maxTaskWorkGroupSizeZ_NV = 1;
+ builtin->maxMeshViewCountNV = 4;
+};
+
+bool compileGlslToSpirV(tcu::TestLog& log, std::string source, glu::ShaderType type, ShaderBinaryDataType* dst)
+{
+ TBuiltInResource builtinRes;
+
+ prepareGlslang();
+ getDefaultBuiltInResources(&builtinRes);
+
+ const EShLanguage shaderStage = getGlslangStage(type);
+
+ glslang::TShader shader(shaderStage);
+ glslang::TProgram program;
+
+ const char* src[] = { source.c_str() };
+
+ shader.setStrings(src, 1);
+ program.addShader(&shader);
+
+ const int compileRes = shader.parse(&builtinRes, 100, false, EShMsgSpvRules);
+ if (compileRes != 0)
+ {
+ const int linkRes = program.link(EShMsgSpvRules);
+
+ if (linkRes != 0)
+ {
+ const glslang::TIntermediate* const intermediate = program.getIntermediate(shaderStage);
+ glslang::GlslangToSpv(*intermediate, *dst);
+
+ return true;
+ }
+ else
+ {
+ log << tcu::TestLog::Message << "Program linking error:\n"
+ << program.getInfoLog() << "\n"
+ << "Source:\n"
+ << source << "\n"
+ << tcu::TestLog::EndMessage;
+ }
+ }
+ else
+ {
+ log << tcu::TestLog::Message << "Shader compilation error:\n"
+ << shader.getInfoLog() << "\n"
+ << "Source:\n"
+ << source << "\n"
+ << tcu::TestLog::EndMessage;
+ }
+
+ return false;
+}
+
+#else // DEQP_HAVE_GLSLANG
+
+bool compileGlslToSpirV(tcu::TestLog& log, std::string source, glu::ShaderType type, ShaderBinaryDataType* dst)
+{
+ DE_UNREF(log);
+ DE_UNREF(source);
+ DE_UNREF(type);
+ DE_UNREF(dst);
+
+ TCU_THROW(InternalError, "Glslang not available.");
+
+ return false;
+}
+
+#endif // DEQP_HAVE_GLSLANG
+
+#if defined DEQP_HAVE_SPIRV_TOOLS
+
+void consumer(spv_message_level_t, const char*, const spv_position_t&, const char* m)
+{
+ std::cerr << "error: " << m << std::endl;
+}
+
+void spirvAssemble(ShaderBinaryDataType& dst, const std::string& src)
+{
+ spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
+
+ core.SetMessageConsumer(consumer);
+
+ if (!core.Assemble(src, &dst))
+ TCU_THROW(InternalError, "Failed to assemble Spir-V source.");
+}
+
+void spirvDisassemble(std::string& dst, const ShaderBinaryDataType& src)
+{
+ spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
+
+ core.SetMessageConsumer(consumer);
+
+ if (!core.Disassemble(src, &dst))
+ TCU_THROW(InternalError, "Failed to disassemble Spir-V module.");
+}
+
+bool spirvValidate(ShaderBinaryDataType& dst, bool throwOnError)
+{
+ spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
+
+ if (throwOnError)
+ core.SetMessageConsumer(consumer);
+
+ if (!core.Validate(dst))
+ {
+ if (throwOnError)
+ TCU_THROW(InternalError, "Failed to validate Spir-V module.");
+ return false;
+ }
+
+ return true;
+}
+
+#else //DEQP_HAVE_SPIRV_TOOLS
+
+void spirvAssemble(ShaderBinaryDataType& dst, const std::string& src)
+{
+ DE_UNREF(dst);
+ DE_UNREF(src);
+
+ TCU_THROW(InternalError, "Spirv-tools not available.");
+}
+
+void spirvDisassemble(std::string& dst, ShaderBinaryDataType& src)
+{
+ DE_UNREF(dst);
+ DE_UNREF(src);
+
+ TCU_THROW(InternalError, "Spirv-tools not available.");
+}
+
+bool spirvValidate(ShaderBinaryDataType& dst, bool throwOnError)
+{
+ DE_UNREF(dst);
+ DE_UNREF(throwOnError);
+
+ TCU_THROW(InternalError, "Spirv-tools not available.");
+}
+
+#endif // DEQP_HAVE_SPIRV_TOOLS
+
+ShaderBinary makeSpirV(tcu::TestLog& log, ShaderSource source)
+{
+ ShaderBinary binary;
+
+ if (!spirvUtils::compileGlslToSpirV(log, source.source, source.shaderType, &binary.binary))
+ TCU_THROW(InternalError, "Failed to convert GLSL to Spir-V");
+
+ binary << source.shaderType << "main";
+
+ return binary;
+}
+
+/** Verifying if GLSL to SpirV mapping was performed correctly
+ *
+ * @param glslSource GLSL shader template
+ * @param spirVSource SpirV disassembled source
+ * @param mappings Glsl to SpirV mappings vector
+ * @param anyOf any occurence indicator
+ *
+ * @return true if GLSL code occurs as many times as all of SpirV code for each mapping if anyOf is false
+ * or true if SpirV code occurs at least once if GLSL code found, false otherwise.
+ **/
+bool verifyMappings(std::string glslSource, std::string spirVSource, SpirVMapping& mappings, bool anyOf)
+{
+ std::vector<std::string> spirVSourceLines = de::splitString(spirVSource, '\n');
+
+ // Iterate through all glsl functions
+ for (SpirVMapping::iterator it = mappings.begin(); it != mappings.end(); it++)
+ {
+ int glslCodeCount = 0;
+ int spirVCodeCount = 0;
+
+ // To avoid finding functions with similar names (ie. "cos", "acos", "cosh")
+ // add characteristic characters that delimits finding results
+ std::string glslCode = it->first;
+
+ // Count GLSL code occurrences in GLSL source
+ size_t codePosition = glslSource.find(glslCode);
+ while (codePosition != std::string::npos)
+ {
+ glslCodeCount++;
+ codePosition = glslSource.find(glslCode, codePosition + 1);
+ }
+
+ if (glslCodeCount > 0)
+ {
+ // Count all SpirV code variants occurrences in SpirV source
+ for (int s = 0; s < (signed)it->second.size(); ++s)
+ {
+ std::vector<std::string> spirVCodes = de::splitString(it->second[s], ' ');
+
+ for (int v = 0; v < (signed)spirVSourceLines.size(); ++v)
+ {
+ std::vector<std::string> spirVLineCodes = de::splitString(spirVSourceLines[v], ' ');
+
+ bool matchAll = true;
+ for (int j = 0; j < (signed)spirVCodes.size(); ++j)
+ {
+ bool match = false;
+ for (int i = 0; i < (signed)spirVLineCodes.size(); ++i)
+ {
+ if (spirVLineCodes[i] == spirVCodes[j])
+ match = true;
+ }
+
+ matchAll = matchAll && match;
+ }
+
+ if (matchAll)
+ spirVCodeCount++;
+ }
+ }
+
+ // Check if both counts match
+ if (anyOf && (glslCodeCount > 0 && spirVCodeCount == 0))
+ return false;
+ else if (!anyOf && glslCodeCount != spirVCodeCount)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+} // namespace spirvUtils
+
+} // namespace glc
\ No newline at end of file
#include "tcuResource.hpp"
#include "tcuTestLog.hpp"
-#if defined DEQP_HAVE_GLSLANG
-#include "SPIRV/GlslangToSpv.h"
-#include "SPIRV/disassemble.h"
-#include "SPIRV/doc.h"
-#include "glslang/MachineIndependent/localintermediate.h"
-#include "glslang/Public/ShaderLang.h"
-#endif // DEQP_HAVE_GLSLANG
-
-#if defined DEQP_HAVE_SPIRV_TOOLS
-#include "spirv-tools/libspirv.hpp"
-#include "spirv-tools/optimizer.hpp"
-#endif // DEQP_HAVE_SPIRV_TOOLS
-
using namespace glu;
using namespace glw;
namespace gl4cts
{
-namespace glslangUtils
-{
-
-#if defined DEQP_HAVE_GLSLANG
-
-EShLanguage getGlslangStage(glu::ShaderType type)
-{
- static const EShLanguage stageMap[] = {
- EShLangVertex, EShLangFragment, EShLangGeometry, EShLangTessControl, EShLangTessEvaluation, EShLangCompute,
- };
-
- return de::getSizedArrayElement<glu::SHADERTYPE_LAST>(stageMap, type);
-}
-
-static volatile deSingletonState s_glslangInitState = DE_SINGLETON_STATE_NOT_INITIALIZED;
-
-void initGlslang(void*)
-{
- // Main compiler
- glslang::InitializeProcess();
-
- // SPIR-V disassembly
- spv::Parameterize();
-}
-
-void prepareGlslang(void)
-{
- deInitSingleton(&s_glslangInitState, initGlslang, DE_NULL);
-}
-
-void getDefaultLimits(TLimits* limits)
-{
- limits->nonInductiveForLoops = true;
- limits->whileLoops = true;
- limits->doWhileLoops = true;
- limits->generalUniformIndexing = true;
- limits->generalAttributeMatrixVectorIndexing = true;
- limits->generalVaryingIndexing = true;
- limits->generalSamplerIndexing = true;
- limits->generalVariableIndexing = true;
- limits->generalConstantMatrixVectorIndexing = true;
-}
-
-void getDefaultBuiltInResources(TBuiltInResource* builtin)
-{
- getDefaultLimits(&builtin->limits);
-
- builtin->maxLights = 32;
- builtin->maxClipPlanes = 6;
- builtin->maxTextureUnits = 32;
- builtin->maxTextureCoords = 32;
- builtin->maxVertexAttribs = 64;
- builtin->maxVertexUniformComponents = 4096;
- builtin->maxVaryingFloats = 64;
- builtin->maxVertexTextureImageUnits = 32;
- builtin->maxCombinedTextureImageUnits = 80;
- builtin->maxTextureImageUnits = 32;
- builtin->maxFragmentUniformComponents = 4096;
- builtin->maxDrawBuffers = 32;
- builtin->maxVertexUniformVectors = 128;
- builtin->maxVaryingVectors = 8;
- builtin->maxFragmentUniformVectors = 16;
- builtin->maxVertexOutputVectors = 16;
- builtin->maxFragmentInputVectors = 15;
- builtin->minProgramTexelOffset = -8;
- builtin->maxProgramTexelOffset = 7;
- builtin->maxClipDistances = 8;
- builtin->maxComputeWorkGroupCountX = 65535;
- builtin->maxComputeWorkGroupCountY = 65535;
- builtin->maxComputeWorkGroupCountZ = 65535;
- builtin->maxComputeWorkGroupSizeX = 1024;
- builtin->maxComputeWorkGroupSizeY = 1024;
- builtin->maxComputeWorkGroupSizeZ = 64;
- builtin->maxComputeUniformComponents = 1024;
- builtin->maxComputeTextureImageUnits = 16;
- builtin->maxComputeImageUniforms = 8;
- builtin->maxComputeAtomicCounters = 8;
- builtin->maxComputeAtomicCounterBuffers = 1;
- builtin->maxVaryingComponents = 60;
- builtin->maxVertexOutputComponents = 64;
- builtin->maxGeometryInputComponents = 64;
- builtin->maxGeometryOutputComponents = 128;
- builtin->maxFragmentInputComponents = 128;
- builtin->maxImageUnits = 8;
- builtin->maxCombinedImageUnitsAndFragmentOutputs = 8;
- builtin->maxCombinedShaderOutputResources = 8;
- builtin->maxImageSamples = 0;
- builtin->maxVertexImageUniforms = 0;
- builtin->maxTessControlImageUniforms = 0;
- builtin->maxTessEvaluationImageUniforms = 0;
- builtin->maxGeometryImageUniforms = 0;
- builtin->maxFragmentImageUniforms = 8;
- builtin->maxCombinedImageUniforms = 8;
- builtin->maxGeometryTextureImageUnits = 16;
- builtin->maxGeometryOutputVertices = 256;
- builtin->maxGeometryTotalOutputComponents = 1024;
- builtin->maxGeometryUniformComponents = 1024;
- builtin->maxGeometryVaryingComponents = 64;
- builtin->maxTessControlInputComponents = 128;
- builtin->maxTessControlOutputComponents = 128;
- builtin->maxTessControlTextureImageUnits = 16;
- builtin->maxTessControlUniformComponents = 1024;
- builtin->maxTessControlTotalOutputComponents = 4096;
- builtin->maxTessEvaluationInputComponents = 128;
- builtin->maxTessEvaluationOutputComponents = 128;
- builtin->maxTessEvaluationTextureImageUnits = 16;
- builtin->maxTessEvaluationUniformComponents = 1024;
- builtin->maxTessPatchComponents = 120;
- builtin->maxPatchVertices = 32;
- builtin->maxTessGenLevel = 64;
- builtin->maxViewports = 16;
- builtin->maxVertexAtomicCounters = 0;
- builtin->maxTessControlAtomicCounters = 0;
- builtin->maxTessEvaluationAtomicCounters = 0;
- builtin->maxGeometryAtomicCounters = 0;
- builtin->maxFragmentAtomicCounters = 8;
- builtin->maxCombinedAtomicCounters = 8;
- builtin->maxAtomicCounterBindings = 1;
- builtin->maxVertexAtomicCounterBuffers = 0;
- builtin->maxTessControlAtomicCounterBuffers = 0;
- builtin->maxTessEvaluationAtomicCounterBuffers = 0;
- builtin->maxGeometryAtomicCounterBuffers = 0;
- builtin->maxFragmentAtomicCounterBuffers = 1;
- builtin->maxCombinedAtomicCounterBuffers = 1;
- builtin->maxAtomicCounterBufferSize = 16384;
- builtin->maxTransformFeedbackBuffers = 4;
- builtin->maxTransformFeedbackInterleavedComponents = 64;
- builtin->maxCullDistances = 8;
- builtin->maxCombinedClipAndCullDistances = 8;
- builtin->maxSamples = 4;
- builtin->maxMeshOutputVerticesNV = 256;
- builtin->maxMeshOutputPrimitivesNV = 256;
- builtin->maxMeshWorkGroupSizeX_NV = 32;
- builtin->maxMeshWorkGroupSizeY_NV = 1;
- builtin->maxMeshWorkGroupSizeZ_NV = 1;
- builtin->maxTaskWorkGroupSizeX_NV = 32;
- builtin->maxTaskWorkGroupSizeY_NV = 1;
- builtin->maxTaskWorkGroupSizeZ_NV = 1;
- builtin->maxMeshViewCountNV = 4;
-};
-
-bool compileGlslToSpirV(tcu::TestLog& log, std::string source, glu::ShaderType type, ShaderBinaryDataType* dst)
-{
- TBuiltInResource builtinRes;
-
- prepareGlslang();
- getDefaultBuiltInResources(&builtinRes);
-
- const EShLanguage shaderStage = getGlslangStage(type);
-
- glslang::TShader shader(shaderStage);
- glslang::TProgram program;
-
- const char* src[] = { source.c_str() };
-
- shader.setStrings(src, 1);
- program.addShader(&shader);
-
- const int compileRes = shader.parse(&builtinRes, 100, false, EShMsgSpvRules);
- if (compileRes != 0)
- {
- const int linkRes = program.link(EShMsgSpvRules);
-
- if (linkRes != 0)
- {
- const glslang::TIntermediate* const intermediate = program.getIntermediate(shaderStage);
- glslang::GlslangToSpv(*intermediate, *dst);
-
- return true;
- }
- else
- {
- log << tcu::TestLog::Message << "Program linking error:\n"
- << program.getInfoLog() << "\n"
- << "Source:\n"
- << source << "\n"
- << tcu::TestLog::EndMessage;
- }
- }
- else
- {
- log << tcu::TestLog::Message << "Shader compilation error:\n"
- << shader.getInfoLog() << "\n"
- << "Source:\n"
- << source << "\n"
- << tcu::TestLog::EndMessage;
- }
-
- return false;
-}
-
-#else // DEQP_HAVE_GLSLANG
-
-bool compileGlslToSpirV(tcu::TestLog& log, std::string source, glu::ShaderType type, ShaderBinaryDataType* dst)
-{
- DE_UNREF(log);
- DE_UNREF(source);
- DE_UNREF(type);
- DE_UNREF(dst);
-
- TCU_THROW(InternalError, "Glslang not available.");
-
- return false;
-}
-
-#endif // DEQP_HAVE_GLSLANG
-
-#if defined DEQP_HAVE_SPIRV_TOOLS
-
-void consumer(spv_message_level_t, const char*, const spv_position_t&, const char* m)
-{
- std::cerr << "error: " << m << std::endl;
-}
-
-void spirvAssemble(ShaderBinaryDataType& dst, const std::string& src)
-{
- spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
-
- core.SetMessageConsumer(consumer);
-
- if (!core.Assemble(src, &dst))
- TCU_THROW(InternalError, "Failed to assemble Spir-V source.");
-}
-
-void spirvDisassemble(std::string& dst, const ShaderBinaryDataType& src)
-{
- spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
-
- core.SetMessageConsumer(consumer);
-
- if (!core.Disassemble(src, &dst))
- TCU_THROW(InternalError, "Failed to disassemble Spir-V module.");
-}
-
-bool spirvValidate(ShaderBinaryDataType& dst, bool throwOnError)
-{
- spvtools::SpirvTools core(SPV_ENV_OPENGL_4_5);
-
- if (throwOnError)
- core.SetMessageConsumer(consumer);
-
- if (!core.Validate(dst))
- {
- if (throwOnError)
- TCU_THROW(InternalError, "Failed to validate Spir-V module.");
- return false;
- }
-
- return true;
-}
-
-#else //DEQP_HAVE_SPIRV_TOOLS
-
-void spirvAssemble(ShaderBinaryDataType& dst, const std::string& src)
-{
- DE_UNREF(dst);
- DE_UNREF(src);
-
- TCU_THROW(InternalError, "Spirv-tools not available.");
-}
-
-void spirvDisassemble(std::string& dst, ShaderBinaryDataType& src)
-{
- DE_UNREF(dst);
- DE_UNREF(src);
-
- TCU_THROW(InternalError, "Spirv-tools not available.");
-}
-
-bool spirvValidate(ShaderBinaryDataType& dst, bool throwOnError)
-{
- DE_UNREF(dst);
- DE_UNREF(throwOnError);
-
- TCU_THROW(InternalError, "Spirv-tools not available.");
-}
-
-#endif // DEQP_HAVE_SPIRV_TOOLS
-
-ShaderBinary makeSpirV(tcu::TestLog& log, ShaderSource source)
-{
- ShaderBinary binary;
-
- if (!glslangUtils::compileGlslToSpirV(log, source.source, source.shaderType, &binary.binary))
- TCU_THROW(InternalError, "Failed to convert GLSL to Spir-V");
-
- binary << source.shaderType << "main";
-
- return binary;
-}
-
-/** Verifying if GLSL to SpirV mapping was performed correctly
- *
- * @param glslSource GLSL shader template
- * @param spirVSource SpirV disassembled source
- * @param mappings Glsl to SpirV mappings vector
- * @param anyOf any occurence indicator
- *
- * @return true if GLSL code occurs as many times as all of SpirV code for each mapping if anyOf is false
- * or true if SpirV code occurs at least once if GLSL code found, false otherwise.
- **/
-bool verifyMappings(std::string glslSource, std::string spirVSource, SpirVMapping& mappings, bool anyOf)
-{
- std::vector<std::string> spirVSourceLines = de::splitString(spirVSource, '\n');
-
- // Iterate through all glsl functions
- for (SpirVMapping::iterator it = mappings.begin(); it != mappings.end(); it++)
- {
- int glslCodeCount = 0;
- int spirVCodeCount = 0;
-
- // To avoid finding functions with similar names (ie. "cos", "acos", "cosh")
- // add characteristic characters that delimits finding results
- std::string glslCode = it->first;
-
- // Count GLSL code occurrences in GLSL source
- size_t codePosition = glslSource.find(glslCode);
- while (codePosition != std::string::npos)
- {
- glslCodeCount++;
- codePosition = glslSource.find(glslCode, codePosition + 1);
- }
-
- if (glslCodeCount > 0)
- {
- // Count all SpirV code variants occurrences in SpirV source
- for (int s = 0; s < (signed)it->second.size(); ++s)
- {
- std::vector<std::string> spirVCodes = de::splitString(it->second[s], ' ');
-
- for (int v = 0; v < (signed)spirVSourceLines.size(); ++v)
- {
- std::vector<std::string> spirVLineCodes = de::splitString(spirVSourceLines[v], ' ');
-
- bool matchAll = true;
- for (int j = 0; j < (signed)spirVCodes.size(); ++j)
- {
- bool match = false;
- for (int i = 0; i < (signed)spirVLineCodes.size(); ++i)
- {
- if (spirVLineCodes[i] == spirVCodes[j])
- match = true;
- }
-
- matchAll = matchAll && match;
- }
-
- if (matchAll)
- spirVCodeCount++;
- }
- }
-
- // Check if both counts match
- if (anyOf && (glslCodeCount > 0 && spirVCodeCount == 0))
- return false;
- else if (!anyOf && glslCodeCount != spirVCodeCount)
- return false;
- }
- }
-
- return true;
-}
-
-} // namespace glslangUtils
-
namespace commonUtils
{
return false;
}
-void checkGlSpirvSupported(deqp::Context& m_context)
-{
- bool is_at_least_gl_46 = (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::core(4, 6)));
- bool is_arb_gl_spirv = m_context.getContextInfo().isExtensionSupported("GL_ARB_gl_spirv");
- if ((!is_at_least_gl_46) && (!is_arb_gl_spirv))
- TCU_THROW(NotSupportedError, "GL_ARB_gl_spirv is not supported");
-}
} // namespace commonUtils
/** Constructor.
/** Stub init method */
void SpirvModulesPositiveTest::init()
{
- commonUtils::checkGlSpirvSupported(m_context);
+ spirvUtils::checkGlSpirvSupported(m_context);
m_vertex = "#version 450\n"
"\n"
{
#if defined DEQP_HAVE_GLSLANG
ProgramBinaries binaries;
- binaries << glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
- binaries << glslangUtils::makeSpirV(m_context.getTestContext().getLog(),
- TessellationControlSource(m_tesselationCtrl));
- binaries << glslangUtils::makeSpirV(m_context.getTestContext().getLog(),
- TessellationEvaluationSource(m_tesselationEval));
- binaries << glslangUtils::makeSpirV(m_context.getTestContext().getLog(), GeometrySource(m_geometry));
- binaries << glslangUtils::makeSpirV(m_context.getTestContext().getLog(), FragmentSource(m_fragment));
+ binaries << spirvUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
+ binaries << spirvUtils::makeSpirV(m_context.getTestContext().getLog(),
+ TessellationControlSource(m_tesselationCtrl));
+ binaries << spirvUtils::makeSpirV(m_context.getTestContext().getLog(),
+ TessellationEvaluationSource(m_tesselationEval));
+ binaries << spirvUtils::makeSpirV(m_context.getTestContext().getLog(), GeometrySource(m_geometry));
+ binaries << spirvUtils::makeSpirV(m_context.getTestContext().getLog(), FragmentSource(m_fragment));
program = new ShaderProgram(gl, binaries);
#else // DEQP_HAVE_GLSLANG
tcu::Archive& archive = m_testCtx.getArchive();
/** Stub init method */
void SpirvShaderBinaryMultipleShaderObjectsTest::init()
{
- commonUtils::checkGlSpirvSupported(m_context);
+ spirvUtils::checkGlSpirvSupported(m_context);
m_spirv = "OpCapability Shader\n"
"%1 = OpExtInstImport \"GLSL.std.450\"\n"
binary << SHADERTYPE_VERTEX << "mainv";
binary << SHADERTYPE_FRAGMENT << "mainf";
- glslangUtils::spirvAssemble(binary.binary, m_spirv);
- glslangUtils::spirvValidate(binary.binary, true);
+ spirvUtils::spirvAssemble(binary.binary, m_spirv);
+ spirvUtils::spirvValidate(binary.binary, true);
#else // DEQP_HAVE_SPIRV_TOOLS
tcu::Archive& archive = m_testCtx.getArchive();
ShaderBinary binary = commonUtils::readSpirV(
/** Stub init method */
void SpirvModulesStateQueriesTest::init()
{
- commonUtils::checkGlSpirvSupported(m_context);
+ spirvUtils::checkGlSpirvSupported(m_context);
m_vertex = "#version 450\n"
"\n"
#if defined DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
{
- vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
+ vertexBinary = spirvUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
// Disassemble Spir-V module
std::string output;
- glslangUtils::spirvDisassemble(output, vertexBinary.binary);
+ spirvUtils::spirvDisassemble(output, vertexBinary.binary);
// Remove name reflection for defined variables
std::vector<std::string> lines = de::splitString(output, '\n');
// Assemble Spir-V module
vertexBinary.binary.clear();
- glslangUtils::spirvAssemble(vertexBinary.binary, input);
- glslangUtils::spirvValidate(vertexBinary.binary, true);
+ spirvUtils::spirvAssemble(vertexBinary.binary, input);
+ spirvUtils::spirvValidate(vertexBinary.binary, true);
}
#else // DEQP_HAVE_GLSLANG && DEQP_HAVE_SPIRV_TOOLS
tcu::Archive& archive = m_testCtx.getArchive();
/** Stub init method */
void SpirvModulesErrorVerificationTest::init()
{
- commonUtils::checkGlSpirvSupported(m_context);
+ spirvUtils::checkGlSpirvSupported(m_context);
const Functions& gl = m_context.getRenderContext().getFunctions();
ShaderBinary vertexBinary;
#if defined DEQP_HAVE_GLSLANG
- vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
+ vertexBinary = spirvUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
#else // DEQP_HAVE_GLSLANG
tcu::Archive& archive = m_testCtx.getArchive();
vertexBinary = commonUtils::readSpirV(archive.getResource("spirv/modules_error_verification/vertex.nspv"));
/** Stub init method */
void SpirvGlslToSpirVEnableTest::init()
{
- commonUtils::checkGlSpirvSupported(m_context);
+ spirvUtils::checkGlSpirvSupported(m_context);
m_vertex = "#version 450\n"
"\n"
const Functions& gl = m_context.getRenderContext().getFunctions();
ProgramBinaries binaries;
- ShaderBinary vertexBinary =
- glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
+ ShaderBinary vertexBinary = spirvUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
binaries << vertexBinary;
ShaderProgram spirvProgram(gl, binaries);
std::string spirvSource;
- glslangUtils::spirvDisassemble(spirvSource, vertexBinary.binary);
+ spirvUtils::spirvDisassemble(spirvSource, vertexBinary.binary);
if (spirvSource.find("OpName %enabled") == std::string::npos)
{
/** Stub init method */
void SpirvGlslToSpirVBuiltInFunctionsTest::init()
{
- commonUtils::checkGlSpirvSupported(m_context);
+ spirvUtils::checkGlSpirvSupported(m_context);
initMappings();
sources << vertexSource;
ShaderBinary vertexBinary;
#if defined DEQP_HAVE_GLSLANG
- vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), vertexSource);
+ vertexBinary = spirvUtils::makeSpirV(m_context.getTestContext().getLog(), vertexSource);
#else // DEQP_HAVE_GLSLANG
tcu::Archive& archive = m_testCtx.getArchive();
vertexBinary =
std::string spirvSource;
#if defined DEQP_HAVE_GLSLANG
- shaderBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), shaderSource);
+ shaderBinary = spirvUtils::makeSpirV(m_context.getTestContext().getLog(), shaderSource);
#else // DEQP_HAVE_GLSLANG
{
std::stringstream ss;
#if defined DEQP_HAVE_SPIRV_TOOLS
{
- glslangUtils::spirvDisassemble(spirvSource, shaderBinary.binary);
+ spirvUtils::spirvDisassemble(spirvSource, shaderBinary.binary);
- if (!glslangUtils::verifyMappings(shaderSource.source, spirvSource, m_mappings, false))
+ if (!spirvUtils::verifyMappings(shaderSource.source, spirvSource, m_mappings, false))
{
m_testCtx.getLog() << tcu::TestLog::Message << "Mappings for shader failed.\n"
<< "GLSL source:\n"
sources << tessEvalSource;
ShaderBinary tessEvalBinary;
#if defined DEQP_HAVE_GLSLANG
- tessEvalBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), tessEvalSource);
+ tessEvalBinary = spirvUtils::makeSpirV(m_context.getTestContext().getLog(), tessEvalSource);
#else // DEQP_HAVE_GLSLANG
tcu::Archive& archive = m_testCtx.getArchive();
tessEvalBinary = commonUtils::readSpirV(
/** Stub init method */
void SpirvGlslToSpirVSpecializationConstantsTest::init()
{
- commonUtils::checkGlSpirvSupported(m_context);
+ spirvUtils::checkGlSpirvSupported(m_context);
const Functions& gl = m_context.getRenderContext().getFunctions();
ShaderBinary fragmentBinary;
#if defined DEQP_HAVE_GLSLANG
{
- vertexBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
- fragmentBinary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), FragmentSource(m_fragment));
+ vertexBinary = spirvUtils::makeSpirV(m_context.getTestContext().getLog(), VertexSource(m_vertex));
+ fragmentBinary = spirvUtils::makeSpirV(m_context.getTestContext().getLog(), FragmentSource(m_fragment));
}
#else // DEQP_HAVE_GLSLANG
{
/** Stub init method */
void SpirvValidationBuiltInVariableDecorationsTest::init()
{
- commonUtils::checkGlSpirvSupported(m_context);
+ spirvUtils::checkGlSpirvSupported(m_context);
m_compute = "#version 450\n"
"\n"
for (int s = 0; s < (signed)m_validations[v].shaders.size(); ++s)
{
ShaderBinary shaderBinary =
- glslangUtils::makeSpirV(m_context.getTestContext().getLog(), m_validations[v].shaders[s]);
+ spirvUtils::makeSpirV(m_context.getTestContext().getLog(), m_validations[v].shaders[s]);
binariesVec.push_back(shaderBinary);
binaries << shaderBinary;
}
{
ShaderSource shaderSource = m_validations[v].shaders[s];
- glslangUtils::spirvDisassemble(spirvSource, binariesVec[s].binary);
+ spirvUtils::spirvDisassemble(spirvSource, binariesVec[s].binary);
- if (!glslangUtils::verifyMappings(shaderSource.source, spirvSource, m_mappings, true))
+ if (!spirvUtils::verifyMappings(shaderSource.source, spirvSource, m_mappings, true))
{
m_testCtx.getLog() << tcu::TestLog::Message << "Mappings for shader failed.\n"
<< "GLSL source:\n"
{
ShaderStage& stage = pipeline[s];
#if defined DEQP_HAVE_GLSLANG
- stage.binary = glslangUtils::makeSpirV(m_context.getTestContext().getLog(), stage.source);
+ stage.binary = spirvUtils::makeSpirV(m_context.getTestContext().getLog(), stage.source);
std::stringstream ssw;
if (stage.name.empty())
ssw << "gl_cts/data/spirv/spirv_validation_capabilities/binary_p" << p << "s" << s << ".nspv";
ShaderBinary binary = stage.binary;
std::string spirVSource;
- glslangUtils::spirvDisassemble(spirVSource, binary.binary);
+ spirvUtils::spirvDisassemble(spirVSource, binary.binary);
for (int c = 0; c < (signed)stage.caps.size(); ++c)
{
else
{
// Assemble and validate cut off SpirV source
- glslangUtils::spirvAssemble(binary.binary, spirVSourceCut);
- if (glslangUtils::spirvValidate(binary.binary, false))
+ spirvUtils::spirvAssemble(binary.binary, spirVSourceCut);
+ if (spirvUtils::spirvValidate(binary.binary, false))
{
m_testCtx.getLog() << tcu::TestLog::Message << "OpCapability (" << stage.caps[c] << ") [" << p
<< "/" << s << "].\n"