1
1
use std:: sync:: Arc ;
2
2
3
+ use bytemuck:: { Pod , Zeroable } ;
3
4
use thiserror:: Error ;
4
5
use winit:: window:: Window ;
5
6
@@ -79,13 +80,15 @@ impl WgpuContext {
79
80
. await
80
81
. unwrap ( ) ;
81
82
83
+ let required_limits = adapter. limits ( ) ;
84
+
82
85
let ( device, queue) = adapter
83
86
. request_device ( & wgpu:: DeviceDescriptor {
84
- required_features : wgpu:: Features :: empty ( ) ,
85
- required_limits : wgpu:: Limits :: default ( ) ,
86
87
label : None ,
88
+ required_features : wgpu:: Features :: PUSH_CONSTANTS ,
89
+ required_limits,
87
90
memory_hints : Default :: default ( ) ,
88
- .. Default :: default ( )
91
+ trace : wgpu :: Trace :: Off ,
89
92
} )
90
93
. await
91
94
. unwrap ( ) ;
@@ -99,10 +102,13 @@ pub(crate) struct GraphicsState {
99
102
surface : wgpu:: Surface < ' static > ,
100
103
context : WgpuContext ,
101
104
config : wgpu:: SurfaceConfiguration ,
102
- texture : Option < wgpu:: Texture > ,
103
- bind_group : Option < wgpu:: BindGroup > ,
104
105
render_pipeline : wgpu:: RenderPipeline ,
105
106
sampler : wgpu:: Sampler ,
107
+ viewport_scale : [ f32 ; 2 ] ,
108
+ viewport_offset : [ f32 ; 2 ] ,
109
+ viewport_texture : Option < wgpu:: Texture > ,
110
+ ui_texture : Option < wgpu:: Texture > ,
111
+ bind_group : Option < wgpu:: BindGroup > ,
106
112
}
107
113
108
114
impl GraphicsState {
@@ -156,6 +162,16 @@ impl GraphicsState {
156
162
wgpu:: BindGroupLayoutEntry {
157
163
binding : 1 ,
158
164
visibility : wgpu:: ShaderStages :: FRAGMENT ,
165
+ ty : wgpu:: BindingType :: Texture {
166
+ multisampled : false ,
167
+ view_dimension : wgpu:: TextureViewDimension :: D2 ,
168
+ sample_type : wgpu:: TextureSampleType :: Float { filterable : true } ,
169
+ } ,
170
+ count : None ,
171
+ } ,
172
+ wgpu:: BindGroupLayoutEntry {
173
+ binding : 2 ,
174
+ visibility : wgpu:: ShaderStages :: FRAGMENT ,
159
175
ty : wgpu:: BindingType :: Sampler ( wgpu:: SamplerBindingType :: Filtering ) ,
160
176
count : None ,
161
177
} ,
@@ -166,7 +182,10 @@ impl GraphicsState {
166
182
let render_pipeline_layout = context. device . create_pipeline_layout ( & wgpu:: PipelineLayoutDescriptor {
167
183
label : Some ( "Render Pipeline Layout" ) ,
168
184
bind_group_layouts : & [ & texture_bind_group_layout] ,
169
- push_constant_ranges : & [ ] ,
185
+ push_constant_ranges : & [ wgpu:: PushConstantRange {
186
+ stages : wgpu:: ShaderStages :: FRAGMENT ,
187
+ range : 0 ..size_of :: < Constants > ( ) as u32 ,
188
+ } ] ,
170
189
} ) ;
171
190
172
191
let render_pipeline = context. device . create_render_pipeline ( & wgpu:: RenderPipelineDescriptor {
@@ -211,10 +230,13 @@ impl GraphicsState {
211
230
surface,
212
231
context,
213
232
config,
214
- texture : None ,
215
- bind_group : None ,
216
233
render_pipeline,
217
234
sampler,
235
+ viewport_scale : [ 1.0 , 1.0 ] ,
236
+ viewport_offset : [ 0.0 , 0.0 ] ,
237
+ viewport_texture : None ,
238
+ ui_texture : None ,
239
+ bind_group : None ,
218
240
}
219
241
}
220
242
@@ -226,25 +248,47 @@ impl GraphicsState {
226
248
}
227
249
}
228
250
229
- pub ( crate ) fn bind_texture ( & mut self , texture : & wgpu:: Texture ) {
230
- let bind_group = self . create_bindgroup ( texture) ;
231
- self . texture = Some ( texture. clone ( ) ) ;
251
+ pub ( crate ) fn bind_ui_texture ( & mut self , texture : & wgpu:: Texture ) {
252
+ let bind_group = self . create_bindgroup ( texture, & self . viewport_texture . clone ( ) . unwrap_or ( texture. clone ( ) ) ) ;
253
+
254
+ self . ui_texture = Some ( texture. clone ( ) ) ;
232
255
233
256
self . bind_group = Some ( bind_group) ;
234
257
}
235
258
236
- fn create_bindgroup ( & self , texture : & wgpu:: Texture ) -> wgpu:: BindGroup {
237
- let texture_view = texture. create_view ( & wgpu:: TextureViewDescriptor :: default ( ) ) ;
259
+ pub ( crate ) fn bind_viewport_texture ( & mut self , texture : & wgpu:: Texture ) {
260
+ let bind_group = self . create_bindgroup ( & self . ui_texture . clone ( ) . unwrap_or ( texture. clone ( ) ) , texture) ;
261
+
262
+ self . viewport_texture = Some ( texture. clone ( ) ) ;
263
+
264
+ self . bind_group = Some ( bind_group) ;
265
+ }
266
+
267
+ pub ( crate ) fn set_viewport_scale ( & mut self , scale : [ f32 ; 2 ] ) {
268
+ self . viewport_scale = scale;
269
+ }
270
+
271
+ pub ( crate ) fn set_viewport_offset ( & mut self , offset : [ f32 ; 2 ] ) {
272
+ self . viewport_offset = offset;
273
+ }
274
+
275
+ fn create_bindgroup ( & self , ui_texture : & wgpu:: Texture , viewport_texture : & wgpu:: Texture ) -> wgpu:: BindGroup {
276
+ let ui_texture_view = ui_texture. create_view ( & wgpu:: TextureViewDescriptor :: default ( ) ) ;
277
+ let viewport_texture_view = viewport_texture. create_view ( & wgpu:: TextureViewDescriptor :: default ( ) ) ;
238
278
239
279
self . context . device . create_bind_group ( & wgpu:: BindGroupDescriptor {
240
280
layout : & self . render_pipeline . get_bind_group_layout ( 0 ) ,
241
281
entries : & [
242
282
wgpu:: BindGroupEntry {
243
283
binding : 0 ,
244
- resource : wgpu:: BindingResource :: TextureView ( & texture_view ) ,
284
+ resource : wgpu:: BindingResource :: TextureView ( & ui_texture_view ) ,
245
285
} ,
246
286
wgpu:: BindGroupEntry {
247
287
binding : 1 ,
288
+ resource : wgpu:: BindingResource :: TextureView ( & viewport_texture_view) ,
289
+ } ,
290
+ wgpu:: BindGroupEntry {
291
+ binding : 2 ,
248
292
resource : wgpu:: BindingResource :: Sampler ( & self . sampler ) ,
249
293
} ,
250
294
] ,
@@ -275,6 +319,14 @@ impl GraphicsState {
275
319
} ) ;
276
320
277
321
render_pass. set_pipeline ( & self . render_pipeline ) ;
322
+ render_pass. set_push_constants (
323
+ wgpu:: ShaderStages :: FRAGMENT ,
324
+ 0 ,
325
+ bytemuck:: bytes_of ( & Constants {
326
+ viewport_scale : self . viewport_scale ,
327
+ viewport_offset : self . viewport_offset ,
328
+ } ) ,
329
+ ) ;
278
330
if let Some ( bind_group) = & self . bind_group {
279
331
render_pass. set_bind_group ( 0 , bind_group, & [ ] ) ;
280
332
render_pass. draw ( 0 ..6 , 0 ..1 ) ; // Draw 3 vertices for fullscreen triangle
@@ -288,3 +340,10 @@ impl GraphicsState {
288
340
Ok ( ( ) )
289
341
}
290
342
}
343
+
344
+ #[ repr( C ) ]
345
+ #[ derive( Copy , Clone , Pod , Zeroable ) ]
346
+ struct Constants {
347
+ viewport_scale : [ f32 ; 2 ] ,
348
+ viewport_offset : [ f32 ; 2 ] ,
349
+ }
0 commit comments