From 84a2584a3f8f96419433ae087d1a3ee6317c7aa7 Mon Sep 17 00:00:00 2001 From: Callum Tolley Date: Sat, 1 Jul 2023 11:53:59 +0100 Subject: [PATCH 1/3] Add downlevel flags to capabilities, and add more capabilities --- crates/bevy_render/src/lib.rs | 2 +- .../src/render_resource/pipeline_cache.rs | 36 ++++++++++++++----- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/crates/bevy_render/src/lib.rs b/crates/bevy_render/src/lib.rs index cb625bf49d9db..a7625e1da1fb0 100644 --- a/crates/bevy_render/src/lib.rs +++ b/crates/bevy_render/src/lib.rs @@ -369,7 +369,7 @@ impl Plugin for RenderPlugin { render_app .insert_resource(RenderInstance(instance)) - .insert_resource(PipelineCache::new(device.clone())) + .insert_resource(PipelineCache::new(render_adapter.clone(), device.clone())) .insert_resource(device) .insert_resource(queue) .insert_resource(render_adapter) diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index 73d9075372987..b516cfdb055b9 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -4,7 +4,7 @@ use crate::{ RawComputePipelineDescriptor, RawFragmentState, RawRenderPipelineDescriptor, RawVertexState, RenderPipeline, RenderPipelineDescriptor, Shader, ShaderImport, Source, }, - renderer::RenderDevice, + renderer::{RenderAdapter, RenderDevice}, Extract, }; use bevy_asset::{AssetEvent, Assets, Handle}; @@ -21,6 +21,7 @@ use std::{borrow::Cow, hash::Hash, mem, ops::Deref}; use thiserror::Error; #[cfg(feature = "shader_format_spirv")] use wgpu::util::make_spirv; +use wgpu::DownlevelFlags; use wgpu::{ Features, PipelineLayoutDescriptor, PushConstantRange, ShaderModuleDescriptor, VertexBufferLayout as RawVertexBufferLayout, @@ -163,8 +164,8 @@ impl ShaderDefVal { } impl ShaderCache { - fn new(render_device: &RenderDevice) -> Self { - const CAPABILITIES: &[(Features, Capabilities)] = &[ + fn new(render_adapter: &RenderAdapter, render_device: &RenderDevice) -> Self { + const FEATURES_CAPABILITIES: &[(Features, Capabilities)] = &[ (Features::PUSH_CONSTANTS, Capabilities::PUSH_CONSTANT), (Features::SHADER_F64, Capabilities::FLOAT64), ( @@ -175,22 +176,41 @@ impl ShaderCache { Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, Capabilities::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, ), + ( + Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + Capabilities::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + ), ( Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, Capabilities::SAMPLER_NON_UNIFORM_INDEXING, ), ( - Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, - Capabilities::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + Features::TEXTURE_FORMAT_16BIT_NORM, + Capabilities::STORAGE_TEXTURE_16BIT_NORM_FORMATS, + ), + (Features::MULTIVIEW, Capabilities::MULTIVIEW), + ( + Features::SHADER_EARLY_DEPTH_TEST, + Capabilities::EARLY_DEPTH_TEST, ), ]; + const DOWNLEVEL_FLAGS_CAPABILITIES: &[(DownlevelFlags, Capabilities)] = &[( + DownlevelFlags::MULTISAMPLED_SHADING, + Capabilities::MULTISAMPLED_SHADING, + )]; let features = render_device.features(); let mut capabilities = Capabilities::empty(); - for (feature, capability) in CAPABILITIES { + for (feature, capability) in FEATURES_CAPABILITIES { if features.contains(*feature) { capabilities |= *capability; } } + let downlevel_flags = render_adapter.get_downlevel_capabilities().flags; + for (downlevel_flag, capability) in DOWNLEVEL_FLAGS_CAPABILITIES { + if downlevel_flags.contains(*downlevel_flag) { + capabilities |= *capability; + } + } #[cfg(debug_assertions)] let composer = naga_oil::compose::Composer::default(); @@ -480,9 +500,9 @@ impl PipelineCache { } /// Create a new pipeline cache associated with the given render device. - pub fn new(device: RenderDevice) -> Self { + pub fn new(adapter: RenderAdapter, device: RenderDevice) -> Self { Self { - shader_cache: ShaderCache::new(&device), + shader_cache: ShaderCache::new(&adapter, &device), device, layout_cache: default(), waiting_pipelines: default(), From cc16bc6d40d3756ce944c197989e891e51bff67e Mon Sep 17 00:00:00 2001 From: Callum Tolley Date: Sat, 1 Jul 2023 11:59:26 +0100 Subject: [PATCH 2/3] Revert change --- crates/bevy_render/src/render_resource/pipeline_cache.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/bevy_render/src/render_resource/pipeline_cache.rs b/crates/bevy_render/src/render_resource/pipeline_cache.rs index b516cfdb055b9..39414583dcf22 100644 --- a/crates/bevy_render/src/render_resource/pipeline_cache.rs +++ b/crates/bevy_render/src/render_resource/pipeline_cache.rs @@ -176,14 +176,14 @@ impl ShaderCache { Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, Capabilities::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, ), - ( - Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, - Capabilities::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, - ), ( Features::SAMPLED_TEXTURE_AND_STORAGE_BUFFER_ARRAY_NON_UNIFORM_INDEXING, Capabilities::SAMPLER_NON_UNIFORM_INDEXING, ), + ( + Features::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + Capabilities::UNIFORM_BUFFER_AND_STORAGE_TEXTURE_ARRAY_NON_UNIFORM_INDEXING, + ), ( Features::TEXTURE_FORMAT_16BIT_NORM, Capabilities::STORAGE_TEXTURE_16BIT_NORM_FORMATS, From aae82bdb83210d42af82566194c5b7f349957b62 Mon Sep 17 00:00:00 2001 From: Callum Tolley Date: Sat, 1 Jul 2023 12:12:07 +0100 Subject: [PATCH 3/3] Add MSAA to shader_prepass example --- examples/shader/shader_prepass.rs | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/examples/shader/shader_prepass.rs b/examples/shader/shader_prepass.rs index 81bc4dc449a71..a0a5a9fa1731e 100644 --- a/examples/shader/shader_prepass.rs +++ b/examples/shader/shader_prepass.rs @@ -29,7 +29,7 @@ fn main() { }, )) .add_systems(Startup, setup) - .add_systems(Update, (rotate, toggle_prepass_view)) + .add_systems(Update, (rotate, toggle_prepass_view, toggle_multisampling)) // Disabling MSAA for maximum compatibility. Shader prepass with MSAA needs GPU capability MULTISAMPLED_SHADING .insert_resource(Msaa::Off) .run(); @@ -142,10 +142,12 @@ fn setup( commands.spawn( TextBundle::from_sections(vec![ TextSection::new("Prepass Output: transparent\n", style.clone()), + TextSection::new("MSAA: Off\n", style.clone()), TextSection::new("\n\n", style.clone()), TextSection::new("Controls\n", style.clone()), TextSection::new("---------------\n", style.clone()), - TextSection::new("Space - Change output\n", style), + TextSection::new("Space - Change output\n", style.clone()), + TextSection::new("M - Change MSAA\n", style), ]) .with_style(Style { position_type: PositionType::Absolute, @@ -242,17 +244,9 @@ fn toggle_prepass_view( 3 => "motion vectors", _ => unreachable!(), }; - let text_color = if *prepass_view == 3 { - Color::BLACK - } else { - Color::WHITE - }; let mut text = text.single_mut(); text.sections[0].value = format!("Prepass Output: {label}\n"); - for section in &mut text.sections { - section.style.color = text_color; - } let handle = material_handle.single(); let mat = materials.get_mut(handle).unwrap(); @@ -261,3 +255,20 @@ fn toggle_prepass_view( mat.settings.show_motion_vectors = (*prepass_view == 3) as u32; } } + +fn toggle_multisampling( + keycode: Res>, + mut text: Query<&mut Text>, + mut msaa: ResMut, +) { + if keycode.just_pressed(KeyCode::M) { + *msaa = match *msaa { + Msaa::Off => Msaa::Sample2, + Msaa::Sample2 => Msaa::Sample4, + Msaa::Sample4 => Msaa::Sample8, + Msaa::Sample8 => Msaa::Off, + }; + let mut text = text.single_mut(); + text.sections[1].value = format!("MSAA: {:?}\n", *msaa); + } +}