понедельник, 17 мая 2010 г.

Packed A-buffer

В презентации AMD можно найти совет по оптимизации работы с A-буфером:

Optimize performace by reducing amount of data to write to/read from UAV.

Узел связанного списка имеет три поля типа uint - RGBA color, depth и address. Как вариант предлагается хранить цвет в формате 565 (альфа - константная) и объединить его с 16-bit depth. Таким образом можно сэкономить один uint. Следуя по стопам приверженцев deferred shading-а, которые любят мозгодробительные комбинации упаковки G-буфера, я решил поиграться в "упаковку A-буфера", благо начиная с SM 4.0 появилась прекрасная возможность маскировать и двигать битики на GPU.

Итак, наша цель - два uint вместо трёх, но попиксельная альфа (не константная), хорошая точность цвета и глубины. Основная возможность сжатия заключается в том, что нам не нужен полный 32-битный адрес для индексации A-буфера требуемых размеров. Это, кстати, ещё та проблема - определить, буфер каких размеров будет достаточным, и сколько бит необходимо для его адресации. Я остановился на 23 битах, т. к. в этом случае можно адресовать 8 388 608 элементов, т. е. буфер размером 1024x1024, 8x overdraw в (каждом) пикселе. Думаю, для спрайтов, огня и дыма этого будет вполне достаточно. Для значения глубины я решил отвести демократичные 16 бит (такая точность иногда использовалась для буфера глубины). Т. к. у нас свободны 9 бит второго поля, которые ранее занимал адрес, то теперь в них можно поместить старшие 9 бит глубины.

Младшие 7 бит придётся делить с цветом в первом поле. Значит, под цвет остаётся 25 бит. Для последнего я решил выбрать "дьявольский" формат хранения 666_7, т. е. для RGB компонентов отводится по 6 бит, для альфы - 7. Считаю, что бандинг альфы при большом overdraw может привести к ухудшению transparency, поэтому необходимо хранить альфу как можно большей точности, к тому же в этой раскладке нет перекосов с точностью RGB-компонент.

Возможны варианты. Например, рядом со мной стоит iMac, монитор которого поддерживает разрешение 2560x1440. Не думаю, что даже hi-end видеокарты смогут быстро работать с A-буфером такого разрешения, но надо смотреть в будущее. Лучшим подходом будет на практике замерять, сколькими элементами оперирует A-буфер, для этого в Direct3D 11 можно воспользоваться методом ID3D11DeviceContext::CopyStructureCount(). Если 23 бит окажется недостаточно для адресации, можно выделить дополнительные два бита, понизив на один бит точность глубины и точность альфы цвета. Но при любой раскладке, вполне реально сэкономить одно поле в узле списка, при минимальных потерях в качестве рендеринга. А это значит, что можно сэкономить треть отводимой под A-буфер видеопамяти и ускорить чтение/запись.

Обновлённое демо: oit_packed_dx11

Update: HD 5850, прирост скорости составляет 5-10%, значит, bottleneck в сортировке. Ну хоть видеопамять сэкономил, она ведь не резиновая.

7 комментариев:

  1. Отвечу здесь
    > Я тоже запускал эту демку из SDK, при большом
    > depth complexity появлялись артефакты.
    > Но в моей программе их-то больше нет.
    На HD5670 есть, возможно проблема в драйвере.

    ОтветитьУдалить
  2. Последний драйвер, результат такой же - http://pixs.ru/showimage/bug1png_8676885_676589.png

    ОтветитьУдалить
  3. Я кажется уже описывал, в чём проблема.

    ОтветитьУдалить
  4. вы используете HW10.0, артефакт есть на HD5670 и не понятно как от него избавиться. То, что HD5670 это HW11, которое под соответствующим HAL не супортит старый растерайзер, погоды не делает - обязана быть обратная совместимость
    у вас на видеокарте HD5770 вы утверждаете что артефакта нету - вот тут и возникает вопрос почему тогда он есть на HD5670, HD5770


    если вам сложно ответить, то больше писать не буду

    ОтветитьУдалить
  5. Я описывал, что тестировал на HD 4330 в feature level 10.1, и были артефакты. После переключения в feature level 10.0 они исчезли (железка та же). То же самое и с reference rasterizer - в 10.1 и 11.0 появляются артефакты, в 10.0 их нет. Демка с А-буфером работает в 11.0, поэтому артефакты неизбежны. В принципе, там они неважны, т. к. есть более эффективный подход, чем K-buffer. Что касается проблем с демкой из NV SDK - это проблема драйверов ATI. Похожий баг, но проблема ужё в чём-то другом.

    ОтветитьУдалить