imgui_sdl3/
utils.rs

1use std::error::Error;
2
3use sdl3::gpu::{Device, TextureCreateInfo, TextureFormat, TextureType, TextureUsage, *};
4
5pub fn create_buffer_with_data<T: Copy>(
6    device: &Device,
7    transfer_buffer: &TransferBuffer,
8    copy_pass: &CopyPass,
9    usage: BufferUsageFlags,
10    data: &[T],
11) -> Result<Buffer, sdl3::Error> {
12    // Figure out the length of the data in bytes
13    let len_bytes = std::mem::size_of_val(data);
14
15    // Create the buffer with the size and usage we want
16    let buffer = device
17        .create_buffer()
18        .with_size(len_bytes as u32)
19        .with_usage(usage)
20        .build()?;
21
22    // Map the transfer buffer's memory into a place we can copy into, and copy the data
23    //
24    // Note: We set `cycle` to true since we're reusing the same transfer buffer to
25    // initialize both the vertex and index buffer. This makes SDL synchronize the transfers
26    // so that one doesn't interfere with the other.
27    let mut map = transfer_buffer.map::<T>(device, true);
28    let mem = map.mem_mut();
29    for (index, &value) in data.iter().enumerate() {
30        mem[index] = value;
31    }
32
33    // Now unmap the memory since we're done copying
34    map.unmap();
35
36    // Finally, add a command to the copy pass to upload this data to the GPU
37    //
38    // Note: We also set `cycle` to true here for the same reason.
39    copy_pass.upload_to_gpu_buffer(
40        TransferBufferLocation::new()
41            .with_offset(0)
42            .with_transfer_buffer(transfer_buffer),
43        BufferRegion::new()
44            .with_offset(0)
45            .with_size(len_bytes as u32)
46            .with_buffer(&buffer),
47        true,
48    );
49
50    Ok(buffer)
51}
52
53pub fn create_texture(
54    device: &Device,
55    copy_pass: &CopyPass,
56    image_data: &[u8],
57    width: u32,
58    height: u32,
59) -> Result<Texture<'static>, Box<dyn Error>> {
60    let size_bytes = width * height * 4; // Assuming RGBA8 format
61
62    let texture = device.create_texture(
63        TextureCreateInfo::new()
64            .with_format(TextureFormat::R8g8b8a8Unorm)
65            .with_type(TextureType::_2D)
66            .with_width(width)
67            .with_height(height)
68            .with_layer_count_or_depth(1)
69            .with_num_levels(1)
70            .with_usage(TextureUsage::SAMPLER),
71    )?;
72
73    let transfer_buffer = device
74        .create_transfer_buffer()
75        .with_size(size_bytes)
76        .with_usage(TransferBufferUsage::UPLOAD)
77        .build()?;
78
79    let mut buffer_mem = transfer_buffer.map::<u8>(device, false);
80    buffer_mem.mem_mut().copy_from_slice(image_data);
81    buffer_mem.unmap();
82
83    copy_pass.upload_to_gpu_texture(
84        TextureTransferInfo::new()
85            .with_transfer_buffer(&transfer_buffer)
86            .with_offset(0),
87        TextureRegion::new()
88            .with_texture(&texture)
89            .with_layer(0)
90            .with_width(width)
91            .with_height(height)
92            .with_depth(1),
93        false,
94    );
95
96    Ok(texture)
97}