@@ -28,11 +28,12 @@ use bevy_ecs::{
2828 relationship:: RelationshipSourceCollection ,
2929 system:: { lifetimeless:: * , SystemParamItem } ,
3030} ;
31- use bevy_image:: { BevyDefault , ImageSampler , TextureFormatPixelInfo } ;
31+ use bevy_image:: { ImageSampler , TextureFormatPixelInfo } ;
3232use bevy_light:: {
3333 EnvironmentMapLight , IrradianceVolume , NotShadowCaster , NotShadowReceiver ,
3434 ShadowFilteringMethod , TransmittedShadowReceiver ,
3535} ;
36+ use bevy_log:: warn_once;
3637use bevy_math:: { Affine3 , Affine3Ext , Rect , UVec2 , Vec3 , Vec4 } ;
3738use bevy_mesh:: {
3839 skinning:: SkinnedMesh , BaseMeshPipelineKey , Mesh , Mesh3d , MeshTag , MeshVertexBufferLayoutRef ,
@@ -401,10 +402,12 @@ pub fn check_views_need_specialization(
401402 has_ssr,
402403 ) in views. iter_mut ( )
403404 {
404- // HACK: we should be specializing by texture format, not bool hdr, but mesh pipeline keys have limited space.
405405 let is_hdr = view. texture_format == ViewTarget :: TEXTURE_FORMAT_HDR ;
406406 let mut view_key =
407407 MeshPipelineKey :: from_msaa_samples ( msaa. samples ( ) ) | MeshPipelineKey :: from_hdr ( is_hdr) ;
408+ if !is_hdr {
409+ view_key |= MeshPipelineKey :: sdr_color_attachment_format_bits ( view. texture_format ) ;
410+ }
408411
409412 if normal_prepass {
410413 view_key |= MeshPipelineKey :: NORMAL_PREPASS ;
@@ -3108,13 +3111,16 @@ bitflags::bitflags! {
31083111 const SCREEN_SPACE_SPECULAR_TRANSMISSION_MEDIUM = 1 << Self :: SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS ;
31093112 const SCREEN_SPACE_SPECULAR_TRANSMISSION_HIGH = 2 << Self :: SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS ;
31103113 const SCREEN_SPACE_SPECULAR_TRANSMISSION_ULTRA = 3 << Self :: SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS ;
3114+ const SDR_COLOR_ATTACHMENT_FORMAT_RESERVED_BITS = Self :: SDR_COLOR_ATTACHMENT_FORMAT_MASK_BITS
3115+ << Self :: SDR_COLOR_ATTACHMENT_FORMAT_SHIFT_BITS ;
31113116 const ALL_RESERVED_BITS =
31123117 Self :: BLEND_RESERVED_BITS . bits( ) |
31133118 Self :: MSAA_RESERVED_BITS . bits( ) |
31143119 Self :: TONEMAP_METHOD_RESERVED_BITS . bits( ) |
31153120 Self :: SHADOW_FILTER_METHOD_RESERVED_BITS . bits( ) |
31163121 Self :: VIEW_PROJECTION_RESERVED_BITS . bits( ) |
3117- Self :: SCREEN_SPACE_SPECULAR_TRANSMISSION_RESERVED_BITS . bits( ) ;
3122+ Self :: SCREEN_SPACE_SPECULAR_TRANSMISSION_RESERVED_BITS . bits( ) |
3123+ Self :: SDR_COLOR_ATTACHMENT_FORMAT_RESERVED_BITS . bits( ) ;
31183124 }
31193125}
31203126
@@ -3142,6 +3148,11 @@ impl MeshPipelineKey {
31423148 const SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS : u64 =
31433149 Self :: VIEW_PROJECTION_MASK_BITS . count_ones ( ) as u64 + Self :: VIEW_PROJECTION_SHIFT_BITS ;
31443150
3151+ const SDR_COLOR_ATTACHMENT_FORMAT_MASK_BITS : u64 = 0b11 ;
3152+ const SDR_COLOR_ATTACHMENT_FORMAT_SHIFT_BITS : u64 =
3153+ Self :: SCREEN_SPACE_SPECULAR_TRANSMISSION_MASK_BITS . count_ones ( ) as u64
3154+ + Self :: SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS ;
3155+
31453156 pub fn from_msaa_samples ( msaa_samples : u32 ) -> Self {
31463157 let msaa_bits =
31473158 ( msaa_samples. trailing_zeros ( ) as u64 & Self :: MSAA_MASK_BITS ) << Self :: MSAA_SHIFT_BITS ;
@@ -3156,6 +3167,42 @@ impl MeshPipelineKey {
31563167 }
31573168 }
31583169
3170+ /// Returns the bits for [`ExtractedView::texture_format`] for non-HDR views
3171+ pub fn sdr_color_attachment_format_bits ( format : TextureFormat ) -> Self {
3172+ let code: u64 = match format {
3173+ TextureFormat :: Rgba8UnormSrgb => 0 ,
3174+ TextureFormat :: Bgra8UnormSrgb => 1 ,
3175+ TextureFormat :: Rgba8Unorm => 2 ,
3176+ _ => {
3177+ warn_once ! (
3178+ "Unknown main pass format {:?}, mesh pipeline uses Rgba8UnormSrgb" ,
3179+ format
3180+ ) ;
3181+ 0
3182+ }
3183+ } ;
3184+ Self :: from_bits_retain (
3185+ ( code & Self :: SDR_COLOR_ATTACHMENT_FORMAT_MASK_BITS )
3186+ << Self :: SDR_COLOR_ATTACHMENT_FORMAT_SHIFT_BITS ,
3187+ )
3188+ }
3189+
3190+ /// Color format of the main pass color attachment for this pipeline key.
3191+ pub fn main_pass_color_attachment_format ( & self ) -> TextureFormat {
3192+ if self . contains ( MeshPipelineKey :: HDR ) {
3193+ ViewTarget :: TEXTURE_FORMAT_HDR
3194+ } else {
3195+ let code = ( self . bits ( ) >> Self :: SDR_COLOR_ATTACHMENT_FORMAT_SHIFT_BITS )
3196+ & Self :: SDR_COLOR_ATTACHMENT_FORMAT_MASK_BITS ;
3197+ match code {
3198+ 0 => TextureFormat :: Rgba8UnormSrgb ,
3199+ 1 => TextureFormat :: Bgra8UnormSrgb ,
3200+ 2 => TextureFormat :: Rgba8Unorm ,
3201+ _ => TextureFormat :: Rgba8UnormSrgb ,
3202+ }
3203+ }
3204+ }
3205+
31593206 pub fn msaa_samples ( & self ) -> u32 {
31603207 1 << ( ( self . bits ( ) >> Self :: MSAA_SHIFT_BITS ) & Self :: MSAA_MASK_BITS )
31613208 }
@@ -3611,11 +3658,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
36113658 }
36123659 }
36133660
3614- let format = if key. contains ( MeshPipelineKey :: HDR ) {
3615- ViewTarget :: TEXTURE_FORMAT_HDR
3616- } else {
3617- TextureFormat :: bevy_default ( )
3618- } ;
3661+ let format = key. main_pass_color_attachment_format ( ) ;
36193662
36203663 // This is defined here so that custom shaders that use something other than
36213664 // the mesh binding from bevy_pbr::mesh_bindings can easily make use of this
0 commit comments