diff --git a/crates/bevy_pbr/src/render_graph/forward_pipeline/mod.rs b/crates/bevy_pbr/src/render_graph/forward_pipeline/mod.rs index 8a3c17e6e1..f8f606ae0d 100644 --- a/crates/bevy_pbr/src/render_graph/forward_pipeline/mod.rs +++ b/crates/bevy_pbr/src/render_graph/forward_pipeline/mod.rs @@ -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) -> 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, diff --git a/crates/bevy_render/src/draw.rs b/crates/bevy_render/src/draw.rs index b4c1450cce..ab6c619246 100644 --- a/crates/bevy_render/src/draw.rs +++ b/crates/bevy_render/src/draw.rs @@ -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); diff --git a/crates/bevy_render/src/mesh/mesh.rs b/crates/bevy_render/src/mesh/mesh.rs index 2f68de5b89..edb309ece0 100644 --- a/crates/bevy_render/src/mesh/mesh.rs +++ b/crates/bevy_render/src/mesh/mesh.rs @@ -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)) = diff --git a/crates/bevy_render/src/pass/render_pass.rs b/crates/bevy_render/src/pass/render_pass.rs index 7d5091b125..40f3ba36bf 100644 --- a/crates/bevy_render/src/pass/render_pass.rs +++ b/crates/bevy_render/src/pass/render_pass.rs @@ -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); fn set_viewport(&mut self, x: f32, y: f32, w: f32, h: f32, min_depth: f32, max_depth: f32); diff --git a/crates/bevy_render/src/pipeline/binding.rs b/crates/bevy_render/src/pipeline/binding.rs index a467d8fd91..a664143c1b 100644 --- a/crates/bevy_render/src/pipeline/binding.rs +++ b/crates/bevy_render/src/pipeline/binding.rs @@ -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, }, } diff --git a/crates/bevy_render/src/pipeline/pipeline.rs b/crates/bevy_render/src/pipeline/pipeline.rs index eb8c836d05..27a8570d88 100644 --- a/crates/bevy_render/src/pipeline/pipeline.rs +++ b/crates/bevy_render/src/pipeline/pipeline.rs @@ -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, pub layout: Option, pub shader_stages: ShaderStages, - pub rasterization_state: Option, - - /// The primitive topology used to interpret vertices. - pub primitive_topology: PrimitiveTopology, + pub primitive: PrimitiveState, + pub depth_stencil: Option, + pub multisample: MultisampleState, /// The effect of draw calls on the color aspect of the output target. - pub color_states: Vec, - - /// The effect of draw calls on the depth and stencil aspects of the output target, if any. - pub depth_stencil_state: Option, - - /// 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, } 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, } } diff --git a/crates/bevy_render/src/pipeline/pipeline_compiler.rs b/crates/bevy_render/src/pipeline/pipeline_compiler.rs index 98c041160f..1831b97bd3 100644 --- a/crates/bevy_render/src/pipeline/pipeline_compiler.rs +++ b/crates/bevy_render/src/pipeline/pipeline_compiler.rs @@ -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, - pub index_format: IndexFormat, - pub vertex_buffer_descriptor: VertexBufferDescriptor, + pub strip_index_format: Option, + 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::::default(); + let mut vertex_buffer_descriptors = Vec::::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( diff --git a/crates/bevy_render/src/pipeline/pipeline_layout.rs b/crates/bevy_render/src/pipeline/pipeline_layout.rs index 3aa3a1ed8a..86702f4dad 100644 --- a/crates/bevy_render/src/pipeline/pipeline_layout.rs +++ b/crates/bevy_render/src/pipeline/pipeline_layout.rs @@ -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, - pub vertex_buffer_descriptors: Vec, + pub vertex_buffer_descriptors: Vec, } 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()); } diff --git a/crates/bevy_render/src/pipeline/state_descriptors.rs b/crates/bevy_render/src/pipeline/state_descriptors.rs index ffd5b99995..cfef5ab8f3 100644 --- a/crates/bevy_render/src/pipeline/state_descriptors.rs +++ b/crates/bevy_render/src/pipeline/state_descriptors.rs @@ -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, 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, diff --git a/crates/bevy_render/src/pipeline/vertex_buffer_descriptor.rs b/crates/bevy_render/src/pipeline/vertex_buffer_descriptor.rs index 42bf9673df..a891cb3720 100644 --- a/crates/bevy_render/src/pipeline/vertex_buffer_descriptor.rs +++ b/crates/bevy_render/src/pipeline/vertex_buffer_descriptor.rs @@ -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, + pub attributes: Vec, } -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, } diff --git a/crates/bevy_render/src/render_graph/nodes/pass_node.rs b/crates/bevy_render/src/render_graph/nodes/pass_node.rs index c9de46d256..2db0058ac5 100644 --- a/crates/bevy_render/src/render_graph/nodes/pass_node.rs +++ b/crates/bevy_render/src/render_graph/nodes/pass_node.rs @@ -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 PassNode { 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>, bind_groups: Vec>, vertex_buffers: Vec>, - 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 { diff --git a/crates/bevy_render/src/renderer/render_resource/render_resource_bindings.rs b/crates/bevy_render/src/renderer/render_resource/render_resource_bindings.rs index e02ce2661e..da98c7ed5e 100644 --- a/crates/bevy_render/src/renderer/render_resource/render_resource_bindings.rs +++ b/crates/bevy_render/src/renderer/render_resource/render_resource_bindings.rs @@ -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, /// 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, - pub index_buffer: Option, + pub index_buffer: Option<(BufferId, IndexFormat)>, assets: HashSet<(HandleUntyped, TypeId)>, bind_groups: HashMap, bind_group_descriptors: HashMap>, @@ -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, diff --git a/crates/bevy_render/src/shader/mod.rs b/crates/bevy_render/src/shader/mod.rs index 5649d28b68..dee5179b79 100644 --- a/crates/bevy_render/src/shader/mod.rs +++ b/crates/bevy_render/src/shader/mod.rs @@ -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, - pub vertex_buffer_descriptors: Vec, + pub vertex_buffer_layout: Vec, pub entry_point: String, } diff --git a/crates/bevy_render/src/shader/shader_reflect.rs b/crates/bevy_render/src/shader/shader_reflect.rs index 695b969727..fe1ff7167f 100644 --- a/crates/bevy_render/src/shader/shader_reflect.rs +++ b/crates/bevy_render/src/shader/shader_reflect.rs @@ -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, }] diff --git a/crates/bevy_render/src/texture/sampler_descriptor.rs b/crates/bevy_render/src/texture/sampler_descriptor.rs index 8ee5e8a56c..453bf70d98 100644 --- a/crates/bevy_render/src/texture/sampler_descriptor.rs +++ b/crates/bevy_render/src/texture/sampler_descriptor.rs @@ -14,6 +14,7 @@ pub struct SamplerDescriptor { pub lod_max_clamp: f32, pub compare_function: Option, pub anisotropy_clamp: Option, + pub border_color: Option, } 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, +} diff --git a/crates/bevy_render/src/texture/texture_descriptor.rs b/crates/bevy_render/src/texture/texture_descriptor.rs index 15ab341ccd..0097849ce5 100644 --- a/crates/bevy_render/src/texture/texture_descriptor.rs +++ b/crates/bevy_render/src/texture/texture_descriptor.rs @@ -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, +} diff --git a/crates/bevy_render/src/texture/texture_dimension.rs b/crates/bevy_render/src/texture/texture_dimension.rs index d230be2303..c5b8e8552f 100644 --- a/crates/bevy_render/src/texture/texture_dimension.rs +++ b/crates/bevy_render/src/texture/texture_dimension.rs @@ -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, } diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index 221df7cb95..43c97a4ed5 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -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) -> 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) -> PipelineDesc pub fn build_sprite_pipeline(shaders: &mut Assets) -> 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, diff --git a/crates/bevy_text/src/draw.rs b/crates/bevy_text/src/draw.rs index 82d54c2f4f..3a00d7bda0 100644 --- a/crates/bevy_text/src/draw.rs +++ b/crates/bevy_text/src/draw.rs @@ -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, 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 { diff --git a/crates/bevy_text/src/text2d.rs b/crates/bevy_text/src/text2d.rs index ad5bbebda4..52b146b843 100644 --- a/crates/bevy_text/src/text2d.rs +++ b/crates/bevy_text/src/text2d.rs @@ -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, }; diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index d95e41db4f..50e92d883d 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -23,33 +23,31 @@ pub const UI_PIPELINE_HANDLE: HandleUntyped = pub fn build_ui_pipeline(shaders: &mut Assets) -> 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, diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index c1f2ab0f43..97d4850d3f 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -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, }; diff --git a/crates/bevy_wgpu/Cargo.toml b/crates/bevy_wgpu/Cargo.toml index 31d9cc1d92..67e9dd9776 100644 --- a/crates/bevy_wgpu/Cargo.toml +++ b/crates/bevy_wgpu/Cargo.toml @@ -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" diff --git a/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs b/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs index 69a9ae7691..6a061a8148 100644 --- a/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs +++ b/crates/bevy_wgpu/src/renderer/wgpu_render_context.rs @@ -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() diff --git a/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs b/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs index 6bbaf74eb4..9399e986d3 100644 --- a/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs +++ b/crates/bevy_wgpu/src/renderer/wgpu_render_resource_context.rs @@ -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::>(); + .collect::>(); let color_states = pipeline_descriptor - .color_states + .color_target_states .iter() .map(|c| c.wgpu_into()) - .collect::>(); + .collect::>(); 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::>(), }, - 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::>(), - }, - 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 { diff --git a/crates/bevy_wgpu/src/wgpu_render_pass.rs b/crates/bevy_wgpu/src/wgpu_render_pass.rs index e68337df2b..bfa15d2980 100644 --- a/crates/bevy_wgpu/src/wgpu_render_pass.rs +++ b/crates/bevy_wgpu/src/wgpu_render_pass.rs @@ -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, base_vertex: i32, instances: Range) { diff --git a/crates/bevy_wgpu/src/wgpu_renderer.rs b/crates/bevy_wgpu/src/wgpu_renderer.rs index d10fa9a0ca..9bb800c6e3 100644 --- a/crates/bevy_wgpu/src/wgpu_renderer.rs +++ b/crates/bevy_wgpu/src/wgpu_renderer.rs @@ -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, ) diff --git a/crates/bevy_wgpu/src/wgpu_type_converter.rs b/crates/bevy_wgpu/src/wgpu_type_converter.rs index e6e176263e..1a83c2466b 100644 --- a/crates/bevy_wgpu/src/wgpu_type_converter.rs +++ b/crates/bevy_wgpu/src/wgpu_type_converter.rs @@ -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 { fn from(val: T) -> Self; @@ -70,9 +72,9 @@ impl WgpuFrom 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 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, + pub attributes: Vec, } -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::>(); + .collect::>(); - 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 for wgpu::TextureComponentType { - fn from(texture_component_type: TextureComponentType) -> Self { +impl WgpuFrom 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 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 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 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 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 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 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 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 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 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 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 for wgpu::FilterMode { } } +impl WgpuFrom 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(), diff --git a/examples/2d/texture_atlas.rs b/examples/2d/texture_atlas.rs index 826f90a451..3a3ef5c3cd 100644 --- a/examples/2d/texture_atlas.rs +++ b/examples/2d/texture_atlas.rs @@ -9,7 +9,7 @@ fn main() { .add_stage_after(stage::UPDATE, STAGE, StateStage::::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(); } }