如何在Vulkan GLSL中构建含buffer_reference类型的复合结构体?
如何在shaderc中无需显式uint64_t转换构建包含buffer_reference类型的复合结构体?
你遇到的是shaderc 1.3.224.1版本的内部bug——当在常量表达式中直接将buffer_reference类型的字面量嵌入复合结构体的构造语句时,编译器优化阶段会出现未定义ID的错误。
问题复现代码
#extension GL_EXT_scalar_block_layout: enable #extension GL_EXT_buffer_reference2 : enable #extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable layout(buffer_reference, buffer_reference_align=4, scalar) buffer test_ref_type{ uint32_t data[]; }; struct RefTest{ test_ref_type test; }; RefTest extract_RefTest(){ return RefTest(test_ref_type(uint64_t(0))); } void main(){ RefTest ref_test = extract_RefTest(); }
报错信息
shaderc: internal error: compilation succeeded but failed to optimize: ID 108[%108] has not been defined %109 = OpConstantComposite %RefTest %108
解决方案:绕开常量构造的bug
无需显式转换为uint64_t,只需要先将buffer_reference赋值给局部变量,再用该变量构造结构体,即可避开编译器的bug:
#extension GL_EXT_scalar_block_layout: enable #extension GL_EXT_buffer_reference2 : enable #extension GL_EXT_shader_explicit_arithmetic_types_int64 : enable layout(buffer_reference, buffer_reference_align=4, scalar) buffer test_ref_type{ uint32_t data[]; }; struct RefTest{ test_ref_type test; }; RefTest extract_RefTest(){ // 先将buffer_reference赋值给局部变量 test_ref_type temp_ref = test_ref_type(uint64_t(0)); // 用局部变量构造结构体返回 return RefTest(temp_ref); } void main(){ RefTest ref_test = extract_RefTest(); }
额外建议
这个bug在后续版本的shaderc中已经被修复,如果你升级到VulkanSDK 1.3.236.0及以上版本,直接使用最初的写法也能正常编译。
内容的提问来源于stack exchange,提问作者Krupip
相关产品推荐
相关产品推荐

