@@ -56,8 +56,8 @@ pub struct ImageBindDesc {
56
56
#[ derive( Debug , Default ) ]
57
57
pub struct BindingDescription {
58
58
// TODO(pat.m): store unresolved named targets separately to resolved/explicit targets to simplify usage
59
- pub buffer_bindings : Vec < BufferBindDesc > ,
60
- pub image_bindings : Vec < ImageBindDesc > ,
59
+ pub buffer_bindings : SmallVec < [ BufferBindDesc ; 4 ] > ,
60
+ pub image_bindings : SmallVec < [ ImageBindDesc ; 4 ] > ,
61
61
62
62
pub framebuffer : Option < FramebufferArgument > ,
63
63
}
@@ -171,79 +171,92 @@ impl BindingDescription {
171
171
pub fn bind ( & self , core : & mut Core , resource_manager : & mut ResourceManager ) {
172
172
let mut barrier_tracker = core. barrier_tracker ( ) ;
173
173
174
- for BufferBindDesc { target, source} in self . buffer_bindings . iter ( ) {
175
- let BufferArgument :: Name { name, range} = * source
176
- else { panic ! ( "Unresolved buffer bind source" ) } ;
174
+ {
175
+ let _span = tracing:: info_span!( "bind buffers" ) . entered ( ) ;
177
176
178
- let Some ( ( index, indexed_target) ) = target. to_raw_index ( ) . zip ( target. to_indexed_buffer_target ( ) )
179
- else { panic ! ( "Unresolved buffer target" ) } ;
177
+ for BufferBindDesc { target, source} in self . buffer_bindings . iter ( ) {
178
+ let BufferArgument :: Name { name, range} = * source
179
+ else { panic ! ( "Unresolved buffer bind source" ) } ;
180
180
181
- match indexed_target {
182
- // TODO(pat.m): this is pessimistic - but we need shader reflection to guarantee that an ssbo is bound
183
- // as readonly.
184
- IndexedBufferTarget :: ShaderStorage => barrier_tracker. write_buffer ( name, gl:: SHADER_STORAGE_BARRIER_BIT ) ,
185
- IndexedBufferTarget :: Uniform => barrier_tracker. read_buffer ( name, gl:: UNIFORM_BARRIER_BIT ) ,
186
- }
181
+ let Some ( ( index, indexed_target) ) = target. to_raw_index ( ) . zip ( target. to_indexed_buffer_target ( ) )
182
+ else { panic ! ( "Unresolved buffer target" ) } ;
183
+
184
+ match indexed_target {
185
+ // TODO(pat.m): this is pessimistic - but we need shader reflection to guarantee that an ssbo is bound
186
+ // as readonly.
187
+ IndexedBufferTarget :: ShaderStorage => barrier_tracker. write_buffer ( name, gl:: SHADER_STORAGE_BARRIER_BIT ) ,
188
+ IndexedBufferTarget :: Uniform => barrier_tracker. read_buffer ( name, gl:: UNIFORM_BARRIER_BIT ) ,
189
+ }
187
190
188
- core. bind_indexed_buffer ( indexed_target, index, name, range) ;
191
+ core. bind_indexed_buffer ( indexed_target, index, name, range) ;
192
+ }
189
193
}
190
194
191
- for ImageBindDesc { target, source, sampler} in self . image_bindings . iter ( ) {
192
- let ImageArgument :: Name ( image_name) = * source
193
- else { panic ! ( "Unresolved image bind source" ) } ;
195
+ {
196
+ let _span = tracing:: info_span!( "bind images" ) . entered ( ) ;
194
197
195
- match * target {
196
- ImageBindTarget :: Sampled ( unit ) => {
197
- barrier_tracker . read_image ( image_name , gl :: TEXTURE_FETCH_BARRIER_BIT ) ;
198
+ for ImageBindDesc { target, source , sampler } in self . image_bindings . iter ( ) {
199
+ let ImageArgument :: Name ( image_name ) = * source
200
+ else { panic ! ( "Unresolved image bind source" ) } ;
198
201
199
- // TODO(pat.m): use default instead of panicking
200
- let sampler_name = match sampler. expect ( "Sampled bind target missing sampler" ) {
201
- SamplerArgument :: Name ( name) => name,
202
- SamplerArgument :: Common ( sampler) => resource_manager. get_common_sampler ( sampler) ,
203
- } ;
202
+ match * target {
203
+ ImageBindTarget :: Sampled ( unit) => {
204
+ barrier_tracker. read_image ( image_name, gl:: TEXTURE_FETCH_BARRIER_BIT ) ;
204
205
205
- core. bind_sampler ( unit, sampler_name) ;
206
- core. bind_sampled_image ( unit, image_name) ;
207
- }
206
+ // TODO(pat.m): use default instead of panicking
207
+ let sampler_name = match sampler. expect ( "Sampled bind target missing sampler" ) {
208
+ SamplerArgument :: Name ( name) => name,
209
+ SamplerArgument :: Common ( sampler) => resource_manager. get_common_sampler ( sampler) ,
210
+ } ;
208
211
209
- ImageBindTarget :: ReadonlyImage ( unit) => {
210
- barrier_tracker. read_image ( image_name, gl:: SHADER_IMAGE_ACCESS_BARRIER_BIT ) ;
211
- core. bind_image ( unit, image_name) ;
212
- }
212
+ core. bind_sampler ( unit, sampler_name) ;
213
+ core. bind_sampled_image ( unit, image_name) ;
214
+ }
213
215
214
- ImageBindTarget :: ReadWriteImage ( unit) => {
215
- barrier_tracker. write_image ( image_name, gl:: SHADER_IMAGE_ACCESS_BARRIER_BIT ) ;
216
- core. bind_image_rw ( unit, image_name) ;
217
- }
216
+ ImageBindTarget :: ReadonlyImage ( unit) => {
217
+ barrier_tracker. read_image ( image_name, gl:: SHADER_IMAGE_ACCESS_BARRIER_BIT ) ;
218
+ core. bind_image ( unit, image_name) ;
219
+ }
220
+
221
+ ImageBindTarget :: ReadWriteImage ( unit) => {
222
+ barrier_tracker. write_image ( image_name, gl:: SHADER_IMAGE_ACCESS_BARRIER_BIT ) ;
223
+ core. bind_image_rw ( unit, image_name) ;
224
+ }
218
225
219
- _ => panic ! ( "Unresolved image bind target" ) ,
226
+ _ => panic ! ( "Unresolved image bind target" ) ,
227
+ }
220
228
}
221
229
}
222
230
223
- // TODO(pat.m): the following should only be done for the Draw command really.
224
- // it doesn't make sense to bind or emit barriers for e.g., Compute.
225
-
226
- // Framebuffer should _ALWAYS_ be defined by this point.
227
- // The global BindingDescription should specify Default
228
- let framebuffer = self . framebuffer . as_ref ( )
229
- . expect ( "Unresolved framebuffer" )
230
- . resolve_name ( core, resource_manager) ;
231
-
232
- if let Some ( framebuffer_name) = framebuffer {
233
- let framebuffer_info = core. get_framebuffer_info ( framebuffer_name) ;
234
- for attachment_image in framebuffer_info. attachments . values ( ) {
235
- // NOTE: only a read barrier since framebuffer writes are implicitly synchronised with later draw calls.
236
- // We only need to make sure that if an image is _modified_ that a barrier is inserted before rendering to it.
237
- barrier_tracker. read_image ( * attachment_image, gl:: FRAMEBUFFER_BARRIER_BIT ) ;
231
+
232
+ {
233
+ let _span = tracing:: info_span!( "bind framebuffer" ) . entered ( ) ;
234
+
235
+ // TODO(pat.m): the following should only be done for the Draw command really.
236
+ // it doesn't make sense to bind or emit barriers for e.g., Compute.
237
+
238
+ // Framebuffer should _ALWAYS_ be defined by this point.
239
+ // The global BindingDescription should specify Default
240
+ let framebuffer = self . framebuffer . as_ref ( )
241
+ . expect ( "Unresolved framebuffer" )
242
+ . resolve_name ( core, resource_manager) ;
243
+
244
+ if let Some ( framebuffer_name) = framebuffer {
245
+ let framebuffer_info = core. get_framebuffer_info ( framebuffer_name) ;
246
+ for attachment_image in framebuffer_info. attachments . values ( ) {
247
+ // NOTE: only a read barrier since framebuffer writes are implicitly synchronised with later draw calls.
248
+ // We only need to make sure that if an image is _modified_ that a barrier is inserted before rendering to it.
249
+ barrier_tracker. read_image ( * attachment_image, gl:: FRAMEBUFFER_BARRIER_BIT ) ;
250
+ }
251
+
252
+ let framebuffer_size = core. get_framebuffer_size ( framebuffer_name) ;
253
+ core. set_viewport ( framebuffer_size) ;
254
+ } else {
255
+ core. set_viewport ( core. backbuffer_size ( ) ) ;
238
256
}
239
257
240
- let framebuffer_size = core. get_framebuffer_size ( framebuffer_name) ;
241
- core. set_viewport ( framebuffer_size) ;
242
- } else {
243
- core. set_viewport ( core. backbuffer_size ( ) ) ;
258
+ core. bind_framebuffer ( framebuffer) ;
244
259
}
245
-
246
- core. bind_framebuffer ( framebuffer) ;
247
260
}
248
261
}
249
262
0 commit comments