From 6c06900a1b7373d2fa46635f29f89b0bbfa997f8 Mon Sep 17 00:00:00 2001 From: Lain-dono Date: Mon, 29 Aug 2022 03:43:27 +0300 Subject: [PATCH 1/2] Use 3 bits of PipelineKey to store MSAA sample count --- crates/bevy_pbr/src/render/mesh.rs | 19 ++++++++++--------- crates/bevy_sprite/src/mesh2d/mesh.rs | 19 ++++++++++--------- crates/bevy_sprite/src/render/mod.rs | 15 ++++++++------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 3d70cfd110eb5..facf379f24ae0 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -500,35 +500,36 @@ impl MeshPipeline { bitflags::bitflags! { #[repr(transparent)] // NOTE: Apparently quadro drivers support up to 64x MSAA. - /// MSAA uses the highest 6 bits for the MSAA sample count - 1 to support up to 64x MSAA. + /// MSAA uses the highest 3 bits for the MSAA log2(sample count) to support up to 128x MSAA. pub struct MeshPipelineKey: u32 { const NONE = 0; const TRANSPARENT_MAIN_PASS = (1 << 0); - const MSAA_RESERVED_BITS = MeshPipelineKey::MSAA_MASK_BITS << MeshPipelineKey::MSAA_SHIFT_BITS; - const PRIMITIVE_TOPOLOGY_RESERVED_BITS = MeshPipelineKey::PRIMITIVE_TOPOLOGY_MASK_BITS << MeshPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS; + const MSAA_RESERVED_BITS = Self::MSAA_MASK_BITS << Self::MSAA_SHIFT_BITS; + const PRIMITIVE_TOPOLOGY_RESERVED_BITS = Self::PRIMITIVE_TOPOLOGY_MASK_BITS << Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS; } } impl MeshPipelineKey { - const MSAA_MASK_BITS: u32 = 0b111111; - const MSAA_SHIFT_BITS: u32 = 32 - 6; + const MSAA_MASK_BITS: u32 = 0b111; + const MSAA_SHIFT_BITS: u32 = 32 - Self::MSAA_MASK_BITS.count_ones(); const PRIMITIVE_TOPOLOGY_MASK_BITS: u32 = 0b111; const PRIMITIVE_TOPOLOGY_SHIFT_BITS: u32 = Self::MSAA_SHIFT_BITS - 3; pub fn from_msaa_samples(msaa_samples: u32) -> Self { - let msaa_bits = ((msaa_samples - 1) & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; - MeshPipelineKey::from_bits(msaa_bits).unwrap() + let msaa_bits = + (msaa_samples.trailing_zeros() & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; + Self::from_bits(msaa_bits).unwrap() } pub fn msaa_samples(&self) -> u32 { - ((self.bits >> Self::MSAA_SHIFT_BITS) & Self::MSAA_MASK_BITS) + 1 + 1 << ((self.bits >> Self::MSAA_SHIFT_BITS) & Self::MSAA_MASK_BITS) } pub fn from_primitive_topology(primitive_topology: PrimitiveTopology) -> Self { let primitive_topology_bits = ((primitive_topology as u32) & Self::PRIMITIVE_TOPOLOGY_MASK_BITS) << Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS; - MeshPipelineKey::from_bits(primitive_topology_bits).unwrap() + Self::from_bits(primitive_topology_bits).unwrap() } pub fn primitive_topology(&self) -> PrimitiveTopology { diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index 18513f0d5362d..54927a0077031 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -269,35 +269,36 @@ impl Mesh2dPipeline { bitflags::bitflags! { #[repr(transparent)] // NOTE: Apparently quadro drivers support up to 64x MSAA. - // MSAA uses the highest 6 bits for the MSAA sample count - 1 to support up to 64x MSAA. + // MSAA uses the highest 3 bits for the MSAA log2(sample count) to support up to 128x MSAA. // FIXME: make normals optional? pub struct Mesh2dPipelineKey: u32 { const NONE = 0; - const MSAA_RESERVED_BITS = Mesh2dPipelineKey::MSAA_MASK_BITS << Mesh2dPipelineKey::MSAA_SHIFT_BITS; - const PRIMITIVE_TOPOLOGY_RESERVED_BITS = Mesh2dPipelineKey::PRIMITIVE_TOPOLOGY_MASK_BITS << Mesh2dPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS; + const MSAA_RESERVED_BITS = Self::MSAA_MASK_BITS << Self::MSAA_SHIFT_BITS; + const PRIMITIVE_TOPOLOGY_RESERVED_BITS = Self::PRIMITIVE_TOPOLOGY_MASK_BITS << Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS; } } impl Mesh2dPipelineKey { - const MSAA_MASK_BITS: u32 = 0b111111; - const MSAA_SHIFT_BITS: u32 = 32 - 6; + const MSAA_MASK_BITS: u32 = 0b111; + const MSAA_SHIFT_BITS: u32 = 32 - Self::MSAA_MASK_BITS.count_ones(); const PRIMITIVE_TOPOLOGY_MASK_BITS: u32 = 0b111; const PRIMITIVE_TOPOLOGY_SHIFT_BITS: u32 = Self::MSAA_SHIFT_BITS - 3; pub fn from_msaa_samples(msaa_samples: u32) -> Self { - let msaa_bits = ((msaa_samples - 1) & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; - Mesh2dPipelineKey::from_bits(msaa_bits).unwrap() + let msaa_bits = + (msaa_samples.trailing_zeros() & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; + Self::from_bits(msaa_bits).unwrap() } pub fn msaa_samples(&self) -> u32 { - ((self.bits >> Self::MSAA_SHIFT_BITS) & Self::MSAA_MASK_BITS) + 1 + 1 << ((self.bits >> Self::MSAA_SHIFT_BITS) & Self::MSAA_MASK_BITS) } pub fn from_primitive_topology(primitive_topology: PrimitiveTopology) -> Self { let primitive_topology_bits = ((primitive_topology as u32) & Self::PRIMITIVE_TOPOLOGY_MASK_BITS) << Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS; - Mesh2dPipelineKey::from_bits(primitive_topology_bits).unwrap() + Self::from_bits(primitive_topology_bits).unwrap() } pub fn primitive_topology(&self) -> PrimitiveTopology { diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index c2f98b2aab286..db1dc1a86d753 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -90,25 +90,26 @@ impl FromWorld for SpritePipeline { bitflags::bitflags! { #[repr(transparent)] // NOTE: Apparently quadro drivers support up to 64x MSAA. - // MSAA uses the highest 6 bits for the MSAA sample count - 1 to support up to 64x MSAA. + // MSAA uses the highest 3 bits for the MSAA log2(sample count) to support up to 128x MSAA. pub struct SpritePipelineKey: u32 { const NONE = 0; const COLORED = (1 << 0); - const MSAA_RESERVED_BITS = SpritePipelineKey::MSAA_MASK_BITS << SpritePipelineKey::MSAA_SHIFT_BITS; + const MSAA_RESERVED_BITS = Self::MSAA_MASK_BITS << Self::MSAA_SHIFT_BITS; } } impl SpritePipelineKey { - const MSAA_MASK_BITS: u32 = 0b111111; - const MSAA_SHIFT_BITS: u32 = 32 - 6; + const MSAA_MASK_BITS: u32 = 0b111; + const MSAA_SHIFT_BITS: u32 = 32 - Self::MSAA_MASK_BITS.count_ones(); pub fn from_msaa_samples(msaa_samples: u32) -> Self { - let msaa_bits = ((msaa_samples - 1) & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; - SpritePipelineKey::from_bits(msaa_bits).unwrap() + let msaa_bits = + (msaa_samples.trailing_zeros() & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; + Self::from_bits(msaa_bits).unwrap() } pub fn msaa_samples(&self) -> u32 { - ((self.bits >> Self::MSAA_SHIFT_BITS) & Self::MSAA_MASK_BITS) + 1 + 1 << ((self.bits >> Self::MSAA_SHIFT_BITS) & Self::MSAA_MASK_BITS) } } From 56b69f6aa814222f15033e9dd68f9351348df872 Mon Sep 17 00:00:00 2001 From: Lain-dono Date: Mon, 29 Aug 2022 04:56:33 +0300 Subject: [PATCH 2/2] fix bevy_pbr::render::mesh::tests::mesh_key_msaa_samples --- crates/bevy_pbr/src/render/mesh.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index facf379f24ae0..f5e9a9ae8519b 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -924,7 +924,7 @@ mod tests { use super::MeshPipelineKey; #[test] fn mesh_key_msaa_samples() { - for i in 1..=64 { + for i in [1, 2, 4, 8, 16, 32, 64, 128] { assert_eq!(MeshPipelineKey::from_msaa_samples(i).msaa_samples(), i); } }