2个版本 (1个稳定版)
1.0.0 | 2021年5月9日 |
---|---|
0.1.0 | 2021年5月6日 |
#43 in 渲染
91,040 每月下载量
用于 208 个crate(4个直接使用)
28KB
344 行
fast-srgb8
小型crate,实现线性浮点数和8位sRGB之间的快速转换。包括执行4个同时转换的API,使用SSE2进行SIMD加速(如果可用)。支持no_std(也不需要libm)。
特性
f32_to_srgb8
:将线性f32
转换为sRGBu8
。符合此转换最相关的公开规范 (正确到0.6ulp,单调范围内等)f32x4_to_srgb8
:产生与连续调用f32_to_srgb8
4次相同的结果,但在x86和x86_64上使用SSE2进行SIMD加速(已知存在SSE2)。否则,它只是调用f32_to_srgb8
(标量等效)4次的结果。srgb8_to_f32
:f32_to_srgb8
的逆操作。使用256项查找表的常规技术。
优势
- 与朴素实现相比性能提升巨大 —— f32->srgb8 转换约5倍,srgb8->f32 转换约20倍。
- 支持
no_std
—— 通常这很棘手,因为这些操作需要powf
朴素地,而这在libcore中是不可用的。 - 无依赖。
- 对转换为sRGB的SIMD支持(转换从sRGB已快20倍于朴素实现,在SIMD中可能会更慢,因此目前未实现)。
- 对边缘情况的一致和正确处理(至少根据一个相关规范),例如NaN/Inf等。
- 对所有输入进行详尽的检查以确保正确性(在测试中)。
基准测试
# Measures `fast_srgb8::f32_to_srgb8` vs ref impl
test tests::bench::fast_scalar ... bench: 144 ns/iter (+/- 11)
test tests::bench::naive_scalar ... bench: 971 ns/iter (+/- 48)
# Measures `fast_srgb8::f32x4_to_srgb8` vs calling reference impl 4 times
test tests::bench::fast_f32x4 ... bench: 440 ns/iter (+/- 29)
test tests::bench::naive_f32x4 ... bench: 3,625 ns/iter (+/- 282)
test tests::bench::fast_f32x4_nosimd ... bench: 482 ns/iter (+/- 27)
# Measures `fast_srgb8::srgb8_to_f32` vs ref impl
test tests::bench::fast_from_srgb8 ... bench: 81 ns/iter (+/- 6)
test tests::bench::naive_from_srgb8 ... bench: 4,026 ns/iter (+/- 282)
(注意,ns/iter
时间不是针对这些函数的单次调用,而是针对多次调用的)
许可证
公有领域,如此处所述。如果不可接受,它也可以根据您的选择,在Apache-2.0或MIT许可证下提供。
float->srgb 代码最初是基于Fabien "ryg" Giesen的公有领域例程,尽管我不确定这些在哪里可以找到。
¹(确切地说:这个crate中的Rust代码是从我的C++游戏引擎中的代码移植过来的,而那个引擎又是基于ryg的代码。这并没有什么区别,但增加了任何错误都是我唯一责任的概率)。