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

    Обновившись в конце апреля на новые драйвера 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 сентября.
    Share post

    Similar posts

    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 35

      +7
      Вот это подход!
        0

        Это не подход, это костыль временная мера.
        Ибо мало того что следующий апдейт заставить патчить либо искать пропатченные либы фиг знает с какой встроенной заразой, так еще в один прекрасный момент amd может пересобрать дрова с поддержкой остальных инструкций из набора.

        +1
        Проц без SSE4.2 — это уже довольно-таки древность. Слабо понимаю, зачем такой машине поддержка ДХ12.
          +4
          Если поставить например копеечный E5450 в материнку на 775 и купить видеокарту среднего уровня — вполне себе жизнеспособный вариант получается.
            +6

            А ещё есть AMD Phenom II, в разогнанном виде они до сих пор неплохи.

              –7
              «неплохи» = «приложения запускаются и даже как-то работают»?
                +2

                Неплохи = невооружённым глазом разницы с i5 на соседнем ПК в повседневном использовании не видно.


                На домашнем сервере, где тоже phenom II был, но на шесть ядер, разницу при переходе на Xeon заметил только в диспетчере задач — загрузка процессора упала с ~25-30% до 5-10% при полудюжине запущенных hyper-v машин.

                  0
                  Если не загружен — тогда, конечно, не будет заметно. А я, например, её везде вижу. Начиная с игр и заканчивая временем компиляции проекта и временем обработки изображений в программе, над которой я работаю. Разница Core i7 с 8-ядерным Будьдозером — более 2 раз, так-то. И это старый Sandy Bridge.
                    +2

                    А что не так с играми? Doom играется, Deus Ex играется, оба упираются в мою видеокарту (GTX660), а не процессор. Понятно, что i7 будет намного лучше, но списывать со счетов камни без SSE 4.2 всё же ещё не стоит. Тем более, что DX12 вроде как раз и должен снижать нагрузку на процессор.

                      –1
                      А в играх просадки ФПС намного меньше с современными процессорами. Посмотрите, например, http://wccftech.com/intel-skylake-6700k-6600k-amd-fx-8370/
                        +3
                        Позвольте, но далеко не каждый может себе позволить купить топовый i7 и R9 Fury Triple Dissipation.

                        Что им теперь, в игры не играть? Запускать что-то, требующее выше 10 DirectX даже не мечтать?

                        Покупают ведь люди и новые компьютеры с Core i3, и вполне себе радуются жизни, хотя они может быть тоже раза в два слабее «старого i7».
                          –1
                          Просадки до 15 ФПС чувствительны безо всяких Fury. А часто и до 25 ФПС (правильнее было бы, наверное, считать время задержки, если это фриз, а не переводить в ФПС). А если у компа средний ФПС такой, то он, пардон, совсем не игровой. На старой технике можно играть с пониженными настройками, но это совсем не то удовольствие. И не всегда помогает — одна из недавних игр на моей предыдущей карточке АМД 6950 была неиграбельна даже на минимальных и с внутренним масштабированием разрешения 50% (то есть 0.5 от экранного).
                            +4
                            но это совсем не то удовольствие

                            Как люди раньше без графона играли…
                              –2
                              Как люди раньше деревянными игрушками играли? А ещё раньше только и делали, что еду искали, не до игр было.
                                0
                                Вам смешно, а я еще помню время когда у меня half life 1 тормозил… В те времена 25 фпс считалось вполне игровым режимом.
                                После обновления компа, еще некоторое время выставлял в драйвере принудительное ограничение в 25 кадров, было непривычно когда их больше 30…

                                Я почти на 90% уверен что комфортно можно и сейчас играть на 25кадрах, если не будет фризов и лагов, и это ограничение будет искусственным.
                                  0
                                  В принципе, да, хотя ещё зависит от движка. Для плавности на 25 лучше добавить немного motion blur, это здорово помогает.
                          • UFO just landed and posted this here
              0
              Хорошая работа!
                0
                dxdiag вылетает с ошибкой. но успевает показать, что DirectX − 12.
                  0
                  С какой ошибкой?
                    0
                    Имя сбойного приложения: dxdiag.exe, версия: 10.0.14393.0, метка времени: 0x57899b4a
                    Имя сбойного модуля: amdxc64.dll, версия: 21.19.134.1, метка времени: 0x57d02449
                    Код исключения: 0xc0000005
                    Смещение ошибки: 0x0000000000035a0e
                    Идентификатор сбойного процесса: 0x1e80
                    Время запуска сбойного приложения: 0x01d216792db489b7
                    Путь сбойного приложения: C:\WINDOWS\system32\dxdiag.exe
                    Путь сбойного модуля: C:\WINDOWS\system32\amdxc64.dll
                    Идентификатор отчета: f3e4b1e0-edb0-4f0b-8246-4a0f881523f9
                    Полное имя сбойного пакета:
                    Код приложения, связанного со сбойным пакетом:
                      0
                      Здесь что-то не так. Драйвер 16.9.1 от 13 сентября использует amdxc64.dll из DriverStore, а не из system32.
                        0
                        Он же их копирует в System32 (и SysWOW64). DriverStore лишь хранилище, разве нет?
                          0
                          Раньше так и было, но начиная с одной из недавних версий это изменилось — теперь он использует их напрямую из хранилища, не копируя в System32/SysWOW64.
                  +2
                  используйте сдвиги с переходом через cf и сложение с нулем и cf. ускорится все немного.
                    +6
                    А почему jmp, а не call и ret? Тогда можно адреса возврата не высчитывать, а просто заменить инструкцию и выровнять код… Я так понимаю вы алгоритм Кернигана 3 раза вставили?
                      0
                      С call и ret мой промах, возьму на заметку.
                      Алгоритм вставлял 6 раз — по 3 раза в x32 и x64 библиотеки. Как написать одну общую функцию (пока) не придумал — вызов popcnt занимает 9 байт, а на передачу только второго аргумента в стек уйдет 7 байт.
                        0
                        а, ясно. каждый раз разный аргумент, который [edi][edx]*4[00000010… Тогда, да… проще jmp…
                      +3
                      Насчёт SSE4.2: всё не совсем так. POPCNT содержится и в SSE4A, а этот набор был уже в первом Phenom (2007 год, пруф: https://en.wikipedia.org/wiki/SSE4). Так что владельцам phenom/phenom II не о чем париться. Скорее всего амд включили не SSE4.2, а SSE4A.
                      • UFO just landed and posted this here
                          +1
                          При выборе алгоритма я рассмотрел еще больше вариантов (их тесты тут), и выбрал Кернигановский по той причине, что он очень прост и в ассемблерном коде занимает меньше всего места, а, значит вероятность допустить ошибку меньше.
                            0
                            Всегда можно написать на С и скомпилировать. GCC в алгоритме любой сложности не ошибется. Лишь бы влезть в сегмент.
                          0
                          Bazanra и правильно сделал что пропатчил.
                          У них явно что-то не так либо с разработкой, либо с тестированием. Год назад фиксил их драйвер для старенькой видяхи HD7770 под Linux (появились мелкие изменения в api ядра) и смотрю ситуация вообще не изменилась. Фикс был отправлен, но до выпуска официального патча прошло еще полгода.
                            0
                            Под Linux у них генеральное направление сменилось на AMDGPU и код прямо в ядре, обновляется соответственно отлично. А вот сил на перевод драйвера на работу с открытым модулем ядра видать ушло очень много и на старое железо слегка забили.
                              0
                              splav_asv, спасибо, в курсе. Драйвер amdgpu, имхо, хорошо себя показал. Только неприятный отпечаток все равно остался, да и в силу обстоятельств железку уже обновил.
                              «Забивательство» AMD (да и других больших кампаний) на устаревшие девайсы, скорее всего, идет со стороны биснеса от вопроса «как стимулировать оборот?» и тут уже ничего не поделать, остается только поддержка сообществом.

                          Only users with full accounts can post comments. Log in, please.