Эффективная реализация декомпрессии текстуры DXT1 в аппаратном обеспечении - PullRequest
0 голосов
/ 06 июня 2019

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

c2 = (2/3)*c0+(1/3)*c1

или изменить их следующим образом:

c2 = (1/3)*(2*c0+c1)

Однако вы переставляетеПриведенное выше уравнение означает, что вам всегда приходится умножать что-то на 1/3 (или делить на 3, такая же сделка еще дороже).И мне кажется странным, что формат текстуры, который разработан для быстрой распаковки в аппаратном обеспечении, потребует умножения или деления.FPGA, в которой я использую свой графический процессор, имеет только ограниченные ресурсы для умножений, и я хочу сохранить их там, где они действительно необходимы.

Так я что-то упустил?Есть ли эффективный способ избежать умножения цветовых каналов на 1/3?Или я должен просто съесть стоимость этого умножения?

Ответы [ 2 ]

1 голос
/ 06 июня 2019

Это может быть плохим способом представить его, но не могли бы вы реализовать его с помощью сложения / вычитания последовательных половинок (сдвигов)?

Поскольку у вас есть 16 бит, это дает вам возможность получитьдовольно точно с последовательными сложениями и вычитаниями.

Третий может быть представлен как

a (n + 1) = a (n) +/- A >> 1, где, список [0, 0, 1, 0, 1 и т. Д.] Показывает, следует ли сложить или вычесть сдвинутый результат.

Я считаю, что это называется дробной математикой.

Однако в FPGA это трудночтобы узнать, действительно ли это более энергоэффективно, чем предоставленные собственные блоки DSP (например, DSP48E1).

1 голос
/ 06 июня 2019

МОЙ лучший ответ, который я могу придумать, это то, что я могу использовать тождество:

x/3 = sum(n=1 to infinity) (x/2^(2n))

и затем взять первые n членов.Используя 4 термина, я получаю:

(x/4)+(x/16)+(x/64)+(x/256)

, что равно

x*0.33203125

, что, вероятно, достаточно хорошо.

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

Любой лучший ответ приветствуется.

** РЕДАКТИРОВАТЬ **: Используя комбинацию этого и ответа @ dyslexicgruffalo Iсделал простую программу на c ++, которая перебирала различные последовательности, пробовал их все и записывал различные средние / максимальные ошибки.

Я сделал это для 0 <= x <= 189 (поскольку 189 - это значение 2 *c0.g + c1.g, когда g (который равен 6 битам) достигает максимума. </p>

Самая короткая правильная последовательность (с максимальной ошибкой 2, средней ошибкой 0,62) и с 4 операциями была:

1 + x/4 + x/16 + x/64.

Наилучшая последовательность с максимальной ошибкой 1, средней ошибкой 0,32, но с 6 операциями была:

x/2 - x/4 + x/8 - x/16 + x/32 - x/64.

Для 5-битовых значений (красного и синего) максимальное значениеравно 31 * 3, и приведенные выше последовательности все еще хороши, но не лучше. Это:

x/4 + x/8 - x/16 + x/32 [max error of 1, average 0.38]

и

1 + x/4 + x/16 [max error of 2, average of 0.68]

(И, к счастью, ни одна из вышеперечисленных последовательностей никогда не угадывает ответ, который является слишком большим, поэтому зажим не требуется, даже если они не идеальны)

...