VGPR用法和gl_FragColor与gl_FragData [n]

时间:2017-08-25 10:34:30

标签: opengl glsl

GPU供应商建议减少着色器中使用的VGPR(矢量通用寄存器)的数量,因为它们的数量有限,过度使用会降低GPU占用率。所以我编译了一个发出白色的简单片段着色器,并使用Radeon GPU Analyzer(RGA)检查了VGPR的使用情况

void main(void)
{
  gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
}

令我惊讶的是,它发出了一个相当大的着色器

1 |   1 | ^                         | label_basic_block_1: v_mov_b32 v0, 0
2 |   2 | :^                        | v_mov_b32 v1, 1.0
3 |   3 | v:^                       | v_cvt_pkrtz_f16_f32 v2, v0, v0
4 |   4 | vv:^                      | v_cvt_pkrtz_f16_f32 v3, v0, v1
5 |   4 | ::vv                      | exp mrt7, v2, v2, v3, v3
6 |   3 | v:   ^                    | v_cvt_pkrtz_f16_f32 v5, v0, v0
7 |   4 | vv   :^                   | v_cvt_pkrtz_f16_f32 v6, v0, v1
8 |   4 | ::   vv                   | exp mrt6, v5, v5, v6, v6
9 |   3 | v:      ^                 | v_cvt_pkrtz_f16_f32 v8, v0, v0
10 |   4 | vv      :^                | v_cvt_pkrtz_f16_f32 v9, v0, v1
11 |   4 | ::      vv                | exp mrt5, v8, v8, v9, v9
12 |   3 | v:         ^              | v_cvt_pkrtz_f16_f32 v11, v0, v0
13 |   4 | vv         :^             | v_cvt_pkrtz_f16_f32 v12, v0, v1
14 |   4 | ::         vv             | exp mrt4, v11, v11, v12, v12
15 |   3 | v:            ^           | v_cvt_pkrtz_f16_f32 v14, v0, v0
16 |   4 | vv            :^          | v_cvt_pkrtz_f16_f32 v15, v0, v1
17 |   4 | ::            vv          | exp mrt3, v14, v14, v15, v15
18 |   3 | v:               ^        | v_cvt_pkrtz_f16_f32 v17, v0, v0
19 |   4 | vv               :^       | v_cvt_pkrtz_f16_f32 v18, v0, v1
20 |   4 | ::               vv       | exp mrt2, v17, v17, v18, v18
21 |   3 | v:                  ^     | v_cvt_pkrtz_f16_f32 v20, v0, v0
22 |   4 | vv                  :^    | v_cvt_pkrtz_f16_f32 v21, v0, v1
23 |   4 | ::                  vv    | exp mrt1, v20, v20, v21, v21
24 |   3 | v:                     ^  | v_cvt_pkrtz_f16_f32 v23, v0, v0
25 |   4 | vv                     :^ | v_cvt_pkrtz_f16_f32 v24, v0, v1
26 |   2 |                        vv | exp mrt0, v23, v23, v24, v24
27 |   0 |                           | s_endpgm 
Maximum # VGPR used   4, # VGPR allocated:  25

仔细观察会显示' exp mrt0',' exp mrt1' ......很明显,所有八个可用的MRT轨迹都被写入。所以我稍微更改了着色器

void main(void)
{
  gl_FragData[0] = vec4( 0.0, 0.0, 0.0, 1.0 );
}

并且寄存器分配从 25降至3 (!),指令数从 27降至6

1 |   1 | ^   | label_basic_block_1: v_mov_b32 v0, 0
2 |   2 | :^  | v_mov_b32 v1, 1.0
3 |   3 | v:^ | v_cvt_pkrtz_f16_f32 v2, v0, v0
4 |   3 | xv: | v_cvt_pkrtz_f16_f32 v0, v0, v1
5 |   2 | v v | exp mrt0, v2, v2, v0, v0
6 |   0 |     | s_endpgm 

Maximum # VGPR used   3, # VGPR allocated:   3

我现在有点困惑。在这种情况下我不需要MRT,但无论如何,

  1. 为什么写入7 MRT(mrt1..mrt7)使用不少于22个VGPR?为什么我们不能从一个寄存器写?

  2. 仅仅是为了感兴趣,这次MRT写作是否并行完成,或者我们真的花了20多条指令呢?

  3. 如果我只写入gl_FragData [0] / MRT0,着色器的执行速度是否会受益于降低的VGPR使用率?如果不是这种情况,在VGPR使用率下降的情况下是否会受益40分配给18个分配的VGPR?

  4. (是的,我知道在最新的GLSL版本中不推荐使用gl_FragDataXY,但我仍然想编写可以在旧卡上运行的代码。)

1 个答案:

答案 0 :(得分:0)

  

为什么写入7 MRT(mrt1..mrt7)使用不少于22个VGPR?为什么我们不能从一个寄存器写?

" can&#t; t"并且"没有"#34;你没有考虑到。事实是它是2017年:gl_FragColor是预定义的输出,已经从GLSL中移除了近十年。 AMD没有理由优化此值的使用。

因此虽然它可能做得更好,但编译器不会做得更好。

  

如果我只写入gl_FragData [0] / MRT0,着色器的执行速度是否会受益于VGPR的使用减少?

优化并不那么简单。没有办法确定,特别是在真实世界的着色器中,写入gl_FragColor的额外VGPR可能无关紧要,因为它可以重用其他代码分配的VGPR。