我有一个带有分支的相当简单的片段着色器,我有点不确定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)
重新说一下科斯所说的,重要的是要知道在执行之前是否可以知道保护条件.是这种情况在这里,因为c1和c0寄存器是常数(常数寄存器开始信'c')等是r1.x寄存器值.
这意味着对于所有调用的片段着色器,此值都相同,因此不会发生线程差异.
顺便说一句,我正在使用AMD GPU ShaderAnalyser将GLSL转换为IL.您还可以为特定代(从HD29xx到HD58xx)生成本机GPU汇编代码.这真是一个很好的工具!
是的,IIRC你不会遇到性能开销,因为单个GPU处理器上单个批处理(warp)中的所有线程都将通过一个分支.'thread'我的意思是'着色器的单个执行行'.
当给定处理器在给定时间执行的线程的一部分(最多像32个线程AFAIK;依赖于硬件,我给出G80架构的数字)将分支到几个分支时,就会出现效率问题-一次两个不同的指令不能由一个处理器执行,因此首先"if"分支将由一部分线程执行(剩下的将等待),然后"else"分支将由其余部分执行.
你的代码不是这样,所以我相信你是安全的.
| 归档时间: |
|
| 查看次数: |
3092 次 |
| 最近记录: |