Что скрывается за технологией Intellisample?
Часть I, оптимизации OpenGL драйвера 43.45 и 43.51

12.05.2003



Спросите у среднестатистического геймера-эстета, какую из функциональных возможностей графического ускорителя он считает наиболее важной с точки зрения улучшения качества изображения в уже существующих сегодня играх, и с очень большой долей вероятности Вы получите следующий ответ: анизотропную фильтрацию. К сожалению, именно анизотропия, безупречная по качеству, но чрезвычайно ресурсоёмкая из-за универсальной реализации 'в лоб', несомненно, была и по-прежнему остаётся самым слабым местом графических процессоров NV25. Не случайно, что от последователя NV25, процессора NV30, многие ждали только одного: быстрой анизотропной фильтрации, способной, наконец, обеспечить играбельную частоту кадров в высоких разрешениях. Не могли не понимать этого и в NVIDIA. Именно для того, чтобы устранить это самое слабое место и избавиться от катастрофического падения производительности при активизации анизотропной фильтрации, и была предназначена технология Intellisample, анонсированная вместе с семейством графических процессоров NV30. Судя по всему, термин Intellisample происходит от словосочетания Intelligent Sampling, то есть NVIDIA, таким образом, намекает на наличие неких интеллектуальных технологий анализа сцены, позволяющих снизить вычислительную ресурсоёмкость процесса анизотропной фильтрации путём внесения упрощений в её алгоритмы в тех случаях, когда они не приводят к значительному ухудшению качества изображения. Действительно, как мы знаем, в OpenGL драйвере уже достаточно давно (а именно, начиная с версии 28.90) появились алгоритмы анализа геометрии сцены, полностью отключающие анизотропную фильтрацию при текстурировании некоторых полигонов и позволяющие достичь очень значительного прироста производительности в режиме мультитекстурирования. Проверка индекса текстурной стадии и использование данного алгоритма только на стадиях с индексами, отличными от нуля, позволили NVIDIA сделать алгоритмы отброса полигонов максимально незаметными для тестов качества изображения, поскольку упрощения в львиной доле случаев касались лишь второстепенных текстур (например, карт освещённости), не оказывающих значительного влияния на чёткость результирующего изображения. Именно этот алгоритм и активизировался OpenGL драйвером в режимах Balanced и Aggressive при форсировании анизотропной фильтрации, и, к сожалению, до недавнего времени данный алгоритм был единственной компонентой технологии Intellisample, доступной всему семейству графических процессоров GeForce в OpenGL. Сразу оговоримся, что в этой статье мы не будем затрагивать специфичный для процессоров NV3x код (а именно, упрощения, связанные с трилинейной фильтрацией, коррекцию LOD bias и т.д.) и поговорим только об общих алгоритмах оптимизации анизотропии, присущих всему семейству GeForce. Благо, что повод для этого есть более чем достойный. Само собой, речь идёт о появлении драйверов Detonator 43.45 и 43.51, поднявших планку производительности анизотропной фильтрации в OpenGL на новый уровень и содержащих принципиально новые алгоритмы оптимизации для всех графических процессоров семейства GeForce. Именно об этих оптимизациях мы сегодня и поговорим.

Итак, не заметить изменений в качестве и, тем более, в скорости при активизации анизотропной фильтрации в OpenGL с последними версиями драйверов Detonator было очень и очень сложно. Более того, и номенклатура режимов Intellisample неоднократно изменялась за последнее время (вначале Application / Balanced / Aggressive были переименованы в Application / Quality / Performance, затем в Quality / Balanced / Performance), что говорит о том, что режимы Intellisample являются если и не первоочередной, то, как минимум, достаточно приоритетной задачей для программистов из NVIDIA. Однако, хотя факты появления новых режимов оптимизации анизотропии и отмечались в многочисленных обзорах, никто до сих пор не дал точного ответа на следующие вопросы: какие же именно упрощения вносятся в алгоритм фильтрации в последних версиях драйверов и за счёт чего так сильно выросла производительность? Давайте попробуем с Вами это сделать.

Для того, чтобы ответить на поставленный перед собой вопрос, нам пришлось заглянуть внутрь OpenGL драйвера и посмотреть, каким образом интерпретируется ключ OGL_QualityEnhancements, который, собственно, и управляет режимами Intellisample. То, что мы там увидели, превзошло все ожидания: в зависимости от выбранного режима Intellisample драйвер использует одну из четырёх заранее сгенерированных таблиц упрощения степени анизотропии:

Таблицы упрощения степени анизотропии в режиме Quality

 

Таблица 1

Таблица 2

Таблица 3

Таблица 4

Level 1

Level 1

Level 1

Level 1

Level 1

Level 2

Level 2

Level 2

Level 2

Level 2

Level 4

Level 4

Level 4

Level 4

Level 4

Level 8

Level 8

Level 8

Level 8

Level 8


Таблицы упрощения степени анизотропии в режиме Balanced

 

Таблица 1

Таблица 2

Таблица 3

Таблица 4

Level 1

Level 1

Level 1

Level 1

Level 1

Level 2

Level 2

Level 2

Level 2

Level 2

Level 4

Level 4

Level 2

Level 2

Level 4

Level 8

Level 8

Level 2

Level 4

Level 8


Таблицы упрощения степени анизотропии в режиме Performance

 

Таблица 1

Таблица 2

Таблица 3

Таблица 4

Level 1

Level 1

Level 1

Level 1

Level 1

Level 2

Level 2

Level 1

Level 1

Level 2

Level 4

Level 4

Level 1

Level 1

Level 4

Level 8

Level 8

Level 1

Level 2

Level 8

Как можно заметить, в зависимости от используемой таблицы максимально качественный Level 8 может быть заменён на Level 1 либо Level 2 в режиме Performance и на Level 2 либо на Level 4 в режиме Balanced. Не зная первоначально критерия выборки индекса таблицы, мы предположили, что в его качестве используется индекс текстурной стадии и программисты из NVIDIA занялись откровенным надувательством, элементарно занижая степень анизотропии на первой и второй текстурных стадиях. Для проверки этой гипотезы мы специально разработали тестовое приложение OpenGL anisotropic filtering quality test v1.0, отображающее тестовую сцену, состоящую из одной единственной поверхности, на которую в режиме мультитекстурирования накладывается до четырёх текстур за один проход:

Кроме этого, наше тестовое приложение позволяет выбрать текущую текстурную стадию, с которой будет ассоциирована однородная текстура белого цвета с цветными mipmap уровнями (чередование белого, красного, зелёного и синего цветов). Совокупность возможности выбора текущей стадии, использующей текстуру с разноцветными mipmap уровнями, и возможность одновременного отображения одной и той же тестовой сцены с различными комбинациями билинейной (изотропной), анизотропной и трилинейной фильтрации должны были неизбежно выявить снижение степени анизотропии на разных текстурных стадиях, если бы оно, конечно, имело место.

К чести программистов NVIDIA отметим, что наша гипотеза не подтвердилась, и качество анизотропной фильтрации никак не зависело от индекса текстурной стадии. Более того, таблицы анизотропии явно не использовались вообще до тех пор, пока мы не форсировали анизотропию из панели настроек драйвера. После форсирования результат немного приблизился к ожидаемому, хотя он попрежнему абсолютно не зависел от стадии:

Режим Quality





Режим Balanced





Режим Performance

Итак, скриншоты явно говорят о том, что в нашем приложении явно используется таблица упрощения анизотропии с индексом 2:

 

    Quality    

   Balanced   

Performance

Level 1

Level 1

Level 2

Level 1

Level 2

Level 2

Level 2

Level 1

Level 4

Level 4

Level 2

Level 1

Level 8

Level 8

Level 2

Level 1

Однако каким образом выбирается индекс таблицы упрощения? Он явно не зависит от текстурной стадии. Более того, в нашем тестовом приложении OpenGL драйвер стабильно выбирал именно вторую таблицу упрощения, и на этот выбор не влиял ни угол поворота, ни размер сцены, то есть выбор индекса явно производился и не на основе геометрии. Для окончательного выяснения этого вопроса нам пришлось провести более глубокий анализ кода OpenGL драйвера. Честно отметим, что мы были очень приятно удивлены результатом. Итак, чем же специфично наше приложение и что заставляет драйвер использовать для него самую грубую таблицу упрощения? Впрочем, ответ лежит на поверхности: наш тест специфичен лишь..... однородной текстурой. Да-да, именно текстурой. Вы не ослышались, максимальный уровень анизотропии теперь напрямую зависит от содержимого фильтруемой текстуры. Остаётся только пожать руку программистам OpenGL драйвера, придумавшим столь оригинальный подход в оптимизации анизотропной фильтрации. Действительно, такой метод оптимизации, бесспорно, имеет право на жизнь: к примеру, зачем загружать графический процессор усреднением цветов тридцати двух текселей для формирования финального цвета пикселя, если цвета этих текселей одинаковы и усреднение четырёх текселей из стандартной билинейной выборки даст абсолютно такой же результат? Теперь алгоритмы Intellisample в OpenGL по праву могут считаться интеллектуальными, поскольку драйвер рассчитывает степень чёткости каждой текстуры при её создании, и именно эта степень чёткости и используется в качестве индекса используемой таблицы упрощения анизотропии.

Для того, чтобы продемонстрировать Вам работу алгоритмов Intellisample, анализирующих чёткость текстуры и выбирающих в соответствии с ней нужную таблицу упрощения анизотропии, мы немного дополнили наше тестовое приложение возможностью регулировки чёткости текстуры. Для этого, вместо однородного цвета текстура текущей стадии и её разноцветные mipmap уровни теперь заполняются периодическим узором, генерирующимся по следующей формуле:

color = 255 - threshold + threshold * sin(tx + cos(ty))

В данной формуле color - цвет текселя, tx и ty - его ненормированные текстурные координаты, а threshold - значение, определяющее максимальную разницу в цветах текселей текстуры, то есть, фактически, уровень её чёткости.

Значение threshold может регулироваться в нашем приложении клавишами [w] и [s], и именно оно и определяет, какая из таблиц упрощения анизотропии будет использоваться OpenGL драйвером. Давайте посмотрим на результаты работы нашего теста с различными значениями параметра threshold:

Режим Balanced, неоднородная текстура средней чёткости





Режим Balanced, неоднородная текстура высокой чёткости





Режим Performance, неоднородная текстура средней чёткости





Режиме Performance, неоднородная текстура высокой чёткости

Как видно, при переходе чёткости текстуры через определённый порог, драйвер переключается сначала на таблицу упрощения 3, а затем и вовсе отключает упрощения, переключившись на таблицу 4. Остаётся только ещё раз виртуально пожать руку программистам, реализовавшим такой метод оптимизации.

Итак, мы выяснили, на чём основаны оптимизации анизотропной фильтрации, появившиеся в OpenGL в одной из последних версий драйвера Detonator. Анализ чёткости и снижение степени анизотропии для однородных текстур, бесспорно, является очень и очень оригинальным решением, однако нам необходимо акцентировать Ваше внимание на двух особенностях, связанных с работой алгоритмов анализа чёткости и способных свести на нет эффект от оптимизации.

Во-первых, вспомним тот факт, что алгоритмы упрощения степени анизотропии на основе анализа чёткости текстур не активизировались в нашем тесте до тех пор, пока мы не форсировали анизотропную фильтрацию в панели настроек драйвера. Изучив код OpenGL ICD, мы пришли к выводу, что драйвер рассчитывает чёткость текстуры при её создании только в том случае, если степень анизотропии установлена в отличное от единицы значение до её создания. Такой подход гарантирует работоспособность алгоритмов анализа степени чёткости текстур при форсировании анизотропной фильтрации, однако далеко не гарантирует его работоспособность в том случае, если анизотропией управляет само OpenGL приложение. Для того, чтобы форсировать использование алгоритмов анализа чёткости текстур в нашем тестовом приложении, мы добавили код установки степени анизотропной фильтрации в значение 2 перед созданием текстур через glTexImage2D. Однако никто не даст Вам никаких гарантий, что разработчики всех OpenGL приложений будут выполнять подобные действия, так что есть вероятность того, что алгоритмы анализа чёткости текстур не будет использованы в некоторых приложениях, контролирующих анизотропию самостоятельно.

Во-вторых, по-видимому, алгоритмы анализа чёткости пока не обучены работе с компрессированными текстурами. Поэтому если используемое Вами приложение использует сжатие текстур, OpenGL драйвер просто не задействует алгоритмы анализа их чёткости. Для того, чтобы это проиллюстрировать, мы добавили в наше тестовое приложение возможность включения компрессии текстур в формат GL_COMPRESSED_RGB_S3TC_DXT1_EXT (ключ командной строки -tc):

Режим Performance, полностью однородная DXT1 текстура

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

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

Процессор

AMD AthlonXP 2400+

Материнская плата

ASUS A7N8X на чипсете NVIDIA nForce2

Оперативная память

512 MB Samsung PC2700 DDRAM, CAS2.5

Видеокарта

Leadtek WinFast A250 Ultra 128 MB (GeForce4 Ti4600 ревизии A3)

Стенд работал под управлением операционной системы Windows XP Professional и драйверов Detonator 43.51. В качестве тестового приложения мы не случайно выбрали Quake III : Arena. Дело в том, что это как раз одно из тех приложений, которые не используют весь потенциал оптимизаций на уровне анализа чёткости текстур из-за включенного по умолчанию сжатия. Поэтому мы приводим результаты тестов как с включенной, так и с отключенной текстурной компрессией, дабы наглядно оценить прирост производительности, который может быть вызван использованием новых оптимизаций. Кроме этого, мы также приводим результат тестирования нашего скрипта AnisoBoosterOGL, который уже достаточно долго включен в утилиту твикинга RivaTuner и позволяет поднять эффективность упоминаемого в статье алгоритма отброса полигонов путём блокирования проверки индекса текстурной стадии, тем самым увеличивающего производительность за счёт применения алгоритмов отброса полигонов и к нулевой текстурной стадии:

 

Обратите внимание на практически идентичные результаты между режимами Intellisample, полученные с включенной компрессией текстур (81,1 FPS в режиме Quality против 84,7 в режиме Performance, разница между ними составляет всего 4.5%), и почти пятидесятипроцентную разницу между ними (72,9 FPS в режиме Quality против 108,8 FPS в режиме Performance) при её отключении. Более того, использование скрипта AnisoBoosterOGL даёт ещё почти десятипроцентную прибавку в производительности. Остаётся только счастливо прослезиться, глянув на максимально возможные 120 FPS и вспомнив 50 FPS, которые мы не так давно получали в тех же самых условиях тестирования до появления в драйвере алгоритмов отброса полигонов и алгоритмов анализа чёткости текстур. Понадеемся на то, что алгоритмы Intellisample будут и далее развиваться такими же семимильными шагами и при этом качество изображения не будет страдать очень сильно.

Выводы:

  • Бесспорно, алгоритмы оптимизации анизотропной фильтрации на основе анализа чёткости текстур заслуживают наших аплодисментов. К сожалению, на протяжении достаточно длительного периода времени оптимизации анизотропной фильтрации появляются только в OpenGL драйвере. Надеемся, что в ближайшем будущем ситуация изменится к лучшему и мы, наконец, увидим подобные оптимизации и в Direct3D. Кроме того, мы очень надеемся, что программисты из NVIDIA, наконец, перестанут упрямиться и возьмут на вооружение и скрипт AnisoBoosterOGL, интегрировав его в драйвер, избавив нас от необходимости его постоянной поддержки. В конце концов, лишние 10% производительности на дороге не валяются.
  • Учитывая специфику работы, а точнее активизации режимов оптимизации анизотропной фильтрации на основе анализа чёткости текстур, мы можем дать следующие рекомендации тем, кто хочет достичь максимальной производительности в OpenGL приложениях при использовании анизотропии:
    • Строго рекомендуется отключать компрессию текстур при использовании анизотропной фильтрации в режимах Balanced и Performance, поскольку на данный момент OpenGL ICD драйвер, по-видимому, просто не обучен анализу сжатых данных, поэтому в случае активизации компрессии на уровне приложения алгоритмы анализа текстур и, соответственно, оптимизации просто не будут задействованы. Напомним, что в режиме Performance компрессия текстур форсируется принудительно, поэтому проблема нехватки локальной видеопамяти из-за отключения сжатия не должна Вас беспокоить. Более того, в OpenGL драйвере, наконец, появилась возможность управления форсированием компрессии текстур, так что если Вас раздражает принудительное сжатие в режиме Performance либо Вы просто хотите управлять данной функцией независимо от настроек Intellisample - не пропустите следующую версию RivaTuner.
    • Для гарантированной активизации алгоритмов анализа чёткости текстур мы рекомендуем форсировать анизотропную фильтрацию в настройках драйвера даже в том случае, если анизотропной фильтрацией управляет само OpenGL приложение.


Николайчук Алексей a.k.a. Unwinder (AlexUnwinder@mail.ru)


Обсудить/дополнить в конференции