use crate::anti_alias::AntiAliasing;
use crate::error::Result;
use crate::pipeline_layouts::{PipelineLayoutCacheKey, PipelineLayoutKey};
use crate::pipelines::compute_pipeline::{ComputePipelineCacheKey, ComputePipelineKey};
use crate::render_passes::material_opaque::shader::cache_key::ShaderCacheKeyMaterialOpaqueEmpty;
use crate::render_passes::{
material_opaque::{
bind_group::MaterialOpaqueBindGroups, shader::cache_key::ShaderCacheKeyMaterialOpaque,
},
RenderPassInitContext,
};
pub struct MaterialOpaquePipelines {
msaa_4_mipmaps_compute_pipeline_key: ComputePipelineKey,
msaa_4_no_mipmaps_compute_pipeline_key: ComputePipelineKey,
singlesampled_mipmaps_compute_pipeline_key: ComputePipelineKey,
singlesampled_no_mipmaps_compute_pipeline_key: ComputePipelineKey,
msaa_4_empty_compute_pipeline_key: ComputePipelineKey,
singlesampled_empty_compute_pipeline_key: ComputePipelineKey,
}
impl MaterialOpaquePipelines {
pub async fn new(
ctx: &mut RenderPassInitContext<'_>,
bind_groups: &MaterialOpaqueBindGroups,
) -> Result<Self> {
let multisampled_pipeline_layout_cache_key = PipelineLayoutCacheKey::new(vec![
bind_groups.multisampled_main_bind_group_layout_key,
bind_groups.lights_bind_group_layout_key,
bind_groups.texture_pool_textures_bind_group_layout_key,
]);
let multisampled_pipeline_layout_key = ctx.pipeline_layouts.get_key(
ctx.gpu,
ctx.bind_group_layouts,
multisampled_pipeline_layout_cache_key,
)?;
let singlesampled_pipeline_layout_cache_key = PipelineLayoutCacheKey::new(vec![
bind_groups.singlesampled_main_bind_group_layout_key,
bind_groups.lights_bind_group_layout_key,
bind_groups.texture_pool_textures_bind_group_layout_key,
]);
let singlesampled_pipeline_layout_key = ctx.pipeline_layouts.get_key(
ctx.gpu,
ctx.bind_group_layouts,
singlesampled_pipeline_layout_cache_key,
)?;
let texture_pool_arrays_len = bind_groups.texture_pool_arrays_len;
let texture_pool_samplers_len = bind_groups.texture_pool_sampler_keys.len() as u32;
let msaa_4_mipmaps_compute_pipeline_key = Self::create_pipeline(
ctx,
texture_pool_arrays_len,
texture_pool_samplers_len,
Some(4),
true,
multisampled_pipeline_layout_key,
)
.await?;
let msaa_4_no_mipmaps_compute_pipeline_key = Self::create_pipeline(
ctx,
texture_pool_arrays_len,
texture_pool_samplers_len,
Some(4),
false,
multisampled_pipeline_layout_key,
)
.await?;
let singlesampled_mipmaps_compute_pipeline_key = Self::create_pipeline(
ctx,
texture_pool_arrays_len,
texture_pool_samplers_len,
None,
true,
singlesampled_pipeline_layout_key,
)
.await?;
let singlesampled_no_mipmaps_compute_pipeline_key = Self::create_pipeline(
ctx,
texture_pool_arrays_len,
texture_pool_samplers_len,
None,
false,
singlesampled_pipeline_layout_key,
)
.await?;
let msaa_4_empty_compute_pipeline_key = Self::create_empty_pipeline(
ctx,
texture_pool_arrays_len,
texture_pool_samplers_len,
Some(4),
multisampled_pipeline_layout_key,
)
.await?;
let singlesampled_empty_compute_pipeline_key = Self::create_empty_pipeline(
ctx,
texture_pool_arrays_len,
texture_pool_samplers_len,
None,
singlesampled_pipeline_layout_key,
)
.await?;
Ok(Self {
msaa_4_mipmaps_compute_pipeline_key,
msaa_4_no_mipmaps_compute_pipeline_key,
singlesampled_mipmaps_compute_pipeline_key,
singlesampled_no_mipmaps_compute_pipeline_key,
msaa_4_empty_compute_pipeline_key,
singlesampled_empty_compute_pipeline_key,
})
}
async fn create_pipeline(
ctx: &mut RenderPassInitContext<'_>,
texture_pool_arrays_len: u32,
texture_pool_samplers_len: u32,
msaa_sample_count: Option<u32>,
mipmaps: bool,
pipeline_layout_key: PipelineLayoutKey,
) -> Result<ComputePipelineKey> {
let shader_cache_key = ShaderCacheKeyMaterialOpaque {
texture_pool_arrays_len,
texture_pool_samplers_len,
msaa_sample_count,
mipmaps,
};
let shader_key = ctx.shaders.get_key(ctx.gpu, shader_cache_key).await?;
let compute_pipeline_cache_key =
ComputePipelineCacheKey::new(shader_key, pipeline_layout_key);
Ok(ctx
.pipelines
.compute
.get_key(
ctx.gpu,
ctx.shaders,
ctx.pipeline_layouts,
compute_pipeline_cache_key,
)
.await?)
}
async fn create_empty_pipeline(
ctx: &mut RenderPassInitContext<'_>,
texture_pool_arrays_len: u32,
texture_pool_samplers_len: u32,
msaa_sample_count: Option<u32>,
pipeline_layout_key: PipelineLayoutKey,
) -> Result<ComputePipelineKey> {
let shader_cache_key = ShaderCacheKeyMaterialOpaqueEmpty {
texture_pool_arrays_len,
texture_pool_samplers_len,
msaa_sample_count,
};
let shader_key = ctx.shaders.get_key(ctx.gpu, shader_cache_key).await?;
let compute_pipeline_cache_key =
ComputePipelineCacheKey::new(shader_key, pipeline_layout_key);
Ok(ctx
.pipelines
.compute
.get_key(
ctx.gpu,
ctx.shaders,
ctx.pipeline_layouts,
compute_pipeline_cache_key,
)
.await?)
}
pub fn get_empty_compute_pipeline_key(
&self,
anti_aliasing: &AntiAliasing,
) -> Option<ComputePipelineKey> {
match anti_aliasing.msaa_sample_count {
Some(4) => Some(self.msaa_4_empty_compute_pipeline_key),
None => Some(self.singlesampled_empty_compute_pipeline_key),
_ => None,
}
}
pub fn get_compute_pipeline_key(
&self,
anti_aliasing: &AntiAliasing,
) -> Option<ComputePipelineKey> {
match (anti_aliasing.msaa_sample_count, anti_aliasing.mipmap) {
(Some(4), true) => Some(self.msaa_4_mipmaps_compute_pipeline_key),
(Some(4), false) => Some(self.msaa_4_no_mipmaps_compute_pipeline_key),
(None, true) => Some(self.singlesampled_mipmaps_compute_pipeline_key),
(None, false) => Some(self.singlesampled_no_mipmaps_compute_pipeline_key),
_ => None,
}
}
}