@@ -11,7 +11,7 @@ use bevy_ecs::{
11
11
use bevy_math:: Mat4 ;
12
12
use bevy_reflect:: TypeUuid ;
13
13
use bevy_render:: {
14
- mesh:: { GpuBufferInfo , Mesh } ,
14
+ mesh:: { GpuBufferInfo , Mesh , VertexLayoutKey } ,
15
15
render_asset:: RenderAssets ,
16
16
render_component:: { ComponentUniforms , DynamicUniformIndex , UniformComponentPlugin } ,
17
17
render_phase:: { EntityRenderCommand , RenderCommandResult , TrackedRenderPass } ,
@@ -356,28 +356,34 @@ impl MeshPipeline {
356
356
}
357
357
}
358
358
359
+ #[ derive( Clone , Copy , Hash , PartialEq , Eq ) ]
360
+ pub struct MeshPipelineKey {
361
+ pub vertex_layout_key : VertexLayoutKey ,
362
+ pub flags : MeshPipelineFlags ,
363
+ }
364
+
359
365
bitflags:: bitflags! {
360
366
#[ repr( transparent) ]
361
367
// NOTE: Apparently quadro drivers support up to 64x MSAA.
362
368
/// MSAA uses the highest 6 bits for the MSAA sample count - 1 to support up to 64x MSAA.
363
- pub struct MeshPipelineKey : u32 {
369
+ pub struct MeshPipelineFlags : u32 {
364
370
const NONE = 0 ;
365
371
const VERTEX_TANGENTS = ( 1 << 0 ) ;
366
372
const TRANSPARENT_MAIN_PASS = ( 1 << 1 ) ;
367
- const MSAA_RESERVED_BITS = MeshPipelineKey :: MSAA_MASK_BITS << MeshPipelineKey :: MSAA_SHIFT_BITS ;
368
- const PRIMITIVE_TOPOLOGY_RESERVED_BITS = MeshPipelineKey :: PRIMITIVE_TOPOLOGY_MASK_BITS << MeshPipelineKey :: PRIMITIVE_TOPOLOGY_SHIFT_BITS ;
373
+ const MSAA_RESERVED_BITS = MeshPipelineFlags :: MSAA_MASK_BITS << MeshPipelineFlags :: MSAA_SHIFT_BITS ;
374
+ const PRIMITIVE_TOPOLOGY_RESERVED_BITS = MeshPipelineFlags :: PRIMITIVE_TOPOLOGY_MASK_BITS << MeshPipelineFlags :: PRIMITIVE_TOPOLOGY_SHIFT_BITS ;
369
375
}
370
376
}
371
377
372
- impl MeshPipelineKey {
378
+ impl MeshPipelineFlags {
373
379
const MSAA_MASK_BITS : u32 = 0b111111 ;
374
380
const MSAA_SHIFT_BITS : u32 = 32 - 6 ;
375
381
const PRIMITIVE_TOPOLOGY_MASK_BITS : u32 = 0b111 ;
376
382
const PRIMITIVE_TOPOLOGY_SHIFT_BITS : u32 = Self :: MSAA_SHIFT_BITS - 3 ;
377
383
378
384
pub fn from_msaa_samples ( msaa_samples : u32 ) -> Self {
379
385
let msaa_bits = ( ( msaa_samples - 1 ) & Self :: MSAA_MASK_BITS ) << Self :: MSAA_SHIFT_BITS ;
380
- MeshPipelineKey :: from_bits ( msaa_bits) . unwrap ( )
386
+ MeshPipelineFlags :: from_bits ( msaa_bits) . unwrap ( )
381
387
}
382
388
383
389
pub fn msaa_samples ( & self ) -> u32 {
@@ -388,7 +394,7 @@ impl MeshPipelineKey {
388
394
let primitive_topology_bits = ( ( primitive_topology as u32 )
389
395
& Self :: PRIMITIVE_TOPOLOGY_MASK_BITS )
390
396
<< Self :: PRIMITIVE_TOPOLOGY_SHIFT_BITS ;
391
- MeshPipelineKey :: from_bits ( primitive_topology_bits) . unwrap ( )
397
+ MeshPipelineFlags :: from_bits ( primitive_topology_bits) . unwrap ( )
392
398
}
393
399
394
400
pub fn primitive_topology ( & self ) -> PrimitiveTopology {
@@ -408,70 +414,19 @@ impl MeshPipelineKey {
408
414
impl SpecializedPipeline for MeshPipeline {
409
415
type Key = MeshPipelineKey ;
410
416
411
- fn specialize ( & self , key : Self :: Key ) -> RenderPipelineDescriptor {
412
- let ( vertex_array_stride, vertex_attributes) =
413
- if key. contains ( MeshPipelineKey :: VERTEX_TANGENTS ) {
414
- (
415
- 48 ,
416
- vec ! [
417
- // Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
418
- VertexAttribute {
419
- format: VertexFormat :: Float32x3 ,
420
- offset: 12 ,
421
- shader_location: 0 ,
422
- } ,
423
- // Normal
424
- VertexAttribute {
425
- format: VertexFormat :: Float32x3 ,
426
- offset: 0 ,
427
- shader_location: 1 ,
428
- } ,
429
- // Uv (GOTCHA! uv is no longer third in the buffer due to how Mesh sorts attributes (alphabetically))
430
- VertexAttribute {
431
- format: VertexFormat :: Float32x2 ,
432
- offset: 40 ,
433
- shader_location: 2 ,
434
- } ,
435
- // Tangent
436
- VertexAttribute {
437
- format: VertexFormat :: Float32x4 ,
438
- offset: 24 ,
439
- shader_location: 3 ,
440
- } ,
441
- ] ,
442
- )
443
- } else {
444
- (
445
- 32 ,
446
- vec ! [
447
- // Position (GOTCHA! Vertex_Position isn't first in the buffer due to how Mesh sorts attributes (alphabetically))
448
- VertexAttribute {
449
- format: VertexFormat :: Float32x3 ,
450
- offset: 12 ,
451
- shader_location: 0 ,
452
- } ,
453
- // Normal
454
- VertexAttribute {
455
- format: VertexFormat :: Float32x3 ,
456
- offset: 0 ,
457
- shader_location: 1 ,
458
- } ,
459
- // Uv
460
- VertexAttribute {
461
- format: VertexFormat :: Float32x2 ,
462
- offset: 24 ,
463
- shader_location: 2 ,
464
- } ,
465
- ] ,
466
- )
467
- } ;
417
+ fn specialize ( & self , cache : & RenderPipelineCache , key : Self :: Key ) -> RenderPipelineDescriptor {
418
+ let vertex_layout = cache
419
+ . vertex_layout_cache
420
+ . get ( & key. vertex_layout_key )
421
+ . unwrap ( ) ;
422
+
468
423
let mut shader_defs = Vec :: new ( ) ;
469
- if key. contains ( MeshPipelineKey :: VERTEX_TANGENTS ) {
424
+ if key. flags . contains ( MeshPipelineFlags :: VERTEX_TANGENTS ) {
470
425
shader_defs. push ( String :: from ( "VERTEX_TANGENTS" ) ) ;
471
426
}
472
427
473
428
let ( label, blend, depth_write_enabled) ;
474
- if key. contains ( MeshPipelineKey :: TRANSPARENT_MAIN_PASS ) {
429
+ if key. flags . contains ( MeshPipelineFlags :: TRANSPARENT_MAIN_PASS ) {
475
430
label = "transparent_mesh_pipeline" . into ( ) ;
476
431
blend = Some ( BlendState :: ALPHA_BLENDING ) ;
477
432
// For the transparent pass, fragments that are closer will be alpha blended
@@ -494,11 +449,7 @@ impl SpecializedPipeline for MeshPipeline {
494
449
shader : MESH_SHADER_HANDLE . typed :: < Shader > ( ) ,
495
450
entry_point : "vertex" . into ( ) ,
496
451
shader_defs : shader_defs. clone ( ) ,
497
- buffers : vec ! [ VertexBufferLayout {
498
- array_stride: vertex_array_stride,
499
- step_mode: VertexStepMode :: Vertex ,
500
- attributes: vertex_attributes,
501
- } ] ,
452
+ buffers : vec ! [ vertex_layout. clone( ) ] ,
502
453
} ,
503
454
fragment : Some ( FragmentState {
504
455
shader : MESH_SHADER_HANDLE . typed :: < Shader > ( ) ,
@@ -517,7 +468,7 @@ impl SpecializedPipeline for MeshPipeline {
517
468
unclipped_depth : false ,
518
469
polygon_mode : PolygonMode :: Fill ,
519
470
conservative : false ,
520
- topology : key. primitive_topology ( ) ,
471
+ topology : key. flags . primitive_topology ( ) ,
521
472
strip_index_format : None ,
522
473
} ,
523
474
depth_stencil : Some ( DepthStencilState {
@@ -537,7 +488,7 @@ impl SpecializedPipeline for MeshPipeline {
537
488
} ,
538
489
} ) ,
539
490
multisample : MultisampleState {
540
- count : key. msaa_samples ( ) ,
491
+ count : key. flags . msaa_samples ( ) ,
541
492
mask : !0 ,
542
493
alpha_to_coverage_enabled : false ,
543
494
} ,
@@ -737,11 +688,11 @@ impl EntityRenderCommand for DrawMesh {
737
688
738
689
#[ cfg( test) ]
739
690
mod tests {
740
- use super :: MeshPipelineKey ;
691
+ use super :: MeshPipelineFlags ;
741
692
#[ test]
742
693
fn mesh_key_msaa_samples ( ) {
743
694
for i in 1 ..=64 {
744
- assert_eq ! ( MeshPipelineKey :: from_msaa_samples( i) . msaa_samples( ) , i) ;
695
+ assert_eq ! ( MeshPipelineFlags :: from_msaa_samples( i) . msaa_samples( ) , i) ;
745
696
}
746
697
}
747
698
}
0 commit comments