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)]
|
#[repr(transparent)]
|
||||||
// NOTE: Apparently quadro drivers support up to 64x MSAA.
|
// 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.
|
/// 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
|
// Nothing
|
||||||
const NONE = 0;
|
const NONE = 0;
|
||||||
|
|
||||||
@ -1058,13 +1058,13 @@ bitflags::bitflags! {
|
|||||||
const LAST_FLAG = Self::IRRADIANCE_VOLUME.bits();
|
const LAST_FLAG = Self::IRRADIANCE_VOLUME.bits();
|
||||||
|
|
||||||
// Bitfields
|
// 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 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_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_NONE = 0 << Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||||
const TONEMAP_METHOD_REINHARD = 1 << Self::TONEMAP_METHOD_SHIFT_BITS;
|
const TONEMAP_METHOD_REINHARD = 1 << Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||||
@ -1099,31 +1099,32 @@ bitflags::bitflags! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MeshPipelineKey {
|
impl MeshPipelineKey {
|
||||||
const MSAA_MASK_BITS: u32 = 0b111;
|
const MSAA_MASK_BITS: u64 = 0b111;
|
||||||
const MSAA_SHIFT_BITS: u32 = Self::LAST_FLAG.bits().trailing_zeros() + 1;
|
const MSAA_SHIFT_BITS: u64 = Self::LAST_FLAG.bits().trailing_zeros() as u64 + 1;
|
||||||
|
|
||||||
const BLEND_MASK_BITS: u32 = 0b111;
|
const BLEND_MASK_BITS: u64 = 0b111;
|
||||||
const BLEND_SHIFT_BITS: u32 = Self::MSAA_MASK_BITS.count_ones() + Self::MSAA_SHIFT_BITS;
|
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_MASK_BITS: u64 = 0b111;
|
||||||
const TONEMAP_METHOD_SHIFT_BITS: u32 =
|
const TONEMAP_METHOD_SHIFT_BITS: u64 =
|
||||||
Self::BLEND_MASK_BITS.count_ones() + Self::BLEND_SHIFT_BITS;
|
Self::BLEND_MASK_BITS.count_ones() as u64 + Self::BLEND_SHIFT_BITS;
|
||||||
|
|
||||||
const SHADOW_FILTER_METHOD_MASK_BITS: u32 = 0b11;
|
const SHADOW_FILTER_METHOD_MASK_BITS: u64 = 0b11;
|
||||||
const SHADOW_FILTER_METHOD_SHIFT_BITS: u32 =
|
const SHADOW_FILTER_METHOD_SHIFT_BITS: u64 =
|
||||||
Self::TONEMAP_METHOD_MASK_BITS.count_ones() + Self::TONEMAP_METHOD_SHIFT_BITS;
|
Self::TONEMAP_METHOD_MASK_BITS.count_ones() as u64 + Self::TONEMAP_METHOD_SHIFT_BITS;
|
||||||
|
|
||||||
const VIEW_PROJECTION_MASK_BITS: u32 = 0b11;
|
const VIEW_PROJECTION_MASK_BITS: u64 = 0b11;
|
||||||
const VIEW_PROJECTION_SHIFT_BITS: u32 =
|
const VIEW_PROJECTION_SHIFT_BITS: u64 = Self::SHADOW_FILTER_METHOD_MASK_BITS.count_ones()
|
||||||
Self::SHADOW_FILTER_METHOD_MASK_BITS.count_ones() + Self::SHADOW_FILTER_METHOD_SHIFT_BITS;
|
as u64
|
||||||
|
+ Self::SHADOW_FILTER_METHOD_SHIFT_BITS;
|
||||||
|
|
||||||
const SCREEN_SPACE_SPECULAR_TRANSMISSION_MASK_BITS: u32 = 0b11;
|
const SCREEN_SPACE_SPECULAR_TRANSMISSION_MASK_BITS: u64 = 0b11;
|
||||||
const SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS: u32 =
|
const SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS: u64 =
|
||||||
Self::VIEW_PROJECTION_MASK_BITS.count_ones() + Self::VIEW_PROJECTION_SHIFT_BITS;
|
Self::VIEW_PROJECTION_MASK_BITS.count_ones() as u64 + Self::VIEW_PROJECTION_SHIFT_BITS;
|
||||||
|
|
||||||
pub fn from_msaa_samples(msaa_samples: u32) -> Self {
|
pub fn from_msaa_samples(msaa_samples: u32) -> Self {
|
||||||
let msaa_bits =
|
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)
|
Self::from_bits_retain(msaa_bits)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1140,7 +1141,7 @@ impl MeshPipelineKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_primitive_topology(primitive_topology: PrimitiveTopology) -> Self {
|
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_MASK_BITS)
|
||||||
<< BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
|
<< BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
|
||||||
Self::from_bits_retain(primitive_topology_bits)
|
Self::from_bits_retain(primitive_topology_bits)
|
||||||
@ -1151,11 +1152,11 @@ impl MeshPipelineKey {
|
|||||||
>> BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS)
|
>> BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_SHIFT_BITS)
|
||||||
& BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_MASK_BITS;
|
& BaseMeshPipelineKey::PRIMITIVE_TOPOLOGY_MASK_BITS;
|
||||||
match primitive_topology_bits {
|
match primitive_topology_bits {
|
||||||
x if x == PrimitiveTopology::PointList as u32 => PrimitiveTopology::PointList,
|
x if x == PrimitiveTopology::PointList as u64 => PrimitiveTopology::PointList,
|
||||||
x if x == PrimitiveTopology::LineList as u32 => PrimitiveTopology::LineList,
|
x if x == PrimitiveTopology::LineList as u64 => PrimitiveTopology::LineList,
|
||||||
x if x == PrimitiveTopology::LineStrip as u32 => PrimitiveTopology::LineStrip,
|
x if x == PrimitiveTopology::LineStrip as u64 => PrimitiveTopology::LineStrip,
|
||||||
x if x == PrimitiveTopology::TriangleList as u32 => PrimitiveTopology::TriangleList,
|
x if x == PrimitiveTopology::TriangleList as u64 => PrimitiveTopology::TriangleList,
|
||||||
x if x == PrimitiveTopology::TriangleStrip as u32 => PrimitiveTopology::TriangleStrip,
|
x if x == PrimitiveTopology::TriangleStrip as u64 => PrimitiveTopology::TriangleStrip,
|
||||||
_ => PrimitiveTopology::default(),
|
_ => PrimitiveTopology::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1168,6 +1169,14 @@ const_assert_eq!(
|
|||||||
0
|
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 {
|
fn is_skinned(layout: &MeshVertexBufferLayoutRef) -> bool {
|
||||||
layout.0.contains(Mesh::ATTRIBUTE_JOINT_INDEX)
|
layout.0.contains(Mesh::ATTRIBUTE_JOINT_INDEX)
|
||||||
&& layout.0.contains(Mesh::ATTRIBUTE_JOINT_WEIGHT)
|
&& 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`
|
/// go upward. This allows the PBR bits in the downstream crate `bevy_pbr`
|
||||||
/// to coexist in the same field without any shifts.
|
/// to coexist in the same field without any shifts.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct BaseMeshPipelineKey: u32 {
|
pub struct BaseMeshPipelineKey: u64 {
|
||||||
const MORPH_TARGETS = 1 << 31;
|
const MORPH_TARGETS = 1 << (u64::BITS - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BaseMeshPipelineKey {
|
impl BaseMeshPipelineKey {
|
||||||
pub const PRIMITIVE_TOPOLOGY_MASK_BITS: u32 = 0b111;
|
pub const PRIMITIVE_TOPOLOGY_MASK_BITS: u64 = 0b111;
|
||||||
pub const PRIMITIVE_TOPOLOGY_SHIFT_BITS: u32 =
|
pub const PRIMITIVE_TOPOLOGY_SHIFT_BITS: u64 =
|
||||||
31 - Self::PRIMITIVE_TOPOLOGY_MASK_BITS.count_ones();
|
(u64::BITS - 1 - Self::PRIMITIVE_TOPOLOGY_MASK_BITS.count_ones()) as u64;
|
||||||
|
|
||||||
pub fn from_primitive_topology(primitive_topology: PrimitiveTopology) -> Self {
|
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_MASK_BITS)
|
||||||
<< Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
|
<< Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS;
|
||||||
Self::from_bits_retain(primitive_topology_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)
|
let primitive_topology_bits = (self.bits() >> Self::PRIMITIVE_TOPOLOGY_SHIFT_BITS)
|
||||||
& Self::PRIMITIVE_TOPOLOGY_MASK_BITS;
|
& Self::PRIMITIVE_TOPOLOGY_MASK_BITS;
|
||||||
match primitive_topology_bits {
|
match primitive_topology_bits {
|
||||||
x if x == PrimitiveTopology::PointList as u32 => PrimitiveTopology::PointList,
|
x if x == PrimitiveTopology::PointList as u64 => PrimitiveTopology::PointList,
|
||||||
x if x == PrimitiveTopology::LineList as u32 => PrimitiveTopology::LineList,
|
x if x == PrimitiveTopology::LineList as u64 => PrimitiveTopology::LineList,
|
||||||
x if x == PrimitiveTopology::LineStrip as u32 => PrimitiveTopology::LineStrip,
|
x if x == PrimitiveTopology::LineStrip as u64 => PrimitiveTopology::LineStrip,
|
||||||
x if x == PrimitiveTopology::TriangleList as u32 => PrimitiveTopology::TriangleList,
|
x if x == PrimitiveTopology::TriangleList as u64 => PrimitiveTopology::TriangleList,
|
||||||
x if x == PrimitiveTopology::TriangleStrip as u32 => PrimitiveTopology::TriangleStrip,
|
x if x == PrimitiveTopology::TriangleStrip as u64 => PrimitiveTopology::TriangleStrip,
|
||||||
_ => PrimitiveTopology::default(),
|
_ => PrimitiveTopology::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user