Skip to content

Commit 9df57ec

Browse files
atlv24beicause
andcommitted
Add more bits to MeshPipelineKey for TextureFormat
Co-authored-by: Luo Zhihao <luo_zhihao@outlook.com>
1 parent 93047ce commit 9df57ec

10 files changed

Lines changed: 138 additions & 144 deletions

File tree

crates/bevy_gizmos_render/src/pipeline_2d.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ use bevy_ecs::{
1515
schedule::IntoScheduleConfigs,
1616
system::{Commands, Query, Res, ResMut},
1717
};
18-
use bevy_image::BevyDefault as _;
1918
use bevy_math::FloatOrd;
2019
use bevy_render::{
2120
render_asset::{prepare_assets, RenderAssets},
@@ -24,7 +23,7 @@ use bevy_render::{
2423
ViewSortedRenderPhases,
2524
},
2625
render_resource::*,
27-
view::{ExtractedView, Msaa, ViewTarget},
26+
view::{ExtractedView, Msaa},
2827
Render, RenderApp, RenderSystems,
2928
};
3029
use bevy_render::{GpuResourceAppExt, RenderStartup};
@@ -111,11 +110,7 @@ impl SpecializedRenderPipeline for LineGizmoPipeline {
111110
type Key = LineGizmoPipelineKey;
112111

113112
fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
114-
let format = if key.mesh_key.contains(Mesh2dPipelineKey::HDR) {
115-
ViewTarget::TEXTURE_FORMAT_HDR
116-
} else {
117-
TextureFormat::bevy_default()
118-
};
113+
let format = key.mesh_key.color_target_format();
119114

120115
let shader_defs = vec![
121116
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
@@ -196,11 +191,7 @@ impl SpecializedRenderPipeline for LineJointGizmoPipeline {
196191
type Key = LineJointGizmoPipelineKey;
197192

198193
fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
199-
let format = if key.mesh_key.contains(Mesh2dPipelineKey::HDR) {
200-
ViewTarget::TEXTURE_FORMAT_HDR
201-
} else {
202-
TextureFormat::bevy_default()
203-
};
194+
let format = key.mesh_key.color_target_format();
204195

205196
let shader_defs = vec![
206197
#[cfg(all(feature = "webgl", target_arch = "wasm32", not(feature = "webgpu")))]
@@ -316,11 +307,8 @@ fn queue_line_and_joint_gizmos_2d(
316307
continue;
317308
};
318309

319-
// HACK: we should be specializing by texture format, not bool hdr, but mesh pipeline keys have limited space.
320-
let is_hdr = view.texture_format == ViewTarget::TEXTURE_FORMAT_HDR;
321-
322310
let mesh_key = Mesh2dPipelineKey::from_msaa_samples(msaa.samples())
323-
| Mesh2dPipelineKey::from_hdr(is_hdr);
311+
| Mesh2dPipelineKey::from_color_target_format(view.texture_format);
324312

325313
let render_layers = render_layers.unwrap_or_default();
326314
for (entity, config) in &line_gizmos {

crates/bevy_gizmos_render/src/pipeline_3d.rs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use bevy_ecs::{
1616
schedule::IntoScheduleConfigs,
1717
system::{Commands, Query, Res, ResMut},
1818
};
19-
use bevy_image::BevyDefault as _;
2019
use bevy_pbr::{
2120
MeshPipeline, MeshPipelineKey, MeshPipelineSet, SetMeshViewBindGroup, ViewKeyCache,
2221
};
@@ -27,7 +26,7 @@ use bevy_render::{
2726
ViewSortedRenderPhases,
2827
},
2928
render_resource::*,
30-
view::{ExtractedView, ViewTarget},
29+
view::ExtractedView,
3130
Render, RenderApp, RenderSystems,
3231
};
3332
use bevy_render::{sync_world::MainEntity, GpuResourceAppExt, RenderStartup};
@@ -155,11 +154,7 @@ impl Specializer<RenderPipeline> for LineGizmoPipelineSpecializer {
155154
fragment.shader_defs.push("PERSPECTIVE".into());
156155
}
157156

158-
let format = if key.view_key.contains(MeshPipelineKey::HDR) {
159-
ViewTarget::TEXTURE_FORMAT_HDR
160-
} else {
161-
TextureFormat::bevy_default()
162-
};
157+
let format = key.view_key.color_target_format();
163158

164159
let fragment_entry_point = match key.line_style {
165160
GizmoLineStyle::Solid => "fragment_solid",
@@ -210,11 +205,7 @@ impl SpecializedRenderPipeline for LineJointGizmoPipeline {
210205
shader_defs.push("PERSPECTIVE".into());
211206
}
212207

213-
let format = if key.view_key.contains(MeshPipelineKey::HDR) {
214-
ViewTarget::TEXTURE_FORMAT_HDR
215-
} else {
216-
TextureFormat::bevy_default()
217-
};
208+
let format = key.view_key.color_target_format();
218209

219210
let view_layout = self
220211
.mesh_pipeline

crates/bevy_pbr/src/deferred/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ impl SpecializedRenderPipeline for DeferredLightingLayout {
349349
shader: self.deferred_lighting_shader.clone(),
350350
shader_defs,
351351
targets: vec![Some(ColorTargetState {
352-
format: key.main_pass_color_attachment_format(),
352+
format: key.color_target_format(),
353353
blend: None,
354354
write_mask: ColorWrites::ALL,
355355
})],
@@ -462,10 +462,7 @@ pub fn prepare_deferred_lighting_pipelines(
462462
}
463463

464464
let is_hdr = view.texture_format == ViewTarget::TEXTURE_FORMAT_HDR;
465-
let mut view_key = MeshPipelineKey::from_hdr(is_hdr);
466-
if !is_hdr {
467-
view_key |= MeshPipelineKey::sdr_color_attachment_format_bits(view.texture_format);
468-
}
465+
let mut view_key = MeshPipelineKey::from_color_target_format(view.texture_format);
469466

470467
if normal_prepass {
471468
view_key |= MeshPipelineKey::NORMAL_PREPASS;

crates/bevy_pbr/src/meshlet/material_pipeline_prepare.rs

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,8 @@ pub fn prepare_material_meshlet_meshes_main_opaque_pass(
8383
) in &mut views
8484
{
8585
let is_hdr = view.texture_format == ViewTarget::TEXTURE_FORMAT_HDR;
86-
let mut view_key =
87-
MeshPipelineKey::from_msaa_samples(1) | MeshPipelineKey::from_hdr(is_hdr);
88-
if !is_hdr {
89-
view_key |= MeshPipelineKey::sdr_color_attachment_format_bits(view.texture_format);
90-
}
86+
let mut view_key = MeshPipelineKey::from_msaa_samples(1)
87+
| MeshPipelineKey::from_color_target_format(view.texture_format);
9188

9289
if normal_prepass {
9390
view_key |= MeshPipelineKey::NORMAL_PREPASS;
@@ -303,11 +300,8 @@ pub fn prepare_material_meshlet_meshes_prepass(
303300
) in &mut views
304301
{
305302
let is_hdr = view.texture_format == ViewTarget::TEXTURE_FORMAT_HDR;
306-
let mut view_key =
307-
MeshPipelineKey::from_msaa_samples(1) | MeshPipelineKey::from_hdr(is_hdr);
308-
if !is_hdr {
309-
view_key |= MeshPipelineKey::sdr_color_attachment_format_bits(view.texture_format);
310-
}
303+
let mut view_key = MeshPipelineKey::from_msaa_samples(1)
304+
| MeshPipelineKey::from_color_target_format(view.texture_format);
311305

312306
if normal_prepass.is_some() {
313307
view_key |= MeshPipelineKey::NORMAL_PREPASS;

crates/bevy_pbr/src/render/mesh.rs

Lines changed: 24 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ use bevy_light::{
3333
EnvironmentMapLight, IrradianceVolume, NotShadowCaster, NotShadowReceiver,
3434
ShadowFilteringMethod, TransmittedShadowReceiver,
3535
};
36-
use bevy_log::warn_once;
3736
use bevy_math::{Affine3, Affine3Ext, Rect, UVec2, Vec3, Vec4};
3837
use bevy_mesh::{
3938
skinning::SkinnedMesh, BaseMeshPipelineKey, Mesh, Mesh3d, MeshTag, MeshVertexBufferLayoutRef,
@@ -101,7 +100,10 @@ use bevy_core_pipeline::tonemapping::{DebandDither, Tonemapping};
101100
use bevy_render::camera::{DirtySpecializations, TemporalJitter};
102101
use bevy_render::prelude::Msaa;
103102
use bevy_render::sync_world::{MainEntity, MainEntityHashMap};
104-
use bevy_render::view::{ExtractedView, RenderShadowMapVisibleEntities, RenderVisibleEntities};
103+
use bevy_render::view::{
104+
color_target_format_from_code, color_target_format_to_code, ExtractedView,
105+
RenderShadowMapVisibleEntities, RenderVisibleEntities,
106+
};
105107
use bevy_render::RenderSystems::PrepareAssets;
106108
use bevy_tasks::ComputeTaskPool;
107109

@@ -403,11 +405,8 @@ pub fn check_views_need_specialization(
403405
) in views.iter_mut()
404406
{
405407
let is_hdr = view.texture_format == ViewTarget::TEXTURE_FORMAT_HDR;
406-
let mut view_key =
407-
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-
}
408+
let mut view_key = MeshPipelineKey::from_msaa_samples(msaa.samples())
409+
| MeshPipelineKey::from_color_target_format(view.texture_format);
411410

412411
if normal_prepass {
413412
view_key |= MeshPipelineKey::NORMAL_PREPASS;
@@ -3043,7 +3042,6 @@ bitflags::bitflags! {
30433042
const MORPH_TARGETS = BaseMeshPipelineKey::MORPH_TARGETS.bits();
30443043

30453044
// Flag bits
3046-
const HDR = 1 << 0;
30473045
const TONEMAP_IN_SHADER = 1 << 1;
30483046
const DEBAND_DITHER = 1 << 2;
30493047
const DEPTH_PREPASS = 1 << 3;
@@ -3111,16 +3109,16 @@ bitflags::bitflags! {
31113109
const SCREEN_SPACE_SPECULAR_TRANSMISSION_MEDIUM = 1 << Self::SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS;
31123110
const SCREEN_SPACE_SPECULAR_TRANSMISSION_HIGH = 2 << Self::SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS;
31133111
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;
3112+
const COLOR_TARGET_FORMAT_RESERVED_BITS = Self::COLOR_TARGET_FORMAT_MASK_BITS
3113+
<< Self::COLOR_TARGET_FORMAT_SHIFT_BITS;
31163114
const ALL_RESERVED_BITS =
31173115
Self::BLEND_RESERVED_BITS.bits() |
31183116
Self::MSAA_RESERVED_BITS.bits() |
31193117
Self::TONEMAP_METHOD_RESERVED_BITS.bits() |
31203118
Self::SHADOW_FILTER_METHOD_RESERVED_BITS.bits() |
31213119
Self::VIEW_PROJECTION_RESERVED_BITS.bits() |
31223120
Self::SCREEN_SPACE_SPECULAR_TRANSMISSION_RESERVED_BITS.bits() |
3123-
Self::SDR_COLOR_ATTACHMENT_FORMAT_RESERVED_BITS.bits();
3121+
Self::COLOR_TARGET_FORMAT_RESERVED_BITS.bits();
31243122
}
31253123
}
31263124

@@ -3148,8 +3146,8 @@ impl MeshPipelineKey {
31483146
const SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS: u64 =
31493147
Self::VIEW_PROJECTION_MASK_BITS.count_ones() as u64 + Self::VIEW_PROJECTION_SHIFT_BITS;
31503148

3151-
const SDR_COLOR_ATTACHMENT_FORMAT_MASK_BITS: u64 = 0b11;
3152-
const SDR_COLOR_ATTACHMENT_FORMAT_SHIFT_BITS: u64 =
3149+
const COLOR_TARGET_FORMAT_MASK_BITS: u64 = 0b1111;
3150+
const COLOR_TARGET_FORMAT_SHIFT_BITS: u64 =
31533151
Self::SCREEN_SPACE_SPECULAR_TRANSMISSION_MASK_BITS.count_ones() as u64
31543152
+ Self::SCREEN_SPACE_SPECULAR_TRANSMISSION_SHIFT_BITS;
31553153

@@ -3159,48 +3157,22 @@ impl MeshPipelineKey {
31593157
Self::from_bits_retain(msaa_bits)
31603158
}
31613159

3162-
pub fn from_hdr(hdr: bool) -> Self {
3163-
if hdr {
3164-
MeshPipelineKey::HDR
3165-
} else {
3166-
MeshPipelineKey::NONE
3167-
}
3168-
}
3169-
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-
};
3160+
/// Create a pipeline key from the view's color target format.
3161+
#[inline]
3162+
pub fn from_color_target_format(format: TextureFormat) -> Self {
3163+
let code = color_target_format_to_code(format) as u64;
31843164
Self::from_bits_retain(
3185-
(code & Self::SDR_COLOR_ATTACHMENT_FORMAT_MASK_BITS)
3186-
<< Self::SDR_COLOR_ATTACHMENT_FORMAT_SHIFT_BITS,
3165+
(code & Self::COLOR_TARGET_FORMAT_MASK_BITS)
3166+
<< Self::COLOR_TARGET_FORMAT_SHIFT_BITS,
31873167
)
31883168
}
31893169

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-
}
3170+
/// Color target format of the main pass for this pipeline key.
3171+
#[inline]
3172+
pub fn color_target_format(&self) -> TextureFormat {
3173+
let code = ((self.bits() >> Self::COLOR_TARGET_FORMAT_SHIFT_BITS)
3174+
& Self::COLOR_TARGET_FORMAT_MASK_BITS) as u8;
3175+
color_target_format_from_code(code)
32043176
}
32053177

32063178
pub fn msaa_samples(&self) -> u32 {
@@ -3658,7 +3630,7 @@ impl SpecializedMeshPipeline for MeshPipeline {
36583630
}
36593631
}
36603632

3661-
let format = key.main_pass_color_attachment_format();
3633+
let format = key.color_target_format();
36623634

36633635
// This is defined here so that custom shaders that use something other than
36643636
// the mesh binding from bevy_pbr::mesh_bindings can easily make use of this

crates/bevy_render/src/view/mod.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,51 @@ static D65_XY: Vec2 = vec2(0.31272, 0.32903);
9494
/// [D65 white point]: https://en.wikipedia.org/wiki/Standard_illuminant#D65_values
9595
static D65_LMS: Vec3 = vec3(0.975538, 1.01648, 1.08475);
9696

97+
/// Encode a [`TextureFormat`] as a 4-bit code for use in pipeline key bitfields.
98+
///
99+
/// Covers all color-renderable formats likely to appear as a main-pass color target.
100+
/// Unknown formats map to `Rgba8UnormSrgb` (code 1).
101+
#[inline]
102+
pub fn color_target_format_to_code(format: TextureFormat) -> u8 {
103+
match format {
104+
TextureFormat::Rgba8Unorm => 0,
105+
TextureFormat::Rgba8UnormSrgb => 1,
106+
TextureFormat::Bgra8Unorm => 2,
107+
TextureFormat::Bgra8UnormSrgb => 3,
108+
TextureFormat::Rgba16Float => 4,
109+
TextureFormat::Rg11b10Ufloat => 5,
110+
TextureFormat::Rgb10a2Unorm => 6,
111+
TextureFormat::R16Float => 7,
112+
TextureFormat::Rg16Float => 8,
113+
TextureFormat::R8Unorm => 9,
114+
TextureFormat::Rg8Unorm => 10,
115+
TextureFormat::Rgba32Float => 11,
116+
_ => 1,
117+
}
118+
}
119+
120+
/// Decode a 4-bit code back into a [`TextureFormat`].
121+
///
122+
/// Inverse of [`color_target_format_to_code`].
123+
#[inline]
124+
pub fn color_target_format_from_code(code: u8) -> TextureFormat {
125+
match code {
126+
0 => TextureFormat::Rgba8Unorm,
127+
1 => TextureFormat::Rgba8UnormSrgb,
128+
2 => TextureFormat::Bgra8Unorm,
129+
3 => TextureFormat::Bgra8UnormSrgb,
130+
4 => TextureFormat::Rgba16Float,
131+
5 => TextureFormat::Rg11b10Ufloat,
132+
6 => TextureFormat::Rgb10a2Unorm,
133+
7 => TextureFormat::R16Float,
134+
8 => TextureFormat::Rg16Float,
135+
9 => TextureFormat::R8Unorm,
136+
10 => TextureFormat::Rg8Unorm,
137+
11 => TextureFormat::Rgba32Float,
138+
_ => TextureFormat::Rgba8UnormSrgb,
139+
}
140+
}
141+
97142
pub struct ViewPlugin;
98143

99144
impl Plugin for ViewPlugin {

0 commit comments

Comments
 (0)