Как устроена видеокарта (видеоадаптер)

Красивые эффекты в операционной системе, вывод фильма или трехмерной игры, - все это требует видеокарты. Как же они устроены?


Информация в видеоадаптерах хранится в виде двумерных массивов пикселов в области памяти видеоадаптера. Такая область памяти называется кадровым буфером (frame buffer).

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

На ранних моделях PC использовались 20-разрядные адресные линии, что позволяло работать с адресным пространством объема до 1 Мбайт. Видеоадаптеру отводилось всего лишь 64 или 128 Кбайт из общего 1-мегабайтного пространства.

Если взять современное разрешение Full HD 1920х1080, при глубине цвета 32 бита, необходимо 8100 Кб памяти на один кадровый буфер. При частоте 60 кадров в секунду это означает обработку 486 Мб видеоданных в секунду.

Представление одного пиксела 8 битами позволяет использовать до 256 разных цветов. Если бы эти цвета жестко фиксировались, то пришлось бы выбрать универсальный набор точек для представления всего цветового пространства RGB – для нормального отображения нашего многоцветного мира это явно недостаточно. Поэтому вместо фиксированного набора цветов видеоадаптер использует цветовую таблицу, называемую палитрой (palette). Для кадрового буфера с 8-миразрядной кодировкой палитра состоит из 256 элементов, каждый из которых соответствует 24-разрядному значению RGB. В кадровом буфере сохраняются не цвета, а индексы в палитре. При косвенном представлении цветов с использованием палитры кадровый буфер, как и раньше, в любой момент времени содержит только 256 различных цветов, однако эти цвета выбираются из 16 миллионов кандидатов 24-разрядного цветового пространства.

В 15-разрядных кадровых буферах High Color каждая из основных цветовых составляющих представляется 5 битами. Информация об одном пикселе хранится в 16-разрядном слове; старший бит остается неопределенным, а за ним следуют 5 бит красной, 5 бит зеленой и младшие 5 бит синей составляющих. 15-разрядный формат пикселов часто обозначается сокращением "5:5:5". Кадровый буфер в этом формате может содержать до 32 768 разных цветов.

В приложениях с особо качественной графикой и играх даже 15- и 16-разрядные кадровые буферы не обеспечивают необходимого разнообразия цветов и плавности цветовых переходов. Например, при выводе изображения в оттенках серого цвета с использованием 15-разрядного кадрового буфера удается вывести лишь 32 уровня серого цвета – каждая цветовая составляющая RGB хранится в 5 битах, что позволяет задействовать 2 в 5 степени уровней интенсивности. В таких приложениях просто необходимо использовать самое лучшее – 24 или 32-разрядные кадровые буферы True Color. И в 24-, и в 32-разрядных кадровых буферах красная, зеленая и синяя составляющие предоставляются 8 битами. В старых видеоадаптерах старшие 8 бит 32-разряднгго пиксела обычно оставались неиспользованными. У новых видеоадаптерах в старших 8 битах хранится информация о прозрачности (transparency).

Составляющая прозрачности обычно называется альфа-каналом (alpha channel). Эта характеристика определяет весовой коэффициент исходного пиксела при выводе на поверхность. Минимальный альфа-коэффициент 0; это означает, что пиксел абсолютно прозрачен и на поверхность вообще не выводится. Максимальный альфа-коэффициент 8-разрядном альфа-канале равен 255. В этом случае пиксел совершенно не прозрачен, поэтому он просто заменяет советующий пиксел принимающей поверхности. При любых промежуточных значениях новый пиксел поверхности вычисляется как взвешенная сумма копируемого пиксела и старого пиксела принимающей поверхности.

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

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

Методика использования двух буферов называется двойной буферизацией (double buffering). Видеоадаптеры должны обеспечивать двойную буферизацию для всего кадрового буфера. Применение двойной буферизации удваивает объем необходимой видеопамяти. Для поддержки 32-разрядного кадрового буфера в разрешении 1920 х 1200 видеоадаптеру требуется минимум 17,5 Мбайт видеопамяти.

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

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

Как обычно, эффективное решение проблемы связано с дополнительными затратами памяти. В нем используется дополнительный буфер глубины, называемый z-буфером (по названию третьей координатной оси). В z-буфере хранится глубина каждого пиксела, то есть расстояние от пиксела объекта до зрителя. При запросе на вывод нового пиксела его глубина сравнивается с соответствующей глубиной из z-буфера. Выводятся лишь пикселы с меньшей глубиной, при этом одновременно обновляется содержимое z-буфера.

Объем z-буфера в памяти зависит от того, сколько дискретных уровней глубины должна различать программа. 8-разрядный z-буфер обеспечивает 256 уровней глубины; для сколько-нибудь нетривиальных целей этого недостаточно. 16-разрядные z-буферы повышают количество уровней глубины до 65 536. Но требования к детализации изображений в играх непрерывно растут и даже 16-разрядного z-буфера может оказаться недостаточно. При выводе объектов с ошибочным порядком глубин возникает так называемая z-размывка (z-aliasing). Существуют видеоадаптеры с 24- и 32-разрядными z-буферами. Также видеоадаптеры могут поддерживать вещественные z-буферы, повышающие точность измерения глубины.

16-разрядный z-буфер увеличивает размер видеопамяти еще на 0,6—4,4 Мбайт. При использовании 32-разрядного z-буфера эта величина удваивается и доходит до 1,2-8,8 Мбайт.

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

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

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

Ниже перечислены некоторые основные возможности, поддерживаемые большинством видеоадаптеров.

Вывод курсора, в том числе с альфа-каналом.
Поддержка двумерной графики: линии и кривые с возможным использованием дробных координат, заливка областей, блиттинг растров, альфа-наложение, градиентные заливки, множественная буферизация и программирование RAMDAC.
Вывод текста, включая сглаживание с использованием глифов нескольких уровней.
Поддержка трехмерной графики: конвейер операций трехмерной графики и различные варианты сглаживания текстур, наложение текстур с учетом перспективы на уровне пикселов, z-буфер, сглаживание краев, сглаживание на уровне пикселов, анизотропная фильтрация, текстуры на базе палитр и т. д.
Видео: декодирование MPEG, MP4 (и т.д.), декодирование DVD, BLU-RAY, плавное масштабирование с фильтрацией, вывод видеоинформации в нескольких окнах с преобразованием цветового пространства и фильтрацией, назначение цветовых ключей на уровне пикселов, оверлеи и т. д.

По материалам: Feng Yuan, Windows Graphics Programming.