glslang
glslang copied to clipboard
API generates invalid SPIRV
I was trying to generate SPIRV (Vulkan 1.3, Spv 1.6) by using the c++ api, but got the following errors:
1st operand of Capability: operand RayTraversalPrimitiveCullingKHR(4478) requires one of these extensions: SPV_KHR_ray_query SPV_KHR_ray_tracing
OpCapability RayTraversalPrimitiveCullingKHR
Here is the related glsl test code.
#version 450
void main() {
gl_Position = vec4(vec3(0.0), 1.0);
}
And some "printouts" of the used objects
TShader Environment
{input={languageFamily=EShSourceGlsl (1) stage=EShLangVertex (0) dialect=EShClientVulkan (1) ...} client=...}
input: {languageFamily=EShSourceGlsl (1) stage=EShLangVertex (0) dialect=EShClientVulkan (1) ...}
client: {client=EShClientVulkan (1) version=EShTargetVulkan_1_3 (4206592) }
target: {language=EShTargetSpv (1) version=EShTargetSpv_1_6 (67072) hlslFunctionality1=false }
TIIntermediate
{language=EShLangVertex (0) entryPoint Name="main" entryPointMangledName="main(" ...}
language: EShLangVertex (0)
entryPointName: "main"
entryPointMangledName: "main("
callGraph: { size=0 }
profile: ECoreProfile (2)
version: 450
spvVersion: {spv=67072 vulkanGlsl=100 vulkan=4206592 ...}
treeRoot: 0x000002d2f6c20498 {sequence={ size=2 } qualifier={ size=0 } name="" ...}
requestedExtensions: { size=0 }
resources: {value={maxLights=0 maxClipPlanes=0 maxTextureUnits=0 ...} isSet=true }
numEntryPoints: 1
numErrors: 0
numPushConstants: 0
...
The problem is, I can't replicate the error by using the glslangValidator to transpile the same source code.
Could you attach the code you were using to generate this SPIR-V?
Yeah, sorry.
#include "SpirvCompiler.hpp"
#include <Engine.Common/Make.hpp>
#include <Engine.Common/Wrapper.hpp>
#include <Engine.Logging/Logger.hpp>
// glslang includes
//#include <glslang/Public/ShaderLang.h>
#include <glslang/Public/ResourceLimits.h>
#include <glslang/SPIRV/GlslangToSpv.h>
// spirv includes
//#include <spirv-tools/libspirv.hpp>
//#include <spirv-tools/linker.hpp>
//#include <spirv-tools/optimizer.hpp>
using namespace hg::engine::gfx::acc;
using namespace hg;
_STD atomic_uint_fast32_t hg::engine::gfx::acc::extern_compiler_ref_count { 0ui32 };
/**/
SpirvCompiler::SpirvCompiler() :
_srcLang(SpirvSrcLang::eGlsl),
_dialect(SpirvDialect::eVulkan),
_targetClient(SpirvTargetClient::eVulkan13),
_targetVersion(SpirvTargetVersion::eSpv16) {
if (extern_compiler_ref_count.fetch_add(1ui32) == 0) {
//ShInitialize();
glslang::InitializeProcess();
}
}
SpirvCompiler::~SpirvCompiler() {
if (extern_compiler_ref_count.fetch_sub(1ui32) == 1ui32) {
//ShFinalize();
glslang::FinalizeProcess();
}
}
SpirvByteCode SpirvCompiler::compile(cref<ModuleSource> module_, cref<Vector<string>> source_) const {
const auto targetStage = static_cast<_STD underlying_type_t<ModuleTargetStage>>(module_.targetStage) - 1;
assert(targetStage >= 0 && targetStage < EShLanguageMaskCount);
EShLanguage stage { reinterpret_cast<cref<EShLanguage>>(targetStage) };
bool status = true;
/**/
uptr<glslang::TProgram> glslProgram = make_uptr<glslang::TProgram>();
uptr<glslang::TShader> glslShader = make_uptr<glslang::TShader>(stage);
glslProgram->addShader(glslShader.get());
/**/
s32 langVersion { 100 /* EShClientVulkan, 100 => SPIR-V */ };
glslShader->setEnvClient(
reinterpret_cast<cref<glslang::EShClient>>(_dialect),
reinterpret_cast<cref<glslang::EShTargetClientVersion>>(_targetClient)
);
glslShader->setEnvInput(
reinterpret_cast<cref<glslang::EShSource>>(_srcLang),
stage,
reinterpret_cast<cref<glslang::EShClient>>(_dialect),
langVersion
);
glslShader->setEnvTarget(
glslang::EShTargetLanguage::EShTargetSpv,
reinterpret_cast<cref<glslang::EShTargetLanguageVersion>>(_targetVersion)
);
Vector<ptr<const char>> codeSnippets {};
Vector<s32> codeSnippetLength {};
codeSnippets.reserve(source_.size());
codeSnippetLength.reserve(source_.size());
for (u32 i = 0; i < source_.size(); ++i) {
codeSnippets.push_back(source_[i].data());
codeSnippetLength.push_back(static_cast<s32>(source_[i].size()));
}
glslShader->setStringsWithLengths(codeSnippets.data(), codeSnippetLength.data(), static_cast<s32>(source_.size()));
/**/
s32 defaultVersion { 110 };
EShMessages msg { EShMsgDefault | EShMsgSpvRules | EShMsgVulkanRules };
glslShader->setDebugInfo(true);
status = glslShader->parse(GetResources(), defaultVersion, false, msg);
if (not status) {
IM_CORE_WARN(glslShader->getInfoLog());
IM_CORE_WARN(glslShader->getInfoDebugLog());
}
/**/
if (status) {
status = glslProgram->link(msg);
}
/**/
SpirvByteCode byteCode {};
if (status) {
const auto* const intermediate = glslProgram->getIntermediate(stage);
glslang::SpvOptions spvOpts {
.validate = true
};
spv::SpvBuildLogger spvLog {};
glslang::GlslangToSpv(*intermediate, reinterpret_cast<ref<Vector<u32>>>(byteCode), &spvLog, &spvOpts);
status = not spvLog.errors.empty();
}
if (not status) {
byteCode.clear();
}
/**/
glslProgram.reset();
glslShader.reset();
/**/
return byteCode;
}
; SPIR-V
; Version: 1.6
; Generator: Khronos Glslang Reference Front End; 11
; Bound: 21
; Schema: 0
OpCapability Shader
OpCapability RayTraversalPrimitiveCullingKHR
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %4 "main" %13
OpMemberDecorate %_struct_11 0 BuiltIn Position
OpMemberDecorate %_struct_11 1 BuiltIn PointSize
OpMemberDecorate %_struct_11 2 BuiltIn ClipDistance
OpMemberDecorate %_struct_11 3 BuiltIn CullDistance
OpDecorate %_struct_11 Block
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
%_arr_float_uint_1 = OpTypeArray %float %uint_1
%_struct_11 = OpTypeStruct %v4float %float %_arr_float_uint_1 %_arr_float_uint_1
%_ptr_Output__struct_11 = OpTypePointer Output %_struct_11
%13 = OpVariable %_ptr_Output__struct_11 Output
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%float_0 = OpConstant %float 0
%float_1 = OpConstant %float 1
%18 = OpConstantComposite %v4float %float_0 %float_0 %float_0 %float_1
%_ptr_Output_v4float = OpTypePointer Output %v4float
%4 = OpFunction %void None %3
%5 = OpLabel
%20 = OpAccessChain %_ptr_Output_v4float %13 %int_0
OpStore %20 %18
OpReturn
OpFunctionEnd
Therefore I guess: https://github.com/KhronosGroup/glslang/blob/main/SPIRV/GlslangToSpv.cpp#L1655C36-L1655C77
If you need it, I can try to make a stripped down version of it.
This seams only to happen, when I use the provided binaries of main-tot
or distributed binaries of vulkan sdk
. Using the "manually" compiled libraries to link seams to work just fine.