古いプロセッサーでDirectX12をサポートするAMDドライバーを返します

4月末に新しいAMD 16.4.2ドライバーに更新すると、すべてのDirectX12アプリケーションが動作しなくなったことがわかりました。 まったく驚きませんでしたが、問題が解決するまで待ち、DirectX12を脇に置くことにしました。 しかし、数ヶ月が経過し、新しいドライバーで状況は変わりませんでした。



Googleは、この問題が広範囲(1、2、3、4)にあり、AMDがまったく反応しないことを示しました。 AMD tapekフォーラムのユーザーは 、デバッグにより、SSE4.2セットからのpopcnt命令が新しいドライバーによって使用されるという問題があることを発見しました。



問題のあるライブラリー(amdxc32.dll)の1つをHiewにロードし、popcnt-F3 0F B8命令でオペコードを検索すると、最大3回呼び出されることがわかりました! これは彼女があまり必要とされていないことを意味し、あなたは彼女の代わりを思い付くことができます。 この命令は、2番目の引数の単一ビットの数を最初の引数に返します。



popcntを置き換えるために、Brian Kernigan / Kernighanアルゴリズムを見てみましょう。

C ++では、次のようになります。



int kernigan(int value){ int count = 0; while(value != 0){ value &= (value-1); count++; } return count; }
      
      





このようなアクメで:



  push ebx push ecx xor eax,eax mov ebx, value kernigan_start: cmp ebx, 0 jz kernigan_end add eax, 1 mov ecx, ebx sub ebx, 1 and ebx, ecx jmp kernigan_start kernigan_end: pop ecx pop ebx retn
      
      





コードセクションの最後で、ゼロで詰まった未割り当ての場所を探しています。 そこで、コードを記述します。



画像






ライブラリでpopcntコマンドの呼び出しを見つけます。



画像






そして、それをコードへの移行に置き換えます。



画像






以前に見つかった場所で、コードを記述し、取得した場所に制御を戻します



画像






次に、このライブラリとamdxc64.dllの両方でpopcntコマンドの残りの呼び出しを使用して上記を繰り返し、元のファイルをそれらに置き換え、SSE4.2なしで再びDirectX12を動作させます。



9月13日付けのドライバ16.9.1用に変更したライブラリへのPS リンク



All Articles