You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 10:05:24