среда, июня 08, 2005

Разработка под видекарты Intel

Вопреки устоявшемуся мнению видеокарты Интел весьма распространены. Сам Интел приводит цифру 40%, возможно они слегка лукавят, но доля значительная. Крупные производители игр не очень жалуют вниманием эти видеокарты, хотя Интел всячески пытается их привлечь на свою сторону. Но для shareware игр Интеловские карточки являются чуть ли не основными.

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

Софтверные TnL(Transform and Lightning) и вертексные шейдеры (vertex shader)
Интеловская карточка не может позволить себе обрабатывать 3D геометрию хардварно, как это делают многие другие. Однако часто разработчики запрашивают только хардварную поддержку, на что им справедливо следует ответ, что ничего нет. То есть вместо IDirect3D::GetCaps() надо спросить IDirect3DDevice::GetCaps(). Соответственно, девайс должен быть создан с флагом D3DCREATE_SOFTWARE_VERTEXPROCESSING.
Интел говорит, что с Pentium4 софтверная обработка будет работать на вполне пристойной скорости, при этом они ненавязчиво предлагают делать игры многопоточными, чтобы использовался гипертрединг(Hyper-Threading Technology).
Пиксельные шейдеры есть на 900 серии карточек, они как раз реализованы хардварно.

Технология Zone Rendering
Используется для того, чтобы увеличить скорость рендеринга. Все треугольники сцены делятся на зоны, достаточно маленькие для того, чтобы они могли поместиться в кэше чипа. Зоны рисуются по-очереди. Сначала треугольники зоны сортируются по грубине, если надо, обрабатывается прозрачность, а потом отрисовываются. Цвет каждого пиксела пишется таким образом только один раз, не тратится время на лишнюю передачу. Это и есть Zone Rendering.

Zone Rendering - это эдакая неизбежная забота. Оно само лучше знает когда ему включаться, а когда выключаться. Оно постарается включиться, но если его что-то обеспокоит, то оно уйдет и придут ТОРМОЗА. Поэтому надо следовать определенным правилам, чтобы Zone Rendering не выключился и работал с максимальной отдачей:

  • Если требуется смена render target, то менять его перед отрисовкой сцены.
  • Не читать из Color, Z, Stencil буферов. Это вообще всегда медленно. Но на Интеловских карточках особенно плохо читать из Z-буфера. Zone Rendering в силу логики своей работы вообще Z-буфер не использует. За счет этого достигается большой рост производительности. А если из него начать читать, то его придется поддерживать.
  • Чистить буферы осторожно, лучше всего одновременно все, один раз в кадр. Когда это невозможно чистить Z и Stencil буферы вместе. Не чистить их по кусочкам.
  • Не смешивать 2D и 3D в одной 3D сцене.

Итак, управлять включением/выключением Zone Rendering можно, но только косвенно. Чтобы его выключить достаточно НЕ следовать вышеперечисленным правилам.

После внимательного изучения работы Zone Rendering возникает несколько вопросов:

Что будет, если треугольники настолько большие, что занимают несколько зон? Ответ на этот вопрос прозвучал на докладе на КРИ. Они будут прокопированы.

Что будет, если треугольники расположены таким образом, что их нельзя отсортировать по глубине? Предполагаю, что треугольники как-то дробятся на части. Выглядит все как и должно выглядеть.



Возникает вопрос и в связи с альфа-геометрией или, по простому, с прозрачностью.
Несколько слов о том, как реализована прозрачность. Все сплошной обман. Если у вас есть прозрачная текстура, то она не обладает прозрачностью в бытовом смысле этого слова. На ней просто нарисовано то, что в данный момент находится _за_ ней. В фильме про Джеймса Бонда была такая прозрачная машина, я помню. Поэтому прозрачные объекты следует выводить на экран в последнюю очередь. А то получится совсем не то, что хотелось бы. Вот пример: за забором находятся ящики. Но если ящики начать рисовать после забора, картина становится странной.



Ну а если Zone Rendering все сортирует за нас, быть может нам уже и не надо заботиться о правильном порядке отрисовки прозрачных объектов? Я попробовала.
Вот у этого забора сначала идут треугольники с красной стороны, потом с синей. Забор отправляется на отрисовку целиком, за один раз.



Вот что нарисовал GeForce6800. Со стороны красной стрелки забор отрисовывается не в том порядке, прозрачностью не кооректная.



А вот что Intel. Глюки с отрисовкой забора сохранились.





То ли догадки оказались неверны, то ли у меня по какой-то причине отключился Zone Rendering...

Dynamic Video Memory Technology (DVMT)
У Интеловской карточки нет своей видеопамяти, поэтому она использует оперативную. Вообще под видеопамять всегда выделено небольшое количество оперативной памяти, размер проставляется в БИОСе. Интеловская карточка может использовать и эту память, плюс запросить еще.
Когда приложение запрашивает видеопамять у Intel Graphics Driver (при запрашивании видеопамяти следует использовать флаг D3DPOOL_MANAGED), то этот запрос передается операционной системе. ОС выделяет нужно количество памяти. Когда приложение, запросившее память, будет закрыто, DVMT отдаст ее обратно ОС. Количество памяти, которую может запросить себе DVMT ограничено и зависит от того, сколько ее вообще есть в наличии.
Для проверки свободной видеопамяти можно использовать функцию GetAvailableTextureMem().

Интеловские карточки не поддерживают антиалиасинг. Интел предлагает его реализовывать вручную :-).

У Интела есть профайлер кода специально для их карточек, но только для 900 серии. Intel Graphics Media Accelerator profiler (IGMAP). Расскажет про доступную видеопамять, сколько треугольников в секунду и в кадр ему было отправлено и пр., ну и конечно включен ли Zone Rendering.

Очень много информации по этому поводу доступно на Intel Game Developers' Center. Все вышеизложенное гораздо подробнее и с примерами кода.

Technorati tag:

5 коммент.:

Анонимный комментирует...

1) ссылка почему-то на robots, а не videocard
2) а зачем мудрить с прозрачностью? есть же стандартный подход - выводить после непрозрачных, и отсортированно по глубине (а перекрывающиеся треуг., как на картинках, разбивать). Правда, у меня тоже есть "новомодный" пример, где прозрачность без z сортировки сделана, но он как раз на GeForce FX и выше рассчитан (и никто - reamde файл - и не обещал, что он должен где-то там еще работать).
// tensor

Alena комментирует...

1) Ссылку поправила, спасибо.
2) Пример с прозрачностью - исключительно ради эксперимента. Когда я прочла про Zone Rendering, у меня сложилось впечатление, что для Интеловских карточек можно не сортировать прозрачные объекты, они сами отсортируются. Но номер не прошел.

А можно ссылку на новомодный пример? :-)

Анонимный комментирует...

Вот он об алгоритме пишет немного "This demo shows using ARB_shadow, ARB_depth_texture, and NV_texture_shader to implement Rui Bastos's idea for getting the layers of z sorted by depth, and using the RGBA at each layer to re-order transparency correctly."
Это из NVidia cg_shader_toolkit, примеры "Order Independent Transparency", "Order Independent Transparency 3X". С сайта NVidia должна вроде быть возможность скачать один пример, не качая весь тулкит (весь тулкит ~90MB).
Правда, слои эти в примере он все равно сортирует, так что не совсем по теме. Да и явно не для shareware игр такое. Просто, для интереса если глянуть.
// tensor

Olexandr комментирует...

Хотелось бы узнать, как обмануть Intel'овскую карту с TnL? Если игра требует TnL... 3DAnalyze пробывал :( увы не то!

Alena комментирует...

Хотелось бы узнать, как обмануть Intel'овскую карту с TnL? Если игра требует TnL...

В смысле, игра требует хардварный TnL и отказывается работать на Интеловской карточке? Боюсь, тут игру надо обманывать, а не карточку. Но как именно - не подскажу.