Как стать автором
Обновить

Возвращаем драйверам AMD поддержку DirectX12 старыми процессорами

Время на прочтение2 мин
Количество просмотров25K
Обновившись в конце апреля на новые драйвера AMD 16.4.2, я обнаружил, что все DirectX12-приложения перестали работать. Ничуть не удивившись, я решил подождать устранения проблемы и отложил DirectX12 в сторону. Но месяцы шли, а с новыми драйверами ситуация не менялась.

Гугл показал, что эта проблема носит массовый характер (раз, два, три, четыре), а AMD никак не реагирует. Пользователь форумов AMD tapek путем дебаггинга выяснил, что проблема заключается в использовании новыми версиями драйверов инструкции 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

Ищем в конце секции кода незанятое место, забитое нулями. Там мы и будем писать наш код:

image

Находим в библиотеке вызов команды popcnt:

image

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

image

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

image

После чего повторяем вышеописанное с оставшимися вызовами команды popcnt как в этой библиотеке, так и в amdxc64.dll, подменяем ими оригиналы и получаем снова работающий DirectX12 без SSE4.2.

P.S. линк на модифицированные мною библиотеки для драйверов 16.9.1 от 13 сентября.
Теги:
Хабы:
Всего голосов 62: ↑61 и ↓1+60
Комментарии35

Публикации

Истории

Ближайшие события

19 августа – 20 октября
RuCode.Финал. Чемпионат по алгоритмическому программированию и ИИ
МоскваНижний НовгородЕкатеринбургСтавропольНовосибрискКалининградПермьВладивостокЧитаКраснорскТомскИжевскПетрозаводскКазаньКурскТюменьВолгоградУфаМурманскБишкекСочиУльяновскСаратовИркутскДолгопрудныйОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн
24 – 25 октября
One Day Offer для AQA Engineer и Developers
Онлайн
25 октября
Конференция по росту продуктов EGC’24
МоскваОнлайн
26 октября
ProIT Network Fest
Санкт-Петербург
7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань