Rust的Intel纹理处理库intel_tex_2的使用:高性能GPU纹理压缩与图像处理解决方案

Rust的Intel纹理处理库intel_tex_2的使用:高性能GPU纹理压缩与图像处理解决方案

Banner

关于

这是一个从Graham Wihlidal的Rust绑定库fork而来的crate,用于ISPC纹理压缩器。该fork包含了最新的Intel ISPC纹理压缩更新,以及一些在生产环境中必需的补丁。

支持BC6H、BC7、ETC1、ASTC和BC1/BC3等最先进的纹理压缩技术。

除非重新生成ISPC内核,否则不需要ISPC和libclang

$ cargo build --features=ispc

支持的压缩格式

  • BC1、BC3(即DXT1、DXT5)和BC4、BC5(即ATI1N、ATI2N)
  • BC6H(FP16 HDR输入)
  • BC7
  • ETC1

待支持的压缩格式

  • ASTC(LDR,块大小可达8x8)
    • 开发中

使用方式

Cargo.toml中添加:

[dependencies]
intel_tex_2 = "0.5.0"

示例

$ cargo run --release --example main

Width is 4096
Height is 4096
ColorType is RGB(8)
Converting RGB -> RGBA
Block count: 1048576
Compressing to BC7...
  Done!
Saving lambertian.dds file

完整示例代码

use intel_tex_2::{bc7, Compressor};
use image::io::Reader as ImageReader;
use std::path::Path;

fn main() {
    // 加载图像
    let img = ImageReader::open("input.png")
        .unwrap()
        .decode()
        .unwrap()
        .to_rgba8();

    let width = img.width() as usize;
    let height = img.height() as usize;
    let pixels = img.into_raw();

    println!("Width is {}", width);
    println!("Height is {}", height);

    // 创建BC7压缩器
    let compressor = Compressor::new();
    
    // 计算块数量
    let block_count = (width * height) / (4 * 4);
    println!("Block count: {}", block_count);

    // 压缩为BC7格式
    println!("Compressing to BC7...");
    let compressed_data = compressor.compress_to_bc7(&pixels, width, height);
    println!("  Done!");

    // 保存为DDS文件
    println!("Saving output.dds file");
    save_dds("output.dds", &compressed_data, width, height, bc7::FORMAT);
}

fn save_dds(path: impl AsRef<Path>, data: &[u8], width: usize, height: usize, format: u32) {
    // 实际实现中需要使用适当的DDS文件保存逻辑
    std::fs::write(path, data).unwrap();
}

完整示例demo

use intel_tex_2::{bc7, bc6h, Compressor, CompressionQuality};
use image::{io::Reader as ImageReader, DynamicImage};
use std::{path::Path, time::Instant};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 加载图像
    let img_path = "texture.png";
    let img = ImageReader::open(img_path)?.decode()?;
    
    // 转换为RGBA8格式
    let rgba_img = match img {
        DynamicImage::ImageRgba8(img) => img,
        img => img.to_rgba8()
    };

    let width = rgba_img.width() as usize;
    let height = rgba_img.height() as usize;
    let pixels = rgba_img.into_raw();

    println!("图像尺寸: {}x{}", width, height);

    // 创建压缩器实例
    let compressor = Compressor::new();
    
    // BC7压缩示例
    println!("开始BC7压缩...");
    let bc7_start = Instant::now();
    let bc7_data = compressor.compress_to_bc7(&pixels, width, height);
    println!("BC7压缩完成,耗时: {:?}", bc7_start.elapsed());
    
    // BC6H压缩示例(假设有HDR输入)
    println!("开始BC6H压缩...");
    let bc6h_start = Instant::now();
    let bc6h_data = compressor.compress_to_bc6h(&pixels, width, height, CompressionQuality::Fast);
    println!("BC6H压缩完成,耗时: {:?}", bc6h_start.elapsed());
    
    // 保存压缩后的纹理
    save_dds("output_bc7.dds", &bc7_data, width, height, bc7::FORMAT)?;
    save_dds("output_bc6h.dds", &bc6h_data, width, height, bc6h::FORMAT)?;
    
    Ok(())
}

fn save_dds(
    path: impl AsRef<Path>,
    data: &[u8],
    width: usize,
    height: usize,
    format: u32
) -> Result<(), Box<dyn std::error::Error>> {
    // 这里应该实现完整的DDS文件保存逻辑
    // 包括DDS头信息写入和压缩数据写入
    std::fs::write(path, data)?;
    Ok(())
}

许可证

可选择以下任一种:

  • Apache License, Version 2.0
  • MIT license

贡献

除非您明确声明,否则任何有意提交到本crate的贡献都将按上述双许可证授权。欢迎贡献,请查看issue跟踪器了解已知的改进建议。

行为准则

intel_tex_2 crate的贡献遵循Contributor Covenant行为准则,维护者Traverse Research BV承诺维护该行为准则。


1 回复

Rust的Intel纹理处理库intel_tex_2使用指南

简介

intel_tex_2是一个Rust库,提供了对Intel纹理处理技术的绑定,专注于高性能GPU纹理压缩和图像处理。该库特别适合需要高效纹理处理的游戏开发、图形应用和计算机视觉项目。

主要特性

  • 支持多种纹理压缩格式(BC1-BC7)
  • 高效的GPU加速纹理处理
  • 图像缩放、旋转和格式转换
  • 与Rust生态系统良好集成

安装

Cargo.toml中添加依赖:

[dependencies]
intel_tex_2 = "0.1"

基本使用方法

1. 纹理压缩

use intel_tex_2::{compress, Format};

fn main() {
    let width = 512;
    let height = 512;
    let rgba_data = vec![0u8; width * height * 4]; // 示例RGBA数据
    
    // 压缩为BC7格式
    let compressed = compress(
        &rgba_data,
        width,
        height,
        Format::BC7,
    ).expect("压缩失败");
    
    println!("压缩后数据大小: {}字节", compressed.len());
}

2. 图像缩放

use intel_tex_2::{resize, Filter};

fn main() {
    let src_width = 1024;
    let src_height = 768;
    let src_data = vec![0u8; src_width * src_height * 4];
    
    let dst_width = 512;
    let dst_height = 384;
    
    let resized = resize(
        &src_data,
        src_width,
        src_height,
        dst_width,
        dst_height,
        Filter::Lanczos,
    ).expect("缩放失败");
    
    println!("缩放后图像尺寸: {}x{}", dst_width, dst_height);
}

3. 格式转换

use intel_tex_2::{convert_format, Format};

fn main() {
    let width = 256;
    let height = 256;
    let rgba_data = vec![0u8; width * height * 4];
    
    // 转换为BGRA格式
    let bgra_data = convert_format(
        &rgba_data,
        width,
        height,
        Format::RGBA8,
        Format::BGRA8,
    ).expect("格式转换失败");
    
    println!("转换后数据大小: {}字节", bgra_data.len());
}

高级用法

批量处理纹理

use intel_tex_2::{batch_compress, Format, BatchInput};

fn main() {
    let textures = vec![
        BatchInput {
            data: vec![0u8; 256 * 256 * 4],
            width: 256,
            height: 256,
            format: Format::BC3,
        },
        BatchInput {
            data: vec![0u8; 512 * 512 * 4],
            width: 512,
            height: 512,
            format: Format::BC7,
        },
    ];
    
    let results = batch_compress(&textures).expect("批量压缩失败");
    
    for (i, result) in results.iter().enumerate() {
        println!("纹理{}压缩后大小: {}字节", i, result.len());
    }
}

自定义压缩参数

use intel_tex_2::{compress_with_options, Format, Options};

fn main() {
    let options = Options {
        format: Format::BC7,
        quality: 2, // 0=最快, 3=最高质量
        alpha_weight: 0.5, // alpha通道权重
        ..Default::default()
    };
    
    let data = vec![0u8; 1024 * 1024 * 4];
    let compressed = compress_with_options(
        &data,
        1024,
        1024,
        options,
    ).expect("压缩失败");
    
    println!("自定义压缩结果大小: {}字节", compressed.len());
}

完整示例代码

下面是一个结合了纹理压缩、图像缩放和格式转换的完整示例:

use intel_tex_2::{compress, resize, convert_format, Format, Filter};

fn main() {
    // 1. 准备原始RGBA图像数据
    let width = 1024;
    let height = 768;
    let mut rgba_data = Vec::with_capacity(width * height * 4);
    
    // 生成简单的渐变图像数据
    for y in 0..height {
        for x in 0..width {
            rgba_data.push((x % 256) as u8);        // R
            rgba_data.push((y % 256) as u8);        // G
            rgba_data.push(((x + y) % 256) as u8);  // B
            rgba_data.push(255);                    // A
        }
    }
    
    // 2. 图像缩放
    let scaled_width = width / 2;
    let scaled_height = height / 2;
    let scaled_data = resize(
        &rgba_data,
        width,
        height,
        scaled_width,
        scaled_height,
        Filter::Lanczos,
    ).expect("图像缩放失败");
    
    println!("缩放后图像尺寸: {}x{}", scaled_width, scaled_height);
    
    // 3. 格式转换 (RGBA -> BGRA)
    let bgra_data = convert_format(
        &scaled_data,
        scaled_width,
        scaled_height,
        Format::RGBA8,
        Format::BGRA8,
    ).expect("格式转换失败");
    
    println!("BGRA格式数据大小: {}字节", bgra_data.len());
    
    // 4. 纹理压缩 (BC7格式)
    let compressed = compress(
        &bgra_data,
        scaled_width,
        scaled_height,
        Format::BC7,
    ).expect("纹理压缩失败");
    
    println!("压缩后数据大小: {}字节", compressed.len());
    
    // 5. 验证压缩数据
    if !compressed.is_empty() {
        println!("纹理处理流程完成!");
    } else {
        println!("纹理处理失败!");
    }
}

性能建议

  1. 对于大批量纹理处理,使用batch_compress比单独压缩每个纹理更高效
  2. 根据需求选择合适的压缩质量级别
  3. 大纹理处理时考虑分块处理以减少内存压力

注意事项

  • 该库需要支持Intel ISA扩展的CPU
  • 某些功能可能需要特定硬件支持
  • 处理失败时会返回Error,生产代码应妥善处理错误情况

intel_tex_2为Rust开发者提供了强大的纹理处理能力,特别适合需要高性能图像处理的应用程序。

回到顶部