notedeck

One damus client to rule them all
git clone git://jb55.com/notedeck
Log | Files | Refs | README | LICENSE

texture.rs (3701B)


      1 pub fn make_1x1_rgba8(
      2     device: &wgpu::Device,
      3     queue: &wgpu::Queue,
      4     format: wgpu::TextureFormat,
      5     rgba: [u8; 4],
      6     label: &str,
      7 ) -> wgpu::TextureView {
      8     let extent = wgpu::Extent3d {
      9         width: 1,
     10         height: 1,
     11         depth_or_array_layers: 1,
     12     };
     13     let tex = device.create_texture(&wgpu::TextureDescriptor {
     14         label: Some(label),
     15         size: extent,
     16         mip_level_count: 1,
     17         sample_count: 1,
     18         dimension: wgpu::TextureDimension::D2,
     19         format,
     20         usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
     21         view_formats: &[],
     22     });
     23 
     24     queue.write_texture(
     25         wgpu::TexelCopyTextureInfo {
     26             texture: &tex,
     27             mip_level: 0,
     28             origin: wgpu::Origin3d::ZERO,
     29             aspect: wgpu::TextureAspect::All,
     30         },
     31         &rgba,
     32         wgpu::TexelCopyBufferLayout {
     33             offset: 0,
     34             bytes_per_row: Some(4),
     35             rows_per_image: Some(1),
     36         },
     37         extent,
     38     );
     39 
     40     tex.create_view(&wgpu::TextureViewDescriptor::default())
     41 }
     42 
     43 pub fn texture_layout_entry(binding: u32) -> wgpu::BindGroupLayoutEntry {
     44     wgpu::BindGroupLayoutEntry {
     45         binding,
     46         visibility: wgpu::ShaderStages::FRAGMENT,
     47         ty: wgpu::BindingType::Texture {
     48             multisampled: false,
     49             view_dimension: wgpu::TextureViewDimension::D2,
     50             sample_type: wgpu::TextureSampleType::Float { filterable: true },
     51         },
     52         count: None,
     53     }
     54 }
     55 
     56 /// Robust texture upload helper (handles row padding)
     57 /// "queue.write_texture is annoying once width*4 isn't 256-aligned. This helper always works"
     58 pub fn upload_rgba8_texture_2d(
     59     device: &wgpu::Device,
     60     queue: &wgpu::Queue,
     61     width: u32,
     62     height: u32,
     63     rgba: &[u8],
     64     format: wgpu::TextureFormat,
     65     label: &str,
     66 ) -> wgpu::TextureView {
     67     assert_eq!(rgba.len(), (width * height * 4) as usize);
     68     assert!(!rgba.is_empty());
     69 
     70     let extent = wgpu::Extent3d {
     71         width,
     72         height,
     73         depth_or_array_layers: 1,
     74     };
     75     let texture = device.create_texture(&wgpu::TextureDescriptor {
     76         label: Some(label),
     77         size: extent,
     78         mip_level_count: 1,
     79         sample_count: 1,
     80         dimension: wgpu::TextureDimension::D2,
     81         format,
     82         usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
     83         view_formats: &[],
     84     });
     85 
     86     let bytes_per_pixel = 4usize;
     87     let unpadded_bytes_per_row = width as usize * bytes_per_pixel;
     88     let align = wgpu::COPY_BYTES_PER_ROW_ALIGNMENT as usize; // 256
     89 
     90     // CEIL division to next multiple of 256
     91     let padded_bytes_per_row = unpadded_bytes_per_row.div_ceil(align) * align;
     92 
     93     assert!(padded_bytes_per_row >= unpadded_bytes_per_row);
     94     assert!(padded_bytes_per_row.is_multiple_of(align));
     95 
     96     let mut padded = vec![0u8; padded_bytes_per_row * height as usize];
     97     for y in 0..height as usize {
     98         let src = &rgba[y * unpadded_bytes_per_row..(y + 1) * unpadded_bytes_per_row];
     99         let dst = &mut padded
    100             [y * padded_bytes_per_row..y * padded_bytes_per_row + unpadded_bytes_per_row];
    101         dst.copy_from_slice(src);
    102     }
    103 
    104     queue.write_texture(
    105         wgpu::TexelCopyTextureInfo {
    106             texture: &texture,
    107             mip_level: 0,
    108             origin: wgpu::Origin3d::ZERO,
    109             aspect: wgpu::TextureAspect::All,
    110         },
    111         &padded,
    112         wgpu::TexelCopyBufferLayout {
    113             offset: 0,
    114             bytes_per_row: Some(padded_bytes_per_row as u32),
    115             rows_per_image: Some(height),
    116         },
    117         extent,
    118     );
    119 
    120     texture.create_view(&wgpu::TextureViewDescriptor::default())
    121 }