- PVSM.RU - https://www.pvsm.ru -
Обновившись в конце апреля на новые драйвера AMD 16.4.2, я обнаружил, что все DirectX12-приложения перестали работать. Ничуть не удивившись, я решил подождать устранения проблемы и отложил DirectX12 в сторону. Но месяцы шли, а с новыми драйверами ситуация не менялась.
Гугл показал, что эта проблема носит массовый характер(раз [1], два [2], три [3], четыре [4]), а AMD никак не реагирует. Пользователь форумов AMD tapek [5] путем дебаггинга выяснил, что проблема заключается в использовании новыми версиями драйверов инструкции popcnt из набора SSE4.2.
Загрузив одну из проблемных библиотек(amdxc32.dll) в Hiew, поиском по опкоду инструкции popcnt — F3 0F B8 обнаруживаем, что она вызывается аж целых три раза! Это значит, что она не сильно там нужна и можно придумать ей замену. Эта инструкция возвращает первому аргументу количество единичных бит второго аргумента.
Для замены popcnt возьмем алгоритм Брайана Кернигана(Brian Kernigan/Kernighan).
На С++ он выглядит так:
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:

И заменяем его на переход на наш код:

В ранее найденном месте пишем наш код и возвращаем управление туда, откуда взяли

После чего повторяем вышеописанное с оставшимися вызовами команды popcnt как в этой библиотеке, так и в amdxc64.dll, подменяем ими оригиналы и получаем снова работающий DirectX12 без SSE4.2.
P.S. линк [6] на модифицированные мною библиотеки для драйверов 16.9.1 от 13 сентября.
Автор: Bazanra
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/amd/191603
Ссылки в тексте:
[1] раз: https://community.amd.com/thread/200247
[2] два: https://community.amd.com/message/2733113
[3] три: https://community.amd.com/message/2747845
[4] четыре: https://community.amd.com/message/2741591
[5] tapek: https://community.amd.com/people/tapek
[6] линк: https://www.dropbox.com/sh/h00td000ol1xy83/AAC6ak1njz-pQ2qCpPZ_r5D-a
[7] Источник: https://habrahabr.ru/post/310864/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.