parent
							
								
									e6e23fdfa9
								
							
						
					
					
						commit
						81809c71ce
					
				@ -2,9 +2,8 @@ use bevy_asset::{Assets, HandleUntyped};
 | 
			
		||||
use bevy_reflect::TypeUuid;
 | 
			
		||||
use bevy_render::{
 | 
			
		||||
    pipeline::{
 | 
			
		||||
        BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite,
 | 
			
		||||
        CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, PipelineDescriptor,
 | 
			
		||||
        RasterizationStateDescriptor, StencilStateDescriptor, StencilStateFaceDescriptor,
 | 
			
		||||
        BlendFactor, BlendOperation, BlendState, ColorTargetState, ColorWrite, CompareFunction,
 | 
			
		||||
        DepthBiasState, DepthStencilState, PipelineDescriptor, StencilFaceState, StencilState,
 | 
			
		||||
    },
 | 
			
		||||
    shader::{Shader, ShaderStage, ShaderStages},
 | 
			
		||||
    texture::TextureFormat,
 | 
			
		||||
@ -15,33 +14,31 @@ pub const FORWARD_PIPELINE_HANDLE: HandleUntyped =
 | 
			
		||||
 | 
			
		||||
pub(crate) fn build_forward_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
 | 
			
		||||
    PipelineDescriptor {
 | 
			
		||||
        rasterization_state: Some(RasterizationStateDescriptor {
 | 
			
		||||
            front_face: FrontFace::Ccw,
 | 
			
		||||
            cull_mode: CullMode::Back,
 | 
			
		||||
            depth_bias: 0,
 | 
			
		||||
            depth_bias_slope_scale: 0.0,
 | 
			
		||||
            depth_bias_clamp: 0.0,
 | 
			
		||||
            clamp_depth: false,
 | 
			
		||||
        }),
 | 
			
		||||
        depth_stencil_state: Some(DepthStencilStateDescriptor {
 | 
			
		||||
        depth_stencil: Some(DepthStencilState {
 | 
			
		||||
            format: TextureFormat::Depth32Float,
 | 
			
		||||
            depth_write_enabled: true,
 | 
			
		||||
            depth_compare: CompareFunction::Less,
 | 
			
		||||
            stencil: StencilStateDescriptor {
 | 
			
		||||
                front: StencilStateFaceDescriptor::IGNORE,
 | 
			
		||||
                back: StencilStateFaceDescriptor::IGNORE,
 | 
			
		||||
            stencil: StencilState {
 | 
			
		||||
                front: StencilFaceState::IGNORE,
 | 
			
		||||
                back: StencilFaceState::IGNORE,
 | 
			
		||||
                read_mask: 0,
 | 
			
		||||
                write_mask: 0,
 | 
			
		||||
            },
 | 
			
		||||
            bias: DepthBiasState {
 | 
			
		||||
                constant: 0,
 | 
			
		||||
                slope_scale: 0.0,
 | 
			
		||||
                clamp: 0.0,
 | 
			
		||||
            },
 | 
			
		||||
            clamp_depth: false,
 | 
			
		||||
        }),
 | 
			
		||||
        color_states: vec![ColorStateDescriptor {
 | 
			
		||||
        color_target_states: vec![ColorTargetState {
 | 
			
		||||
            format: TextureFormat::default(),
 | 
			
		||||
            color_blend: BlendDescriptor {
 | 
			
		||||
            color_blend: BlendState {
 | 
			
		||||
                src_factor: BlendFactor::SrcAlpha,
 | 
			
		||||
                dst_factor: BlendFactor::OneMinusSrcAlpha,
 | 
			
		||||
                operation: BlendOperation::Add,
 | 
			
		||||
            },
 | 
			
		||||
            alpha_blend: BlendDescriptor {
 | 
			
		||||
            alpha_blend: BlendState {
 | 
			
		||||
                src_factor: BlendFactor::One,
 | 
			
		||||
                dst_factor: BlendFactor::One,
 | 
			
		||||
                operation: BlendOperation::Add,
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
use crate::{
 | 
			
		||||
    pipeline::{PipelineCompiler, PipelineDescriptor, PipelineLayout, PipelineSpecialization},
 | 
			
		||||
    pipeline::{
 | 
			
		||||
        IndexFormat, PipelineCompiler, PipelineDescriptor, PipelineLayout, PipelineSpecialization,
 | 
			
		||||
    },
 | 
			
		||||
    renderer::{
 | 
			
		||||
        AssetRenderResourceBindings, BindGroup, BindGroupId, BufferId, RenderResource,
 | 
			
		||||
        RenderResourceBinding, RenderResourceBindings, RenderResourceContext, SharedBuffers,
 | 
			
		||||
@ -26,6 +28,7 @@ pub enum RenderCommand {
 | 
			
		||||
    SetIndexBuffer {
 | 
			
		||||
        buffer: BufferId,
 | 
			
		||||
        offset: u64,
 | 
			
		||||
        index_format: IndexFormat,
 | 
			
		||||
    },
 | 
			
		||||
    SetBindGroup {
 | 
			
		||||
        index: u32,
 | 
			
		||||
@ -95,8 +98,12 @@ impl Draw {
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn set_index_buffer(&mut self, buffer: BufferId, offset: u64) {
 | 
			
		||||
        self.render_command(RenderCommand::SetIndexBuffer { buffer, offset });
 | 
			
		||||
    pub fn set_index_buffer(&mut self, buffer: BufferId, offset: u64, index_format: IndexFormat) {
 | 
			
		||||
        self.render_command(RenderCommand::SetIndexBuffer {
 | 
			
		||||
            buffer,
 | 
			
		||||
            offset,
 | 
			
		||||
            index_format,
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup) {
 | 
			
		||||
@ -325,8 +332,8 @@ impl<'a> DrawContext<'a> {
 | 
			
		||||
        render_resource_bindings: &[&RenderResourceBindings],
 | 
			
		||||
    ) -> Result<(), DrawError> {
 | 
			
		||||
        for bindings in render_resource_bindings.iter() {
 | 
			
		||||
            if let Some(index_buffer) = bindings.index_buffer {
 | 
			
		||||
                draw.set_index_buffer(index_buffer, 0);
 | 
			
		||||
            if let Some((index_buffer, index_format)) = bindings.index_buffer {
 | 
			
		||||
                draw.set_index_buffer(index_buffer, 0, index_format);
 | 
			
		||||
            }
 | 
			
		||||
            if let Some(main_vertex_buffer) = bindings.vertex_attribute_buffer {
 | 
			
		||||
                draw.set_vertex_buffer(0, main_vertex_buffer, 0);
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,7 @@ use bevy_math::*;
 | 
			
		||||
use bevy_reflect::TypeUuid;
 | 
			
		||||
use std::borrow::Cow;
 | 
			
		||||
 | 
			
		||||
use crate::pipeline::{InputStepMode, VertexAttributeDescriptor, VertexBufferDescriptor};
 | 
			
		||||
use crate::pipeline::{InputStepMode, VertexAttribute, VertexBufferLayout};
 | 
			
		||||
use bevy_utils::{HashMap, HashSet};
 | 
			
		||||
 | 
			
		||||
pub const INDEX_BUFFER_ASSET_INDEX: u64 = 0;
 | 
			
		||||
@ -256,12 +256,12 @@ impl Mesh {
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn get_vertex_buffer_descriptor(&self) -> VertexBufferDescriptor {
 | 
			
		||||
    pub fn get_vertex_buffer_layout(&self) -> VertexBufferLayout {
 | 
			
		||||
        let mut attributes = Vec::new();
 | 
			
		||||
        let mut accumulated_offset = 0;
 | 
			
		||||
        for (attribute_name, attribute_values) in self.attributes.iter() {
 | 
			
		||||
            let vertex_format = VertexFormat::from(attribute_values);
 | 
			
		||||
            attributes.push(VertexAttributeDescriptor {
 | 
			
		||||
            attributes.push(VertexAttribute {
 | 
			
		||||
                name: attribute_name.clone(),
 | 
			
		||||
                offset: accumulated_offset,
 | 
			
		||||
                format: vertex_format,
 | 
			
		||||
@ -270,7 +270,7 @@ impl Mesh {
 | 
			
		||||
            accumulated_offset += vertex_format.get_size();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        VertexBufferDescriptor {
 | 
			
		||||
        VertexBufferLayout {
 | 
			
		||||
            name: Default::default(),
 | 
			
		||||
            stride: accumulated_offset,
 | 
			
		||||
            step_mode: InputStepMode::Vertex,
 | 
			
		||||
@ -453,21 +453,22 @@ fn update_entity_mesh(
 | 
			
		||||
    for render_pipeline in render_pipelines.pipelines.iter_mut() {
 | 
			
		||||
        render_pipeline.specialization.primitive_topology = mesh.primitive_topology;
 | 
			
		||||
        // TODO: don't allocate a new vertex buffer descriptor for every entity
 | 
			
		||||
        render_pipeline.specialization.vertex_buffer_descriptor =
 | 
			
		||||
            mesh.get_vertex_buffer_descriptor();
 | 
			
		||||
        render_pipeline.specialization.index_format = mesh
 | 
			
		||||
            .indices()
 | 
			
		||||
            .map(|i| i.into())
 | 
			
		||||
            .unwrap_or(IndexFormat::Uint32);
 | 
			
		||||
        render_pipeline.specialization.vertex_buffer_layout = mesh.get_vertex_buffer_layout();
 | 
			
		||||
        if let PrimitiveTopology::LineStrip | PrimitiveTopology::TriangleStrip =
 | 
			
		||||
            mesh.primitive_topology
 | 
			
		||||
        {
 | 
			
		||||
            render_pipeline.specialization.strip_index_format =
 | 
			
		||||
                mesh.indices().map(|indices| indices.into());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if let Some(RenderResourceId::Buffer(index_buffer_resource)) =
 | 
			
		||||
        render_resource_context.get_asset_resource(handle, INDEX_BUFFER_ASSET_INDEX)
 | 
			
		||||
    {
 | 
			
		||||
        let index_format: IndexFormat = mesh.indices().unwrap().into();
 | 
			
		||||
        // set index buffer into binding
 | 
			
		||||
        render_pipelines
 | 
			
		||||
            .bindings
 | 
			
		||||
            .set_index_buffer(index_buffer_resource);
 | 
			
		||||
            .set_index_buffer(index_buffer_resource, index_format);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if let Some(RenderResourceId::Buffer(vertex_attribute_buffer_resource)) =
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
use crate::{
 | 
			
		||||
    pipeline::{BindGroupDescriptorId, PipelineDescriptor},
 | 
			
		||||
    pipeline::{BindGroupDescriptorId, IndexFormat, PipelineDescriptor},
 | 
			
		||||
    renderer::{BindGroupId, BufferId, RenderContext},
 | 
			
		||||
};
 | 
			
		||||
use bevy_asset::Handle;
 | 
			
		||||
@ -7,7 +7,7 @@ use std::ops::Range;
 | 
			
		||||
 | 
			
		||||
pub trait RenderPass {
 | 
			
		||||
    fn get_render_context(&self) -> &dyn RenderContext;
 | 
			
		||||
    fn set_index_buffer(&mut self, buffer: BufferId, offset: u64);
 | 
			
		||||
    fn set_index_buffer(&mut self, buffer: BufferId, offset: u64, index_format: IndexFormat);
 | 
			
		||||
    fn set_vertex_buffer(&mut self, start_slot: u32, buffer: BufferId, offset: u64);
 | 
			
		||||
    fn set_pipeline(&mut self, pipeline_handle: &Handle<PipelineDescriptor>);
 | 
			
		||||
    fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32);
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,7 @@
 | 
			
		||||
use super::UniformProperty;
 | 
			
		||||
use crate::texture::{TextureComponentType, TextureFormat, TextureViewDimension};
 | 
			
		||||
use crate::texture::{
 | 
			
		||||
    StorageTextureAccess, TextureFormat, TextureSampleType, TextureViewDimension,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bitflags::bitflags! {
 | 
			
		||||
    pub struct BindingShaderStage: u32 {
 | 
			
		||||
@ -20,25 +22,35 @@ pub struct BindingDescriptor {
 | 
			
		||||
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
 | 
			
		||||
pub enum BindType {
 | 
			
		||||
    Uniform {
 | 
			
		||||
        dynamic: bool,
 | 
			
		||||
        has_dynamic_offset: bool,
 | 
			
		||||
        property: UniformProperty,
 | 
			
		||||
    },
 | 
			
		||||
    StorageBuffer {
 | 
			
		||||
        dynamic: bool,
 | 
			
		||||
        has_dynamic_offset: bool,
 | 
			
		||||
        readonly: bool,
 | 
			
		||||
    },
 | 
			
		||||
    Sampler {
 | 
			
		||||
        /// The sampling result is produced based on more than a single color sample from a texture,
 | 
			
		||||
        /// e.g. when bilinear interpolation is enabled.
 | 
			
		||||
        ///
 | 
			
		||||
        /// A filtering sampler can only be used with a filterable texture.
 | 
			
		||||
        filtering: bool,
 | 
			
		||||
        /// Use as a comparison sampler instead of a normal sampler.
 | 
			
		||||
        /// For more info take a look at the analogous functionality in OpenGL: https://www.khronos.org/opengl/wiki/Sampler_Object#Comparison_mode.
 | 
			
		||||
        comparison: bool,
 | 
			
		||||
    },
 | 
			
		||||
    SampledTexture {
 | 
			
		||||
    Texture {
 | 
			
		||||
        multisampled: bool,
 | 
			
		||||
        dimension: TextureViewDimension,
 | 
			
		||||
        component_type: TextureComponentType,
 | 
			
		||||
        view_dimension: TextureViewDimension,
 | 
			
		||||
        sample_type: TextureSampleType,
 | 
			
		||||
    },
 | 
			
		||||
    StorageTexture {
 | 
			
		||||
        dimension: TextureViewDimension,
 | 
			
		||||
        /// Allowed access to this texture.
 | 
			
		||||
        access: StorageTextureAccess,
 | 
			
		||||
        /// Format of the texture.
 | 
			
		||||
        format: TextureFormat,
 | 
			
		||||
        readonly: bool,
 | 
			
		||||
        /// Dimension of the texture view that is going to be sampled.
 | 
			
		||||
        view_dimension: TextureViewDimension,
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,12 +1,18 @@
 | 
			
		||||
use super::{
 | 
			
		||||
    state_descriptors::{
 | 
			
		||||
        BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite,
 | 
			
		||||
        CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat,
 | 
			
		||||
        PrimitiveTopology, RasterizationStateDescriptor, StencilStateFaceDescriptor,
 | 
			
		||||
        BlendFactor, BlendOperation, ColorWrite, CompareFunction, CullMode, FrontFace,
 | 
			
		||||
        PrimitiveTopology,
 | 
			
		||||
    },
 | 
			
		||||
    PipelineLayout, StencilStateDescriptor,
 | 
			
		||||
    PipelineLayout,
 | 
			
		||||
};
 | 
			
		||||
use crate::{
 | 
			
		||||
    pipeline::{
 | 
			
		||||
        BlendState, ColorTargetState, DepthBiasState, DepthStencilState, MultisampleState,
 | 
			
		||||
        PolygonMode, PrimitiveState, StencilFaceState, StencilState,
 | 
			
		||||
    },
 | 
			
		||||
    shader::ShaderStages,
 | 
			
		||||
    texture::TextureFormat,
 | 
			
		||||
};
 | 
			
		||||
use crate::{shader::ShaderStages, texture::TextureFormat};
 | 
			
		||||
use bevy_reflect::TypeUuid;
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, TypeUuid)]
 | 
			
		||||
@ -15,32 +21,12 @@ pub struct PipelineDescriptor {
 | 
			
		||||
    pub name: Option<String>,
 | 
			
		||||
    pub layout: Option<PipelineLayout>,
 | 
			
		||||
    pub shader_stages: ShaderStages,
 | 
			
		||||
    pub rasterization_state: Option<RasterizationStateDescriptor>,
 | 
			
		||||
 | 
			
		||||
    /// The primitive topology used to interpret vertices.
 | 
			
		||||
    pub primitive_topology: PrimitiveTopology,
 | 
			
		||||
    pub primitive: PrimitiveState,
 | 
			
		||||
    pub depth_stencil: Option<DepthStencilState>,
 | 
			
		||||
    pub multisample: MultisampleState,
 | 
			
		||||
 | 
			
		||||
    /// The effect of draw calls on the color aspect of the output target.
 | 
			
		||||
    pub color_states: Vec<ColorStateDescriptor>,
 | 
			
		||||
 | 
			
		||||
    /// The effect of draw calls on the depth and stencil aspects of the output target, if any.
 | 
			
		||||
    pub depth_stencil_state: Option<DepthStencilStateDescriptor>,
 | 
			
		||||
 | 
			
		||||
    /// The format of any index buffers used with this pipeline.
 | 
			
		||||
    pub index_format: IndexFormat,
 | 
			
		||||
 | 
			
		||||
    /// The number of samples calculated per pixel (for MSAA).
 | 
			
		||||
    pub sample_count: u32,
 | 
			
		||||
 | 
			
		||||
    /// Bitmask that restricts the samples of a pixel modified by this pipeline.
 | 
			
		||||
    pub sample_mask: u32,
 | 
			
		||||
 | 
			
		||||
    /// When enabled, produces another sample mask per pixel based on the alpha output value, that
 | 
			
		||||
    /// is AND-ed with the sample_mask and the primitive coverage to restrict the set of samples
 | 
			
		||||
    /// affected by a primitive.
 | 
			
		||||
    /// The implicit mask produced for alpha of zero is guaranteed to be zero, and for alpha of one
 | 
			
		||||
    /// is guaranteed to be all 1-s.
 | 
			
		||||
    pub alpha_to_coverage_enabled: bool,
 | 
			
		||||
    pub color_target_states: Vec<ColorTargetState>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PipelineDescriptor {
 | 
			
		||||
@ -48,60 +34,71 @@ impl PipelineDescriptor {
 | 
			
		||||
        PipelineDescriptor {
 | 
			
		||||
            name: None,
 | 
			
		||||
            layout: None,
 | 
			
		||||
            color_states: Vec::new(),
 | 
			
		||||
            depth_stencil_state: None,
 | 
			
		||||
            color_target_states: Vec::new(),
 | 
			
		||||
            depth_stencil: None,
 | 
			
		||||
            shader_stages,
 | 
			
		||||
            rasterization_state: None,
 | 
			
		||||
            primitive_topology: PrimitiveTopology::TriangleList,
 | 
			
		||||
            index_format: IndexFormat::Uint32,
 | 
			
		||||
            sample_count: 1,
 | 
			
		||||
            sample_mask: !0,
 | 
			
		||||
            alpha_to_coverage_enabled: false,
 | 
			
		||||
            primitive: PrimitiveState {
 | 
			
		||||
                topology: PrimitiveTopology::TriangleList,
 | 
			
		||||
                strip_index_format: None,
 | 
			
		||||
                front_face: FrontFace::Ccw,
 | 
			
		||||
                cull_mode: CullMode::Back,
 | 
			
		||||
                polygon_mode: PolygonMode::Fill,
 | 
			
		||||
            },
 | 
			
		||||
            multisample: MultisampleState {
 | 
			
		||||
                count: 1,
 | 
			
		||||
                mask: !0,
 | 
			
		||||
                alpha_to_coverage_enabled: false,
 | 
			
		||||
            },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn default_config(shader_stages: ShaderStages) -> Self {
 | 
			
		||||
        PipelineDescriptor {
 | 
			
		||||
            name: None,
 | 
			
		||||
            primitive_topology: PrimitiveTopology::TriangleList,
 | 
			
		||||
            layout: None,
 | 
			
		||||
            index_format: IndexFormat::Uint32,
 | 
			
		||||
            sample_count: 1,
 | 
			
		||||
            sample_mask: !0,
 | 
			
		||||
            alpha_to_coverage_enabled: false,
 | 
			
		||||
            rasterization_state: Some(RasterizationStateDescriptor {
 | 
			
		||||
            primitive: PrimitiveState {
 | 
			
		||||
                topology: PrimitiveTopology::TriangleList,
 | 
			
		||||
                strip_index_format: None,
 | 
			
		||||
                front_face: FrontFace::Ccw,
 | 
			
		||||
                cull_mode: CullMode::Back,
 | 
			
		||||
                depth_bias: 0,
 | 
			
		||||
                depth_bias_slope_scale: 0.0,
 | 
			
		||||
                depth_bias_clamp: 0.0,
 | 
			
		||||
                clamp_depth: false,
 | 
			
		||||
            }),
 | 
			
		||||
            depth_stencil_state: Some(DepthStencilStateDescriptor {
 | 
			
		||||
                polygon_mode: PolygonMode::Fill,
 | 
			
		||||
            },
 | 
			
		||||
            layout: None,
 | 
			
		||||
            depth_stencil: Some(DepthStencilState {
 | 
			
		||||
                format: TextureFormat::Depth32Float,
 | 
			
		||||
                depth_write_enabled: true,
 | 
			
		||||
                depth_compare: CompareFunction::Less,
 | 
			
		||||
                stencil: StencilStateDescriptor {
 | 
			
		||||
                    front: StencilStateFaceDescriptor::IGNORE,
 | 
			
		||||
                    back: StencilStateFaceDescriptor::IGNORE,
 | 
			
		||||
                stencil: StencilState {
 | 
			
		||||
                    front: StencilFaceState::IGNORE,
 | 
			
		||||
                    back: StencilFaceState::IGNORE,
 | 
			
		||||
                    read_mask: 0,
 | 
			
		||||
                    write_mask: 0,
 | 
			
		||||
                },
 | 
			
		||||
                bias: DepthBiasState {
 | 
			
		||||
                    constant: 0,
 | 
			
		||||
                    slope_scale: 0.0,
 | 
			
		||||
                    clamp: 0.0,
 | 
			
		||||
                },
 | 
			
		||||
                clamp_depth: false,
 | 
			
		||||
            }),
 | 
			
		||||
            color_states: vec![ColorStateDescriptor {
 | 
			
		||||
            color_target_states: vec![ColorTargetState {
 | 
			
		||||
                format: TextureFormat::default(),
 | 
			
		||||
                color_blend: BlendDescriptor {
 | 
			
		||||
                color_blend: BlendState {
 | 
			
		||||
                    src_factor: BlendFactor::SrcAlpha,
 | 
			
		||||
                    dst_factor: BlendFactor::OneMinusSrcAlpha,
 | 
			
		||||
                    operation: BlendOperation::Add,
 | 
			
		||||
                },
 | 
			
		||||
                alpha_blend: BlendDescriptor {
 | 
			
		||||
                alpha_blend: BlendState {
 | 
			
		||||
                    src_factor: BlendFactor::One,
 | 
			
		||||
                    dst_factor: BlendFactor::One,
 | 
			
		||||
                    operation: BlendOperation::Add,
 | 
			
		||||
                },
 | 
			
		||||
                write_mask: ColorWrite::ALL,
 | 
			
		||||
            }],
 | 
			
		||||
            multisample: MultisampleState {
 | 
			
		||||
                count: 1,
 | 
			
		||||
                mask: !0,
 | 
			
		||||
                alpha_to_coverage_enabled: false,
 | 
			
		||||
            },
 | 
			
		||||
            shader_stages,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
use super::{state_descriptors::PrimitiveTopology, IndexFormat, PipelineDescriptor};
 | 
			
		||||
use crate::{
 | 
			
		||||
    pipeline::{BindType, InputStepMode, VertexBufferDescriptor},
 | 
			
		||||
    pipeline::{BindType, InputStepMode, VertexBufferLayout},
 | 
			
		||||
    renderer::RenderResourceContext,
 | 
			
		||||
    shader::{Shader, ShaderError},
 | 
			
		||||
};
 | 
			
		||||
@ -15,8 +15,8 @@ pub struct PipelineSpecialization {
 | 
			
		||||
    pub shader_specialization: ShaderSpecialization,
 | 
			
		||||
    pub primitive_topology: PrimitiveTopology,
 | 
			
		||||
    pub dynamic_bindings: HashSet<String>,
 | 
			
		||||
    pub index_format: IndexFormat,
 | 
			
		||||
    pub vertex_buffer_descriptor: VertexBufferDescriptor,
 | 
			
		||||
    pub strip_index_format: Option<IndexFormat>,
 | 
			
		||||
    pub vertex_buffer_layout: VertexBufferLayout,
 | 
			
		||||
    pub sample_count: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -24,11 +24,11 @@ impl Default for PipelineSpecialization {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        Self {
 | 
			
		||||
            sample_count: 1,
 | 
			
		||||
            index_format: IndexFormat::Uint32,
 | 
			
		||||
            strip_index_format: None,
 | 
			
		||||
            shader_specialization: Default::default(),
 | 
			
		||||
            primitive_topology: Default::default(),
 | 
			
		||||
            dynamic_bindings: Default::default(),
 | 
			
		||||
            vertex_buffer_descriptor: Default::default(),
 | 
			
		||||
            vertex_buffer_layout: Default::default(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -178,10 +178,11 @@ impl PipelineCompiler {
 | 
			
		||||
                        .any(|b| b == &binding.name)
 | 
			
		||||
                    {
 | 
			
		||||
                        if let BindType::Uniform {
 | 
			
		||||
                            ref mut dynamic, ..
 | 
			
		||||
                            ref mut has_dynamic_offset,
 | 
			
		||||
                            ..
 | 
			
		||||
                        } = binding.bind_type
 | 
			
		||||
                        {
 | 
			
		||||
                            *dynamic = true;
 | 
			
		||||
                            *has_dynamic_offset = true;
 | 
			
		||||
                            binding_changed = true;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@ -197,12 +198,12 @@ impl PipelineCompiler {
 | 
			
		||||
        // create a vertex layout that provides all attributes from either the specialized vertex buffers or a zero buffer
 | 
			
		||||
        let mut pipeline_layout = specialized_descriptor.layout.as_mut().unwrap();
 | 
			
		||||
        // the vertex buffer descriptor of the mesh
 | 
			
		||||
        let mesh_vertex_buffer_descriptor = &pipeline_specialization.vertex_buffer_descriptor;
 | 
			
		||||
        let mesh_vertex_buffer_layout = &pipeline_specialization.vertex_buffer_layout;
 | 
			
		||||
 | 
			
		||||
        // the vertex buffer descriptor that will be used for this pipeline
 | 
			
		||||
        let mut compiled_vertex_buffer_descriptor = VertexBufferDescriptor {
 | 
			
		||||
        let mut compiled_vertex_buffer_descriptor = VertexBufferLayout {
 | 
			
		||||
            step_mode: InputStepMode::Vertex,
 | 
			
		||||
            stride: mesh_vertex_buffer_descriptor.stride,
 | 
			
		||||
            stride: mesh_vertex_buffer_layout.stride,
 | 
			
		||||
            ..Default::default()
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@ -212,7 +213,7 @@ impl PipelineCompiler {
 | 
			
		||||
                .get(0)
 | 
			
		||||
                .expect("Reflected layout has no attributes.");
 | 
			
		||||
 | 
			
		||||
            if let Some(target_vertex_attribute) = mesh_vertex_buffer_descriptor
 | 
			
		||||
            if let Some(target_vertex_attribute) = mesh_vertex_buffer_layout
 | 
			
		||||
                .attributes
 | 
			
		||||
                .iter()
 | 
			
		||||
                .find(|x| x.name == shader_vertex_attribute.name)
 | 
			
		||||
@ -233,13 +234,14 @@ impl PipelineCompiler {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //TODO: add other buffers (like instancing) here
 | 
			
		||||
        let mut vertex_buffer_descriptors = Vec::<VertexBufferDescriptor>::default();
 | 
			
		||||
        let mut vertex_buffer_descriptors = Vec::<VertexBufferLayout>::default();
 | 
			
		||||
        vertex_buffer_descriptors.push(compiled_vertex_buffer_descriptor);
 | 
			
		||||
 | 
			
		||||
        pipeline_layout.vertex_buffer_descriptors = vertex_buffer_descriptors;
 | 
			
		||||
        specialized_descriptor.sample_count = pipeline_specialization.sample_count;
 | 
			
		||||
        specialized_descriptor.primitive_topology = pipeline_specialization.primitive_topology;
 | 
			
		||||
        specialized_descriptor.index_format = pipeline_specialization.index_format;
 | 
			
		||||
        specialized_descriptor.multisample.count = pipeline_specialization.sample_count;
 | 
			
		||||
        specialized_descriptor.primitive.topology = pipeline_specialization.primitive_topology;
 | 
			
		||||
        specialized_descriptor.primitive.strip_index_format =
 | 
			
		||||
            pipeline_specialization.strip_index_format;
 | 
			
		||||
 | 
			
		||||
        let specialized_pipeline_handle = pipelines.add(specialized_descriptor);
 | 
			
		||||
        render_resource_context.create_render_pipeline(
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
use super::{BindGroupDescriptor, VertexBufferDescriptor};
 | 
			
		||||
use super::{BindGroupDescriptor, VertexBufferLayout};
 | 
			
		||||
use crate::shader::ShaderLayout;
 | 
			
		||||
use bevy_utils::HashMap;
 | 
			
		||||
use std::hash::Hash;
 | 
			
		||||
@ -6,7 +6,7 @@ use std::hash::Hash;
 | 
			
		||||
#[derive(Clone, Debug, Default)]
 | 
			
		||||
pub struct PipelineLayout {
 | 
			
		||||
    pub bind_groups: Vec<BindGroupDescriptor>,
 | 
			
		||||
    pub vertex_buffer_descriptors: Vec<VertexBufferDescriptor>,
 | 
			
		||||
    pub vertex_buffer_descriptors: Vec<VertexBufferLayout>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl PipelineLayout {
 | 
			
		||||
@ -49,7 +49,7 @@ impl PipelineLayout {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for vertex_buffer_descriptor in shader_layouts[0].vertex_buffer_descriptors.iter() {
 | 
			
		||||
        for vertex_buffer_descriptor in shader_layouts[0].vertex_buffer_layout.iter() {
 | 
			
		||||
            vertex_buffer_descriptors.push(vertex_buffer_descriptor.clone());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,20 +3,48 @@ use bevy_reflect::Reflect;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct DepthStencilStateDescriptor {
 | 
			
		||||
pub struct DepthStencilState {
 | 
			
		||||
    pub format: TextureFormat,
 | 
			
		||||
    pub depth_write_enabled: bool,
 | 
			
		||||
    pub depth_compare: CompareFunction,
 | 
			
		||||
    pub stencil: StencilStateDescriptor,
 | 
			
		||||
    pub stencil: StencilState,
 | 
			
		||||
    pub bias: DepthBiasState,
 | 
			
		||||
    pub clamp_depth: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct StencilStateDescriptor {
 | 
			
		||||
    pub front: StencilStateFaceDescriptor,
 | 
			
		||||
    pub back: StencilStateFaceDescriptor,
 | 
			
		||||
pub struct StencilState {
 | 
			
		||||
    pub front: StencilFaceState,
 | 
			
		||||
    pub back: StencilFaceState,
 | 
			
		||||
    pub read_mask: u32,
 | 
			
		||||
    pub write_mask: u32,
 | 
			
		||||
}
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct MultisampleState {
 | 
			
		||||
    /// The number of samples calculated per pixel (for MSAA). For non-multisampled textures,
 | 
			
		||||
    /// this should be `1`
 | 
			
		||||
    pub count: u32,
 | 
			
		||||
    /// Bitmask that restricts the samples of a pixel modified by this pipeline. All samples
 | 
			
		||||
    /// can be enabled using the value `!0`
 | 
			
		||||
    pub mask: u64,
 | 
			
		||||
    /// When enabled, produces another sample mask per pixel based on the alpha output value, that
 | 
			
		||||
    /// is ANDed with the sample_mask and the primitive coverage to restrict the set of samples
 | 
			
		||||
    /// affected by a primitive.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The implicit mask produced for alpha of zero is guaranteed to be zero, and for alpha of one
 | 
			
		||||
    /// is guaranteed to be all 1-s.
 | 
			
		||||
    pub alpha_to_coverage_enabled: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct DepthBiasState {
 | 
			
		||||
    /// Constant depth biasing factor, in basic units of the depth format.
 | 
			
		||||
    pub constant: i32,
 | 
			
		||||
    /// Slope depth biasing factor.
 | 
			
		||||
    pub slope_scale: f32,
 | 
			
		||||
    /// Depth bias clamp value (absolute).
 | 
			
		||||
    pub clamp: f32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
 | 
			
		||||
pub enum StencilOperation {
 | 
			
		||||
@ -31,15 +59,15 @@ pub enum StencilOperation {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, PartialEq)]
 | 
			
		||||
pub struct StencilStateFaceDescriptor {
 | 
			
		||||
pub struct StencilFaceState {
 | 
			
		||||
    pub compare: CompareFunction,
 | 
			
		||||
    pub fail_op: StencilOperation,
 | 
			
		||||
    pub depth_fail_op: StencilOperation,
 | 
			
		||||
    pub pass_op: StencilOperation,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl StencilStateFaceDescriptor {
 | 
			
		||||
    pub const IGNORE: Self = StencilStateFaceDescriptor {
 | 
			
		||||
impl StencilFaceState {
 | 
			
		||||
    pub const IGNORE: Self = StencilFaceState {
 | 
			
		||||
        compare: CompareFunction::Always,
 | 
			
		||||
        fail_op: StencilOperation::Keep,
 | 
			
		||||
        depth_fail_op: StencilOperation::Keep,
 | 
			
		||||
@ -99,33 +127,48 @@ impl Default for CullMode {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
 | 
			
		||||
pub enum PolygonMode {
 | 
			
		||||
    /// Polygons are filled
 | 
			
		||||
    Fill = 0,
 | 
			
		||||
    /// Polygons are draw as line segments
 | 
			
		||||
    Line = 1,
 | 
			
		||||
    /// Polygons are draw as points
 | 
			
		||||
    Point = 2,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for PolygonMode {
 | 
			
		||||
    fn default() -> Self {
 | 
			
		||||
        PolygonMode::Fill
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Default)]
 | 
			
		||||
pub struct RasterizationStateDescriptor {
 | 
			
		||||
pub struct PrimitiveState {
 | 
			
		||||
    pub topology: PrimitiveTopology,
 | 
			
		||||
    pub strip_index_format: Option<IndexFormat>,
 | 
			
		||||
    pub front_face: FrontFace,
 | 
			
		||||
    pub cull_mode: CullMode,
 | 
			
		||||
    pub depth_bias: i32,
 | 
			
		||||
    pub depth_bias_slope_scale: f32,
 | 
			
		||||
    pub depth_bias_clamp: f32,
 | 
			
		||||
    pub clamp_depth: bool,
 | 
			
		||||
    pub polygon_mode: PolygonMode,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct ColorStateDescriptor {
 | 
			
		||||
pub struct ColorTargetState {
 | 
			
		||||
    pub format: TextureFormat,
 | 
			
		||||
    pub alpha_blend: BlendDescriptor,
 | 
			
		||||
    pub color_blend: BlendDescriptor,
 | 
			
		||||
    pub alpha_blend: BlendState,
 | 
			
		||||
    pub color_blend: BlendState,
 | 
			
		||||
    pub write_mask: ColorWrite,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, PartialEq)]
 | 
			
		||||
pub struct BlendDescriptor {
 | 
			
		||||
pub struct BlendState {
 | 
			
		||||
    pub src_factor: BlendFactor,
 | 
			
		||||
    pub dst_factor: BlendFactor,
 | 
			
		||||
    pub operation: BlendOperation,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl BlendDescriptor {
 | 
			
		||||
    pub const REPLACE: Self = BlendDescriptor {
 | 
			
		||||
impl BlendState {
 | 
			
		||||
    pub const REPLACE: Self = BlendState {
 | 
			
		||||
        src_factor: BlendFactor::One,
 | 
			
		||||
        dst_factor: BlendFactor::Zero,
 | 
			
		||||
        operation: BlendOperation::Add,
 | 
			
		||||
 | 
			
		||||
@ -8,23 +8,23 @@ use std::{
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Eq, PartialEq, Default, Reflect, Serialize, Deserialize)]
 | 
			
		||||
#[reflect_value(Serialize, Deserialize, PartialEq)]
 | 
			
		||||
pub struct VertexBufferDescriptor {
 | 
			
		||||
pub struct VertexBufferLayout {
 | 
			
		||||
    pub name: Cow<'static, str>,
 | 
			
		||||
    pub stride: u64,
 | 
			
		||||
    pub step_mode: InputStepMode,
 | 
			
		||||
    pub attributes: Vec<VertexAttributeDescriptor>,
 | 
			
		||||
    pub attributes: Vec<VertexAttribute>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl VertexBufferDescriptor {
 | 
			
		||||
impl VertexBufferLayout {
 | 
			
		||||
    pub fn new_from_attribute(
 | 
			
		||||
        attribute: VertexAttributeDescriptor,
 | 
			
		||||
        attribute: VertexAttribute,
 | 
			
		||||
        step_mode: InputStepMode,
 | 
			
		||||
    ) -> VertexBufferDescriptor {
 | 
			
		||||
        VertexBufferDescriptor {
 | 
			
		||||
    ) -> VertexBufferLayout {
 | 
			
		||||
        VertexBufferLayout {
 | 
			
		||||
            name: attribute.name.clone(),
 | 
			
		||||
            stride: attribute.format.get_size(),
 | 
			
		||||
            step_mode,
 | 
			
		||||
            attributes: vec![attribute.clone()],
 | 
			
		||||
            attributes: vec![attribute],
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -41,10 +41,10 @@ impl Default for InputStepMode {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
 | 
			
		||||
pub struct VertexAttributeDescriptor {
 | 
			
		||||
pub struct VertexAttribute {
 | 
			
		||||
    pub name: Cow<'static, str>,
 | 
			
		||||
    pub offset: u64,
 | 
			
		||||
    pub format: VertexFormat,
 | 
			
		||||
    pub offset: u64,
 | 
			
		||||
    pub shader_location: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,8 @@ use crate::{
 | 
			
		||||
    draw::{Draw, RenderCommand},
 | 
			
		||||
    pass::{ClearColor, LoadOp, PassDescriptor, TextureAttachment},
 | 
			
		||||
    pipeline::{
 | 
			
		||||
        BindGroupDescriptor, BindType, BindingDescriptor, BindingShaderStage, PipelineDescriptor,
 | 
			
		||||
        UniformProperty,
 | 
			
		||||
        BindGroupDescriptor, BindType, BindingDescriptor, BindingShaderStage, IndexFormat,
 | 
			
		||||
        PipelineDescriptor, UniformProperty,
 | 
			
		||||
    },
 | 
			
		||||
    prelude::Visible,
 | 
			
		||||
    render_graph::{Node, ResourceSlotInfo, ResourceSlots},
 | 
			
		||||
@ -109,7 +109,7 @@ impl<Q: WorldQuery> PassNode<Q> {
 | 
			
		||||
                name: "Camera".to_string(),
 | 
			
		||||
                index: 0,
 | 
			
		||||
                bind_type: BindType::Uniform {
 | 
			
		||||
                    dynamic: false,
 | 
			
		||||
                    has_dynamic_offset: false,
 | 
			
		||||
                    property: UniformProperty::Struct(vec![UniformProperty::Mat4]),
 | 
			
		||||
                },
 | 
			
		||||
                shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
 | 
			
		||||
@ -301,12 +301,12 @@ where
 | 
			
		||||
                                    render_pass.set_vertex_buffer(*slot, *buffer, *offset);
 | 
			
		||||
                                    draw_state.set_vertex_buffer(*slot, *buffer, *offset);
 | 
			
		||||
                                }
 | 
			
		||||
                                RenderCommand::SetIndexBuffer { buffer, offset } => {
 | 
			
		||||
                                    if draw_state.is_index_buffer_set(*buffer, *offset) {
 | 
			
		||||
                                RenderCommand::SetIndexBuffer { buffer, offset, index_format } => {
 | 
			
		||||
                                    if draw_state.is_index_buffer_set(*buffer, *offset, *index_format) {
 | 
			
		||||
                                        continue;
 | 
			
		||||
                                    }
 | 
			
		||||
                                    render_pass.set_index_buffer(*buffer, *offset);
 | 
			
		||||
                                    draw_state.set_index_buffer(*buffer, *offset)
 | 
			
		||||
                                    render_pass.set_index_buffer(*buffer, *offset, *index_format);
 | 
			
		||||
                                    draw_state.set_index_buffer(*buffer, *offset, *index_format);
 | 
			
		||||
                                }
 | 
			
		||||
                                RenderCommand::SetBindGroup {
 | 
			
		||||
                                    index,
 | 
			
		||||
@ -344,7 +344,7 @@ struct DrawState {
 | 
			
		||||
    pipeline: Option<Handle<PipelineDescriptor>>,
 | 
			
		||||
    bind_groups: Vec<Option<BindGroupId>>,
 | 
			
		||||
    vertex_buffers: Vec<Option<(BufferId, u64)>>,
 | 
			
		||||
    index_buffer: Option<(BufferId, u64)>,
 | 
			
		||||
    index_buffer: Option<(BufferId, u64, IndexFormat)>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl DrawState {
 | 
			
		||||
@ -364,12 +364,17 @@ impl DrawState {
 | 
			
		||||
        self.vertex_buffers[index as usize] == Some((buffer, offset))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn set_index_buffer(&mut self, buffer: BufferId, offset: u64) {
 | 
			
		||||
        self.index_buffer = Some((buffer, offset));
 | 
			
		||||
    pub fn set_index_buffer(&mut self, buffer: BufferId, offset: u64, index_format: IndexFormat) {
 | 
			
		||||
        self.index_buffer = Some((buffer, offset, index_format));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn is_index_buffer_set(&self, buffer: BufferId, offset: u64) -> bool {
 | 
			
		||||
        self.index_buffer == Some((buffer, offset))
 | 
			
		||||
    pub fn is_index_buffer_set(
 | 
			
		||||
        &self,
 | 
			
		||||
        buffer: BufferId,
 | 
			
		||||
        offset: u64,
 | 
			
		||||
        index_format: IndexFormat,
 | 
			
		||||
    ) -> bool {
 | 
			
		||||
        self.index_buffer == Some((buffer, offset, index_format))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn can_draw(&self) -> bool {
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
use super::{BindGroup, BindGroupId, BufferId, SamplerId, TextureId};
 | 
			
		||||
use crate::{
 | 
			
		||||
    pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor},
 | 
			
		||||
    pipeline::{BindGroupDescriptor, BindGroupDescriptorId, IndexFormat, PipelineDescriptor},
 | 
			
		||||
    renderer::RenderResourceContext,
 | 
			
		||||
};
 | 
			
		||||
use bevy_asset::{Asset, Handle, HandleUntyped};
 | 
			
		||||
@ -69,7 +69,7 @@ pub struct RenderResourceBindings {
 | 
			
		||||
    pub vertex_attribute_buffer: Option<BufferId>,
 | 
			
		||||
    /// A Buffer that is filled with zeros that will be used for attributes required by the shader, but undefined by the mesh.
 | 
			
		||||
    pub vertex_fallback_buffer: Option<BufferId>,
 | 
			
		||||
    pub index_buffer: Option<BufferId>,
 | 
			
		||||
    pub index_buffer: Option<(BufferId, IndexFormat)>,
 | 
			
		||||
    assets: HashSet<(HandleUntyped, TypeId)>,
 | 
			
		||||
    bind_groups: HashMap<BindGroupId, BindGroup>,
 | 
			
		||||
    bind_group_descriptors: HashMap<BindGroupDescriptorId, Option<BindGroupId>>,
 | 
			
		||||
@ -116,8 +116,8 @@ impl RenderResourceBindings {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn set_index_buffer(&mut self, index_buffer: BufferId) {
 | 
			
		||||
        self.index_buffer = Some(index_buffer);
 | 
			
		||||
    pub fn set_index_buffer(&mut self, index_buffer: BufferId, index_format: IndexFormat) {
 | 
			
		||||
        self.index_buffer = Some((index_buffer, index_format));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn create_bind_group(&mut self, descriptor: &BindGroupDescriptor) -> BindGroupStatus {
 | 
			
		||||
@ -303,7 +303,7 @@ mod tests {
 | 
			
		||||
                    index: 0,
 | 
			
		||||
                    name: "a".to_string(),
 | 
			
		||||
                    bind_type: BindType::Uniform {
 | 
			
		||||
                        dynamic: false,
 | 
			
		||||
                        has_dynamic_offset: false,
 | 
			
		||||
                        property: UniformProperty::Struct(vec![UniformProperty::Mat4]),
 | 
			
		||||
                    },
 | 
			
		||||
                    shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
 | 
			
		||||
@ -312,7 +312,7 @@ mod tests {
 | 
			
		||||
                    index: 1,
 | 
			
		||||
                    name: "b".to_string(),
 | 
			
		||||
                    bind_type: BindType::Uniform {
 | 
			
		||||
                        dynamic: false,
 | 
			
		||||
                        has_dynamic_offset: false,
 | 
			
		||||
                        property: UniformProperty::Float,
 | 
			
		||||
                    },
 | 
			
		||||
                    shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
 | 
			
		||||
 | 
			
		||||
@ -11,13 +11,13 @@ pub use shader_defs::*;
 | 
			
		||||
#[cfg(not(target_arch = "wasm32"))]
 | 
			
		||||
pub use shader_reflect::*;
 | 
			
		||||
 | 
			
		||||
use crate::pipeline::{BindGroupDescriptor, VertexBufferDescriptor};
 | 
			
		||||
use crate::pipeline::{BindGroupDescriptor, VertexBufferLayout};
 | 
			
		||||
 | 
			
		||||
/// Defines the memory layout of a shader
 | 
			
		||||
#[derive(Debug, Clone, PartialEq, Eq)]
 | 
			
		||||
pub struct ShaderLayout {
 | 
			
		||||
    pub bind_groups: Vec<BindGroupDescriptor>,
 | 
			
		||||
    pub vertex_buffer_descriptors: Vec<VertexBufferDescriptor>,
 | 
			
		||||
    pub vertex_buffer_layout: Vec<VertexBufferLayout>,
 | 
			
		||||
    pub entry_point: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,10 @@
 | 
			
		||||
use crate::{
 | 
			
		||||
    pipeline::{
 | 
			
		||||
        BindGroupDescriptor, BindType, BindingDescriptor, BindingShaderStage, InputStepMode,
 | 
			
		||||
        UniformProperty, VertexAttributeDescriptor, VertexBufferDescriptor, VertexFormat,
 | 
			
		||||
        UniformProperty, VertexAttribute, VertexBufferLayout, VertexFormat,
 | 
			
		||||
    },
 | 
			
		||||
    shader::{ShaderLayout, GL_INSTANCE_INDEX, GL_VERTEX_INDEX},
 | 
			
		||||
    texture::{TextureComponentType, TextureViewDimension},
 | 
			
		||||
    texture::{TextureSampleType, TextureViewDimension},
 | 
			
		||||
};
 | 
			
		||||
use bevy_core::AsBytes;
 | 
			
		||||
use spirv_reflect::{
 | 
			
		||||
@ -29,7 +29,7 @@ impl ShaderLayout {
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // obtain attribute descriptors from reflection
 | 
			
		||||
                let mut vertex_attribute_descriptors = Vec::new();
 | 
			
		||||
                let mut vertex_attributes = Vec::new();
 | 
			
		||||
                for input_variable in module.enumerate_input_variables(None).unwrap() {
 | 
			
		||||
                    if input_variable.name == GL_VERTEX_INDEX
 | 
			
		||||
                        || input_variable.name == GL_INSTANCE_INDEX
 | 
			
		||||
@ -37,7 +37,7 @@ impl ShaderLayout {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    // reflect vertex attribute descriptor and record it
 | 
			
		||||
                    vertex_attribute_descriptors.push(VertexAttributeDescriptor {
 | 
			
		||||
                    vertex_attributes.push(VertexAttribute {
 | 
			
		||||
                        name: input_variable.name.clone().into(),
 | 
			
		||||
                        format: reflect_vertex_format(
 | 
			
		||||
                            input_variable.type_description.as_ref().unwrap(),
 | 
			
		||||
@ -47,20 +47,19 @@ impl ShaderLayout {
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                vertex_attribute_descriptors
 | 
			
		||||
                    .sort_by(|a, b| a.shader_location.cmp(&b.shader_location));
 | 
			
		||||
                vertex_attributes.sort_by(|a, b| a.shader_location.cmp(&b.shader_location));
 | 
			
		||||
 | 
			
		||||
                let mut vertex_buffer_descriptors = Vec::new();
 | 
			
		||||
                for vertex_attribute_descriptor in vertex_attribute_descriptors.drain(..) {
 | 
			
		||||
                let mut vertex_buffer_layout = Vec::new();
 | 
			
		||||
                for vertex_attribute in vertex_attributes.drain(..) {
 | 
			
		||||
                    let mut instance = false;
 | 
			
		||||
                    // obtain buffer name and instancing flag
 | 
			
		||||
                    let current_buffer_name = {
 | 
			
		||||
                        if bevy_conventions {
 | 
			
		||||
                            if vertex_attribute_descriptor.name == GL_VERTEX_INDEX {
 | 
			
		||||
                            if vertex_attribute.name == GL_VERTEX_INDEX {
 | 
			
		||||
                                GL_VERTEX_INDEX.to_string()
 | 
			
		||||
                            } else {
 | 
			
		||||
                                instance = vertex_attribute_descriptor.name.starts_with("I_");
 | 
			
		||||
                                vertex_attribute_descriptor.name.to_string()
 | 
			
		||||
                                instance = vertex_attribute.name.starts_with("I_");
 | 
			
		||||
                                vertex_attribute.name.to_string()
 | 
			
		||||
                            }
 | 
			
		||||
                        } else {
 | 
			
		||||
                            "DefaultVertex".to_string()
 | 
			
		||||
@ -68,8 +67,8 @@ impl ShaderLayout {
 | 
			
		||||
                    };
 | 
			
		||||
 | 
			
		||||
                    // create a new buffer descriptor, per attribute!
 | 
			
		||||
                    vertex_buffer_descriptors.push(VertexBufferDescriptor {
 | 
			
		||||
                        attributes: vec![vertex_attribute_descriptor],
 | 
			
		||||
                    vertex_buffer_layout.push(VertexBufferLayout {
 | 
			
		||||
                        attributes: vec![vertex_attribute],
 | 
			
		||||
                        name: current_buffer_name.into(),
 | 
			
		||||
                        step_mode: if instance {
 | 
			
		||||
                            InputStepMode::Instance
 | 
			
		||||
@ -82,7 +81,7 @@ impl ShaderLayout {
 | 
			
		||||
 | 
			
		||||
                ShaderLayout {
 | 
			
		||||
                    bind_groups,
 | 
			
		||||
                    vertex_buffer_descriptors,
 | 
			
		||||
                    vertex_buffer_layout,
 | 
			
		||||
                    entry_point: entry_point_name,
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@ -123,27 +122,34 @@ fn reflect_binding(
 | 
			
		||||
        ReflectDescriptorType::UniformBuffer => (
 | 
			
		||||
            &type_description.type_name,
 | 
			
		||||
            BindType::Uniform {
 | 
			
		||||
                dynamic: false,
 | 
			
		||||
                has_dynamic_offset: false,
 | 
			
		||||
                property: reflect_uniform(type_description),
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        ReflectDescriptorType::SampledImage => (
 | 
			
		||||
            &binding.name,
 | 
			
		||||
            BindType::SampledTexture {
 | 
			
		||||
                dimension: reflect_dimension(type_description),
 | 
			
		||||
                component_type: TextureComponentType::Float,
 | 
			
		||||
            BindType::Texture {
 | 
			
		||||
                view_dimension: reflect_dimension(type_description),
 | 
			
		||||
                sample_type: TextureSampleType::Float { filterable: true },
 | 
			
		||||
                multisampled: false,
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        ReflectDescriptorType::StorageBuffer => (
 | 
			
		||||
            &type_description.type_name,
 | 
			
		||||
            BindType::StorageBuffer {
 | 
			
		||||
                dynamic: false,
 | 
			
		||||
                has_dynamic_offset: false,
 | 
			
		||||
                readonly: true,
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        // TODO: detect comparison "true" case: https://github.com/gpuweb/gpuweb/issues/552
 | 
			
		||||
        ReflectDescriptorType::Sampler => (&binding.name, BindType::Sampler { comparison: false }),
 | 
			
		||||
        // TODO: detect filtering "true" case
 | 
			
		||||
        ReflectDescriptorType::Sampler => (
 | 
			
		||||
            &binding.name,
 | 
			
		||||
            BindType::Sampler {
 | 
			
		||||
                comparison: false,
 | 
			
		||||
                filtering: false,
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        _ => panic!("Unsupported bind type {:?}.", binding.descriptor_type),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
@ -302,8 +308,8 @@ mod tests {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    use crate::shader::{Shader, ShaderStage};
 | 
			
		||||
 | 
			
		||||
    impl VertexBufferDescriptor {
 | 
			
		||||
        pub fn test_zero_stride(mut self) -> VertexBufferDescriptor {
 | 
			
		||||
    impl VertexBufferLayout {
 | 
			
		||||
        pub fn test_zero_stride(mut self) -> VertexBufferLayout {
 | 
			
		||||
            self.stride = 0;
 | 
			
		||||
            self
 | 
			
		||||
        }
 | 
			
		||||
@ -338,9 +344,9 @@ mod tests {
 | 
			
		||||
            layout,
 | 
			
		||||
            ShaderLayout {
 | 
			
		||||
                entry_point: "main".into(),
 | 
			
		||||
                vertex_buffer_descriptors: vec![
 | 
			
		||||
                    VertexBufferDescriptor::new_from_attribute(
 | 
			
		||||
                        VertexAttributeDescriptor {
 | 
			
		||||
                vertex_buffer_layout: vec![
 | 
			
		||||
                    VertexBufferLayout::new_from_attribute(
 | 
			
		||||
                        VertexAttribute {
 | 
			
		||||
                            name: "Vertex_Position".into(),
 | 
			
		||||
                            format: VertexFormat::Float4,
 | 
			
		||||
                            offset: 0,
 | 
			
		||||
@ -349,8 +355,8 @@ mod tests {
 | 
			
		||||
                        InputStepMode::Vertex
 | 
			
		||||
                    )
 | 
			
		||||
                    .test_zero_stride(),
 | 
			
		||||
                    VertexBufferDescriptor::new_from_attribute(
 | 
			
		||||
                        VertexAttributeDescriptor {
 | 
			
		||||
                    VertexBufferLayout::new_from_attribute(
 | 
			
		||||
                        VertexAttribute {
 | 
			
		||||
                            name: "Vertex_Normal".into(),
 | 
			
		||||
                            format: VertexFormat::Uint4,
 | 
			
		||||
                            offset: 0,
 | 
			
		||||
@ -359,8 +365,8 @@ mod tests {
 | 
			
		||||
                        InputStepMode::Vertex
 | 
			
		||||
                    )
 | 
			
		||||
                    .test_zero_stride(),
 | 
			
		||||
                    VertexBufferDescriptor::new_from_attribute(
 | 
			
		||||
                        VertexAttributeDescriptor {
 | 
			
		||||
                    VertexBufferLayout::new_from_attribute(
 | 
			
		||||
                        VertexAttribute {
 | 
			
		||||
                            name: "I_TestInstancing_Property".into(),
 | 
			
		||||
                            format: VertexFormat::Uint4,
 | 
			
		||||
                            offset: 0,
 | 
			
		||||
@ -377,7 +383,7 @@ mod tests {
 | 
			
		||||
                            index: 0,
 | 
			
		||||
                            name: "Camera".into(),
 | 
			
		||||
                            bind_type: BindType::Uniform {
 | 
			
		||||
                                dynamic: false,
 | 
			
		||||
                                has_dynamic_offset: false,
 | 
			
		||||
                                property: UniformProperty::Struct(vec![UniformProperty::Mat4]),
 | 
			
		||||
                            },
 | 
			
		||||
                            shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
 | 
			
		||||
@ -388,10 +394,10 @@ mod tests {
 | 
			
		||||
                        vec![BindingDescriptor {
 | 
			
		||||
                            index: 0,
 | 
			
		||||
                            name: "Texture".into(),
 | 
			
		||||
                            bind_type: BindType::SampledTexture {
 | 
			
		||||
                            bind_type: BindType::Texture {
 | 
			
		||||
                                multisampled: false,
 | 
			
		||||
                                dimension: TextureViewDimension::D2,
 | 
			
		||||
                                component_type: TextureComponentType::Float,
 | 
			
		||||
                                view_dimension: TextureViewDimension::D2,
 | 
			
		||||
                                sample_type: TextureSampleType::Float { filterable: true }
 | 
			
		||||
                            },
 | 
			
		||||
                            shader_stage: BindingShaderStage::VERTEX,
 | 
			
		||||
                        }]
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,7 @@ pub struct SamplerDescriptor {
 | 
			
		||||
    pub lod_max_clamp: f32,
 | 
			
		||||
    pub compare_function: Option<CompareFunction>,
 | 
			
		||||
    pub anisotropy_clamp: Option<NonZeroU8>,
 | 
			
		||||
    pub border_color: Option<SamplerBorderColor>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl SamplerDescriptor {
 | 
			
		||||
@ -38,6 +39,7 @@ impl Default for SamplerDescriptor {
 | 
			
		||||
            lod_max_clamp: std::f32::MAX,
 | 
			
		||||
            compare_function: None,
 | 
			
		||||
            anisotropy_clamp: None,
 | 
			
		||||
            border_color: None,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -68,3 +70,10 @@ impl Default for FilterMode {
 | 
			
		||||
        FilterMode::Nearest
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
 | 
			
		||||
pub enum SamplerBorderColor {
 | 
			
		||||
    TransparentBlack,
 | 
			
		||||
    OpaqueBlack,
 | 
			
		||||
    OpaqueWhite,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -40,3 +40,29 @@ impl Default for TextureDescriptor {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Hash, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
 | 
			
		||||
pub enum StorageTextureAccess {
 | 
			
		||||
    /// The texture can only be read in the shader and it must be annotated with `readonly`.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Example GLSL syntax:
 | 
			
		||||
    /// ```cpp,ignore
 | 
			
		||||
    /// layout(set=0, binding=0, r32f) readonly uniform image2D myStorageImage;
 | 
			
		||||
    /// ```
 | 
			
		||||
    ReadOnly,
 | 
			
		||||
    /// The texture can only be written in the shader and it must be annotated with `writeonly`.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Example GLSL syntax:
 | 
			
		||||
    /// ```cpp,ignore
 | 
			
		||||
    /// layout(set=0, binding=0, r32f) writeonly uniform image2D myStorageImage;
 | 
			
		||||
    /// ```
 | 
			
		||||
    WriteOnly,
 | 
			
		||||
    /// The texture can be both read and written in the shader.
 | 
			
		||||
    /// [`Features::STORAGE_TEXTURE_ACCESS_READ_WRITE`] must be enabled to use this access mode.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Example GLSL syntax:
 | 
			
		||||
    /// ```cpp,ignore
 | 
			
		||||
    /// layout(set=0, binding=0, r32f) uniform image2D myStorageImage;
 | 
			
		||||
    /// ```
 | 
			
		||||
    ReadWrite,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -49,9 +49,41 @@ impl Extent3d {
 | 
			
		||||
 | 
			
		||||
/// Type of data shaders will read from a texture.
 | 
			
		||||
#[derive(Copy, Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
 | 
			
		||||
pub enum TextureComponentType {
 | 
			
		||||
    Float,
 | 
			
		||||
pub enum TextureSampleType {
 | 
			
		||||
    /// Sampling returns floats.
 | 
			
		||||
    ///
 | 
			
		||||
    /// If `filterable` is false, the texture can't be sampled with
 | 
			
		||||
    /// a filtering sampler.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Example GLSL syntax:
 | 
			
		||||
    /// ```cpp,ignore
 | 
			
		||||
    /// layout(binding = 0)
 | 
			
		||||
    /// uniform texture2D t;
 | 
			
		||||
    /// ```
 | 
			
		||||
    Float { filterable: bool },
 | 
			
		||||
    /// Sampling does the depth reference comparison.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Example GLSL syntax:
 | 
			
		||||
    /// ```cpp,ignore
 | 
			
		||||
    /// layout(binding = 0)
 | 
			
		||||
    /// uniform texture2DShadow t;
 | 
			
		||||
    /// ```
 | 
			
		||||
    Depth,
 | 
			
		||||
    /// Sampling returns signed integers.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Example GLSL syntax:
 | 
			
		||||
    /// ```cpp,ignore
 | 
			
		||||
    /// layout(binding = 0)
 | 
			
		||||
    /// uniform itexture2D t;
 | 
			
		||||
    /// ```
 | 
			
		||||
    Sint,
 | 
			
		||||
    /// Sampling returns unsigned integers.
 | 
			
		||||
    ///
 | 
			
		||||
    /// Example GLSL syntax:
 | 
			
		||||
    /// ```cpp,ignore
 | 
			
		||||
    /// layout(binding = 0)
 | 
			
		||||
    /// uniform utexture2D t;
 | 
			
		||||
    /// ```
 | 
			
		||||
    Uint,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -4,9 +4,8 @@ use bevy_ecs::Resources;
 | 
			
		||||
use bevy_reflect::TypeUuid;
 | 
			
		||||
use bevy_render::{
 | 
			
		||||
    pipeline::{
 | 
			
		||||
        BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite,
 | 
			
		||||
        CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, PipelineDescriptor,
 | 
			
		||||
        RasterizationStateDescriptor, StencilStateDescriptor, StencilStateFaceDescriptor,
 | 
			
		||||
        BlendFactor, BlendOperation, BlendState, ColorTargetState, ColorWrite, CompareFunction,
 | 
			
		||||
        DepthBiasState, DepthStencilState, PipelineDescriptor, StencilFaceState, StencilState,
 | 
			
		||||
    },
 | 
			
		||||
    render_graph::{base, AssetRenderResourcesNode, RenderGraph, RenderResourcesNode},
 | 
			
		||||
    shader::{Shader, ShaderStage, ShaderStages},
 | 
			
		||||
@ -21,33 +20,31 @@ pub const SPRITE_SHEET_PIPELINE_HANDLE: HandleUntyped =
 | 
			
		||||
 | 
			
		||||
pub fn build_sprite_sheet_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
 | 
			
		||||
    PipelineDescriptor {
 | 
			
		||||
        rasterization_state: Some(RasterizationStateDescriptor {
 | 
			
		||||
            front_face: FrontFace::Ccw,
 | 
			
		||||
            cull_mode: CullMode::None,
 | 
			
		||||
            depth_bias: 0,
 | 
			
		||||
            depth_bias_slope_scale: 0.0,
 | 
			
		||||
            depth_bias_clamp: 0.0,
 | 
			
		||||
            clamp_depth: false,
 | 
			
		||||
        }),
 | 
			
		||||
        depth_stencil_state: Some(DepthStencilStateDescriptor {
 | 
			
		||||
        depth_stencil: Some(DepthStencilState {
 | 
			
		||||
            format: TextureFormat::Depth32Float,
 | 
			
		||||
            depth_write_enabled: true,
 | 
			
		||||
            depth_compare: CompareFunction::LessEqual,
 | 
			
		||||
            stencil: StencilStateDescriptor {
 | 
			
		||||
                front: StencilStateFaceDescriptor::IGNORE,
 | 
			
		||||
                back: StencilStateFaceDescriptor::IGNORE,
 | 
			
		||||
            stencil: StencilState {
 | 
			
		||||
                front: StencilFaceState::IGNORE,
 | 
			
		||||
                back: StencilFaceState::IGNORE,
 | 
			
		||||
                read_mask: 0,
 | 
			
		||||
                write_mask: 0,
 | 
			
		||||
            },
 | 
			
		||||
            bias: DepthBiasState {
 | 
			
		||||
                constant: 0,
 | 
			
		||||
                slope_scale: 0.0,
 | 
			
		||||
                clamp: 0.0,
 | 
			
		||||
            },
 | 
			
		||||
            clamp_depth: false,
 | 
			
		||||
        }),
 | 
			
		||||
        color_states: vec![ColorStateDescriptor {
 | 
			
		||||
        color_target_states: vec![ColorTargetState {
 | 
			
		||||
            format: TextureFormat::default(),
 | 
			
		||||
            color_blend: BlendDescriptor {
 | 
			
		||||
            color_blend: BlendState {
 | 
			
		||||
                src_factor: BlendFactor::SrcAlpha,
 | 
			
		||||
                dst_factor: BlendFactor::OneMinusSrcAlpha,
 | 
			
		||||
                operation: BlendOperation::Add,
 | 
			
		||||
            },
 | 
			
		||||
            alpha_blend: BlendDescriptor {
 | 
			
		||||
            alpha_blend: BlendState {
 | 
			
		||||
                src_factor: BlendFactor::One,
 | 
			
		||||
                dst_factor: BlendFactor::One,
 | 
			
		||||
                operation: BlendOperation::Add,
 | 
			
		||||
@ -69,33 +66,31 @@ pub fn build_sprite_sheet_pipeline(shaders: &mut Assets<Shader>) -> PipelineDesc
 | 
			
		||||
 | 
			
		||||
pub fn build_sprite_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
 | 
			
		||||
    PipelineDescriptor {
 | 
			
		||||
        rasterization_state: Some(RasterizationStateDescriptor {
 | 
			
		||||
            front_face: FrontFace::Ccw,
 | 
			
		||||
            cull_mode: CullMode::None,
 | 
			
		||||
            depth_bias: 0,
 | 
			
		||||
            depth_bias_slope_scale: 0.0,
 | 
			
		||||
            depth_bias_clamp: 0.0,
 | 
			
		||||
            clamp_depth: false,
 | 
			
		||||
        }),
 | 
			
		||||
        depth_stencil_state: Some(DepthStencilStateDescriptor {
 | 
			
		||||
        depth_stencil: Some(DepthStencilState {
 | 
			
		||||
            format: TextureFormat::Depth32Float,
 | 
			
		||||
            depth_write_enabled: true,
 | 
			
		||||
            depth_compare: CompareFunction::LessEqual,
 | 
			
		||||
            stencil: StencilStateDescriptor {
 | 
			
		||||
                front: StencilStateFaceDescriptor::IGNORE,
 | 
			
		||||
                back: StencilStateFaceDescriptor::IGNORE,
 | 
			
		||||
            stencil: StencilState {
 | 
			
		||||
                front: StencilFaceState::IGNORE,
 | 
			
		||||
                back: StencilFaceState::IGNORE,
 | 
			
		||||
                read_mask: 0,
 | 
			
		||||
                write_mask: 0,
 | 
			
		||||
            },
 | 
			
		||||
            bias: DepthBiasState {
 | 
			
		||||
                constant: 0,
 | 
			
		||||
                slope_scale: 0.0,
 | 
			
		||||
                clamp: 0.0,
 | 
			
		||||
            },
 | 
			
		||||
            clamp_depth: false,
 | 
			
		||||
        }),
 | 
			
		||||
        color_states: vec![ColorStateDescriptor {
 | 
			
		||||
        color_target_states: vec![ColorTargetState {
 | 
			
		||||
            format: TextureFormat::default(),
 | 
			
		||||
            color_blend: BlendDescriptor {
 | 
			
		||||
            color_blend: BlendState {
 | 
			
		||||
                src_factor: BlendFactor::SrcAlpha,
 | 
			
		||||
                dst_factor: BlendFactor::OneMinusSrcAlpha,
 | 
			
		||||
                operation: BlendOperation::Add,
 | 
			
		||||
            },
 | 
			
		||||
            alpha_blend: BlendDescriptor {
 | 
			
		||||
            alpha_blend: BlendState {
 | 
			
		||||
                src_factor: BlendFactor::One,
 | 
			
		||||
                dst_factor: BlendFactor::One,
 | 
			
		||||
                operation: BlendOperation::Add,
 | 
			
		||||
 | 
			
		||||
@ -3,13 +3,14 @@ use bevy_render::{
 | 
			
		||||
    draw::{Draw, DrawContext, DrawError, Drawable},
 | 
			
		||||
    mesh,
 | 
			
		||||
    mesh::Mesh,
 | 
			
		||||
    pipeline::{PipelineSpecialization, VertexBufferDescriptor},
 | 
			
		||||
    pipeline::{PipelineSpecialization, VertexBufferLayout},
 | 
			
		||||
    prelude::Msaa,
 | 
			
		||||
    renderer::{BindGroup, RenderResourceBindings, RenderResourceId},
 | 
			
		||||
};
 | 
			
		||||
use bevy_sprite::TextureAtlasSprite;
 | 
			
		||||
 | 
			
		||||
use crate::{PositionedGlyph, TextSection};
 | 
			
		||||
use bevy_render::pipeline::IndexFormat;
 | 
			
		||||
 | 
			
		||||
pub struct DrawableText<'a> {
 | 
			
		||||
    pub render_resource_bindings: &'a mut RenderResourceBindings,
 | 
			
		||||
@ -18,7 +19,7 @@ pub struct DrawableText<'a> {
 | 
			
		||||
    pub sections: &'a [TextSection],
 | 
			
		||||
    pub text_glyphs: &'a Vec<PositionedGlyph>,
 | 
			
		||||
    pub msaa: &'a Msaa,
 | 
			
		||||
    pub font_quad_vertex_descriptor: &'a VertexBufferDescriptor,
 | 
			
		||||
    pub font_quad_vertex_layout: &'a VertexBufferLayout,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> Drawable for DrawableText<'a> {
 | 
			
		||||
@ -28,7 +29,7 @@ impl<'a> Drawable for DrawableText<'a> {
 | 
			
		||||
            &bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE.typed(),
 | 
			
		||||
            &PipelineSpecialization {
 | 
			
		||||
                sample_count: self.msaa.samples,
 | 
			
		||||
                vertex_buffer_descriptor: self.font_quad_vertex_descriptor.clone(),
 | 
			
		||||
                vertex_buffer_layout: self.font_quad_vertex_layout.clone(),
 | 
			
		||||
                ..Default::default()
 | 
			
		||||
            },
 | 
			
		||||
        )?;
 | 
			
		||||
@ -53,7 +54,7 @@ impl<'a> Drawable for DrawableText<'a> {
 | 
			
		||||
                mesh::INDEX_BUFFER_ASSET_INDEX,
 | 
			
		||||
            )
 | 
			
		||||
        {
 | 
			
		||||
            draw.set_index_buffer(quad_index_buffer, 0);
 | 
			
		||||
            draw.set_index_buffer(quad_index_buffer, 0, IndexFormat::Uint32);
 | 
			
		||||
            if let Some(buffer_info) = render_resource_context.get_buffer_info(quad_index_buffer) {
 | 
			
		||||
                indices = 0..(buffer_info.size / 4) as u32;
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ pub fn draw_text2d_system(
 | 
			
		||||
    >,
 | 
			
		||||
) {
 | 
			
		||||
    let font_quad = meshes.get(&QUAD_HANDLE).unwrap();
 | 
			
		||||
    let vertex_buffer_descriptor = font_quad.get_vertex_buffer_descriptor();
 | 
			
		||||
    let font_quad_vertex_layout = font_quad.get_vertex_buffer_layout();
 | 
			
		||||
 | 
			
		||||
    let scale_factor = if let Some(window) = windows.get_primary() {
 | 
			
		||||
        window.scale_factor() as f32
 | 
			
		||||
@ -106,7 +106,7 @@ pub fn draw_text2d_system(
 | 
			
		||||
                position,
 | 
			
		||||
                msaa: &msaa,
 | 
			
		||||
                text_glyphs: &text_glyphs.glyphs,
 | 
			
		||||
                font_quad_vertex_descriptor: &vertex_buffer_descriptor,
 | 
			
		||||
                font_quad_vertex_layout: &font_quad_vertex_layout,
 | 
			
		||||
                scale_factor,
 | 
			
		||||
                sections: &text.sections,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
@ -23,33 +23,31 @@ pub const UI_PIPELINE_HANDLE: HandleUntyped =
 | 
			
		||||
 | 
			
		||||
pub fn build_ui_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
 | 
			
		||||
    PipelineDescriptor {
 | 
			
		||||
        rasterization_state: Some(RasterizationStateDescriptor {
 | 
			
		||||
            front_face: FrontFace::Ccw,
 | 
			
		||||
            cull_mode: CullMode::Back,
 | 
			
		||||
            depth_bias: 0,
 | 
			
		||||
            depth_bias_slope_scale: 0.0,
 | 
			
		||||
            depth_bias_clamp: 0.0,
 | 
			
		||||
            clamp_depth: false,
 | 
			
		||||
        }),
 | 
			
		||||
        depth_stencil_state: Some(DepthStencilStateDescriptor {
 | 
			
		||||
        depth_stencil: Some(DepthStencilState {
 | 
			
		||||
            format: TextureFormat::Depth32Float,
 | 
			
		||||
            depth_write_enabled: true,
 | 
			
		||||
            depth_compare: CompareFunction::Less,
 | 
			
		||||
            stencil: StencilStateDescriptor {
 | 
			
		||||
                front: StencilStateFaceDescriptor::IGNORE,
 | 
			
		||||
                back: StencilStateFaceDescriptor::IGNORE,
 | 
			
		||||
            stencil: StencilState {
 | 
			
		||||
                front: StencilFaceState::IGNORE,
 | 
			
		||||
                back: StencilFaceState::IGNORE,
 | 
			
		||||
                read_mask: 0,
 | 
			
		||||
                write_mask: 0,
 | 
			
		||||
            },
 | 
			
		||||
            bias: DepthBiasState {
 | 
			
		||||
                constant: 0,
 | 
			
		||||
                slope_scale: 0.0,
 | 
			
		||||
                clamp: 0.0,
 | 
			
		||||
            },
 | 
			
		||||
            clamp_depth: false,
 | 
			
		||||
        }),
 | 
			
		||||
        color_states: vec![ColorStateDescriptor {
 | 
			
		||||
        color_target_states: vec![ColorTargetState {
 | 
			
		||||
            format: TextureFormat::default(),
 | 
			
		||||
            color_blend: BlendDescriptor {
 | 
			
		||||
            color_blend: BlendState {
 | 
			
		||||
                src_factor: BlendFactor::SrcAlpha,
 | 
			
		||||
                dst_factor: BlendFactor::OneMinusSrcAlpha,
 | 
			
		||||
                operation: BlendOperation::Add,
 | 
			
		||||
            },
 | 
			
		||||
            alpha_blend: BlendDescriptor {
 | 
			
		||||
            alpha_blend: BlendState {
 | 
			
		||||
                src_factor: BlendFactor::One,
 | 
			
		||||
                dst_factor: BlendFactor::One,
 | 
			
		||||
                operation: BlendOperation::Add,
 | 
			
		||||
 | 
			
		||||
@ -142,7 +142,7 @@ pub fn draw_text_system(
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let font_quad = meshes.get(&QUAD_HANDLE).unwrap();
 | 
			
		||||
    let vertex_buffer_descriptor = font_quad.get_vertex_buffer_descriptor();
 | 
			
		||||
    let vertex_buffer_layout = font_quad.get_vertex_buffer_layout();
 | 
			
		||||
 | 
			
		||||
    for (entity, mut draw, visible, text, node, global_transform) in query.iter_mut() {
 | 
			
		||||
        if !visible.is_visible {
 | 
			
		||||
@ -158,7 +158,7 @@ pub fn draw_text_system(
 | 
			
		||||
                scale_factor: scale_factor as f32,
 | 
			
		||||
                msaa: &msaa,
 | 
			
		||||
                text_glyphs: &text_glyphs.glyphs,
 | 
			
		||||
                font_quad_vertex_descriptor: &vertex_buffer_descriptor,
 | 
			
		||||
                font_quad_vertex_layout: &vertex_buffer_layout,
 | 
			
		||||
                sections: &text.sections,
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,7 @@ bevy_winit = { path = "../bevy_winit", optional = true, version = "0.4.0" }
 | 
			
		||||
bevy_utils = { path = "../bevy_utils", version = "0.4.0" }
 | 
			
		||||
 | 
			
		||||
# other
 | 
			
		||||
wgpu = "0.6"
 | 
			
		||||
wgpu = "0.7"
 | 
			
		||||
futures-lite = "1.4.0"
 | 
			
		||||
crossbeam-channel = "0.4.4"
 | 
			
		||||
crossbeam-utils = "0.7.2"
 | 
			
		||||
 | 
			
		||||
@ -206,6 +206,7 @@ pub fn create_render_pass<'a, 'b>(
 | 
			
		||||
    encoder: &'a mut wgpu::CommandEncoder,
 | 
			
		||||
) -> wgpu::RenderPass<'a> {
 | 
			
		||||
    encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
 | 
			
		||||
        label: None,
 | 
			
		||||
        color_attachments: &pass_descriptor
 | 
			
		||||
            .color_attachments
 | 
			
		||||
            .iter()
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,6 @@
 | 
			
		||||
use crate::{
 | 
			
		||||
    wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto},
 | 
			
		||||
    WgpuBindGroupInfo, WgpuResources,
 | 
			
		||||
};
 | 
			
		||||
use crate::{wgpu_type_converter::WgpuInto, WgpuBindGroupInfo, WgpuResources};
 | 
			
		||||
 | 
			
		||||
use crate::wgpu_type_converter::OwnedWgpuVertexBufferLayout;
 | 
			
		||||
use bevy_asset::{Assets, Handle, HandleUntyped};
 | 
			
		||||
use bevy_render::{
 | 
			
		||||
    pipeline::{
 | 
			
		||||
@ -18,7 +16,7 @@ use bevy_render::{
 | 
			
		||||
use bevy_utils::tracing::trace;
 | 
			
		||||
use bevy_window::{Window, WindowId};
 | 
			
		||||
use futures_lite::future;
 | 
			
		||||
use std::{borrow::Cow, ops::Range, sync::Arc};
 | 
			
		||||
use std::{borrow::Cow, num::NonZeroU64, ops::Range, sync::Arc};
 | 
			
		||||
use wgpu::util::DeviceExt;
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
@ -331,7 +329,11 @@ impl RenderResourceContext for WgpuRenderResourceContext {
 | 
			
		||||
        let spirv: Cow<[u32]> = shader.get_spirv(None).unwrap().into();
 | 
			
		||||
        let shader_module = self
 | 
			
		||||
            .device
 | 
			
		||||
            .create_shader_module(wgpu::ShaderModuleSource::SpirV(spirv));
 | 
			
		||||
            .create_shader_module(&wgpu::ShaderModuleDescriptor {
 | 
			
		||||
                label: None,
 | 
			
		||||
                source: wgpu::ShaderSource::SpirV(spirv),
 | 
			
		||||
                flags: Default::default(),
 | 
			
		||||
            });
 | 
			
		||||
        shader_modules.insert(shader_handle.clone_weak(), shader_module);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -453,13 +455,13 @@ impl RenderResourceContext for WgpuRenderResourceContext {
 | 
			
		||||
            .vertex_buffer_descriptors
 | 
			
		||||
            .iter()
 | 
			
		||||
            .map(|v| v.wgpu_into())
 | 
			
		||||
            .collect::<Vec<OwnedWgpuVertexBufferDescriptor>>();
 | 
			
		||||
            .collect::<Vec<OwnedWgpuVertexBufferLayout>>();
 | 
			
		||||
 | 
			
		||||
        let color_states = pipeline_descriptor
 | 
			
		||||
            .color_states
 | 
			
		||||
            .color_target_states
 | 
			
		||||
            .iter()
 | 
			
		||||
            .map(|c| c.wgpu_into())
 | 
			
		||||
            .collect::<Vec<wgpu::ColorStateDescriptor>>();
 | 
			
		||||
            .collect::<Vec<wgpu::ColorTargetState>>();
 | 
			
		||||
 | 
			
		||||
        self.create_shader_module(&pipeline_descriptor.shader_stages.vertex, shaders);
 | 
			
		||||
 | 
			
		||||
@ -476,41 +478,31 @@ impl RenderResourceContext for WgpuRenderResourceContext {
 | 
			
		||||
            Some(ref fragment_handle) => Some(shader_modules.get(fragment_handle).unwrap()),
 | 
			
		||||
            None => None,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
 | 
			
		||||
            label: None,
 | 
			
		||||
            layout: Some(&pipeline_layout),
 | 
			
		||||
            vertex_stage: wgpu::ProgrammableStageDescriptor {
 | 
			
		||||
            vertex: wgpu::VertexState {
 | 
			
		||||
                module: &vertex_shader_module,
 | 
			
		||||
                entry_point: "main",
 | 
			
		||||
                buffers: &owned_vertex_buffer_descriptors
 | 
			
		||||
                    .iter()
 | 
			
		||||
                    .map(|v| v.into())
 | 
			
		||||
                    .collect::<Vec<wgpu::VertexBufferLayout>>(),
 | 
			
		||||
            },
 | 
			
		||||
            fragment_stage: match pipeline_descriptor.shader_stages.fragment {
 | 
			
		||||
                Some(_) => Some(wgpu::ProgrammableStageDescriptor {
 | 
			
		||||
            fragment: match pipeline_descriptor.shader_stages.fragment {
 | 
			
		||||
                Some(_) => Some(wgpu::FragmentState {
 | 
			
		||||
                    entry_point: "main",
 | 
			
		||||
                    module: fragment_shader_module.as_ref().unwrap(),
 | 
			
		||||
                    targets: color_states.as_slice(),
 | 
			
		||||
                }),
 | 
			
		||||
                None => None,
 | 
			
		||||
            },
 | 
			
		||||
            rasterization_state: pipeline_descriptor
 | 
			
		||||
                .rasterization_state
 | 
			
		||||
                .as_ref()
 | 
			
		||||
                .map(|r| r.wgpu_into()),
 | 
			
		||||
            primitive_topology: pipeline_descriptor.primitive_topology.wgpu_into(),
 | 
			
		||||
            color_states: &color_states,
 | 
			
		||||
            depth_stencil_state: pipeline_descriptor
 | 
			
		||||
                .depth_stencil_state
 | 
			
		||||
                .as_ref()
 | 
			
		||||
                .map(|d| d.wgpu_into()),
 | 
			
		||||
            vertex_state: wgpu::VertexStateDescriptor {
 | 
			
		||||
                index_format: pipeline_descriptor.index_format.wgpu_into(),
 | 
			
		||||
                vertex_buffers: &owned_vertex_buffer_descriptors
 | 
			
		||||
                    .iter()
 | 
			
		||||
                    .map(|v| v.into())
 | 
			
		||||
                    .collect::<Vec<wgpu::VertexBufferDescriptor>>(),
 | 
			
		||||
            },
 | 
			
		||||
            sample_count: pipeline_descriptor.sample_count,
 | 
			
		||||
            sample_mask: pipeline_descriptor.sample_mask,
 | 
			
		||||
            alpha_to_coverage_enabled: pipeline_descriptor.alpha_to_coverage_enabled,
 | 
			
		||||
            primitive: pipeline_descriptor.primitive.clone().wgpu_into(),
 | 
			
		||||
            depth_stencil: pipeline_descriptor
 | 
			
		||||
                .depth_stencil
 | 
			
		||||
                .clone()
 | 
			
		||||
                .map(|depth_stencil| depth_stencil.wgpu_into()),
 | 
			
		||||
            multisample: pipeline_descriptor.multisample.clone().wgpu_into(),
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        let render_pipeline = self
 | 
			
		||||
@ -564,7 +556,13 @@ impl RenderResourceContext for WgpuRenderResourceContext {
 | 
			
		||||
                        }
 | 
			
		||||
                        RenderResourceBinding::Buffer { buffer, range, .. } => {
 | 
			
		||||
                            let wgpu_buffer = buffers.get(&buffer).unwrap();
 | 
			
		||||
                            wgpu::BindingResource::Buffer(wgpu_buffer.slice(range.clone()))
 | 
			
		||||
                            let size = NonZeroU64::new(range.end - range.start)
 | 
			
		||||
                                .expect("Size of the buffer needs to be greater than 0!");
 | 
			
		||||
                            wgpu::BindingResource::Buffer {
 | 
			
		||||
                                buffer: wgpu_buffer,
 | 
			
		||||
                                offset: range.start,
 | 
			
		||||
                                size: Some(size),
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    };
 | 
			
		||||
                    wgpu::BindGroupEntry {
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
use crate::{renderer::WgpuRenderContext, WgpuResourceRefs};
 | 
			
		||||
use crate::{renderer::WgpuRenderContext, wgpu_type_converter::WgpuInto, WgpuResourceRefs};
 | 
			
		||||
use bevy_asset::Handle;
 | 
			
		||||
use bevy_render::{
 | 
			
		||||
    pass::RenderPass,
 | 
			
		||||
    pipeline::{BindGroupDescriptorId, PipelineDescriptor},
 | 
			
		||||
    pipeline::{BindGroupDescriptorId, IndexFormat, PipelineDescriptor},
 | 
			
		||||
    renderer::{BindGroupId, BufferId, RenderContext},
 | 
			
		||||
};
 | 
			
		||||
use bevy_utils::tracing::trace;
 | 
			
		||||
@ -40,9 +40,10 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
 | 
			
		||||
        self.render_pass.set_stencil_reference(reference);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn set_index_buffer(&mut self, buffer_id: BufferId, offset: u64) {
 | 
			
		||||
    fn set_index_buffer(&mut self, buffer_id: BufferId, offset: u64, index_format: IndexFormat) {
 | 
			
		||||
        let buffer = self.wgpu_resources.buffers.get(&buffer_id).unwrap();
 | 
			
		||||
        self.render_pass.set_index_buffer(buffer.slice(offset..));
 | 
			
		||||
        self.render_pass
 | 
			
		||||
            .set_index_buffer(buffer.slice(offset..), index_format.wgpu_into());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,7 @@ impl WgpuRenderer {
 | 
			
		||||
            .request_adapter(&wgpu::RequestAdapterOptions {
 | 
			
		||||
                power_preference: match options.power_pref {
 | 
			
		||||
                    WgpuPowerOptions::HighPerformance => wgpu::PowerPreference::HighPerformance,
 | 
			
		||||
                    WgpuPowerOptions::Adaptive => wgpu::PowerPreference::Default,
 | 
			
		||||
                    WgpuPowerOptions::Adaptive => wgpu::PowerPreference::LowPower,
 | 
			
		||||
                    WgpuPowerOptions::LowPower => wgpu::PowerPreference::LowPower,
 | 
			
		||||
                },
 | 
			
		||||
                compatible_surface: None,
 | 
			
		||||
@ -53,9 +53,9 @@ impl WgpuRenderer {
 | 
			
		||||
        let (device, queue) = adapter
 | 
			
		||||
            .request_device(
 | 
			
		||||
                &wgpu::DeviceDescriptor {
 | 
			
		||||
                    label: None,
 | 
			
		||||
                    features: wgpu::Features::empty(),
 | 
			
		||||
                    limits: wgpu::Limits::default(),
 | 
			
		||||
                    shader_validation: true,
 | 
			
		||||
                },
 | 
			
		||||
                trace_path,
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
@ -2,19 +2,21 @@ use bevy_render::{
 | 
			
		||||
    color::Color,
 | 
			
		||||
    pass::{LoadOp, Operations},
 | 
			
		||||
    pipeline::{
 | 
			
		||||
        BindType, BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite,
 | 
			
		||||
        CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat,
 | 
			
		||||
        InputStepMode, PrimitiveTopology, RasterizationStateDescriptor, StencilOperation,
 | 
			
		||||
        StencilStateDescriptor, StencilStateFaceDescriptor, VertexAttributeDescriptor,
 | 
			
		||||
        VertexBufferDescriptor, VertexFormat,
 | 
			
		||||
        BindType, BlendFactor, BlendOperation, BlendState, ColorTargetState, ColorWrite,
 | 
			
		||||
        CompareFunction, CullMode, DepthBiasState, DepthStencilState, FrontFace, IndexFormat,
 | 
			
		||||
        InputStepMode, MultisampleState, PolygonMode, PrimitiveState, PrimitiveTopology,
 | 
			
		||||
        StencilFaceState, StencilOperation, StencilState, VertexAttribute, VertexBufferLayout,
 | 
			
		||||
        VertexFormat,
 | 
			
		||||
    },
 | 
			
		||||
    renderer::BufferUsage,
 | 
			
		||||
    texture::{
 | 
			
		||||
        AddressMode, Extent3d, FilterMode, SamplerDescriptor, TextureComponentType,
 | 
			
		||||
        TextureDescriptor, TextureDimension, TextureFormat, TextureUsage, TextureViewDimension,
 | 
			
		||||
        AddressMode, Extent3d, FilterMode, SamplerBorderColor, SamplerDescriptor,
 | 
			
		||||
        StorageTextureAccess, TextureDescriptor, TextureDimension, TextureFormat,
 | 
			
		||||
        TextureSampleType, TextureUsage, TextureViewDimension,
 | 
			
		||||
    },
 | 
			
		||||
};
 | 
			
		||||
use bevy_window::Window;
 | 
			
		||||
use wgpu::BufferBindingType;
 | 
			
		||||
 | 
			
		||||
pub trait WgpuFrom<T> {
 | 
			
		||||
    fn from(val: T) -> Self;
 | 
			
		||||
@ -70,9 +72,9 @@ impl WgpuFrom<VertexFormat> for wgpu::VertexFormat {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&VertexAttributeDescriptor> for wgpu::VertexAttributeDescriptor {
 | 
			
		||||
    fn from(val: &VertexAttributeDescriptor) -> Self {
 | 
			
		||||
        wgpu::VertexAttributeDescriptor {
 | 
			
		||||
impl WgpuFrom<&VertexAttribute> for wgpu::VertexAttribute {
 | 
			
		||||
    fn from(val: &VertexAttribute) -> Self {
 | 
			
		||||
        wgpu::VertexAttribute {
 | 
			
		||||
            format: val.format.wgpu_into(),
 | 
			
		||||
            offset: val.offset,
 | 
			
		||||
            shader_location: val.shader_location,
 | 
			
		||||
@ -90,34 +92,34 @@ impl WgpuFrom<InputStepMode> for wgpu::InputStepMode {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug)]
 | 
			
		||||
pub struct OwnedWgpuVertexBufferDescriptor {
 | 
			
		||||
    pub stride: wgpu::BufferAddress,
 | 
			
		||||
pub struct OwnedWgpuVertexBufferLayout {
 | 
			
		||||
    pub array_stride: wgpu::BufferAddress,
 | 
			
		||||
    pub step_mode: wgpu::InputStepMode,
 | 
			
		||||
    pub attributes: Vec<wgpu::VertexAttributeDescriptor>,
 | 
			
		||||
    pub attributes: Vec<wgpu::VertexAttribute>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&VertexBufferDescriptor> for OwnedWgpuVertexBufferDescriptor {
 | 
			
		||||
    fn from(val: &VertexBufferDescriptor) -> OwnedWgpuVertexBufferDescriptor {
 | 
			
		||||
impl WgpuFrom<&VertexBufferLayout> for OwnedWgpuVertexBufferLayout {
 | 
			
		||||
    fn from(val: &VertexBufferLayout) -> OwnedWgpuVertexBufferLayout {
 | 
			
		||||
        let attributes = val
 | 
			
		||||
            .attributes
 | 
			
		||||
            .iter()
 | 
			
		||||
            .map(|a| a.wgpu_into())
 | 
			
		||||
            .collect::<Vec<wgpu::VertexAttributeDescriptor>>();
 | 
			
		||||
            .collect::<Vec<wgpu::VertexAttribute>>();
 | 
			
		||||
 | 
			
		||||
        OwnedWgpuVertexBufferDescriptor {
 | 
			
		||||
        OwnedWgpuVertexBufferLayout {
 | 
			
		||||
            step_mode: val.step_mode.wgpu_into(),
 | 
			
		||||
            stride: val.stride,
 | 
			
		||||
            array_stride: val.stride,
 | 
			
		||||
            attributes,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'a> From<&'a OwnedWgpuVertexBufferDescriptor> for wgpu::VertexBufferDescriptor<'a> {
 | 
			
		||||
    fn from(val: &'a OwnedWgpuVertexBufferDescriptor) -> Self {
 | 
			
		||||
        wgpu::VertexBufferDescriptor {
 | 
			
		||||
impl<'a> From<&'a OwnedWgpuVertexBufferLayout> for wgpu::VertexBufferLayout<'a> {
 | 
			
		||||
    fn from(val: &'a OwnedWgpuVertexBufferLayout) -> Self {
 | 
			
		||||
        wgpu::VertexBufferLayout {
 | 
			
		||||
            attributes: &val.attributes,
 | 
			
		||||
            step_mode: val.step_mode,
 | 
			
		||||
            stride: val.stride,
 | 
			
		||||
            array_stride: val.array_stride,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -181,46 +183,71 @@ where
 | 
			
		||||
impl WgpuFrom<&BindType> for wgpu::BindingType {
 | 
			
		||||
    fn from(bind_type: &BindType) -> Self {
 | 
			
		||||
        match bind_type {
 | 
			
		||||
            BindType::Uniform { dynamic, .. } => wgpu::BindingType::UniformBuffer {
 | 
			
		||||
                dynamic: *dynamic,
 | 
			
		||||
            BindType::Uniform {
 | 
			
		||||
                has_dynamic_offset, ..
 | 
			
		||||
            } => wgpu::BindingType::Buffer {
 | 
			
		||||
                ty: BufferBindingType::Uniform,
 | 
			
		||||
                has_dynamic_offset: *has_dynamic_offset,
 | 
			
		||||
                min_binding_size: bind_type.get_uniform_size().and_then(wgpu::BufferSize::new),
 | 
			
		||||
            },
 | 
			
		||||
            BindType::StorageBuffer { dynamic, readonly } => wgpu::BindingType::StorageBuffer {
 | 
			
		||||
                dynamic: *dynamic,
 | 
			
		||||
                readonly: *readonly,
 | 
			
		||||
            BindType::StorageBuffer {
 | 
			
		||||
                has_dynamic_offset,
 | 
			
		||||
                readonly,
 | 
			
		||||
            } => wgpu::BindingType::Buffer {
 | 
			
		||||
                ty: BufferBindingType::Storage {
 | 
			
		||||
                    read_only: *readonly,
 | 
			
		||||
                },
 | 
			
		||||
                has_dynamic_offset: *has_dynamic_offset,
 | 
			
		||||
                min_binding_size: bind_type.get_uniform_size().and_then(wgpu::BufferSize::new),
 | 
			
		||||
            },
 | 
			
		||||
            BindType::SampledTexture {
 | 
			
		||||
                dimension,
 | 
			
		||||
            BindType::Texture {
 | 
			
		||||
                view_dimension,
 | 
			
		||||
                multisampled,
 | 
			
		||||
                component_type,
 | 
			
		||||
            } => wgpu::BindingType::SampledTexture {
 | 
			
		||||
                dimension: (*dimension).wgpu_into(),
 | 
			
		||||
                sample_type,
 | 
			
		||||
            } => wgpu::BindingType::Texture {
 | 
			
		||||
                view_dimension: (*view_dimension).wgpu_into(),
 | 
			
		||||
                multisampled: *multisampled,
 | 
			
		||||
                component_type: (*component_type).wgpu_into(),
 | 
			
		||||
                sample_type: (*sample_type).wgpu_into(),
 | 
			
		||||
            },
 | 
			
		||||
            BindType::Sampler { comparison } => wgpu::BindingType::Sampler {
 | 
			
		||||
            BindType::Sampler {
 | 
			
		||||
                comparison,
 | 
			
		||||
                filtering,
 | 
			
		||||
            } => wgpu::BindingType::Sampler {
 | 
			
		||||
                filtering: *filtering,
 | 
			
		||||
                comparison: *comparison,
 | 
			
		||||
            },
 | 
			
		||||
            BindType::StorageTexture {
 | 
			
		||||
                dimension,
 | 
			
		||||
                view_dimension,
 | 
			
		||||
                format,
 | 
			
		||||
                readonly,
 | 
			
		||||
                access,
 | 
			
		||||
            } => wgpu::BindingType::StorageTexture {
 | 
			
		||||
                dimension: (*dimension).wgpu_into(),
 | 
			
		||||
                access: (*access).wgpu_into(),
 | 
			
		||||
                view_dimension: (*view_dimension).wgpu_into(),
 | 
			
		||||
                format: (*format).wgpu_into(),
 | 
			
		||||
                readonly: *readonly,
 | 
			
		||||
            },
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<TextureComponentType> for wgpu::TextureComponentType {
 | 
			
		||||
    fn from(texture_component_type: TextureComponentType) -> Self {
 | 
			
		||||
impl WgpuFrom<TextureSampleType> for wgpu::TextureSampleType {
 | 
			
		||||
    fn from(texture_component_type: TextureSampleType) -> Self {
 | 
			
		||||
        match texture_component_type {
 | 
			
		||||
            TextureComponentType::Float => wgpu::TextureComponentType::Float,
 | 
			
		||||
            TextureComponentType::Sint => wgpu::TextureComponentType::Sint,
 | 
			
		||||
            TextureComponentType::Uint => wgpu::TextureComponentType::Uint,
 | 
			
		||||
            TextureSampleType::Float { filterable } => {
 | 
			
		||||
                wgpu::TextureSampleType::Float { filterable }
 | 
			
		||||
            }
 | 
			
		||||
            TextureSampleType::Sint => wgpu::TextureSampleType::Sint,
 | 
			
		||||
            TextureSampleType::Uint => wgpu::TextureSampleType::Uint,
 | 
			
		||||
            TextureSampleType::Depth => wgpu::TextureSampleType::Depth,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<StorageTextureAccess> for wgpu::StorageTextureAccess {
 | 
			
		||||
    fn from(storage_texture_access: StorageTextureAccess) -> Self {
 | 
			
		||||
        match storage_texture_access {
 | 
			
		||||
            StorageTextureAccess::ReadOnly => wgpu::StorageTextureAccess::ReadOnly,
 | 
			
		||||
            StorageTextureAccess::WriteOnly => wgpu::StorageTextureAccess::WriteOnly,
 | 
			
		||||
            StorageTextureAccess::ReadWrite => wgpu::StorageTextureAccess::ReadWrite,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -323,9 +350,9 @@ impl WgpuFrom<TextureUsage> for wgpu::TextureUsage {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&StencilStateDescriptor> for wgpu::StencilStateDescriptor {
 | 
			
		||||
    fn from(val: &StencilStateDescriptor) -> Self {
 | 
			
		||||
        wgpu::StencilStateDescriptor {
 | 
			
		||||
impl WgpuFrom<&StencilState> for wgpu::StencilState {
 | 
			
		||||
    fn from(val: &StencilState) -> Self {
 | 
			
		||||
        wgpu::StencilState {
 | 
			
		||||
            back: (&val.back).wgpu_into(),
 | 
			
		||||
            front: (&val.front).wgpu_into(),
 | 
			
		||||
            read_mask: val.read_mask,
 | 
			
		||||
@ -334,20 +361,32 @@ impl WgpuFrom<&StencilStateDescriptor> for wgpu::StencilStateDescriptor {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&DepthStencilStateDescriptor> for wgpu::DepthStencilStateDescriptor {
 | 
			
		||||
    fn from(val: &DepthStencilStateDescriptor) -> Self {
 | 
			
		||||
        wgpu::DepthStencilStateDescriptor {
 | 
			
		||||
impl WgpuFrom<DepthStencilState> for wgpu::DepthStencilState {
 | 
			
		||||
    fn from(val: DepthStencilState) -> Self {
 | 
			
		||||
        wgpu::DepthStencilState {
 | 
			
		||||
            depth_compare: val.depth_compare.wgpu_into(),
 | 
			
		||||
            depth_write_enabled: val.depth_write_enabled,
 | 
			
		||||
            format: val.format.wgpu_into(),
 | 
			
		||||
            stencil: (&val.stencil).wgpu_into(),
 | 
			
		||||
            bias: val.bias.wgpu_into(),
 | 
			
		||||
            clamp_depth: val.clamp_depth,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&StencilStateFaceDescriptor> for wgpu::StencilStateFaceDescriptor {
 | 
			
		||||
    fn from(val: &StencilStateFaceDescriptor) -> Self {
 | 
			
		||||
        wgpu::StencilStateFaceDescriptor {
 | 
			
		||||
impl WgpuFrom<MultisampleState> for wgpu::MultisampleState {
 | 
			
		||||
    fn from(val: MultisampleState) -> Self {
 | 
			
		||||
        wgpu::MultisampleState {
 | 
			
		||||
            count: val.count,
 | 
			
		||||
            mask: val.mask,
 | 
			
		||||
            alpha_to_coverage_enabled: val.alpha_to_coverage_enabled,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&StencilFaceState> for wgpu::StencilFaceState {
 | 
			
		||||
    fn from(val: &StencilFaceState) -> Self {
 | 
			
		||||
        wgpu::StencilFaceState {
 | 
			
		||||
            compare: val.compare.wgpu_into(),
 | 
			
		||||
            depth_fail_op: val.depth_fail_op.wgpu_into(),
 | 
			
		||||
            fail_op: val.fail_op.wgpu_into(),
 | 
			
		||||
@ -441,22 +480,29 @@ impl WgpuFrom<CullMode> for wgpu::CullMode {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&RasterizationStateDescriptor> for wgpu::RasterizationStateDescriptor {
 | 
			
		||||
    fn from(val: &RasterizationStateDescriptor) -> Self {
 | 
			
		||||
        wgpu::RasterizationStateDescriptor {
 | 
			
		||||
            front_face: val.front_face.wgpu_into(),
 | 
			
		||||
            cull_mode: val.cull_mode.wgpu_into(),
 | 
			
		||||
            depth_bias: val.depth_bias,
 | 
			
		||||
            depth_bias_slope_scale: val.depth_bias_slope_scale,
 | 
			
		||||
            depth_bias_clamp: val.depth_bias_clamp,
 | 
			
		||||
            clamp_depth: val.clamp_depth,
 | 
			
		||||
impl WgpuFrom<PolygonMode> for wgpu::PolygonMode {
 | 
			
		||||
    fn from(val: PolygonMode) -> wgpu::PolygonMode {
 | 
			
		||||
        match val {
 | 
			
		||||
            PolygonMode::Fill => wgpu::PolygonMode::Fill,
 | 
			
		||||
            PolygonMode::Line => wgpu::PolygonMode::Line,
 | 
			
		||||
            PolygonMode::Point => wgpu::PolygonMode::Point,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&ColorStateDescriptor> for wgpu::ColorStateDescriptor {
 | 
			
		||||
    fn from(val: &ColorStateDescriptor) -> Self {
 | 
			
		||||
        wgpu::ColorStateDescriptor {
 | 
			
		||||
impl WgpuFrom<DepthBiasState> for wgpu::DepthBiasState {
 | 
			
		||||
    fn from(val: DepthBiasState) -> Self {
 | 
			
		||||
        wgpu::DepthBiasState {
 | 
			
		||||
            constant: val.constant,
 | 
			
		||||
            slope_scale: val.slope_scale,
 | 
			
		||||
            clamp: val.clamp,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&ColorTargetState> for wgpu::ColorTargetState {
 | 
			
		||||
    fn from(val: &ColorTargetState) -> Self {
 | 
			
		||||
        wgpu::ColorTargetState {
 | 
			
		||||
            format: val.format.wgpu_into(),
 | 
			
		||||
            alpha_blend: (&val.alpha_blend).wgpu_into(),
 | 
			
		||||
            color_blend: (&val.color_blend).wgpu_into(),
 | 
			
		||||
@ -465,15 +511,29 @@ impl WgpuFrom<&ColorStateDescriptor> for wgpu::ColorStateDescriptor {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<PrimitiveState> for wgpu::PrimitiveState {
 | 
			
		||||
    fn from(val: PrimitiveState) -> Self {
 | 
			
		||||
        wgpu::PrimitiveState {
 | 
			
		||||
            topology: val.topology.wgpu_into(),
 | 
			
		||||
            strip_index_format: val
 | 
			
		||||
                .strip_index_format
 | 
			
		||||
                .map(|index_format| index_format.wgpu_into()),
 | 
			
		||||
            front_face: val.front_face.wgpu_into(),
 | 
			
		||||
            cull_mode: val.cull_mode.wgpu_into(),
 | 
			
		||||
            polygon_mode: val.polygon_mode.wgpu_into(),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<ColorWrite> for wgpu::ColorWrite {
 | 
			
		||||
    fn from(val: ColorWrite) -> Self {
 | 
			
		||||
        wgpu::ColorWrite::from_bits(val.bits()).unwrap()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&BlendDescriptor> for wgpu::BlendDescriptor {
 | 
			
		||||
    fn from(val: &BlendDescriptor) -> Self {
 | 
			
		||||
        wgpu::BlendDescriptor {
 | 
			
		||||
impl WgpuFrom<&BlendState> for wgpu::BlendState {
 | 
			
		||||
    fn from(val: &BlendState) -> Self {
 | 
			
		||||
        wgpu::BlendState {
 | 
			
		||||
            src_factor: val.src_factor.wgpu_into(),
 | 
			
		||||
            dst_factor: val.dst_factor.wgpu_into(),
 | 
			
		||||
            operation: val.operation.wgpu_into(),
 | 
			
		||||
@ -536,6 +596,9 @@ impl WgpuFrom<SamplerDescriptor> for wgpu::SamplerDescriptor<'_> {
 | 
			
		||||
            lod_max_clamp: sampler_descriptor.lod_max_clamp,
 | 
			
		||||
            compare: sampler_descriptor.compare_function.map(|c| c.wgpu_into()),
 | 
			
		||||
            anisotropy_clamp: sampler_descriptor.anisotropy_clamp,
 | 
			
		||||
            border_color: sampler_descriptor
 | 
			
		||||
                .border_color
 | 
			
		||||
                .map(|border_color| border_color.wgpu_into()),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -559,10 +622,20 @@ impl WgpuFrom<FilterMode> for wgpu::FilterMode {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<SamplerBorderColor> for wgpu::SamplerBorderColor {
 | 
			
		||||
    fn from(val: SamplerBorderColor) -> Self {
 | 
			
		||||
        match val {
 | 
			
		||||
            SamplerBorderColor::TransparentBlack => wgpu::SamplerBorderColor::TransparentBlack,
 | 
			
		||||
            SamplerBorderColor::OpaqueBlack => wgpu::SamplerBorderColor::OpaqueBlack,
 | 
			
		||||
            SamplerBorderColor::OpaqueWhite => wgpu::SamplerBorderColor::OpaqueWhite,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl WgpuFrom<&Window> for wgpu::SwapChainDescriptor {
 | 
			
		||||
    fn from(window: &Window) -> Self {
 | 
			
		||||
        wgpu::SwapChainDescriptor {
 | 
			
		||||
            usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
 | 
			
		||||
            usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
 | 
			
		||||
            format: TextureFormat::default().wgpu_into(),
 | 
			
		||||
            width: window.physical_width(),
 | 
			
		||||
            height: window.physical_height(),
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ fn main() {
 | 
			
		||||
        .add_stage_after(stage::UPDATE, STAGE, StateStage::<AppState>::default())
 | 
			
		||||
        .on_state_enter(STAGE, AppState::Setup, load_textures.system())
 | 
			
		||||
        .on_state_update(STAGE, AppState::Setup, check_textures.system())
 | 
			
		||||
        .on_state_enter(STAGE, AppState::Finshed, setup.system())
 | 
			
		||||
        .on_state_enter(STAGE, AppState::Finished, setup.system())
 | 
			
		||||
        .run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,7 +18,7 @@ const STAGE: &str = "app_state";
 | 
			
		||||
#[derive(Clone)]
 | 
			
		||||
enum AppState {
 | 
			
		||||
    Setup,
 | 
			
		||||
    Finshed,
 | 
			
		||||
    Finished,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Default)]
 | 
			
		||||
@ -38,7 +38,7 @@ fn check_textures(
 | 
			
		||||
    if let LoadState::Loaded =
 | 
			
		||||
        asset_server.get_group_load_state(rpg_sprite_handles.handles.iter().map(|handle| handle.id))
 | 
			
		||||
    {
 | 
			
		||||
        state.set_next(AppState::Finshed).unwrap();
 | 
			
		||||
        state.set_next(AppState::Finished).unwrap();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user