use super::ShaderDefVal;
use crate::{
define_atomic_id,
render_resource::{resource_macros::render_resource_wrapper, BindGroupLayout, Shader},
};
use bevy_asset::Handle;
use std::{borrow::Cow, ops::Deref};
use wgpu::{
BufferAddress, ColorTargetState, DepthStencilState, MultisampleState, PrimitiveState,
PushConstantRange, VertexAttribute, VertexFormat, VertexStepMode,
};
define_atomic_id!(RenderPipelineId);
render_resource_wrapper!(ErasedRenderPipeline, wgpu::RenderPipeline);
#[derive(Clone, Debug)]
pub struct RenderPipeline {
id: RenderPipelineId,
value: ErasedRenderPipeline,
}
impl RenderPipeline {
#[inline]
pub fn id(&self) -> RenderPipelineId {
self.id
}
}
impl From<wgpu::RenderPipeline> for RenderPipeline {
fn from(value: wgpu::RenderPipeline) -> Self {
RenderPipeline {
id: RenderPipelineId::new(),
value: ErasedRenderPipeline::new(value),
}
}
}
impl Deref for RenderPipeline {
type Target = wgpu::RenderPipeline;
#[inline]
fn deref(&self) -> &Self::Target {
&self.value
}
}
define_atomic_id!(ComputePipelineId);
render_resource_wrapper!(ErasedComputePipeline, wgpu::ComputePipeline);
#[derive(Clone, Debug)]
pub struct ComputePipeline {
id: ComputePipelineId,
value: ErasedComputePipeline,
}
impl ComputePipeline {
#[inline]
pub fn id(&self) -> ComputePipelineId {
self.id
}
}
impl From<wgpu::ComputePipeline> for ComputePipeline {
fn from(value: wgpu::ComputePipeline) -> Self {
ComputePipeline {
id: ComputePipelineId::new(),
value: ErasedComputePipeline::new(value),
}
}
}
impl Deref for ComputePipeline {
type Target = wgpu::ComputePipeline;
#[inline]
fn deref(&self) -> &Self::Target {
&self.value
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct RenderPipelineDescriptor {
pub label: Option<Cow<'static, str>>,
pub layout: Vec<BindGroupLayout>,
pub push_constant_ranges: Vec<PushConstantRange>,
pub vertex: VertexState,
pub primitive: PrimitiveState,
pub depth_stencil: Option<DepthStencilState>,
pub multisample: MultisampleState,
pub fragment: Option<FragmentState>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct VertexState {
pub shader: Handle<Shader>,
pub shader_defs: Vec<ShaderDefVal>,
pub entry_point: Cow<'static, str>,
pub buffers: Vec<VertexBufferLayout>,
}
#[derive(Default, Clone, Debug, Hash, Eq, PartialEq)]
pub struct VertexBufferLayout {
pub array_stride: BufferAddress,
pub step_mode: VertexStepMode,
pub attributes: Vec<VertexAttribute>,
}
impl VertexBufferLayout {
pub fn from_vertex_formats<T: IntoIterator<Item = VertexFormat>>(
step_mode: VertexStepMode,
vertex_formats: T,
) -> Self {
let mut offset = 0;
let mut attributes = Vec::new();
for (shader_location, format) in vertex_formats.into_iter().enumerate() {
attributes.push(VertexAttribute {
format,
offset,
shader_location: shader_location as u32,
});
offset += format.size();
}
VertexBufferLayout {
array_stride: offset,
step_mode,
attributes,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct FragmentState {
pub shader: Handle<Shader>,
pub shader_defs: Vec<ShaderDefVal>,
pub entry_point: Cow<'static, str>,
pub targets: Vec<Option<ColorTargetState>>,
}
#[derive(Clone, Debug)]
pub struct ComputePipelineDescriptor {
pub label: Option<Cow<'static, str>>,
pub layout: Vec<BindGroupLayout>,
pub push_constant_ranges: Vec<PushConstantRange>,
pub shader: Handle<Shader>,
pub shader_defs: Vec<ShaderDefVal>,
pub entry_point: Cow<'static, str>,
}