swamp_wgpu/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/piot/swamp-render
 * Licensed under the MIT License. See LICENSE in the project root for license information.
 */

use wgpu::util::DeviceExt;
use wgpu::{BindGroup, BindGroupLayout, Buffer, Sampler, ShaderModule, Texture};

use bytemuck::{Pod, Zeroable};

pub fn create_shader_module(
    device: &wgpu::Device,
    name: &str,
    shader_source: &str,
) -> ShaderModule {
    device.create_shader_module(wgpu::ShaderModuleDescriptor {
        label: Some(name),
        source: wgpu::ShaderSource::Wgsl(shader_source.into()),
    })
}

pub fn create_nearest_sampler(device: &wgpu::Device, label: &str) -> Sampler {
    device.create_sampler(&wgpu::SamplerDescriptor {
        label: Some(label),
        address_mode_u: wgpu::AddressMode::ClampToEdge,
        address_mode_v: wgpu::AddressMode::ClampToEdge,
        address_mode_w: wgpu::AddressMode::ClampToEdge,
        mag_filter: wgpu::FilterMode::Nearest,
        min_filter: wgpu::FilterMode::Nearest,
        mipmap_filter: wgpu::FilterMode::Nearest,
        compare: None,
        anisotropy_clamp: 1,
        lod_min_clamp: 0.0,
        lod_max_clamp: 32.0,
        border_color: None,
    })
}

pub fn create_texture(device: &wgpu::Device, width: u32, height: u32) -> Texture {
    let texture_size = wgpu::Extent3d {
        width,
        height,
        depth_or_array_layers: 1,
    };

    device.create_texture(&wgpu::TextureDescriptor {
        label: Some("My Texture"),
        size: texture_size,
        mip_level_count: 1,
        sample_count: 1,
        dimension: wgpu::TextureDimension::D2,
        format: wgpu::TextureFormat::Rgba8Unorm,
        usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
        view_formats: &[wgpu::TextureFormat::Rgba8Unorm], // Specify the view format(s),
    })
}

/// A struct that holds uniform data to be passed to shaders.
/// In this case, it contains the combined view-projection matrix.
#[repr(C)]
#[derive(Copy, Clone)]
pub struct Uniforms {
    pub view_proj: [[f32; 4]; 4],
}

unsafe impl Pod for Uniforms {}
unsafe impl Zeroable for Uniforms {}

pub fn create_uniform_buffer(device: &wgpu::Device, label: &str) -> Buffer {
    let uniforms = Uniforms {
        view_proj: [[0.0; 4]; 4],
    };

    device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
        label: Some(label),
        contents: bytemuck::cast_slice(&[uniforms]),
        usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
    })
}

/// Creates a standard uniform (any user-defined struct) bind group layout
pub fn create_uniform_bind_group_layout(
    device: &wgpu::Device,
    binding_index: u32,
    label: &str,
) -> BindGroupLayout {
    device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
        label: Some(label),
        entries: &[wgpu::BindGroupLayoutEntry {
            binding: binding_index,
            visibility: wgpu::ShaderStages::VERTEX,
            ty: wgpu::BindingType::Buffer {
                ty: wgpu::BufferBindingType::Uniform,
                has_dynamic_offset: false,
                min_binding_size: None,
            },
            count: None,
        }],
    })
}

/// Create Uniform Bind Group (any user-defined struct) bind group
pub fn create_uniform_bind_group(
    device: &wgpu::Device,
    binding_index: u32,
    bind_group_layout: &BindGroupLayout,
    uniform_buffer: &Buffer,
    label: &str,
) -> BindGroup {
    device.create_bind_group(&wgpu::BindGroupDescriptor {
        label: Some(label),
        layout: bind_group_layout,
        entries: &[wgpu::BindGroupEntry {
            binding: binding_index,
            resource: uniform_buffer.as_entire_binding(),
        }],
    })
}