@@ -2,16 +2,20 @@ mod prepass_bindings;
22
33use crate :: material_bind_groups:: MaterialBindGroupAllocator ;
44use bevy_render:: {
5- mesh:: { Mesh3d , MeshVertexBufferLayoutRef , RenderMesh } ,
5+ mesh:: { allocator :: MeshAllocator , Mesh3d , MeshVertexBufferLayoutRef , RenderMesh } ,
66 render_resource:: binding_types:: uniform_buffer,
7+ renderer:: RenderAdapter ,
78 sync_world:: RenderEntity ,
89 view:: { RenderVisibilityRanges , VISIBILITY_RANGES_STORAGE_BUFFER_COUNT } ,
910} ;
1011pub use prepass_bindings:: * ;
1112
1213use bevy_asset:: { load_internal_asset, AssetServer } ;
1314use bevy_core_pipeline:: {
14- core_3d:: CORE_3D_DEPTH_FORMAT , deferred:: * , prelude:: Camera3d , prepass:: * ,
15+ core_3d:: { Opaque3dBatchSetKey , Opaque3dBinKey , CORE_3D_DEPTH_FORMAT } ,
16+ deferred:: * ,
17+ prelude:: Camera3d ,
18+ prepass:: * ,
1519} ;
1620use bevy_ecs:: {
1721 prelude:: * ,
@@ -259,12 +263,18 @@ pub struct PrepassPipeline<M: Material> {
259263 pub skins_use_uniform_buffers : bool ,
260264
261265 pub depth_clip_control_supported : bool ,
266+
267+ /// Whether binding arrays (a.k.a. bindless textures) are usable on the
268+ /// current render device.
269+ pub binding_arrays_are_usable : bool ,
270+
262271 _marker : PhantomData < M > ,
263272}
264273
265274impl < M : Material > FromWorld for PrepassPipeline < M > {
266275 fn from_world ( world : & mut World ) -> Self {
267276 let render_device = world. resource :: < RenderDevice > ( ) ;
277+ let render_adapter = world. resource :: < RenderAdapter > ( ) ;
268278 let asset_server = world. resource :: < AssetServer > ( ) ;
269279
270280 let visibility_ranges_buffer_binding_type = render_device
@@ -352,6 +362,7 @@ impl<M: Material> FromWorld for PrepassPipeline<M> {
352362 material_pipeline : world. resource :: < MaterialPipeline < M > > ( ) . clone ( ) ,
353363 skins_use_uniform_buffers : skin:: skins_use_uniform_buffers ( render_device) ,
354364 depth_clip_control_supported,
365+ binding_arrays_are_usable : binding_arrays_are_usable ( render_device, render_adapter) ,
355366 _marker : PhantomData ,
356367 }
357368 }
@@ -505,6 +516,10 @@ where
505516 shader_defs. push ( "BINDLESS" . into ( ) ) ;
506517 }
507518
519+ if self . binding_arrays_are_usable {
520+ shader_defs. push ( "MULTIPLE_LIGHTMAPS_IN_ARRAY" . into ( ) ) ;
521+ }
522+
508523 if key
509524 . mesh_key
510525 . contains ( MeshPipelineKey :: VISIBILITY_RANGE_DITHER )
@@ -764,7 +779,10 @@ pub fn queue_prepass_material_meshes<M: Material>(
764779 render_material_instances : Res < RenderMaterialInstances < M > > ,
765780 render_lightmaps : Res < RenderLightmaps > ,
766781 render_visibility_ranges : Res < RenderVisibilityRanges > ,
767- material_bind_group_allocator : Res < MaterialBindGroupAllocator < M > > ,
782+ ( mesh_allocator, material_bind_group_allocator) : (
783+ Res < MeshAllocator > ,
784+ Res < MaterialBindGroupAllocator < M > > ,
785+ ) ,
768786 mut opaque_prepass_render_phases : ResMut < ViewBinnedRenderPhases < Opaque3dPrepass > > ,
769787 mut alpha_mask_prepass_render_phases : ResMut < ViewBinnedRenderPhases < AlphaMask3dPrepass > > ,
770788 mut opaque_deferred_render_phases : ResMut < ViewBinnedRenderPhases < Opaque3dDeferred > > ,
@@ -893,15 +911,11 @@ pub fn queue_prepass_material_meshes<M: Material>(
893911 mesh_key |= MeshPipelineKey :: DEFERRED_PREPASS ;
894912 }
895913
896- // Even though we don't use the lightmap in the prepass, the
897- // `SetMeshBindGroup` render command will bind the data for it. So
898- // we need to include the appropriate flag in the mesh pipeline key
899- // to ensure that the necessary bind group layout entries are
900- // present.
901- if render_lightmaps
914+ let lightmap_slab_index = render_lightmaps
902915 . render_lightmaps
903- . contains_key ( visible_entity)
904- {
916+ . get ( visible_entity)
917+ . map ( |lightmap| lightmap. slab_index ) ;
918+ if lightmap_slab_index. is_some ( ) {
905919 mesh_key |= MeshPipelineKey :: LIGHTMAPPED ;
906920 }
907921
@@ -949,12 +963,18 @@ pub fn queue_prepass_material_meshes<M: Material>(
949963 {
950964 MeshPipelineKey :: BLEND_OPAQUE | MeshPipelineKey :: BLEND_ALPHA_TO_COVERAGE => {
951965 if deferred {
966+ let ( vertex_slab, index_slab) =
967+ mesh_allocator. mesh_slabs ( & mesh_instance. mesh_asset_id ) ;
952968 opaque_deferred_phase. as_mut ( ) . unwrap ( ) . add (
953- OpaqueNoLightmap3dBinKey {
954- batch_set_key : OpaqueNoLightmap3dBatchSetKey {
969+ Opaque3dBinKey {
970+ batch_set_key : Opaque3dBatchSetKey {
955971 draw_function : opaque_draw_deferred,
956972 pipeline : pipeline_id,
957973 material_bind_group_index : Some ( material. binding . group . 0 ) ,
974+ vertex_slab : vertex_slab. unwrap_or_default ( ) ,
975+ index_slab,
976+ lightmap_slab : lightmap_slab_index
977+ . map ( |lightmap_slab_index| * lightmap_slab_index) ,
958978 } ,
959979 asset_id : mesh_instance. mesh_asset_id . into ( ) ,
960980 } ,
0 commit comments