pub mod coverage;
pub mod display;
pub mod effects;
pub mod geometry;
pub mod hzb;
pub mod light_culling;
pub mod lines;
pub mod material_classify;
pub mod material_decal;
pub mod material_opaque;
pub mod material_transparent;
pub mod occlusion;
pub mod shader_cache_key;
pub mod shader_template;
pub mod shadow_masked;
pub mod shared;
use std::ops::Range;
use awsm_renderer_core::renderer::AwsmRendererWebGpu;
use crate::error::Result;
use crate::features::RendererFeatures;
use crate::pipelines::compute_pipeline::{ComputePipelineCacheKey, ComputePipelineKey};
use crate::pipelines::render_pipeline::{RenderPipelineCacheKey, RenderPipelineKey};
use crate::render_passes::effects::render_pass::EffectsRenderPass;
use crate::shaders::ShaderCacheKey;
use crate::{
bind_group_layout::BindGroupLayouts,
pipeline_layouts::PipelineLayouts,
pipelines::Pipelines,
render_passes::{
coverage::render_pass::CoverageRenderPass, display::render_pass::DisplayRenderPass,
geometry::render_pass::GeometryRenderPass, hzb::render_pass::HzbRenderPass,
light_culling::render_pass::LightCullingRenderPass,
material_classify::render_pass::MaterialClassifyRenderPass,
material_decal::render_pass::MaterialDecalRenderPass,
material_opaque::render_pass::MaterialOpaqueRenderPass,
material_transparent::render_pass::MaterialTransparentRenderPass,
occlusion::compaction::CompactionRenderPass, occlusion::render_pass::OcclusionRenderPass,
},
render_textures::RenderTextureFormats,
shaders::Shaders,
textures::Textures,
};
pub struct RenderPasses {
pub geometry: GeometryRenderPass,
pub shadow_masked: shadow_masked::ShadowMaskedRenderPass,
pub coverage: Option<CoverageRenderPass>,
pub hzb: Option<HzbRenderPass>,
pub occlusion: Option<OcclusionRenderPass>,
pub occlusion_compaction: Option<CompactionRenderPass>,
pub light_culling: LightCullingRenderPass,
pub material_classify: MaterialClassifyRenderPass,
pub material_decal: Option<MaterialDecalRenderPass>,
pub material_opaque: MaterialOpaqueRenderPass,
pub material_transparent: MaterialTransparentRenderPass,
pub effects: EffectsRenderPass,
pub display: DisplayRenderPass,
}
pub struct RenderPassesShaderPlan {
bindings: RenderPassesBindings,
pub shader_cache_keys: Vec<ShaderCacheKey>,
}
impl RenderPassesShaderPlan {
pub fn geometry_bind_groups(&self) -> &geometry::bind_group::GeometryBindGroups {
&self.bindings.geometry_bg
}
}
struct RenderPassesBindings {
geometry_bg: geometry::bind_group::GeometryBindGroups,
geometry_masked_bg: geometry::masked_bind_group::GeometryMaskedBindGroup,
geometry_masked_pipelines: geometry::masked_pipeline::GeometryMaskedPipelines,
shadow_masked_bg: shadow_masked::bind_group::ShadowMaskedBindGroup,
shadow_masked_pipelines: shadow_masked::pipeline::ShadowMaskedPipelines,
coverage_bg_single: Option<coverage::bind_group::CoverageBindGroups>,
coverage_bg_msaa: Option<coverage::bind_group::CoverageBindGroups>,
hzb_bg: Option<hzb::bind_group::HzbBindGroups>,
occlusion_bg: Option<occlusion::bind_group::OcclusionBindGroups>,
compaction_bg: Option<occlusion::compaction::CompactionBindGroups>,
light_culling: LightCullingRenderPass,
classify_bg: material_classify::bind_group::MaterialClassifyBindGroups,
decal_bg: Option<material_decal::bind_group::MaterialDecalBindGroups>,
decal_classify_bg: Option<material_decal::classify::bind_group::DecalClassifyBindGroups>,
opaque_bg: material_opaque::bind_group::MaterialOpaqueBindGroups,
opaque_edge_bind_group_layouts: material_opaque::edge_bind_group::MaterialEdgeBindGroupLayouts,
transparent_bg: material_transparent::bind_group::MaterialTransparentBindGroups,
transparent_pipelines: material_transparent::pipeline::MaterialTransparentPipelines,
effects_bg: effects::bind_group::EffectsBindGroups,
effects_pipelines: effects::pipeline::EffectsPipelines,
display_bg: display::bind_group::DisplayBindGroups,
display_pipelines: display::pipeline::DisplayPipelines,
}
pub struct RenderPassesDescriptors {
bindings: RenderPassesBindings,
pub compute_pipeline_cache_keys: Vec<ComputePipelineCacheKey>,
pub render_pipeline_cache_keys: Vec<RenderPipelineCacheKey>,
ranges: RenderPassesRanges,
per_pass_descs: RenderPassesPerPassDescs,
material_decal_composite: Option<material_decal::composite::MaterialDecalComposite>,
hzb_texture: Option<hzb::texture::HzbTexture>,
}
impl RenderPassesDescriptors {
pub fn effects_pipelines(&self) -> &effects::pipeline::EffectsPipelines {
&self.bindings.effects_pipelines
}
pub fn display_pipelines(&self) -> &display::pipeline::DisplayPipelines {
&self.bindings.display_pipelines
}
}
struct RenderPassesRanges {
geometry: Range<usize>,
coverage_single: Option<Range<usize>>,
coverage_msaa: Option<Range<usize>>,
hzb: Option<Range<usize>>,
occlusion: Option<Range<usize>>,
compaction: Option<Range<usize>>,
classify: Range<usize>,
decal: Option<Range<usize>>,
decal_classify: Option<Range<usize>>,
opaque: Range<usize>,
}
struct RenderPassesPerPassDescs {
geometry: crate::render_passes::geometry::pipeline::GeometryPrewarmDescriptors,
opaque_slots: Vec<crate::render_passes::material_opaque::pipeline::OpaquePipelineSlot>,
classify_slot_msaa: Vec<Option<u32>>,
hzb_slot: Vec<crate::render_passes::hzb::pipeline::HzbPipelineSlot>,
decal_is_msaa: Option<Vec<bool>>,
}
impl RenderPasses {
pub async fn new<'a>(
ctx: &mut RenderPassInitContext<'a>,
features: &RendererFeatures,
) -> Result<Self> {
let mut plan = Self::describe_shaders(ctx, features).await?;
let shader_keys = std::mem::take(&mut plan.shader_cache_keys);
ctx.shaders.ensure_keys(ctx.gpu, shader_keys).await?;
let mut descs = Self::describe_pipelines(plan, ctx, features).await?;
let compute_pool = std::mem::take(&mut descs.compute_pipeline_cache_keys);
let render_pool = std::mem::take(&mut descs.render_pipeline_cache_keys);
let compute_keys = ctx
.pipelines
.compute
.ensure_keys(ctx.gpu, ctx.shaders, ctx.pipeline_layouts, compute_pool)
.await?;
let render_keys = ctx
.pipelines
.render
.ensure_keys(ctx.gpu, ctx.shaders, ctx.pipeline_layouts, render_pool)
.await?;
Self::from_resolved(descs, compute_keys, render_keys)
}
pub async fn describe_shaders<'a>(
ctx: &mut RenderPassInitContext<'a>,
features: &RendererFeatures,
) -> Result<RenderPassesShaderPlan> {
use crate::render_passes::coverage::pipeline::CoveragePipelines;
use crate::render_passes::geometry::pipeline::GeometryPipelines;
use crate::render_passes::hzb::pipeline::HzbPipelines;
use crate::render_passes::material_classify::pipeline::MaterialClassifyPipelines;
use crate::render_passes::material_decal::classify::pipeline::DecalClassifyPipelines;
use crate::render_passes::material_decal::pipeline::MaterialDecalPipelines;
use crate::render_passes::material_opaque::pipeline::MaterialOpaquePipelines;
use crate::render_passes::occlusion::compaction::CompactionPipeline;
use crate::render_passes::occlusion::pipeline::OcclusionPipelines;
let geometry_bg = geometry::bind_group::GeometryBindGroups::new(ctx).await?;
let geometry_masked_bg =
geometry::masked_bind_group::GeometryMaskedBindGroup::new(ctx).await?;
let geometry_masked_pipelines = geometry::masked_pipeline::GeometryMaskedPipelines::new(
ctx,
&geometry_masked_bg,
&geometry_bg,
)?;
let shadow_masked_bg = shadow_masked::bind_group::ShadowMaskedBindGroup::new(ctx)?;
let shadow_masked_pipelines = shadow_masked::pipeline::ShadowMaskedPipelines::new(
ctx,
&shadow_masked_bg,
&geometry_bg,
)?;
let (coverage_bg_single, coverage_bg_msaa) = if features.coverage_lod {
(
Some(coverage::bind_group::CoverageBindGroups::new(ctx, false).await?),
Some(coverage::bind_group::CoverageBindGroups::new(ctx, true).await?),
)
} else {
(None, None)
};
let hzb_bg = if features.gpu_culling {
Some(hzb::bind_group::HzbBindGroups::new(ctx).await?)
} else {
None
};
let occlusion_bg = if features.gpu_culling {
Some(occlusion::bind_group::OcclusionBindGroups::new(ctx).await?)
} else {
None
};
let compaction_bg = if features.gpu_culling {
Some(occlusion::compaction::CompactionBindGroups::new(ctx).await?)
} else {
None
};
let light_culling = LightCullingRenderPass::new(ctx).await?;
let classify_bg =
material_classify::bind_group::MaterialClassifyBindGroups::new(ctx).await?;
let (decal_bg, decal_classify_bg) = if features.decals {
(
Some(material_decal::bind_group::MaterialDecalBindGroups::new(ctx).await?),
Some(
material_decal::classify::bind_group::DecalClassifyBindGroups::new(ctx).await?,
),
)
} else {
(None, None)
};
let opaque_bg = material_opaque::bind_group::MaterialOpaqueBindGroups::new(ctx).await?;
let opaque_edge_bind_group_layouts =
material_opaque::edge_bind_group::MaterialEdgeBindGroupLayouts::new(ctx)?;
let transparent_bg =
material_transparent::bind_group::MaterialTransparentBindGroups::new(ctx).await?;
let effects_bg = effects::bind_group::EffectsBindGroups::new(ctx).await?;
let display_bg = display::bind_group::DisplayBindGroups::new(ctx).await?;
let transparent_pipelines =
material_transparent::pipeline::MaterialTransparentPipelines::new(ctx, &transparent_bg)
.await?;
let effects_pipelines = effects::pipeline::EffectsPipelines::new(ctx, &effects_bg).await?;
let display_pipelines = display::pipeline::DisplayPipelines::new(ctx, &display_bg).await?;
let mut shader_cache_keys: Vec<ShaderCacheKey> = Vec::new();
let multisampled_geometry = ctx.anti_aliasing.has_msaa_checked()?;
shader_cache_keys.extend(GeometryPipelines::shader_cache_keys(multisampled_geometry));
if features.gpu_culling {
shader_cache_keys.extend(HzbPipelines::shader_cache_keys(ctx.anti_aliasing));
shader_cache_keys.extend(OcclusionPipelines::shader_cache_keys());
shader_cache_keys.extend(CompactionPipeline::shader_cache_keys(features));
}
let first_party_entries = crate::dynamic_materials::first_party_bucket_entries();
shader_cache_keys.extend(MaterialClassifyPipelines::shader_cache_keys(
ctx.gpu,
&first_party_entries,
ctx.anti_aliasing,
));
if let Some(bg) = coverage_bg_single.as_ref() {
shader_cache_keys.extend(CoveragePipelines::shader_cache_keys(bg));
}
if let Some(bg) = coverage_bg_msaa.as_ref() {
shader_cache_keys.extend(CoveragePipelines::shader_cache_keys(bg));
}
if let Some(bg) = decal_bg.as_ref() {
shader_cache_keys.extend(MaterialDecalPipelines::build_shader_cache_keys(ctx, bg)?);
}
if let Some(bg) = decal_classify_bg.as_ref() {
shader_cache_keys.extend(DecalClassifyPipelines::shader_cache_keys(bg));
}
shader_cache_keys.extend(MaterialOpaquePipelines::build_shader_cache_keys(
ctx, &opaque_bg,
)?);
Ok(RenderPassesShaderPlan {
bindings: RenderPassesBindings {
geometry_bg,
geometry_masked_bg,
geometry_masked_pipelines,
shadow_masked_bg,
shadow_masked_pipelines,
coverage_bg_single,
coverage_bg_msaa,
hzb_bg,
occlusion_bg,
compaction_bg,
light_culling,
classify_bg,
decal_bg,
decal_classify_bg,
opaque_bg,
opaque_edge_bind_group_layouts,
transparent_bg,
transparent_pipelines,
effects_bg,
effects_pipelines,
display_bg,
display_pipelines,
},
shader_cache_keys,
})
}
pub async fn describe_pipelines<'a>(
plan: RenderPassesShaderPlan,
ctx: &mut RenderPassInitContext<'a>,
_features: &RendererFeatures,
) -> Result<RenderPassesDescriptors> {
use crate::render_passes::coverage::pipeline::CoveragePipelines;
use crate::render_passes::geometry::pipeline::GeometryPipelines;
use crate::render_passes::hzb::pipeline::HzbPipelines;
use crate::render_passes::material_classify::pipeline::MaterialClassifyPipelines;
use crate::render_passes::material_decal::classify::pipeline::DecalClassifyPipelines;
use crate::render_passes::material_decal::pipeline::MaterialDecalPipelines;
use crate::render_passes::material_opaque::pipeline::MaterialOpaquePipelines;
use crate::render_passes::occlusion::compaction::CompactionPipeline;
use crate::render_passes::occlusion::pipeline::OcclusionPipelines;
let bindings = plan.bindings;
let mut compute_pool: Vec<ComputePipelineCacheKey> = Vec::new();
let mut render_pool: Vec<RenderPipelineCacheKey> = Vec::new();
let multisampled_geometry = ctx.anti_aliasing.has_msaa_checked()?;
let geometry_descs =
GeometryPipelines::build_descriptors(ctx, &bindings.geometry_bg, multisampled_geometry)
.await?;
let geometry_range =
render_pool.len()..render_pool.len() + geometry_descs.pipeline_cache_keys.len();
render_pool.extend(geometry_descs.pipeline_cache_keys.iter().cloned());
let (hzb_range, hzb_slot) = if let Some(bg) = bindings.hzb_bg.as_ref() {
let descs = HzbPipelines::build_descriptors(ctx, bg).await?;
let start = compute_pool.len();
let end = start + descs.pipeline_cache_keys.len();
compute_pool.extend(descs.pipeline_cache_keys.iter().cloned());
(Some(start..end), descs.slot)
} else {
(None, Vec::new())
};
let occlusion_range = if let Some(bg) = bindings.occlusion_bg.as_ref() {
let descs = OcclusionPipelines::build_descriptors(ctx, bg).await?;
let start = compute_pool.len();
let end = start + descs.pipeline_cache_keys.len();
compute_pool.extend(descs.pipeline_cache_keys.iter().cloned());
Some(start..end)
} else {
None
};
let compaction_range = if let Some(bg) = bindings.compaction_bg.as_ref() {
let descs = CompactionPipeline::build_descriptors(ctx, bg).await?;
let start = compute_pool.len();
let end = start + descs.pipeline_cache_keys.len();
compute_pool.extend(descs.pipeline_cache_keys.iter().cloned());
Some(start..end)
} else {
None
};
let classify_first_party_entries = crate::dynamic_materials::first_party_bucket_entries();
let classify_descs = MaterialClassifyPipelines::build_descriptors(
ctx,
&bindings.classify_bg,
&classify_first_party_entries,
)
.await?;
let classify_range =
compute_pool.len()..compute_pool.len() + classify_descs.pipeline_cache_keys.len();
compute_pool.extend(classify_descs.pipeline_cache_keys.iter().cloned());
let coverage_single_range = if let Some(bg) = bindings.coverage_bg_single.as_ref() {
let descs = CoveragePipelines::build_descriptors(ctx, bg).await?;
let start = compute_pool.len();
let end = start + descs.pipeline_cache_keys.len();
compute_pool.extend(descs.pipeline_cache_keys.iter().cloned());
Some(start..end)
} else {
None
};
let coverage_msaa_range = if let Some(bg) = bindings.coverage_bg_msaa.as_ref() {
let descs = CoveragePipelines::build_descriptors(ctx, bg).await?;
let start = compute_pool.len();
let end = start + descs.pipeline_cache_keys.len();
compute_pool.extend(descs.pipeline_cache_keys.iter().cloned());
Some(start..end)
} else {
None
};
let (decal_range, decal_classify_range, decal_is_msaa) =
if let (Some(decal_bg), Some(decal_classify_bg)) = (
bindings.decal_bg.as_ref(),
bindings.decal_classify_bg.as_ref(),
) {
let descs = MaterialDecalPipelines::build_descriptors(ctx, decal_bg).await?;
let start = compute_pool.len();
let end = start + descs.pipeline_cache_keys.len();
compute_pool.extend(descs.pipeline_cache_keys.iter().cloned());
let decal_range = start..end;
let is_msaa = descs.is_msaa;
let classify_descs =
DecalClassifyPipelines::build_descriptors(ctx, decal_classify_bg).await?;
let start = compute_pool.len();
let end = start + classify_descs.pipeline_cache_keys.len();
compute_pool.extend(classify_descs.pipeline_cache_keys.iter().cloned());
let decal_classify_range = start..end;
(Some(decal_range), Some(decal_classify_range), Some(is_msaa))
} else {
(None, None, None)
};
let opaque_descs =
MaterialOpaquePipelines::build_descriptors(ctx, &bindings.opaque_bg).await?;
let opaque_range =
compute_pool.len()..compute_pool.len() + opaque_descs.pipeline_cache_keys.len();
compute_pool.extend(opaque_descs.pipeline_cache_keys.iter().cloned());
let material_decal_composite = if bindings.decal_bg.is_some() {
Some(material_decal::composite::MaterialDecalComposite::new(ctx).await?)
} else {
None
};
let hzb_texture = if bindings.hzb_bg.is_some() {
Some(hzb::texture::HzbTexture::new(ctx.gpu, 1, 1)?)
} else {
None
};
Ok(RenderPassesDescriptors {
bindings,
compute_pipeline_cache_keys: compute_pool,
render_pipeline_cache_keys: render_pool,
ranges: RenderPassesRanges {
geometry: geometry_range,
coverage_single: coverage_single_range,
coverage_msaa: coverage_msaa_range,
hzb: hzb_range,
occlusion: occlusion_range,
compaction: compaction_range,
classify: classify_range,
decal: decal_range,
decal_classify: decal_classify_range,
opaque: opaque_range,
},
per_pass_descs: RenderPassesPerPassDescs {
geometry: geometry_descs,
opaque_slots: opaque_descs.slots,
classify_slot_msaa: classify_descs.slot_msaa,
hzb_slot,
decal_is_msaa,
},
material_decal_composite,
hzb_texture,
})
}
pub fn from_resolved(
descs: RenderPassesDescriptors,
compute_keys: Vec<ComputePipelineKey>,
render_keys: Vec<RenderPipelineKey>,
) -> Result<Self> {
use crate::render_passes::coverage::pipeline::CoveragePipelines;
use crate::render_passes::geometry::pipeline::GeometryPipelines;
use crate::render_passes::hzb::pipeline::HzbPipelines;
use crate::render_passes::material_decal::classify::pipeline::DecalClassifyPipelines;
use crate::render_passes::material_decal::pipeline::MaterialDecalPipelines;
use crate::render_passes::material_opaque::pipeline::MaterialOpaquePipelines;
use crate::render_passes::occlusion::compaction::CompactionPipeline;
use crate::render_passes::occlusion::pipeline::OcclusionPipelines;
let RenderPassesDescriptors {
bindings,
ranges,
per_pass_descs,
material_decal_composite,
hzb_texture,
..
} = descs;
let RenderPassesBindings {
geometry_bg,
geometry_masked_bg,
geometry_masked_pipelines,
shadow_masked_bg,
shadow_masked_pipelines,
coverage_bg_single,
coverage_bg_msaa,
hzb_bg,
occlusion_bg,
compaction_bg,
light_culling,
classify_bg,
decal_bg,
decal_classify_bg,
opaque_bg,
opaque_edge_bind_group_layouts,
transparent_bg,
transparent_pipelines,
effects_bg,
effects_pipelines,
display_bg,
display_pipelines,
} = bindings;
let geometry = GeometryRenderPass {
bind_groups: geometry_bg,
pipelines: GeometryPipelines::from_resolved(
&per_pass_descs.geometry,
render_keys[ranges.geometry].to_vec(),
)?,
masked_bind_group: geometry_masked_bg,
masked_pipelines: geometry_masked_pipelines,
};
let shadow_masked = shadow_masked::ShadowMaskedRenderPass {
bind_group: shadow_masked_bg,
pipelines: shadow_masked_pipelines,
};
let coverage = match (
coverage_bg_single,
ranges.coverage_single,
coverage_bg_msaa,
ranges.coverage_msaa,
) {
(Some(bg_s), Some(r_s), Some(bg_m), Some(r_m)) => Some(CoverageRenderPass {
bind_groups_singlesampled: bg_s,
bind_groups_multisampled: bg_m,
pipelines_singlesampled: CoveragePipelines::from_resolved(
compute_keys[r_s].to_vec(),
),
pipelines_multisampled: CoveragePipelines::from_resolved(
compute_keys[r_m].to_vec(),
),
}),
_ => None,
};
let hzb = match (hzb_bg, ranges.hzb, hzb_texture) {
(Some(bg), Some(range), Some(texture)) => Some(HzbRenderPass {
bind_groups: bg,
pipelines: HzbPipelines::from_resolved(
per_pass_descs.hzb_slot,
compute_keys[range].to_vec(),
),
texture,
}),
_ => None,
};
let occlusion = match (occlusion_bg, ranges.occlusion) {
(Some(bg), Some(range)) => Some(OcclusionRenderPass {
bind_groups: bg,
pipelines: OcclusionPipelines::from_resolved(compute_keys[range].to_vec()),
}),
_ => None,
};
let occlusion_compaction = match (compaction_bg, ranges.compaction) {
(Some(bg), Some(range)) => Some(CompactionRenderPass {
bind_groups: bg,
pipeline: CompactionPipeline::from_resolved(compute_keys[range].to_vec()),
}),
_ => None,
};
let _ = (&per_pass_descs.classify_slot_msaa, &ranges.classify);
let material_classify = MaterialClassifyRenderPass {
bind_groups: classify_bg,
pipeline_cache: std::cell::RefCell::new(std::collections::HashMap::new()),
};
let material_decal = match (
decal_bg,
ranges.decal,
decal_classify_bg,
ranges.decal_classify,
per_pass_descs.decal_is_msaa,
material_decal_composite,
) {
(
Some(decal_bg),
Some(decal_range),
Some(decal_classify_bg),
Some(decal_classify_range),
Some(decal_is_msaa),
Some(composite),
) => Some(MaterialDecalRenderPass {
bind_groups: decal_bg,
pipelines: MaterialDecalPipelines::from_resolved(
decal_is_msaa,
compute_keys[decal_range].to_vec(),
),
composite,
classify_pass: material_decal::classify::render_pass::DecalClassifyRenderPass {
bind_groups: decal_classify_bg,
pipelines: DecalClassifyPipelines::from_resolved(
compute_keys[decal_classify_range].to_vec(),
),
},
}),
_ => None,
};
let material_opaque = MaterialOpaqueRenderPass {
bind_groups: opaque_bg,
pipelines: MaterialOpaquePipelines::from_resolved(
per_pass_descs.opaque_slots,
compute_keys[ranges.opaque].to_vec(),
),
edge_pipelines:
crate::render_passes::material_opaque::edge_pipeline::MaterialEdgePipelines::new(),
edge_bind_group_layouts: opaque_edge_bind_group_layouts,
};
let material_transparent = MaterialTransparentRenderPass {
bind_groups: transparent_bg,
pipelines: transparent_pipelines,
};
let effects = EffectsRenderPass {
bind_groups: effects_bg,
pipelines: effects_pipelines,
};
let display = DisplayRenderPass {
bind_groups: display_bg,
pipelines: display_pipelines,
last_exposure_scale: std::cell::Cell::new(None),
};
Ok(Self {
geometry,
shadow_masked,
coverage,
hzb,
occlusion,
occlusion_compaction,
light_culling,
material_classify,
material_decal,
material_opaque,
material_transparent,
effects,
display,
})
}
}
pub struct RenderPassInitContext<'a> {
pub gpu: &'a AwsmRendererWebGpu,
pub bind_group_layouts: &'a mut BindGroupLayouts,
pub textures: &'a mut Textures,
pub pipeline_layouts: &'a mut PipelineLayouts,
pub pipelines: &'a mut Pipelines,
pub shaders: &'a mut Shaders,
pub render_texture_formats: &'a mut RenderTextureFormats,
pub features: &'a RendererFeatures,
pub anti_aliasing: &'a crate::anti_alias::AntiAliasing,
pub post_processing: &'a crate::post_process::PostProcessing,
}