oxiui_render_wgpu/gpu/
texture.rs1use crate::gpu::buffer::TexVertex;
11use crate::gpu::device::TARGET_FORMAT;
12use oxiui_core::paint::{ImageData, ImageFilter};
13use oxiui_core::UiError;
14
15pub struct TexturedDraw {
22 pub verts: Vec<TexVertex>,
24 pub image: ImageData,
26 pub filter: ImageFilter,
28 pub scissor: Option<[u32; 4]>,
30}
31
32pub fn upload_image(
44 device: &wgpu::Device,
45 queue: &wgpu::Queue,
46 image: &ImageData,
47 filter: ImageFilter,
48) -> Result<(wgpu::TextureView, wgpu::Sampler), UiError> {
49 if image.width == 0 || image.height == 0 {
50 return Err(UiError::Render("zero-dimension image".to_string()));
51 }
52
53 let texture = device.create_texture(&wgpu::TextureDescriptor {
54 label: Some("oxiui-render-wgpu uploaded texture"),
55 size: wgpu::Extent3d {
56 width: image.width,
57 height: image.height,
58 depth_or_array_layers: 1,
59 },
60 mip_level_count: 1,
61 sample_count: 1,
62 dimension: wgpu::TextureDimension::D2,
63 format: TARGET_FORMAT,
64 usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
65 view_formats: &[],
66 });
67
68 queue.write_texture(
69 wgpu::TexelCopyTextureInfo {
70 texture: &texture,
71 mip_level: 0,
72 origin: wgpu::Origin3d::ZERO,
73 aspect: wgpu::TextureAspect::All,
74 },
75 &image.rgba,
76 wgpu::TexelCopyBufferLayout {
77 offset: 0,
78 bytes_per_row: Some(image.width * 4),
79 rows_per_image: Some(image.height),
80 },
81 wgpu::Extent3d {
82 width: image.width,
83 height: image.height,
84 depth_or_array_layers: 1,
85 },
86 );
87
88 let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
89
90 let filter_mode = match filter {
91 ImageFilter::Nearest => wgpu::FilterMode::Nearest,
92 ImageFilter::Bilinear => wgpu::FilterMode::Linear,
93 };
94
95 let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
96 label: Some("oxiui-render-wgpu texture sampler"),
97 address_mode_u: wgpu::AddressMode::ClampToEdge,
98 address_mode_v: wgpu::AddressMode::ClampToEdge,
99 address_mode_w: wgpu::AddressMode::ClampToEdge,
100 mag_filter: filter_mode,
101 min_filter: filter_mode,
102 mipmap_filter: wgpu::MipmapFilterMode::Nearest,
103 lod_min_clamp: 0.0,
104 lod_max_clamp: 32.0,
105 compare: None,
106 anisotropy_clamp: 1,
107 border_color: None,
108 });
109
110 Ok((view, sampler))
111}