1
+ use bytemuck:: bytes_of;
1
2
use bytemuck:: cast_slice;
2
3
use bytemuck:: Pod ;
3
4
use bytemuck:: Zeroable ;
@@ -8,12 +9,6 @@ use wgpu::MemoryHints::Performance;
8
9
use wgpu:: ShaderSource ;
9
10
use winit:: window:: Window ;
10
11
11
- #[ repr( C ) ]
12
- #[ derive( Debug , Copy , Clone , Pod , Zeroable ) ]
13
- struct Uniforms {
14
- screen_size : [ f32 ; 2 ] ,
15
- }
16
-
17
12
#[ repr( C ) ]
18
13
#[ derive( Copy , Clone , Debug , Pod , Zeroable ) ]
19
14
struct Instance {
@@ -41,9 +36,7 @@ pub struct Gpu<'window> {
41
36
num_indices : u32 ,
42
37
instance_buffer : wgpu:: Buffer ,
43
38
instance_count : u32 ,
44
-
45
- uniform_buffer : wgpu:: Buffer ,
46
- uniform_bind_group : wgpu:: BindGroup ,
39
+ viewport : [ f32 ; 2 ] ,
47
40
}
48
41
49
42
impl < ' window > Gpu < ' window > {
@@ -52,16 +45,22 @@ impl<'window> Gpu<'window> {
52
45
}
53
46
54
47
pub async fn new_async ( window : Arc < Window > ) -> Gpu < ' window > {
48
+ /*
49
+ * window
50
+ */
51
+
55
52
let size = window. inner_size ( ) ;
56
53
let width = size. width . max ( 1 ) ;
57
54
let height = size. height . max ( 1 ) ;
55
+ let viewport = [ width as f32 , height as f32 ] ;
58
56
59
57
/*
60
58
* wgpu
61
59
*/
62
60
63
61
let instance = wgpu:: Instance :: default ( ) ;
64
62
let surface = instance. create_surface ( Arc :: clone ( & window) ) . unwrap ( ) ;
63
+ let push_const_size = std:: mem:: size_of :: < [ f32 ; 2 ] > ( ) as u32 ;
65
64
66
65
let adapter = instance
67
66
. request_adapter ( & wgpu:: RequestAdapterOptions {
@@ -76,9 +75,11 @@ impl<'window> Gpu<'window> {
76
75
. request_device (
77
76
& wgpu:: DeviceDescriptor {
78
77
label : None ,
79
- required_features : wgpu:: Features :: empty ( ) ,
80
- required_limits : wgpu:: Limits :: downlevel_webgl2_defaults ( )
81
- . using_resolution ( adapter. limits ( ) ) ,
78
+ required_features : wgpu:: Features :: PUSH_CONSTANTS ,
79
+ required_limits : wgpu:: Limits {
80
+ max_push_constant_size : push_const_size,
81
+ ..Default :: default ( )
82
+ } ,
82
83
memory_hints : Performance ,
83
84
} ,
84
85
None ,
@@ -90,6 +91,15 @@ impl<'window> Gpu<'window> {
90
91
91
92
surface. configure ( & device, & config) ;
92
93
94
+ /*
95
+ * push constants
96
+ */
97
+
98
+ let push_constant_range = wgpu:: PushConstantRange {
99
+ stages : wgpu:: ShaderStages :: VERTEX ,
100
+ range : 0 ..push_const_size,
101
+ } ;
102
+
93
103
/*
94
104
* rects
95
105
*/
@@ -100,17 +110,6 @@ impl<'window> Gpu<'window> {
100
110
Instance :: new( 700.0 , 100.0 , 200.0 , 200.0 ) ,
101
111
] ;
102
112
103
- /*
104
- * instances
105
- */
106
-
107
- let instance_buffer = device. create_buffer_init ( & wgpu:: util:: BufferInitDescriptor {
108
- label : Some ( "Instance Buffer" ) ,
109
- contents : cast_slice ( & rects) ,
110
- usage : wgpu:: BufferUsages :: VERTEX ,
111
- } ) ;
112
- let instance_count = rects. len ( ) as u32 ;
113
-
114
113
/*
115
114
* vertices
116
115
*/
@@ -138,42 +137,15 @@ impl<'window> Gpu<'window> {
138
137
let num_indices = indices. len ( ) as u32 ;
139
138
140
139
/*
141
- * uniforms
140
+ * instances
142
141
*/
143
142
144
- let uniforms = Uniforms {
145
- screen_size : [ width as f32 , height as f32 ] ,
146
- } ;
147
-
148
- let uniform_buffer = device. create_buffer_init ( & wgpu:: util:: BufferInitDescriptor {
149
- label : Some ( "Uniform Buffer" ) ,
150
- contents : cast_slice ( & [ uniforms] ) ,
151
- usage : wgpu:: BufferUsages :: UNIFORM | wgpu:: BufferUsages :: COPY_DST ,
152
- } ) ;
153
-
154
- let uniform_bind_group_layout =
155
- device. create_bind_group_layout ( & wgpu:: BindGroupLayoutDescriptor {
156
- label : Some ( "Uniform Bind Group Layout" ) ,
157
- entries : & [ wgpu:: BindGroupLayoutEntry {
158
- binding : 0 ,
159
- visibility : wgpu:: ShaderStages :: VERTEX ,
160
- ty : wgpu:: BindingType :: Buffer {
161
- ty : wgpu:: BufferBindingType :: Uniform ,
162
- has_dynamic_offset : false ,
163
- min_binding_size : None ,
164
- } ,
165
- count : None ,
166
- } ] ,
167
- } ) ;
168
-
169
- let uniform_bind_group = device. create_bind_group ( & wgpu:: BindGroupDescriptor {
170
- label : Some ( "Uniform Bind Group" ) ,
171
- layout : & uniform_bind_group_layout,
172
- entries : & [ wgpu:: BindGroupEntry {
173
- binding : 0 ,
174
- resource : uniform_buffer. as_entire_binding ( ) ,
175
- } ] ,
143
+ let instance_buffer = device. create_buffer_init ( & wgpu:: util:: BufferInitDescriptor {
144
+ label : Some ( "Instance Buffer" ) ,
145
+ contents : cast_slice ( & rects) ,
146
+ usage : wgpu:: BufferUsages :: VERTEX ,
176
147
} ) ;
148
+ let instance_count = rects. len ( ) as u32 ;
177
149
178
150
/*
179
151
* shader
@@ -191,8 +163,8 @@ impl<'window> Gpu<'window> {
191
163
let render_pipeline_layout =
192
164
device. create_pipeline_layout ( & wgpu:: PipelineLayoutDescriptor {
193
165
label : Some ( "Render Pipeline Layout" ) ,
194
- bind_group_layouts : & [ & uniform_bind_group_layout ] ,
195
- push_constant_ranges : & [ ] ,
166
+ bind_group_layouts : & [ ] ,
167
+ push_constant_ranges : & [ push_constant_range ] ,
196
168
} ) ;
197
169
198
170
let render_pipeline = device. create_render_pipeline ( & wgpu:: RenderPipelineDescriptor {
@@ -202,6 +174,7 @@ impl<'window> Gpu<'window> {
202
174
module : & shader,
203
175
entry_point : Some ( "vs_main" ) ,
204
176
buffers : & [
177
+ // Vertex buffer
205
178
wgpu:: VertexBufferLayout {
206
179
array_stride : std:: mem:: size_of :: < [ f32 ; 2 ] > ( ) as wgpu:: BufferAddress ,
207
180
step_mode : wgpu:: VertexStepMode :: Vertex ,
@@ -211,6 +184,7 @@ impl<'window> Gpu<'window> {
211
184
format : wgpu:: VertexFormat :: Float32x2 ,
212
185
} ] ,
213
186
} ,
187
+ // Instance buffer
214
188
wgpu:: VertexBufferLayout {
215
189
array_stride : std:: mem:: size_of :: < Instance > ( ) as wgpu:: BufferAddress ,
216
190
step_mode : wgpu:: VertexStepMode :: Instance ,
@@ -238,16 +212,6 @@ impl<'window> Gpu<'window> {
238
212
} ) ,
239
213
primitive : wgpu:: PrimitiveState {
240
214
topology : wgpu:: PrimitiveTopology :: TriangleList ,
241
- // strip_index_format: None,
242
- // front_face: wgpu::FrontFace::Ccw,
243
- // cull_mode: Some(wgpu::Face::Back),
244
- // // Setting this to anything other than Fill requires Features::POLYGON_MODE_LINE
245
- // // or Features::POLYGON_MODE_POINT
246
- // polygon_mode: wgpu::PolygonMode::Fill,
247
- // // Requires Features::DEPTH_CLIP_CONTROL
248
- // unclipped_depth: false,
249
- // // Requires Features::CONSERVATIVE_RASTERIZATION
250
- // conservative: false,
251
215
..Default :: default ( )
252
216
} ,
253
217
depth_stencil : None ,
@@ -267,31 +231,23 @@ impl<'window> Gpu<'window> {
267
231
num_indices,
268
232
instance_buffer,
269
233
instance_count,
270
- uniform_buffer,
271
- uniform_bind_group,
234
+ viewport,
272
235
}
273
236
}
274
237
275
- pub fn resize ( & mut self , width : u32 , height : u32 ) {
276
- self . device . poll ( wgpu:: Maintain :: Wait ) ;
277
-
238
+ pub fn set_size ( & mut self , width : u32 , height : u32 ) {
278
239
let width = width. max ( 1 ) ;
279
240
let height = height. max ( 1 ) ;
280
241
281
242
self . config . width = width;
282
243
self . config . height = height;
283
-
284
244
self . surface . configure ( & self . device , & self . config ) ;
285
-
286
- let surface_uniform = Uniforms {
287
- screen_size : [ width as f32 , height as f32 ] ,
288
- } ;
289
-
290
- self . queue
291
- . write_buffer ( & self . uniform_buffer , 0 , cast_slice ( & [ surface_uniform] ) ) ;
245
+ self . viewport = [ width as f32 , height as f32 ] ;
292
246
}
293
247
294
248
pub fn draw ( & mut self ) {
249
+ self . device . poll ( wgpu:: Maintain :: Wait ) ;
250
+
295
251
let frame = self
296
252
. surface
297
253
. get_current_texture ( )
@@ -314,12 +270,7 @@ impl<'window> Gpu<'window> {
314
270
view : & view,
315
271
resolve_target : None ,
316
272
ops : wgpu:: Operations {
317
- load : wgpu:: LoadOp :: Clear ( wgpu:: Color {
318
- r : 0.104 ,
319
- g : 0.133 ,
320
- b : 0.212 ,
321
- a : 1.0 ,
322
- } ) ,
273
+ load : wgpu:: LoadOp :: Clear ( wgpu:: Color :: BLACK ) ,
323
274
store : wgpu:: StoreOp :: Store ,
324
275
} ,
325
276
} ) ] ,
@@ -329,7 +280,7 @@ impl<'window> Gpu<'window> {
329
280
} ) ;
330
281
331
282
rpass. set_pipeline ( & self . render_pipeline ) ;
332
- rpass. set_bind_group ( 0 , & self . uniform_bind_group , & [ ] ) ;
283
+ rpass. set_push_constants ( wgpu :: ShaderStages :: VERTEX , 0 , bytes_of ( & self . viewport ) ) ;
333
284
rpass. set_vertex_buffer ( 0 , self . vertex_buffer . slice ( ..) ) ;
334
285
rpass. set_vertex_buffer ( 1 , self . instance_buffer . slice ( ..) ) ;
335
286
rpass. set_index_buffer ( self . index_buffer . slice ( ..) , wgpu:: IndexFormat :: Uint16 ) ;
0 commit comments