use a u64 for MeshPipelineKey (#13015)
# Objective - `MeshPipelineKey` use some bits for two things - First commit in this PR adds an assertion that doesn't work currently on main - This leads to some mesh topology not working anymore, for example `LineStrip` - With examples `lines`, there should be two groups of lines, the blue one doesn't display currently ## Solution - Change the `MeshPipelineKey` to be backed by a `u64` instead, to have enough bits
This commit is contained in:
parent
13cac2eeff
commit
c40b485095
@ -1031,7 +1031,7 @@ bitflags::bitflags! {
|
||||
#[repr(transparent)]
|
||||
// NOTE: Apparently quadro drivers 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 {
|
||||
pub struct MeshPipelineKey: u64 {
|
||||
// Nothing
|
||||
const NONE = 0;
|
||||
|
||||
@ -1058,13 +1058,13 @@ bitflags::bitflags! {
|
||||
const LAST_FLAG = Self::IRRADIANCE_VOLUME.bits();
|
||||
|
||||
// Bitfields
|
||||
const BLEND_RESERVED_BITS = Self::BLEND_MASK_BITS << Self::BLEND_SHIFT_BITS; // ← Bitmask reserving bits for the blend state
|
||||
const BLEND_OPAQUE = 0 << Self::BLEND_SHIFT_BITS; // ← Values are just sequential within the mask, and can range from 0 to 3
|
||||
const BLEND_PREMULTIPLIED_ALPHA = 1 << Self::BLEND_SHIFT_BITS; //
|
||||
const BLEND_MULTIPLY = 2 << Self::BLEND_SHIFT_BITS; // ← We still have room for one more value without adding more bits
|
||||
const BLEND_ALPHA = 3 << Self::BLEND_SHIFT_BITS;
|
||||
const BLEND_ALPHA_TO_COVERAGE = 4 << Self::BLEND_SHIFT_BITS;
|
||||
const MSAA_RESERVED_BITS = Self::MSAA_MASK_BITS << Self::MSAA_SHIFT_BITS;
|
||||
const BLEND_RESERVED_BITS = Self::BLEND_MASK_BITS << Self::BLEND_SHIFT_BITS; // ← Bitmask reserving bits for the blend state
|
||||
const BLEND_OPAQUE = 0 << Self::BLEND_SHIFT_BITS; // ← Values are just sequential within the mask
|
||||
const BLEND_PREMULTIPLIED_ALPHA = 1 << Self::BLEND_SHIFT_BITS; // ← As blend states is on 3 bits, it can range from 0 to 7
|
||||
const BLEND_MULTIPLY = 2 << Self::BLEND_SHIFT_BITS; // ← See `BLEND_MASK_BITS` for the number of bits available
|
||||
const BLEND_ALPHA = 3 << Self::BLEND_SHIFT_BITS; //
|
||||
const BLEND_ALPHA_TO_COVERAGE = 4 << Self::BLEND_SHIFT_BITS; // ← We still have room for three more values without adding more bits
|
||||
const TONEMAP_METHOD_RESERVED_BITS = Self::TONEMAP_METHOD_MASK_BITS << Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||
const TONEMAP_METHOD_NONE = 0 << Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||
const TONEMAP_METHOD_REINHARD = 1 << Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||
@ -1099,31 +1099,32 @@ bitflags::bitflags! {
|
||||
}
|
||||
|
||||
impl MeshPipelineKey {
|
||||
const MSAA_MASK_BITS: u32 = 0b111;
|
||||
const MSAA_SHIFT_BITS: u32 = Self::LAST_FLAG.bits().trailing_zeros() + 1;
|
||||
const MSAA_MASK_BITS: u64 = 0b111;
|
||||
const MSAA_SHIFT_BITS: u64 = Self::LAST_FLAG.bits().trailing_zeros() as u64 + 1;
|
||||
|
||||
const BLEND_MASK_BITS: u32 = 0b111;
|
||||
const BLEND_SHIFT_BITS: u32 = Self::MSAA_MASK_BITS.count_ones() + Self::MSAA_SHIFT_BITS;
|
||||
const BLEND_MASK_BITS: u64 = 0b111;
|
||||
const BLEND_SHIFT_BITS: u64 = Self::MSAA_MASK_BITS.count_ones() as u64 + Self::MSAA_SHIFT_BITS;
|
||||
|
||||
const TONEMAP_METHOD_MASK_BITS: u32 = 0b111;
|
||||
const TONEMAP_METHOD_SHIFT_BITS: u32 =
|
||||
Self::BLEND_MASK_BITS.count_ones() + Self::BLEND_SHIFT_BITS;
|
||||
const TONEMAP_METHOD_MASK_BITS: u64 = 0b111;
|
||||
const TONEMAP_METHOD_SHIFT_BITS: u64 =
|
||||
Self::BLEND_MASK_BITS.count_ones() as u64 + Self::BLEND_SHIFT_BITS;
|
||||
|
||||
const SHADOW_FILTER_METHOD_MASK_BITS: u32 = 0b11;
|
||||
const SHADOW_FILTER_METHOD_SHIFT_BITS: u32 =
|
||||
Self::TONEMAP_METHOD_MASK_BITS.count_ones() + Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||
const SHADOW_FILTER_METHOD_MASK_BITS: u64 = 0b11;
|
||||
const SHADOW_FILTER_METHOD_SHIFT_BITS: u64 =
|
||||
Self::TONEMAP_METHOD_MASK_BITS.count_ones() as u64 + Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||
|
||||
const VIEW_PROJECTION_MASK_BITS: u32 = 0b11;
|
||||
const VIEW_PROJECTION_SHIFT_BITS: u32 =
|
||||
Self::SHADOW_FILTER_METHOD_MASK_BITS.count_ones() + Self::SHADOW_FILTER_METHOD_SHIFT_BITS;
|
||||
const VIEW_PROJECTION_MASK_BITS: u64 = 0b11;
|
||||
const VIEW_PROJECTION_SHIFT_BITS: u64 = Self::SHADOW_FILTER_METHOD_MASK_BITS.count_ones()
|
||||
as u64
|
||||
+ Self::SHADOW_FILTER_METHOD_SHIFT_BITS;
|
||||
|
||||
const SCREEN_SPACE_SPECULAR_TRANSMISSION_MASK_BITS: u32 = 0b11;
|
||||
const SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS: u32 =
|
||||
Self::VIEW_PROJECTION_MASK_BITS.count_ones() + Self::VIEW_PROJECTION_SHIFT_BITS;
|
||||
const SCREEN_SPACE_SPECULAR_TRANSMISSION_MASK_BITS: u64 = 0b11;
|
||||
const SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS: u64 =
|
||||
Self::VIEW_PROJECTION_MASK_BITS.count_ones() as u64 + Self::VIEW_PROJECTION_SHIFT_BITS;
|
||||
|
||||
pub fn from_msaa_samples(msaa_samples: u32) -> Self {
|
||||
let msaa_bits =
|
||||
(msaa_samples.trailing_zeros() & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS;
|
||||
(msaa_samples.trailing_zeros() as u64 & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS;
|
||||
Self::from_bits_retain(msaa_bits)
|
||||
}
|
||||
|
||||
@ -1140,7 +1141,7 @@ impl MeshPipelineKey {
|
||||
}
|
||||
|
||||
pub fn from_primitive_topology(primitive_topology: PrimitiveTopology) -> Self {
|
||||
let primitive_topology_bits = ((primitive_topology as u32)
|
||||
let primitive_topology_bits = ((primitive_topology as u64)
|
||||
& BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_MASK_BITS)
|
||||
<< BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
|
||||
Self::from_bits_retain(primitive_topology_bits)
|
||||
@ -1151,11 +1152,11 @@ impl MeshPipelineKey {
|
||||
>> BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS)
|
||||
& BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_MASK_BITS;
|
||||
match primitive_topology_bits {
|
||||
x if x == PrimitiveTopology::PointList as u32 => PrimitiveTopology::PointList,
|
||||
x if x == PrimitiveTopology::LineList as u32 => PrimitiveTopology::LineList,
|
||||
x if x == PrimitiveTopology::LineStrip as u32 => PrimitiveTopology::LineStrip,
|
||||
x if x == PrimitiveTopology::TriangleList as u32 => PrimitiveTopology::TriangleList,
|
||||
x if x == PrimitiveTopology::TriangleStrip as u32 => PrimitiveTopology::TriangleStrip,
|
||||
x if x == PrimitiveTopology::PointList as u64 => PrimitiveTopology::PointList,
|
||||
x if x == PrimitiveTopology::LineList as u64 => PrimitiveTopology::LineList,
|
||||
x if x == PrimitiveTopology::LineStrip as u64 => PrimitiveTopology::LineStrip,
|
||||
x if x == PrimitiveTopology::TriangleList as u64 => PrimitiveTopology::TriangleList,
|
||||
x if x == PrimitiveTopology::TriangleStrip as u64 => PrimitiveTopology::TriangleStrip,
|
||||
_ => PrimitiveTopology::default(),
|
||||
}
|
||||
}
|
||||
@ -1168,6 +1169,14 @@ const_assert_eq!(
|
||||
0
|
||||
);
|
||||
|
||||
// Ensure that the reserved bits don't overlap with the topology bits
|
||||
const_assert_eq!(
|
||||
(BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_MASK_BITS
|
||||
<< BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS)
|
||||
& MeshPipelineKey::ALL_RESERVED_BITS.bits(),
|
||||
0
|
||||
);
|
||||
|
||||
fn is_skinned(layout: &MeshVertexBufferLayoutRef) -> bool {
|
||||
layout.0.contains(Mesh::ATTRIBUTE_JOINT_INDEX)
|
||||
&& layout.0.contains(Mesh::ATTRIBUTE_JOINT_WEIGHT)
|
||||
|
||||
@ -1401,18 +1401,18 @@ bitflags! {
|
||||
/// go upward. This allows the PBR bits in the downstream crate `bevy_pbr`
|
||||
/// to coexist in the same field without any shifts.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BaseMeshPipelineKey: u32 {
|
||||
const MORPH_TARGETS = 1 << 31;
|
||||
pub struct BaseMeshPipelineKey: u64 {
|
||||
const MORPH_TARGETS = 1 << (u64::BITS - 1);
|
||||
}
|
||||
}
|
||||
|
||||
impl BaseMeshPipelineKey {
|
||||
pub const PRIMITIVE_TOPOLOGY_MASK_BITS: u32 = 0b111;
|
||||
pub const PRIMITIVE_TOPOLOGY_SHIFT_BITS: u32 =
|
||||
31 - Self::PRIMITIVE_TOPOLOGY_MASK_BITS.count_ones();
|
||||
pub const PRIMITIVE_TOPOLOGY_MASK_BITS: u64 = 0b111;
|
||||
pub const PRIMITIVE_TOPOLOGY_SHIFT_BITS: u64 =
|
||||
(u64::BITS - 1 - Self::PRIMITIVE_TOPOLOGY_MASK_BITS.count_ones()) as u64;
|
||||
|
||||
pub fn from_primitive_topology(primitive_topology: PrimitiveTopology) -> Self {
|
||||
let primitive_topology_bits = ((primitive_topology as u32)
|
||||
let primitive_topology_bits = ((primitive_topology as u64)
|
||||
& Self::PRIMITIVE_TOPOLOGY_MASK_BITS)
|
||||
<< Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
|
||||
Self::from_bits_retain(primitive_topology_bits)
|
||||
@ -1422,11 +1422,11 @@ impl BaseMeshPipelineKey {
|
||||
let primitive_topology_bits = (self.bits() >> Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS)
|
||||
& Self::PRIMITIVE_TOPOLOGY_MASK_BITS;
|
||||
match primitive_topology_bits {
|
||||
x if x == PrimitiveTopology::PointList as u32 => PrimitiveTopology::PointList,
|
||||
x if x == PrimitiveTopology::LineList as u32 => PrimitiveTopology::LineList,
|
||||
x if x == PrimitiveTopology::LineStrip as u32 => PrimitiveTopology::LineStrip,
|
||||
x if x == PrimitiveTopology::TriangleList as u32 => PrimitiveTopology::TriangleList,
|
||||
x if x == PrimitiveTopology::TriangleStrip as u32 => PrimitiveTopology::TriangleStrip,
|
||||
x if x == PrimitiveTopology::PointList as u64 => PrimitiveTopology::PointList,
|
||||
x if x == PrimitiveTopology::LineList as u64 => PrimitiveTopology::LineList,
|
||||
x if x == PrimitiveTopology::LineStrip as u64 => PrimitiveTopology::LineStrip,
|
||||
x if x == PrimitiveTopology::TriangleList as u64 => PrimitiveTopology::TriangleList,
|
||||
x if x == PrimitiveTopology::TriangleStrip as u64 => PrimitiveTopology::TriangleStrip,
|
||||
_ => PrimitiveTopology::default(),
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user