@@ -20,7 +20,7 @@ use bevy_platform::collections::{HashMap, HashSet};
2020use bevy_render:: erased_render_asset:: ErasedRenderAssets ;
2121use bevy_render:: { camera:: TemporalJitter , render_resource:: * , view:: ExtractedView } ;
2222use bevy_utils:: default;
23- use core:: any:: { Any , TypeId } ;
23+ use core:: any:: TypeId ;
2424
2525/// A list of `(Material ID, Pipeline, BindGroup)` for a view for use in [`meshlet_main_opaque_pass`](`super::meshlet_main_opaque_pass`).
2626#[ derive( Component , Deref , DerefMut , Default ) ]
@@ -165,79 +165,84 @@ pub fn prepare_material_meshlet_meshes_main_opaque_pass(
165165 continue ;
166166 }
167167
168- let erased_key = ErasedMaterialPipelineKey {
169- mesh_key : ErasedMeshPipelineKey :: new ( view_key) ,
170- material_key : material. properties . material_key . clone ( ) ,
171- type_id : material_id. type_id ( ) ,
172- } ;
173- let material_pipeline_specializer = MaterialPipelineSpecializer {
174- pipeline : material_pipeline. clone ( ) ,
175- properties : material. properties . clone ( ) ,
176- } ;
177- let Ok ( material_pipeline_descriptor) =
178- material_pipeline_specializer. specialize ( erased_key, fake_vertex_buffer_layout)
179- else {
180- continue ;
181- } ;
182- let material_fragment = material_pipeline_descriptor. fragment . unwrap ( ) ;
183-
184- let mut shader_defs = material_fragment. shader_defs ;
185- shader_defs. push ( "MESHLET_MESH_MATERIAL_PASS" . into ( ) ) ;
186-
187- let layout = mesh_pipeline. get_view_layout ( view_key. into ( ) ) ;
188- let layout = vec ! [
189- layout. main_layout. clone( ) ,
190- layout. binding_array_layout. clone( ) ,
191- resource_manager. material_shade_bind_group_layout. clone( ) ,
192- material
193- . properties
194- . material_layout
195- . as_ref( )
196- . unwrap( )
197- . clone( ) ,
198- ] ;
199-
200- let pipeline_descriptor = RenderPipelineDescriptor {
201- label : material_pipeline_descriptor. label ,
202- layout,
203- immediate_size : 0 ,
204- vertex : VertexState {
205- shader : meshlet_pipelines. meshlet_mesh_material . clone ( ) ,
206- shader_defs : shader_defs. clone ( ) ,
207- entry_point : material_pipeline_descriptor. vertex . entry_point ,
208- buffers : Vec :: new ( ) ,
209- } ,
210- primitive : PrimitiveState :: default ( ) ,
211- depth_stencil : Some ( DepthStencilState {
212- format : TextureFormat :: Depth16Unorm ,
213- depth_write_enabled : Some ( false ) ,
214- depth_compare : Some ( CompareFunction :: Equal ) ,
215- stencil : StencilState :: default ( ) ,
216- bias : DepthBiasState :: default ( ) ,
217- } ) ,
218- multisample : MultisampleState :: default ( ) ,
219- fragment : Some ( FragmentState {
220- shader : match material. properties . get_shader ( MeshletFragmentShader ) {
221- Some ( shader) => shader. clone ( ) ,
222- None => meshlet_pipelines. meshlet_mesh_material . clone ( ) ,
223- } ,
224- shader_defs,
225- entry_point : material_fragment. entry_point ,
226- targets : material_fragment. targets ,
227- } ) ,
228- zero_initialize_workgroup_memory : false ,
229- } ;
230168 let type_id = material_id. type_id ( ) ;
231169 let Some ( material_bind_group_allocator) = material_bind_group_allocators. get ( & type_id)
232170 else {
233171 continue ;
234172 } ;
235- let material_id = instance_manager. get_material_id ( material_id) ;
236173
237- let pipeline_id = * cache. entry ( ( view_key, type_id) ) . or_insert_with ( || {
238- pipeline_cache. queue_render_pipeline ( pipeline_descriptor. clone ( ) )
239- } ) ;
174+ let pipeline_id = if let Some ( & id) = cache. get ( & ( view_key, type_id) ) {
175+ id
176+ } else {
177+ let erased_key = ErasedMaterialPipelineKey {
178+ mesh_key : ErasedMeshPipelineKey :: new ( view_key) ,
179+ material_key : material. properties . material_key . clone ( ) ,
180+ type_id,
181+ } ;
182+ let material_pipeline_specializer = MaterialPipelineSpecializer {
183+ pipeline : material_pipeline. clone ( ) ,
184+ properties : material. properties . clone ( ) ,
185+ } ;
186+ let Ok ( material_pipeline_descriptor) =
187+ material_pipeline_specializer. specialize ( erased_key, fake_vertex_buffer_layout)
188+ else {
189+ continue ;
190+ } ;
191+ let material_fragment = material_pipeline_descriptor. fragment . unwrap ( ) ;
192+
193+ let mut shader_defs = material_fragment. shader_defs ;
194+ shader_defs. push ( "MESHLET_MESH_MATERIAL_PASS" . into ( ) ) ;
195+
196+ let layout = mesh_pipeline. get_view_layout ( view_key. into ( ) ) ;
197+ let layout = vec ! [
198+ layout. main_layout. clone( ) ,
199+ layout. binding_array_layout. clone( ) ,
200+ resource_manager. material_shade_bind_group_layout. clone( ) ,
201+ material
202+ . properties
203+ . material_layout
204+ . as_ref( )
205+ . unwrap( )
206+ . clone( ) ,
207+ ] ;
208+
209+ let pipeline_descriptor = RenderPipelineDescriptor {
210+ label : material_pipeline_descriptor. label ,
211+ layout,
212+ immediate_size : 0 ,
213+ vertex : VertexState {
214+ shader : meshlet_pipelines. meshlet_mesh_material . clone ( ) ,
215+ shader_defs : shader_defs. clone ( ) ,
216+ entry_point : material_pipeline_descriptor. vertex . entry_point ,
217+ buffers : Vec :: new ( ) ,
218+ } ,
219+ primitive : PrimitiveState :: default ( ) ,
220+ depth_stencil : Some ( DepthStencilState {
221+ format : TextureFormat :: Depth16Unorm ,
222+ depth_write_enabled : Some ( false ) ,
223+ depth_compare : Some ( CompareFunction :: Equal ) ,
224+ stencil : StencilState :: default ( ) ,
225+ bias : DepthBiasState :: default ( ) ,
226+ } ) ,
227+ multisample : MultisampleState :: default ( ) ,
228+ fragment : Some ( FragmentState {
229+ shader : match material. properties . get_shader ( MeshletFragmentShader ) {
230+ Some ( shader) => shader. clone ( ) ,
231+ None => meshlet_pipelines. meshlet_mesh_material . clone ( ) ,
232+ } ,
233+ shader_defs,
234+ entry_point : material_fragment. entry_point ,
235+ targets : material_fragment. targets ,
236+ } ) ,
237+ zero_initialize_workgroup_memory : false ,
238+ } ;
239+
240+ let pipeline_id = pipeline_cache. queue_render_pipeline ( pipeline_descriptor) ;
241+ cache. insert ( ( view_key, type_id) , pipeline_id) ;
242+ pipeline_id
243+ } ;
240244
245+ let material_id = instance_manager. get_material_id ( material_id) ;
241246 let Some ( material_bind_group) =
242247 material_bind_group_allocator. get ( material. binding . group )
243248 else {
@@ -318,8 +323,8 @@ pub fn prepare_material_meshlet_meshes_prepass(
318323 let Some ( material) = render_materials. get ( material_id) else {
319324 continue ;
320325 } ;
321- let Some ( material_bind_group_allocator ) =
322- material_bind_group_allocators. get ( & material_id . type_id ( ) )
326+ let type_id = material_id . type_id ( ) ;
327+ let Some ( material_bind_group_allocator ) = material_bind_group_allocators. get ( & type_id)
323328 else {
324329 continue ;
325330 } ;
@@ -340,93 +345,94 @@ pub fn prepare_material_meshlet_meshes_prepass(
340345 continue ;
341346 }
342347
343- let erased_key = ErasedMaterialPipelineKey {
344- mesh_key : ErasedMeshPipelineKey :: new ( view_key) ,
345- material_key : material. properties . material_key . clone ( ) ,
346- type_id : material_id. type_id ( ) ,
347- } ;
348- let material_pipeline_specializer = PrepassPipelineSpecializer {
349- pipeline : prepass_pipeline. clone ( ) ,
350- properties : material. properties . clone ( ) ,
351- } ;
352- let Ok ( material_pipeline_descriptor) =
353- material_pipeline_specializer. specialize ( erased_key, fake_vertex_buffer_layout)
354- else {
355- continue ;
356- } ;
357- let material_fragment = material_pipeline_descriptor. fragment . unwrap ( ) ;
358-
359- let mut shader_defs = material_fragment. shader_defs ;
360- shader_defs. push ( "MESHLET_MESH_MATERIAL_PASS" . into ( ) ) ;
361-
362- let view_layout = if view_key. contains ( MeshPipelineKey :: MOTION_VECTOR_PREPASS ) {
363- prepass_pipeline. view_layout_motion_vectors . clone ( )
364- } else {
365- prepass_pipeline. view_layout_no_motion_vectors . clone ( )
366- } ;
367-
368- let fragment_shader = if view_key. contains ( MeshPipelineKey :: DEFERRED_PREPASS ) {
369- material
370- . properties
371- . get_shader ( MeshletDeferredFragmentShader )
372- . unwrap_or ( meshlet_pipelines. meshlet_mesh_material . clone ( ) )
373- } else {
374- material
375- . properties
376- . get_shader ( MeshletPrepassFragmentShader )
377- . unwrap_or ( meshlet_pipelines. meshlet_mesh_material . clone ( ) )
378- } ;
379-
380- let entry_point = if fragment_shader == meshlet_pipelines. meshlet_mesh_material {
381- material_fragment. entry_point . clone ( )
348+ let pipeline_id = if let Some ( & id) = cache. get ( & ( view_key, type_id) ) {
349+ id
382350 } else {
383- None
384- } ;
385-
386- let pipeline_descriptor = RenderPipelineDescriptor {
387- label : material_pipeline_descriptor. label ,
388- layout : vec ! [
389- view_layout,
390- prepass_pipeline. empty_layout. clone( ) ,
391- resource_manager. material_shade_bind_group_layout. clone( ) ,
351+ let erased_key = ErasedMaterialPipelineKey {
352+ mesh_key : ErasedMeshPipelineKey :: new ( view_key) ,
353+ material_key : material. properties . material_key . clone ( ) ,
354+ type_id,
355+ } ;
356+ let material_pipeline_specializer = PrepassPipelineSpecializer {
357+ pipeline : prepass_pipeline. clone ( ) ,
358+ properties : material. properties . clone ( ) ,
359+ } ;
360+ let Ok ( material_pipeline_descriptor) =
361+ material_pipeline_specializer. specialize ( erased_key, fake_vertex_buffer_layout)
362+ else {
363+ continue ;
364+ } ;
365+ let material_fragment = material_pipeline_descriptor. fragment . unwrap ( ) ;
366+
367+ let mut shader_defs = material_fragment. shader_defs ;
368+ shader_defs. push ( "MESHLET_MESH_MATERIAL_PASS" . into ( ) ) ;
369+
370+ let view_layout = if view_key. contains ( MeshPipelineKey :: MOTION_VECTOR_PREPASS ) {
371+ prepass_pipeline. view_layout_motion_vectors . clone ( )
372+ } else {
373+ prepass_pipeline. view_layout_no_motion_vectors . clone ( )
374+ } ;
375+
376+ let fragment_shader = if view_key. contains ( MeshPipelineKey :: DEFERRED_PREPASS ) {
392377 material
393378 . properties
394- . material_layout
395- . as_ref( )
396- . unwrap( )
397- . clone( ) ,
398- ] ,
399- vertex : VertexState {
400- shader : meshlet_pipelines. meshlet_mesh_material . clone ( ) ,
401- shader_defs : shader_defs. clone ( ) ,
402- entry_point : material_pipeline_descriptor. vertex . entry_point ,
379+ . get_shader ( MeshletDeferredFragmentShader )
380+ . unwrap_or ( meshlet_pipelines. meshlet_mesh_material . clone ( ) )
381+ } else {
382+ material
383+ . properties
384+ . get_shader ( MeshletPrepassFragmentShader )
385+ . unwrap_or ( meshlet_pipelines. meshlet_mesh_material . clone ( ) )
386+ } ;
387+
388+ let entry_point = if fragment_shader == meshlet_pipelines. meshlet_mesh_material {
389+ material_fragment. entry_point . clone ( )
390+ } else {
391+ None
392+ } ;
393+
394+ let pipeline_descriptor = RenderPipelineDescriptor {
395+ label : material_pipeline_descriptor. label ,
396+ layout : vec ! [
397+ view_layout,
398+ prepass_pipeline. empty_layout. clone( ) ,
399+ resource_manager. material_shade_bind_group_layout. clone( ) ,
400+ material
401+ . properties
402+ . material_layout
403+ . as_ref( )
404+ . unwrap( )
405+ . clone( ) ,
406+ ] ,
407+ vertex : VertexState {
408+ shader : meshlet_pipelines. meshlet_mesh_material . clone ( ) ,
409+ shader_defs : shader_defs. clone ( ) ,
410+ entry_point : material_pipeline_descriptor. vertex . entry_point ,
411+ ..default ( )
412+ } ,
413+ primitive : PrimitiveState :: default ( ) ,
414+ depth_stencil : Some ( DepthStencilState {
415+ format : TextureFormat :: Depth16Unorm ,
416+ depth_write_enabled : Some ( false ) ,
417+ depth_compare : Some ( CompareFunction :: Equal ) ,
418+ stencil : StencilState :: default ( ) ,
419+ bias : DepthBiasState :: default ( ) ,
420+ } ) ,
421+ fragment : Some ( FragmentState {
422+ shader : fragment_shader,
423+ shader_defs,
424+ entry_point,
425+ targets : material_fragment. targets ,
426+ } ) ,
403427 ..default ( )
404- } ,
405- primitive : PrimitiveState :: default ( ) ,
406- depth_stencil : Some ( DepthStencilState {
407- format : TextureFormat :: Depth16Unorm ,
408- depth_write_enabled : Some ( false ) ,
409- depth_compare : Some ( CompareFunction :: Equal ) ,
410- stencil : StencilState :: default ( ) ,
411- bias : DepthBiasState :: default ( ) ,
412- } ) ,
413- fragment : Some ( FragmentState {
414- shader : fragment_shader,
415- shader_defs,
416- entry_point,
417- targets : material_fragment. targets ,
418- } ) ,
419- ..default ( )
428+ } ;
429+
430+ let pipeline_id = pipeline_cache. queue_render_pipeline ( pipeline_descriptor) ;
431+ cache. insert ( ( view_key, type_id) , pipeline_id) ;
432+ pipeline_id
420433 } ;
421434
422435 let material_id = instance_manager. get_material_id ( material_id) ;
423-
424- let pipeline_id = * cache
425- . entry ( ( view_key, material_id. type_id ( ) ) )
426- . or_insert_with ( || {
427- pipeline_cache. queue_render_pipeline ( pipeline_descriptor. clone ( ) )
428- } ) ;
429-
430436 let Some ( material_bind_group) =
431437 material_bind_group_allocator. get ( material. binding . group )
432438 else {
0 commit comments