glslang
glslang copied to clipboard
Crash using below code
Hello, I am using git tag version 11.13.0 and I have below code
std::vector<char> glslToSpirv(const std::vector<char>& data,
EShLanguage shaderStage, const char* entryPoint) {
static bool glslangInitialized = false;
if (!glslangInitialized) {
glslang::InitializeProcess();
glslangInitialized = true;
}
glslang::TShader tshader(shaderStage);
const char* glslCStr = data.data();
tshader.setStrings(&glslCStr, 1);
glslang::EshTargetClientVersion clientVersion = glslang::EShTargetVulkan_1_1;
glslang::EShTargetLanguageVersion langVersion = glslang::EShTargetSpv_1_3;
tshader.setEnvInput(glslang::EShSourceGlsl, shaderStage,
glslang::EShClientVulkan,
460); // 100 means version glsl version 1.0 (as defined
// by KHR_vulkan_glsl)
tshader.setEnvClient(glslang::EShClientVulkan, clientVersion);
tshader.setEnvTarget(glslang::EShTargetSpv, langVersion);
#ifdef _DEBUG
tshader.setDebugInfo(true);
#endif
tshader.setEntryPoint(entryPoint);
tshader.setSourceEntryPoint(entryPoint);
const TBuiltInResource* resources = GetDefaultResources();
const EShMessages messages =
static_cast<EShMessages>(EShMsgSpvRules | EShMsgVulkanRules);
glslang::TShader::ForbidIncluder includer;
std::string preprocessedGLSL;
if (!tshader.preprocess(resources, 460, ENoProfile, false, false, messages,
&preprocessedGLSL, includer)) {
std::cout << "Preprocessing failed for shader " << std::endl;
std::cout << tshader.getInfoLog() << std::endl;
std::cout << tshader.getInfoDebugLog() << std::endl;
ASSERT(false, "preprocess failed");
return std::vector<char>();
}
const char* preprocessedGLSLStr = preprocessedGLSL.c_str();
tshader.setStrings(&preprocessedGLSLStr, 1);
if (!tshader.parse(resources, 460, false, messages)) {
std::cout << "Parsing failed for shader " << std::endl;
std::cout << tshader.getInfoLog() << std::endl;
std::cout << tshader.getInfoDebugLog() << std::endl;
ASSERT(false, "parse failed");
return std::vector<char>();
}
glslang::SpvOptions options;
#ifdef _DEBUG
options.generateDebugInfo = false;
options.disableOptimizer = false;
options.optimizeSize = true;
options.stripDebugInfo = true;
#else
options.disableOptimizer = false;
options.disableOptimizer = false;
options.optimizeSize = true;
options.stripDebugInfo = true;
#endif
glslang::TProgram program;
program.addShader(&tshader);
if (!program.link(messages)) {
std::cout << "Parsing failed for shader " << std::endl;
std::cout << program.getInfoLog() << std::endl;
std::cout << program.getInfoDebugLog() << std::endl;
ASSERT(false, "link failed");
}
std::vector<uint32_t> spirvData;
spv::SpvBuildLogger spvLogger;
glslang::GlslangToSpv(*program.getIntermediate(shaderStage), spirvData,
&spvLogger, &options);
std::vector<char> byteCode;
byteCode.resize(spirvData.size() * (sizeof(uint32_t) / sizeof(char)));
std::memcpy(byteCode.data(), spirvData.data(), byteCode.size());
return byteCode;
}
As soon as I add if/else to my shader it crashes? Below is my shader code
#version 460
layout(location = 0) in vec4 inColor;
layout(location = 1) in vec2 texCoords;
layout(location = 0) out vec4 outColor;
layout (set = 0, binding = 0) uniform texture2D textureCheckered;
layout (set = 1, binding = 0) uniform sampler samplerTex;
void main() {
float myval = 1.0;
if(myval == 1.0) {
const vec4 tex = texture(sampler2D(textureCheckered, samplerTex), texCoords) * inColor;
outColor = tex;
} else {
vec4 tex = texture(sampler2D(textureCheckered, samplerTex), texCoords) * inColor;
tex.r = 0.0;
outColor = tex;
}
}
looks like removing tshader.setDebugInfo(true); makes it works
setting it after parse also works fine, I guess may be it's not useful to tshader.setDebugInfo before parsing?
I don't think glslang ought to be crashing even if you are passing the incorrect options. I'm going to take a look and see if I can reproduce this and get a backtrace. I've also reformatted your comment so the code doesn't get mangled, for future reference you can enclose code between triple-backticks to keep it from getting mangled by the HTML parser, or you can just attach the file as an attachment.
Hi. How is this going? I've been experiencing the same issue.
[...]
spv::SpvBuildLogger logger;
glslang::SpvOptions spv_options{};
spv_options.generateDebugInfo = true; <-- make it crash
std::vector<u32> spv;
glslang::GlslangToSpv(*intermediary, spv, &logger, &spv_options);
This is the error that I got:
Assertion failed: !currentDebugScopeId.empty(), file C:\dev\utils\vcpkg\buildtrees\glslang\src\12.2.0-7aaf2a2782.clean\SPIRV\SpvBuilder.cpp, line 2131
I hope it'll be fixed soon. Cheers!
If we're using glslang::TShader::setDebugInfo
with true
, we seem to need to to set glslang::SpvOptions::emitNonSemanticShaderDebugInfo
to true
in order for the crash not to manifest itself.
I would have liked to tackle this further but I think an interface design decision needs to be made here.
Direct cause
When glslang::TShader::setDebugInfo
is called with true
,
on glslang::TShader::parse
, EOpScope
instead of EOpSequence
is emitted for LEFT_BRACE statement_list RIGHT_BRACE
:
https://github.com/KhronosGroup/glslang/blob/a91631b260cba3f22858d6c6827511e636c2458a/glslang/MachineIndependent/glslang.y#L3765-L3769
With glslang::SpvOptions::emitNonSemanticShaderDebugInfo
set to false
(the dafault value),
spv::Builder::enterFunction
doesn't initialize the top level debug scope:
https://github.com/KhronosGroup/glslang/blob/a91631b260cba3f22858d6c6827511e636c2458a/SPIRV/SpvBuilder.cpp#L2272-L2285
So when TGlslangToSpvTraverser::visitAggregate
gets to an EOpScope
and calls spv::Builder::enterScope
:
https://github.com/KhronosGroup/glslang/blob/a91631b260cba3f22858d6c6827511e636c2458a/SPIRV/GlslangToSpv.cpp#L2896-L2897
spv::Builder::enterScope
calls spv::Builder::makeDebugLexicalBlock
, which fails the assertion assert(!currentDebugScopeId.empty())
:
https://github.com/KhronosGroup/glslang/blob/a91631b260cba3f22858d6c6827511e636c2458a/SPIRV/SpvBuilder.cpp#L2213-L2223