Merge ef52124c40
into f964ee1e3a
This commit is contained in:
commit
2d1fd85fbe
@ -18,11 +18,35 @@ use core::{fmt::Debug, hash::Hash};
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
|
/// A trait that allows constructing different variants of a render pipeline from a key.
|
||||||
|
///
|
||||||
|
/// Note: This is intended for modifying your pipeline descriptor on the basis of a key. If your key
|
||||||
|
/// contains no data then you don't need to specialize. For example, if you are using the
|
||||||
|
/// [`AsBindGroup`](crate::render_resource::AsBindGroup) without the `#[bind_group_data]` attribute,
|
||||||
|
/// you don't need to specialize. Instead, create the pipeline directly from [`PipelineCache`] and
|
||||||
|
/// store its ID.
|
||||||
|
///
|
||||||
|
/// See [`SpecializedRenderPipelines`] for more info.
|
||||||
pub trait SpecializedRenderPipeline {
|
pub trait SpecializedRenderPipeline {
|
||||||
|
/// The key that defines each "variant" of the render pipeline.
|
||||||
type Key: Clone + Hash + PartialEq + Eq;
|
type Key: Clone + Hash + PartialEq + Eq;
|
||||||
|
|
||||||
|
/// Construct a new render pipeline based on the provided key.
|
||||||
fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor;
|
fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A convenience cache for creating different variants of a render pipeline based on some key.
|
||||||
|
///
|
||||||
|
/// Some render pipelines may need to be configured differently depending on the exact situation.
|
||||||
|
/// This cache allows constructing different render pipelines for each situation based on a key,
|
||||||
|
/// making it easy to A) construct the necessary pipelines, and B) reuse already constructed
|
||||||
|
/// pipelines.
|
||||||
|
///
|
||||||
|
/// Note: This is intended for modifying your pipeline descriptor on the basis of a key. If your key
|
||||||
|
/// contains no data then you don't need to specialize. For example, if you are using the
|
||||||
|
/// [`AsBindGroup`](crate::render_resource::AsBindGroup) without the `#[bind_group_data]` attribute,
|
||||||
|
/// you don't need to specialize. Instead, create the pipeline directly from [`PipelineCache`] and
|
||||||
|
/// store its ID.
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct SpecializedRenderPipelines<S: SpecializedRenderPipeline> {
|
pub struct SpecializedRenderPipelines<S: SpecializedRenderPipeline> {
|
||||||
cache: HashMap<S::Key, CachedRenderPipelineId>,
|
cache: HashMap<S::Key, CachedRenderPipelineId>,
|
||||||
@ -35,24 +59,49 @@ impl<S: SpecializedRenderPipeline> Default for SpecializedRenderPipelines<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S: SpecializedRenderPipeline> SpecializedRenderPipelines<S> {
|
impl<S: SpecializedRenderPipeline> SpecializedRenderPipelines<S> {
|
||||||
|
/// Get or create a specialized instance of the pipeline corresponding to `key`.
|
||||||
pub fn specialize(
|
pub fn specialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
cache: &PipelineCache,
|
cache: &PipelineCache,
|
||||||
specialize_pipeline: &S,
|
pipeline_specializer: &S,
|
||||||
key: S::Key,
|
key: S::Key,
|
||||||
) -> CachedRenderPipelineId {
|
) -> CachedRenderPipelineId {
|
||||||
*self.cache.entry(key.clone()).or_insert_with(|| {
|
*self.cache.entry(key.clone()).or_insert_with(|| {
|
||||||
let descriptor = specialize_pipeline.specialize(key);
|
let descriptor = pipeline_specializer.specialize(key);
|
||||||
cache.queue_render_pipeline(descriptor)
|
cache.queue_render_pipeline(descriptor)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A trait that allows constructing different variants of a compute pipeline from a key.
|
||||||
|
///
|
||||||
|
/// Note: This is intended for modifying your pipeline descriptor on the basis of a key. If your key
|
||||||
|
/// contains no data then you don't need to specialize. For example, if you are using the
|
||||||
|
/// [`AsBindGroup`](crate::render_resource::AsBindGroup) without the `#[bind_group_data]` attribute,
|
||||||
|
/// you don't need to specialize. Instead, create the pipeline directly from [`PipelineCache`] and
|
||||||
|
/// store its ID.
|
||||||
|
///
|
||||||
|
/// See [`SpecializedComputePipelines`] for more info.
|
||||||
pub trait SpecializedComputePipeline {
|
pub trait SpecializedComputePipeline {
|
||||||
|
/// The key that defines each "variant" of the compute pipeline.
|
||||||
type Key: Clone + Hash + PartialEq + Eq;
|
type Key: Clone + Hash + PartialEq + Eq;
|
||||||
|
|
||||||
|
/// Construct a new compute pipeline based on the provided key.
|
||||||
fn specialize(&self, key: Self::Key) -> ComputePipelineDescriptor;
|
fn specialize(&self, key: Self::Key) -> ComputePipelineDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A convenience cache for creating different variants of a compute pipeline based on some key.
|
||||||
|
///
|
||||||
|
/// Some compute pipelines may need to be configured differently depending on the exact situation.
|
||||||
|
/// This cache allows constructing different compute pipelines for each situation based on a key,
|
||||||
|
/// making it easy to A) construct the necessary pipelines, and B) reuse already constructed
|
||||||
|
/// pipelines.
|
||||||
|
///
|
||||||
|
/// Note: This is intended for modifying your pipeline descriptor on the basis of a key. If your key
|
||||||
|
/// contains no data then you don't need to specialize. For example, if you are using the
|
||||||
|
/// [`AsBindGroup`](crate::render_resource::AsBindGroup) without the `#[bind_group_data]` attribute,
|
||||||
|
/// you don't need to specialize. Instead, create the pipeline directly from [`PipelineCache`] and
|
||||||
|
/// store its ID.
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct SpecializedComputePipelines<S: SpecializedComputePipeline> {
|
pub struct SpecializedComputePipelines<S: SpecializedComputePipeline> {
|
||||||
cache: HashMap<S::Key, CachedComputePipelineId>,
|
cache: HashMap<S::Key, CachedComputePipelineId>,
|
||||||
@ -65,6 +114,7 @@ impl<S: SpecializedComputePipeline> Default for SpecializedComputePipelines<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S: SpecializedComputePipeline> SpecializedComputePipelines<S> {
|
impl<S: SpecializedComputePipeline> SpecializedComputePipelines<S> {
|
||||||
|
/// Get or create a specialized instance of the pipeline corresponding to `key`.
|
||||||
pub fn specialize(
|
pub fn specialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
cache: &PipelineCache,
|
cache: &PipelineCache,
|
||||||
@ -78,8 +128,18 @@ impl<S: SpecializedComputePipeline> SpecializedComputePipelines<S> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A trait that allows constructing different variants of a render pipeline from a key and the
|
||||||
|
/// particular mesh's vertex buffer layout.
|
||||||
|
///
|
||||||
|
/// See [`SpecializedMeshPipelines`] for more info.
|
||||||
pub trait SpecializedMeshPipeline {
|
pub trait SpecializedMeshPipeline {
|
||||||
|
/// The key that defines each "variant" of the render pipeline.
|
||||||
type Key: Clone + Hash + PartialEq + Eq;
|
type Key: Clone + Hash + PartialEq + Eq;
|
||||||
|
|
||||||
|
/// Construct a new render pipeline based on the provided key and vertex layout.
|
||||||
|
///
|
||||||
|
/// The returned pipeline descriptor should have a single vertex buffer, which is derived from
|
||||||
|
/// `layout`.
|
||||||
fn specialize(
|
fn specialize(
|
||||||
&self,
|
&self,
|
||||||
key: Self::Key,
|
key: Self::Key,
|
||||||
@ -87,13 +147,15 @@ pub trait SpecializedMeshPipeline {
|
|||||||
) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError>;
|
) -> Result<RenderPipelineDescriptor, SpecializedMeshPipelineError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A cache of different variants of a render pipeline based on a key and the particular mesh's
|
||||||
|
/// vertex buffer layout.
|
||||||
#[derive(Resource)]
|
#[derive(Resource)]
|
||||||
pub struct SpecializedMeshPipelines<S: SpecializedMeshPipeline> {
|
pub struct SpecializedMeshPipelines<S: SpecializedMeshPipeline> {
|
||||||
mesh_layout_cache: HashMap<(MeshVertexBufferLayoutRef, S::Key), CachedRenderPipelineId>,
|
mesh_layout_cache: HashMap<(MeshVertexBufferLayoutRef, S::Key), CachedRenderPipelineId>,
|
||||||
vertex_layout_cache: VertexLayoutCache<S>,
|
vertex_layout_cache: VertexLayoutCache<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type VertexLayoutCache<S> = HashMap<
|
type VertexLayoutCache<S> = HashMap<
|
||||||
VertexBufferLayout,
|
VertexBufferLayout,
|
||||||
HashMap<<S as SpecializedMeshPipeline>::Key, CachedRenderPipelineId>,
|
HashMap<<S as SpecializedMeshPipeline>::Key, CachedRenderPipelineId>,
|
||||||
>;
|
>;
|
||||||
@ -108,11 +170,13 @@ impl<S: SpecializedMeshPipeline> Default for SpecializedMeshPipelines<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<S: SpecializedMeshPipeline> SpecializedMeshPipelines<S> {
|
impl<S: SpecializedMeshPipeline> SpecializedMeshPipelines<S> {
|
||||||
|
/// Construct a new render pipeline based on the provided key and the mesh's vertex buffer
|
||||||
|
/// layout.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn specialize(
|
pub fn specialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
cache: &PipelineCache,
|
cache: &PipelineCache,
|
||||||
specialize_pipeline: &S,
|
pipeline_specializer: &S,
|
||||||
key: S::Key,
|
key: S::Key,
|
||||||
layout: &MeshVertexBufferLayoutRef,
|
layout: &MeshVertexBufferLayoutRef,
|
||||||
) -> Result<CachedRenderPipelineId, SpecializedMeshPipelineError> {
|
) -> Result<CachedRenderPipelineId, SpecializedMeshPipelineError> {
|
||||||
@ -121,7 +185,7 @@ impl<S: SpecializedMeshPipeline> SpecializedMeshPipelines<S> {
|
|||||||
Entry::Vacant(entry) => specialize_slow(
|
Entry::Vacant(entry) => specialize_slow(
|
||||||
&mut self.vertex_layout_cache,
|
&mut self.vertex_layout_cache,
|
||||||
cache,
|
cache,
|
||||||
specialize_pipeline,
|
pipeline_specializer,
|
||||||
key,
|
key,
|
||||||
layout,
|
layout,
|
||||||
entry,
|
entry,
|
||||||
|
Loading…
Reference in New Issue
Block a user