GLSL分支行为

ron*_*nag 13 opengl glsl

我有一个带有分支的相当简单的片段着色器,我有点不确定GLSL编译器如何处理它以及它将如何影响性能.

uniform sampler2D sampler;
uniform vec2 texSize;
uniform vec2 targetSize; 

void main()               
{                  
    vec4 color;
    if(texSize == targetSize)
        color = texture2DNearest(sampler, gl_TexCoord[0]);
    else
        color = texture2DBicubic(sampler, gl_TexCoord[0]);
    gl_FragColor = color;        
}
Run Code Online (Sandbox Code Playgroud)

我从AMD的文档中读到,有时两个分支都被执行,在这种情况下这不是一个好主意.如果没有进一步的信息或访问反汇编,我不确定该怎么想,如果有问题怎么避免呢?

而且根据我的理解,基于统一变量的分支不会产生任何显着的开销,因为它在一次传递中是恒定的?

Str*_*ger 12

在这里你有:

il_ps_2_0
dcl_input_generic_interp(linear) v1
dcl_resource_id(0)_type(2d)_fmtx(float)_fmty(float)_fmtz(float)_fmtw(float)
eq r2.xy__, c1.xyyy, c0.xyyy
imul r5.x___, r2.x, r2.y
mov r1.x___, r5.x
if_logicalnz r1.x
    sample_resource(0)_sampler(0) r6, v1.xyyy
    mov r7, r6
else
    sample_resource(0)_sampler(0) r8, v1.xyyy
    mov r7, r8
endif
mov r9, r7
mov oC0, r9
endmain
Run Code Online (Sandbox Code Playgroud)

重新说一下科斯所说的,重要的是要知道在执行之前是否可以知道保护条件.是这种情况在这里,因为c1c0寄存器是常数(常数寄存器开始信'c')等是r1.x寄存器值.

这意味着对于所有调用的片段着色器,此值都相同,因此不会发生线程差异.

顺便说一句,我正在使用AMD GPU ShaderAnalyser将GLSL转换为IL.您还可以为特定代(从HD29xx到HD58xx)生成本机GPU汇编代码.这真是一个很好的工具!

  • 太糟糕了它只是窗户:( (5认同)

Kos*_*Kos 5

是的,IIRC你不会遇到性能开销,因为单个GPU处理器上单个批处理(warp)中的所有线程都将通过一个分支.'thread'我的意思是'着色器的单个执行行'.

当给定处理器在给定时间执行的线程的一部分(最多像32个线程AFAIK;依赖于硬件,我给出G80架构的数字)将分支到几个分支时,就会出现效率问题-一次两个不同的指令不能由一个处理器执行,因此首先"if"分支将由一部分线程执行(剩下的将等待),然后"else"分支将由其余部分执行.

你的代码不是这样,所以我相信你是安全的.