【问题标题】:Efficiently implementing DXT1 texture decompression in hardware在硬件中高效实现 DXT1 纹理解压
【发布时间】:2019-06-06 09:43:31
【问题描述】:

DXT1 compression 设计用于在用于纹理采样器的硬件中快速解压缩。维基百科文章说,在某些情况下,您可以计算出插值颜色的系数:

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

或重新排列:

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

但是,如果您重新排列上述等式,那么您最终总是不得不将某个值乘以 1/3(或除以 3,同样的交易更昂贵)。我觉得很奇怪,设计为在硬件中快速解压缩的纹理格式需要乘法或除法。我在其上实现 GPU 的 FPGA 只有有限的乘法资源,我想将这些资源保存到真正需要的地方。

所以我错过了什么吗?有没有一种有效的方法可以避免将颜色通道乘以 1/3?还是我应该只吃乘法的成本?

【问题讨论】:

    标签: gpu vhdl texture-mapping hdl dxt


    【解决方案1】:

    这可能是一种不好的想象方式,但是您可以通过使用连续一半(移位)的加法/减法来实现它吗?

    由于您有 16 位,这使您能够通过连续的加法和减法获得相当准确的结果。

    三分之一可以表示为

    a(n+1) = a(n) +/- A>>1,其中,列表 [0, 0, 1, 0, 1, etc] 显示是否添加或减去移位结果。

    我相信这叫做分数数学。

    但是,在 FPGA 中,很难知道这是否真的比提供的原生 DSP 模块(例如 DSP48E1)更节能。

    【讨论】:

    • 我开始认为这是(我们的两种方式)一种很好的方式。我误读了文档,尽管您将比较作为 16 位整数进行,但您对每种颜色分别进行插值(使用 1/3 系数)。这意味着该值的最大大小为 6 位 [0-63]。因此,如果我小心的话,我可能会得到完全准确的结果,或者可能像这样获得所需结果的 +/-1。至于不使用 DSP 对我来说不是力量,只是它们的数量是有限的,我希望尽可能多地同时渲染图块,而 DSP 是我的限制因素。
    • (这是我正在制作的一个有趣的家庭项目 GPU,所以我可以选择忽略电源 - mikevine.net
    【解决方案2】:

    我能想到的最佳答案是我可以使用身份:

    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 个加法。

    感谢任何更好的答案。

    ** 编辑**:结合使用这个和@dyslexicgruffalo 的答案,我制作了一个简单的 c++ 程序,它迭代了各种序列并尝试了它们并记录了各种平均/最大错误。

    我这样做是为了 0

    最短的好序列(最大误差为 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]
    

    (而且,幸运的是,上述序列都没有猜到一个太大的答案,因此即使它们并不完美,也不需要钳位)

    【讨论】:

    • 道歉@Mike Vine,我想我们已经写了相同的答案!
    猜你喜欢
    • 2013-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多