Coelacanth's Dream

AMDVLK ドライバーが RDNA 3/GFX11, Navi31 に対応

2022-12-15 付で、RDNA 3/GFX11Navi31 に対応した AMDVLK ドライバー v-2022.Q4.4 がリリースされた。
AMDVLK を構成する各種ライブラリも同時に更新され、Navi31 に対応するコミットが公開されている。
AMDVLK ドライバーは AMD が公式にオープンソースで開発しており、ハードウェアに密接した情報がコードやコメントの形で公開されることがある。そうして得られた情報が Mesa3D RADV (Vulkan) ドライバーに取り込まれることもある。

ここではその中から自分でもある程度読み取れる部分だけを取り上げる。

Index

Mesh Shader

RDNA 3 アーキテクチャ では Mesh Shader に関する改良も施され、Mesh Shader パイプラインで必要とする WorkgroupID を SGPR (スカラレジスタ) を介してハードウェアから返すことが可能になったため、RDNA 2 アーキテクチャ で必要としていた追加のエミュレーション処理を省くことができる。

    +#if LLPC_BUILD_GFX11
    +  // NOTE: For GFX11+, HW will provide workgroup ID via SGPRs. We don't need flat workgroup ID to do emulation.
    +  if (pipelineState->getTargetInfo().getGfxIpVersion().major >= 11)
    +    return false;
    +#endif

RT IP 2.0

AMD GPU の RayTracing Unit には、RDNA 2 アーキテクチャ では RT IP 1.1 が採用されていたが、RDNA 3 アーキテクチャ ではバージョンが進んだ RT IP 2.0 が採用されている。
RT IP 2.0 では BoxSort 機能への [Largest, MidPoint, LargestFirstOrClosest, LargestFirstOrClosestMidPoint] の追加、DXR Ray Flag に準拠したポインターフラグ機能が追加されている。
RayTracing 関連では、BVH ノードスタックの管理を最適化する ds_bvh_stack_rtn 命令が追加されている。(ds_ から始まる命令は共有メモリ {LDS/GDS} にデータを転送するための命令。)

         RtIp1_0 = 0x1,     ///< First Implementation of HW RT
         RtIp1_1 = 0x2,     ///< Added computation of triangle barycentrics into HW
    +#if PAL_BUILD_GFX11
    +    RtIp2_0 = 0x3,     ///< Added more Hardware RayTracing features, such as BoxSort, PointerFlag, etc
    +#endif
     enum class BoxSortHeuristic : uint32
     {
         Closest = 0x0,
    +#if GPURT_BUILD_RTIP2
    +    Largest = 0x1,
    +    MidPoint = 0x2,
    +#endif
         Disabled = 0x3,
    +#if GPURT_BUILD_RTIP2
    +    LargestFirstOrClosest = 0x4,
    +    LargestFirstOrClosestMidPoint = 0x5,
    +#endif
         DisabledOnAcceptFirstHit = 0x6
     };
    +#if GPURT_BUILD_RTIP2
    +//=====================================================================================================================
    +// Instance base pointer layout from the HW raytracing IP 2.0 spec:
    +// Zero                         [ 2: 0]
    +// Tree Base Address (64B index)[53: 3]
    +// Force Opaque                 [   54]
    +// Force Non-Opaque             [   55]
    +// Disable Triangle Cull        [   56]
    +// Flip Facedness               [   57]
    +// Cull Back Facing Triangles   [   58]
    +// Cull Front Facing Triangles  [   59]
    +// Cull Opaque                  [   60]
    +// Cull Non-Opaque              [   61]
    +// Skip Triangles               [   62]
    +// Skip Procedural              [   63]
    +//
    +// Since GPU VAs can only be 48 bits, only 42 bits of the Tree Base Address field are used:
    +// Used Address                 [44: 3]
    +// Unused Address               [53:45]
    +#endif

DispatchInterleaveSize

ShaderEngine (SE) に送る Thread-group (Work-group) を制御する機能が RDNA 3 アーキテクチャ では追加されている。
この機能は Compute Shader, Task Shader 用の機能とされ、グラフィクスパイプラインでは Task Shader が使用されていない場合は無視される。

    +#if PAL_BUILD_GFX11
    +/// Constant used for dispactch shader engine interleave. Value is the number of thread groups sent to one SE before
    +/// switching to another.  Default is 64. Other programmable values are: 128, 256, or 512. You can also disable
    +/// interleaving altogether.
    +enum class DispatchInterleaveSize : uint32
    +{
    +    Default = 0x0,
    +    Disable = 0x1,
    +    _128    = 0x2,
    +    _256    = 0x3,
    +    _512    = 0x4,
    +    Count
    +};
    +#endif
    +#if PAL_BUILD_GFX11
    +    DispatchInterleaveSize    taskInterleaveSize; ///< Ignored for pipelines without a task shader. For pipelines with
    +                                                  ///  a task shader, controls how many thread groups are sent to one
    +                                                  ///  SE before switching to the next one.
    +#endif

misc

一部の Atomic 操作が RDNA 3 アーキテクチャ では削除されたらしいが理由は不明。

    +#if PAL_BUILD_GFX11
    +    else if (IsGfx11(pInfo->gfxLevel))
    +    {
    +        pInfo->gfx9.supportAddrOffsetDumpAndSetShPkt = 1;
    +        pInfo->gfx9.supportAddrOffsetSetSh256Pkt     = (cpUcodeVersion >= Gfx10UcodeVersionSetShRegOffset256B);
    +        pInfo->gfx9.supportPostDepthCoverage         = 1;
    +
    +        //       FP32 image atomic operations are removed in Gfx11
    +        pInfo->gfxip.supportFloat32BufferAtomics     = 1;
    +        pInfo->gfxip.supportFloat32ImageAtomics      = 0;
    +        //       FP64 atomic operations are removed from GL2 in Gfx11
    +        pInfo->gfx9.supportFloat64Atomics            = 0;
    +

Mesa3D の RadeonSI (OpenGL) ドライバーでは RDNA 3 アーキテクチャNavi31/33, Phoenix APU の A0 リビジョンのいくつかでは命令のプリフェッチ機能が無効化するようにされているが1、AMDVLK ではそうした回避策が見られない。
RadeonSI ドライバーでは正確には GPU の内部レジスタから読み出せる rev_id を参照し、rev_id が 0 の場合に無効化しているため、条件に当てはまらない Navi31/33, Phoenix もあるということだろうか。
rev_id の値は RadeonSI (OpenGL) ドライバーであれば AMD_DEBUG=info glxinfo -B といったコマンドで確認することができる。

    +        pInfo->gfxip.shaderPrefetchBytes    = 3 * ShaderICacheLineSize;
    +        pInfo->gfxip.supportsSwStrmout      = 1;
    +        pInfo->gfxip.supportsHwVs           = 0;
    +
    +        pInfo->gfxip.gl1cSizePerSa          = 256_KiB;
    +
    +    }

RDNA 3 のハードウェアに存在するバグについて、自分なりに公開されている範囲で触れると、まず SGPR (スカラレジスタ) の初期化処理に関するバグは Navi31 (GFX1100), Navi33 (GFX1102) が影響を受ける。
V_MAD_U64/I64 命令のフォワーディングに関するバグは現状 RDNA 3 全体で影響を受けるとしている。

    def FeatureISAVersion11_0_0 : FeatureSet<
      !listconcat(FeatureISAVersion11_Common.Features,
        [FeatureGFX11FullVGPRs,
         FeatureUserSGPRInit16Bug])>;
    
    def FeatureISAVersion11_0_1 : FeatureSet<
      !listconcat(FeatureISAVersion11_Common.Features,
        [FeatureGFX11FullVGPRs])>;
    
    def FeatureISAVersion11_0_2 : FeatureSet<
      !listconcat(FeatureISAVersion11_Common.Features,
        [FeatureUserSGPRInit16Bug])>;
    
    def FeatureISAVersion11_0_3 : FeatureSet<
      !listconcat(FeatureISAVersion11_Common.Features,
        [])>;
     def FeatureUserSGPRInit16Bug : SubtargetFeature<"user-sgpr-init16-bug",
      "UserSGPRInit16Bug",
      "true",
      "Bug requiring at least 16 user+system SGPRs to be enabled"
    >;
    def FeatureMADIntraFwdBug : SubtargetFeature<"mad-intra-fwd-bug",
      "HasMADIntraFwdBug",
      "true",
      "MAD_U64/I64 intra instruction forwarding bug"
    >;

RadeonSI ドライバーで公開されているものでは、おそらくは最終的な色の出力機能に関するバグ (export_conflict_bug) があり、これも RDNA 3 全体が影響を受けるとしている。2
しかし、程度の差はあれどハードウェア的なバグは基本どの世代でも存在し、バグとそれに対するソフトウェア側の回避策が実性能にどれだけ影響するかはそれぞれ異なる。
オープンソースソフトウェアの範囲で公開されている上記のバグが、どれだけ影響するかも不明である。

参考リンク