forked from Rust-GPU/rust-gpu-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrenderer.rs
More file actions
115 lines (104 loc) · 3.95 KB
/
renderer.rs
File metadata and controls
115 lines (104 loc) · 3.95 KB
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
use crate::wgpu_renderer::render_pipeline::MyRenderPipeline;
use mygraphics_shaders::ShaderConstants;
use wgpu::util::{BufferInitDescriptor, DeviceExt};
use wgpu::wgt::CommandEncoderDescriptor;
use wgpu::{
BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor,
BindGroupLayoutEntry, BindingResource, BindingType, Buffer, BufferBinding, BufferBindingType,
BufferUsages, Color, Device, LoadOp, Operations, Queue, RenderPassColorAttachment,
RenderPassDescriptor, ShaderStages, StoreOp, TextureFormat, TextureView,
};
pub struct MyRenderer {
pub device: Device,
pub queue: Queue,
global_bind_group_layout: GlobalBindGroupLayout,
pipeline: MyRenderPipeline,
}
impl MyRenderer {
pub fn new(device: Device, queue: Queue, out_format: TextureFormat) -> anyhow::Result<Self> {
let global_bind_group_layout = GlobalBindGroupLayout::new(&device);
let pipeline = MyRenderPipeline::new(&device, &global_bind_group_layout, out_format)?;
Ok(Self {
global_bind_group_layout,
pipeline,
device,
queue,
})
}
pub fn render(&self, shader_constants: &ShaderConstants, output: TextureView) {
let global_bind_group = self
.global_bind_group_layout
.create(&self.device, shader_constants);
let mut cmd = self
.device
.create_command_encoder(&CommandEncoderDescriptor {
label: Some("main draw"),
});
let mut rpass = cmd.begin_render_pass(&RenderPassDescriptor {
label: Some("main renderpass"),
color_attachments: &[Some(RenderPassColorAttachment {
view: &output,
depth_slice: None,
resolve_target: None,
ops: Operations {
load: LoadOp::Clear(Color::BLACK),
store: StoreOp::Store,
},
})],
depth_stencil_attachment: None,
timestamp_writes: None,
occlusion_query_set: None,
multiview_mask: None,
});
self.pipeline.draw(&mut rpass, &global_bind_group);
drop(rpass);
self.queue.submit(std::iter::once(cmd.finish()));
}
}
#[derive(Debug, Clone)]
pub struct GlobalBindGroupLayout(pub BindGroupLayout);
impl GlobalBindGroupLayout {
pub fn new(device: &Device) -> Self {
Self(device.create_bind_group_layout(&BindGroupLayoutDescriptor {
label: Some("GlobalBindGroupLayout"),
entries: &[BindGroupLayoutEntry {
binding: 0,
visibility: ShaderStages::VERTEX_FRAGMENT,
ty: BindingType::Buffer {
ty: BufferBindingType::Storage { read_only: true },
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}],
}))
}
pub fn create(&self, device: &Device, shader_constants: &ShaderConstants) -> GlobalBindGroup {
let shader_constants = device.create_buffer_init(&BufferInitDescriptor {
label: Some("ShaderConstants"),
contents: bytemuck::bytes_of(shader_constants),
usage: BufferUsages::STORAGE,
});
self.create_from_buffer(device, &shader_constants)
}
pub fn create_from_buffer(
&self,
device: &Device,
shader_constants: &Buffer,
) -> GlobalBindGroup {
GlobalBindGroup(device.create_bind_group(&BindGroupDescriptor {
label: Some("GlobalBindGroup"),
layout: &self.0,
entries: &[BindGroupEntry {
binding: 0,
resource: BindingResource::Buffer(BufferBinding {
buffer: shader_constants,
offset: 0,
size: None,
}),
}],
}))
}
}
#[derive(Debug, Clone)]
pub struct GlobalBindGroup(pub BindGroup);