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

OpenGL中readInvocationARB读取非活跃调用返回结果不一致问题

问题背景

编写着色器程序时,我需要对多组不同输入重复执行相同算法计算中间结果,再合并中间结果得到最终输出。由于所用计算数据与游戏内世界位置绑定,同一子组内各调用的数据差异极小,因此我采用了并行方案:在不同调用上同时处理所有输入,再通过子组内调用间的数据传递完成中间结果合并,得到最终值。

该方案的难点在于:部分分支下中间结果计算完成后可提前退出流程,这就导致部分调用依赖其他调用的计算结果,但被依赖的调用在跨调用传递数据的节点可能已经处于非活跃状态。

OpenGL提供ARB_shader_ballot扩展,支持开发者读取子组内其他调用的变量值,核心接口为readInvocationARB(genUType value, uint invocationIndex)。该接口的公开说明仅提到两点:

  • readInvocationARB会向子组内所有活跃调用返回指定invocationIndex对应调用传入的<value>
  • 所有活跃调用传入的invocationIndex参数必须保持一致,否则结果未定义

但规范并未明确说明:当被读取的目标调用处于非活跃状态时,返回的<value>是否有明确定义。

验证测试

为验证该行为,我编写了第一版测试着色器:

第一版测试着色器

#version 460
#extension GL_ARB_shader_ballot : enable

uniform uint data;
layout(location = 0) out vec4 color;

void main() { 
    uint var;
    var = data;
    
    if(gl_SubGroupInvocationARB != 20) {
        const uint result = readInvocationARB(var, 20);
        color = vec4(result == data);
    }
    else color = vec4(1, 0, 0, 1);
}

该着色器运行后输出带红色点的白色图像,说明此时读取到的、处于非活跃状态的20号调用的var值为此前写入的data值。

第二版测试着色器

随后我修改变量赋值逻辑,增加条件分支,编写了第二版测试着色器:

#version 460
#extension GL_ARB_shader_ballot : enable

uniform uint threshold;
uniform uint data;

layout(location = 0) out vec4 color;

void main() { 
    uint var;
    if(gl_SubGroupInvocationARB < threshold)
         var = data;
    else var = 10;
    
    if(gl_SubGroupInvocationARB != 20) {
        const uint result = readInvocationARB(var, 20);
        color = vec4(result == data);
    }
    else color = vec4(1, 0, 0, 1);
    
    return; 
}

测试时我将data uniform的值设为10,保证所有分支下var的实际赋值恒为10,且threshold的取值不会改变var的实际值。但在搭载Nvidia显卡的设备上运行该着色器时,输出为带红色点的黑色图像,说明读取到的20号调用的var值并非此前写入的数值(实测返回值为0)。后续我在搭载AMD显卡的设备上运行上述两个版本的着色器,输出均为带红色点的白色图像,与Nvidia设备上第二版着色器的运行结果存在明显差异。上述非严谨测试表明,不同软硬件配置下,相同着色器的运行结果不一致。

待解答问题

现就此问题提出问询:

  1. 是否我遗漏了规范相关说明——readInvocationARB读取非活跃调用的返回结果本身属于未定义行为?如果是,哪里可以获取该扩展的完整权威规范说明?
  2. 若该场景下的返回结果是明确定义的,是我的测试代码存在错误,还是某一厂商的驱动实现不符合规范?

内容的提问来源于stack exchange,提问作者Arkadiy Mel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 02:18:03