mirror of
https://github.com/bevyengine/bevy
synced 2024-11-10 15:14:50 +00:00
parent
e6e23fdfa9
commit
81809c71ce
29 changed files with 574 additions and 370 deletions
|
@ -2,9 +2,8 @@ use bevy_asset::{Assets, HandleUntyped};
|
||||||
use bevy_reflect::TypeUuid;
|
use bevy_reflect::TypeUuid;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pipeline::{
|
pipeline::{
|
||||||
BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite,
|
BlendFactor, BlendOperation, BlendState, ColorTargetState, ColorWrite, CompareFunction,
|
||||||
CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, PipelineDescriptor,
|
DepthBiasState, DepthStencilState, PipelineDescriptor, StencilFaceState, StencilState,
|
||||||
RasterizationStateDescriptor, StencilStateDescriptor, StencilStateFaceDescriptor,
|
|
||||||
},
|
},
|
||||||
shader::{Shader, ShaderStage, ShaderStages},
|
shader::{Shader, ShaderStage, ShaderStages},
|
||||||
texture::TextureFormat,
|
texture::TextureFormat,
|
||||||
|
@ -15,33 +14,31 @@ pub const FORWARD_PIPELINE_HANDLE: HandleUntyped =
|
||||||
|
|
||||||
pub(crate) fn build_forward_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
pub(crate) fn build_forward_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
depth_stencil: Some(DepthStencilState {
|
||||||
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 {
|
|
||||||
format: TextureFormat::Depth32Float,
|
format: TextureFormat::Depth32Float,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: true,
|
||||||
depth_compare: CompareFunction::Less,
|
depth_compare: CompareFunction::Less,
|
||||||
stencil: StencilStateDescriptor {
|
stencil: StencilState {
|
||||||
front: StencilStateFaceDescriptor::IGNORE,
|
front: StencilFaceState::IGNORE,
|
||||||
back: StencilStateFaceDescriptor::IGNORE,
|
back: StencilFaceState::IGNORE,
|
||||||
read_mask: 0,
|
read_mask: 0,
|
||||||
write_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(),
|
format: TextureFormat::default(),
|
||||||
color_blend: BlendDescriptor {
|
color_blend: BlendState {
|
||||||
src_factor: BlendFactor::SrcAlpha,
|
src_factor: BlendFactor::SrcAlpha,
|
||||||
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
},
|
},
|
||||||
alpha_blend: BlendDescriptor {
|
alpha_blend: BlendState {
|
||||||
src_factor: BlendFactor::One,
|
src_factor: BlendFactor::One,
|
||||||
dst_factor: BlendFactor::One,
|
dst_factor: BlendFactor::One,
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{PipelineCompiler, PipelineDescriptor, PipelineLayout, PipelineSpecialization},
|
pipeline::{
|
||||||
|
IndexFormat, PipelineCompiler, PipelineDescriptor, PipelineLayout, PipelineSpecialization,
|
||||||
|
},
|
||||||
renderer::{
|
renderer::{
|
||||||
AssetRenderResourceBindings, BindGroup, BindGroupId, BufferId, RenderResource,
|
AssetRenderResourceBindings, BindGroup, BindGroupId, BufferId, RenderResource,
|
||||||
RenderResourceBinding, RenderResourceBindings, RenderResourceContext, SharedBuffers,
|
RenderResourceBinding, RenderResourceBindings, RenderResourceContext, SharedBuffers,
|
||||||
|
@ -26,6 +28,7 @@ pub enum RenderCommand {
|
||||||
SetIndexBuffer {
|
SetIndexBuffer {
|
||||||
buffer: BufferId,
|
buffer: BufferId,
|
||||||
offset: u64,
|
offset: u64,
|
||||||
|
index_format: IndexFormat,
|
||||||
},
|
},
|
||||||
SetBindGroup {
|
SetBindGroup {
|
||||||
index: u32,
|
index: u32,
|
||||||
|
@ -95,8 +98,12 @@ impl Draw {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_index_buffer(&mut self, buffer: BufferId, offset: u64) {
|
pub fn set_index_buffer(&mut self, buffer: BufferId, offset: u64, index_format: IndexFormat) {
|
||||||
self.render_command(RenderCommand::SetIndexBuffer { buffer, offset });
|
self.render_command(RenderCommand::SetIndexBuffer {
|
||||||
|
buffer,
|
||||||
|
offset,
|
||||||
|
index_format,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup) {
|
pub fn set_bind_group(&mut self, index: u32, bind_group: &BindGroup) {
|
||||||
|
@ -325,8 +332,8 @@ impl<'a> DrawContext<'a> {
|
||||||
render_resource_bindings: &[&RenderResourceBindings],
|
render_resource_bindings: &[&RenderResourceBindings],
|
||||||
) -> Result<(), DrawError> {
|
) -> Result<(), DrawError> {
|
||||||
for bindings in render_resource_bindings.iter() {
|
for bindings in render_resource_bindings.iter() {
|
||||||
if let Some(index_buffer) = bindings.index_buffer {
|
if let Some((index_buffer, index_format)) = bindings.index_buffer {
|
||||||
draw.set_index_buffer(index_buffer, 0);
|
draw.set_index_buffer(index_buffer, 0, index_format);
|
||||||
}
|
}
|
||||||
if let Some(main_vertex_buffer) = bindings.vertex_attribute_buffer {
|
if let Some(main_vertex_buffer) = bindings.vertex_attribute_buffer {
|
||||||
draw.set_vertex_buffer(0, main_vertex_buffer, 0);
|
draw.set_vertex_buffer(0, main_vertex_buffer, 0);
|
||||||
|
|
|
@ -10,7 +10,7 @@ use bevy_math::*;
|
||||||
use bevy_reflect::TypeUuid;
|
use bevy_reflect::TypeUuid;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use crate::pipeline::{InputStepMode, VertexAttributeDescriptor, VertexBufferDescriptor};
|
use crate::pipeline::{InputStepMode, VertexAttribute, VertexBufferLayout};
|
||||||
use bevy_utils::{HashMap, HashSet};
|
use bevy_utils::{HashMap, HashSet};
|
||||||
|
|
||||||
pub const INDEX_BUFFER_ASSET_INDEX: u64 = 0;
|
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 attributes = Vec::new();
|
||||||
let mut accumulated_offset = 0;
|
let mut accumulated_offset = 0;
|
||||||
for (attribute_name, attribute_values) in self.attributes.iter() {
|
for (attribute_name, attribute_values) in self.attributes.iter() {
|
||||||
let vertex_format = VertexFormat::from(attribute_values);
|
let vertex_format = VertexFormat::from(attribute_values);
|
||||||
attributes.push(VertexAttributeDescriptor {
|
attributes.push(VertexAttribute {
|
||||||
name: attribute_name.clone(),
|
name: attribute_name.clone(),
|
||||||
offset: accumulated_offset,
|
offset: accumulated_offset,
|
||||||
format: vertex_format,
|
format: vertex_format,
|
||||||
|
@ -270,7 +270,7 @@ impl Mesh {
|
||||||
accumulated_offset += vertex_format.get_size();
|
accumulated_offset += vertex_format.get_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexBufferDescriptor {
|
VertexBufferLayout {
|
||||||
name: Default::default(),
|
name: Default::default(),
|
||||||
stride: accumulated_offset,
|
stride: accumulated_offset,
|
||||||
step_mode: InputStepMode::Vertex,
|
step_mode: InputStepMode::Vertex,
|
||||||
|
@ -453,21 +453,22 @@ fn update_entity_mesh(
|
||||||
for render_pipeline in render_pipelines.pipelines.iter_mut() {
|
for render_pipeline in render_pipelines.pipelines.iter_mut() {
|
||||||
render_pipeline.specialization.primitive_topology = mesh.primitive_topology;
|
render_pipeline.specialization.primitive_topology = mesh.primitive_topology;
|
||||||
// TODO: don't allocate a new vertex buffer descriptor for every entity
|
// TODO: don't allocate a new vertex buffer descriptor for every entity
|
||||||
render_pipeline.specialization.vertex_buffer_descriptor =
|
render_pipeline.specialization.vertex_buffer_layout = mesh.get_vertex_buffer_layout();
|
||||||
mesh.get_vertex_buffer_descriptor();
|
if let PrimitiveTopology::LineStrip | PrimitiveTopology::TriangleStrip =
|
||||||
render_pipeline.specialization.index_format = mesh
|
mesh.primitive_topology
|
||||||
.indices()
|
{
|
||||||
.map(|i| i.into())
|
render_pipeline.specialization.strip_index_format =
|
||||||
.unwrap_or(IndexFormat::Uint32);
|
mesh.indices().map(|indices| indices.into());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(RenderResourceId::Buffer(index_buffer_resource)) =
|
if let Some(RenderResourceId::Buffer(index_buffer_resource)) =
|
||||||
render_resource_context.get_asset_resource(handle, INDEX_BUFFER_ASSET_INDEX)
|
render_resource_context.get_asset_resource(handle, INDEX_BUFFER_ASSET_INDEX)
|
||||||
{
|
{
|
||||||
|
let index_format: IndexFormat = mesh.indices().unwrap().into();
|
||||||
// set index buffer into binding
|
// set index buffer into binding
|
||||||
render_pipelines
|
render_pipelines
|
||||||
.bindings
|
.bindings
|
||||||
.set_index_buffer(index_buffer_resource);
|
.set_index_buffer(index_buffer_resource, index_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(RenderResourceId::Buffer(vertex_attribute_buffer_resource)) =
|
if let Some(RenderResourceId::Buffer(vertex_attribute_buffer_resource)) =
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{BindGroupDescriptorId, IndexFormat, PipelineDescriptor},
|
||||||
renderer::{BindGroupId, BufferId, RenderContext},
|
renderer::{BindGroupId, BufferId, RenderContext},
|
||||||
};
|
};
|
||||||
use bevy_asset::Handle;
|
use bevy_asset::Handle;
|
||||||
|
@ -7,7 +7,7 @@ use std::ops::Range;
|
||||||
|
|
||||||
pub trait RenderPass {
|
pub trait RenderPass {
|
||||||
fn get_render_context(&self) -> &dyn RenderContext;
|
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_vertex_buffer(&mut self, start_slot: u32, buffer: BufferId, offset: u64);
|
||||||
fn set_pipeline(&mut self, pipeline_handle: &Handle<PipelineDescriptor>);
|
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);
|
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 super::UniformProperty;
|
||||||
use crate::texture::{TextureComponentType, TextureFormat, TextureViewDimension};
|
use crate::texture::{
|
||||||
|
StorageTextureAccess, TextureFormat, TextureSampleType, TextureViewDimension,
|
||||||
|
};
|
||||||
|
|
||||||
bitflags::bitflags! {
|
bitflags::bitflags! {
|
||||||
pub struct BindingShaderStage: u32 {
|
pub struct BindingShaderStage: u32 {
|
||||||
|
@ -20,25 +22,35 @@ pub struct BindingDescriptor {
|
||||||
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
pub enum BindType {
|
pub enum BindType {
|
||||||
Uniform {
|
Uniform {
|
||||||
dynamic: bool,
|
has_dynamic_offset: bool,
|
||||||
property: UniformProperty,
|
property: UniformProperty,
|
||||||
},
|
},
|
||||||
StorageBuffer {
|
StorageBuffer {
|
||||||
dynamic: bool,
|
has_dynamic_offset: bool,
|
||||||
readonly: bool,
|
readonly: bool,
|
||||||
},
|
},
|
||||||
Sampler {
|
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,
|
comparison: bool,
|
||||||
},
|
},
|
||||||
SampledTexture {
|
Texture {
|
||||||
multisampled: bool,
|
multisampled: bool,
|
||||||
dimension: TextureViewDimension,
|
view_dimension: TextureViewDimension,
|
||||||
component_type: TextureComponentType,
|
sample_type: TextureSampleType,
|
||||||
},
|
},
|
||||||
StorageTexture {
|
StorageTexture {
|
||||||
dimension: TextureViewDimension,
|
/// Allowed access to this texture.
|
||||||
|
access: StorageTextureAccess,
|
||||||
|
/// Format of the texture.
|
||||||
format: TextureFormat,
|
format: TextureFormat,
|
||||||
readonly: bool,
|
/// Dimension of the texture view that is going to be sampled.
|
||||||
|
view_dimension: TextureViewDimension,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
use super::{
|
use super::{
|
||||||
state_descriptors::{
|
state_descriptors::{
|
||||||
BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite,
|
BlendFactor, BlendOperation, ColorWrite, CompareFunction, CullMode, FrontFace,
|
||||||
CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat,
|
PrimitiveTopology,
|
||||||
PrimitiveTopology, RasterizationStateDescriptor, StencilStateFaceDescriptor,
|
|
||||||
},
|
},
|
||||||
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;
|
use bevy_reflect::TypeUuid;
|
||||||
|
|
||||||
#[derive(Clone, Debug, TypeUuid)]
|
#[derive(Clone, Debug, TypeUuid)]
|
||||||
|
@ -15,32 +21,12 @@ pub struct PipelineDescriptor {
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub layout: Option<PipelineLayout>,
|
pub layout: Option<PipelineLayout>,
|
||||||
pub shader_stages: ShaderStages,
|
pub shader_stages: ShaderStages,
|
||||||
pub rasterization_state: Option<RasterizationStateDescriptor>,
|
pub primitive: PrimitiveState,
|
||||||
|
pub depth_stencil: Option<DepthStencilState>,
|
||||||
/// The primitive topology used to interpret vertices.
|
pub multisample: MultisampleState,
|
||||||
pub primitive_topology: PrimitiveTopology,
|
|
||||||
|
|
||||||
/// The effect of draw calls on the color aspect of the output target.
|
/// The effect of draw calls on the color aspect of the output target.
|
||||||
pub color_states: Vec<ColorStateDescriptor>,
|
pub color_target_states: Vec<ColorTargetState>,
|
||||||
|
|
||||||
/// 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,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipelineDescriptor {
|
impl PipelineDescriptor {
|
||||||
|
@ -48,60 +34,71 @@ impl PipelineDescriptor {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
name: None,
|
name: None,
|
||||||
layout: None,
|
layout: None,
|
||||||
color_states: Vec::new(),
|
color_target_states: Vec::new(),
|
||||||
depth_stencil_state: None,
|
depth_stencil: None,
|
||||||
shader_stages,
|
shader_stages,
|
||||||
rasterization_state: None,
|
primitive: PrimitiveState {
|
||||||
primitive_topology: PrimitiveTopology::TriangleList,
|
topology: PrimitiveTopology::TriangleList,
|
||||||
index_format: IndexFormat::Uint32,
|
strip_index_format: None,
|
||||||
sample_count: 1,
|
front_face: FrontFace::Ccw,
|
||||||
sample_mask: !0,
|
cull_mode: CullMode::Back,
|
||||||
alpha_to_coverage_enabled: false,
|
polygon_mode: PolygonMode::Fill,
|
||||||
|
},
|
||||||
|
multisample: MultisampleState {
|
||||||
|
count: 1,
|
||||||
|
mask: !0,
|
||||||
|
alpha_to_coverage_enabled: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_config(shader_stages: ShaderStages) -> Self {
|
pub fn default_config(shader_stages: ShaderStages) -> Self {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
name: None,
|
name: None,
|
||||||
primitive_topology: PrimitiveTopology::TriangleList,
|
primitive: PrimitiveState {
|
||||||
layout: None,
|
topology: PrimitiveTopology::TriangleList,
|
||||||
index_format: IndexFormat::Uint32,
|
strip_index_format: None,
|
||||||
sample_count: 1,
|
|
||||||
sample_mask: !0,
|
|
||||||
alpha_to_coverage_enabled: false,
|
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
|
||||||
front_face: FrontFace::Ccw,
|
front_face: FrontFace::Ccw,
|
||||||
cull_mode: CullMode::Back,
|
cull_mode: CullMode::Back,
|
||||||
depth_bias: 0,
|
polygon_mode: PolygonMode::Fill,
|
||||||
depth_bias_slope_scale: 0.0,
|
},
|
||||||
depth_bias_clamp: 0.0,
|
layout: None,
|
||||||
clamp_depth: false,
|
depth_stencil: Some(DepthStencilState {
|
||||||
}),
|
|
||||||
depth_stencil_state: Some(DepthStencilStateDescriptor {
|
|
||||||
format: TextureFormat::Depth32Float,
|
format: TextureFormat::Depth32Float,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: true,
|
||||||
depth_compare: CompareFunction::Less,
|
depth_compare: CompareFunction::Less,
|
||||||
stencil: StencilStateDescriptor {
|
stencil: StencilState {
|
||||||
front: StencilStateFaceDescriptor::IGNORE,
|
front: StencilFaceState::IGNORE,
|
||||||
back: StencilStateFaceDescriptor::IGNORE,
|
back: StencilFaceState::IGNORE,
|
||||||
read_mask: 0,
|
read_mask: 0,
|
||||||
write_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(),
|
format: TextureFormat::default(),
|
||||||
color_blend: BlendDescriptor {
|
color_blend: BlendState {
|
||||||
src_factor: BlendFactor::SrcAlpha,
|
src_factor: BlendFactor::SrcAlpha,
|
||||||
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
},
|
},
|
||||||
alpha_blend: BlendDescriptor {
|
alpha_blend: BlendState {
|
||||||
src_factor: BlendFactor::One,
|
src_factor: BlendFactor::One,
|
||||||
dst_factor: BlendFactor::One,
|
dst_factor: BlendFactor::One,
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
},
|
},
|
||||||
write_mask: ColorWrite::ALL,
|
write_mask: ColorWrite::ALL,
|
||||||
}],
|
}],
|
||||||
|
multisample: MultisampleState {
|
||||||
|
count: 1,
|
||||||
|
mask: !0,
|
||||||
|
alpha_to_coverage_enabled: false,
|
||||||
|
},
|
||||||
shader_stages,
|
shader_stages,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{state_descriptors::PrimitiveTopology, IndexFormat, PipelineDescriptor};
|
use super::{state_descriptors::PrimitiveTopology, IndexFormat, PipelineDescriptor};
|
||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{BindType, InputStepMode, VertexBufferDescriptor},
|
pipeline::{BindType, InputStepMode, VertexBufferLayout},
|
||||||
renderer::RenderResourceContext,
|
renderer::RenderResourceContext,
|
||||||
shader::{Shader, ShaderError},
|
shader::{Shader, ShaderError},
|
||||||
};
|
};
|
||||||
|
@ -15,8 +15,8 @@ pub struct PipelineSpecialization {
|
||||||
pub shader_specialization: ShaderSpecialization,
|
pub shader_specialization: ShaderSpecialization,
|
||||||
pub primitive_topology: PrimitiveTopology,
|
pub primitive_topology: PrimitiveTopology,
|
||||||
pub dynamic_bindings: HashSet<String>,
|
pub dynamic_bindings: HashSet<String>,
|
||||||
pub index_format: IndexFormat,
|
pub strip_index_format: Option<IndexFormat>,
|
||||||
pub vertex_buffer_descriptor: VertexBufferDescriptor,
|
pub vertex_buffer_layout: VertexBufferLayout,
|
||||||
pub sample_count: u32,
|
pub sample_count: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,11 +24,11 @@ impl Default for PipelineSpecialization {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
sample_count: 1,
|
sample_count: 1,
|
||||||
index_format: IndexFormat::Uint32,
|
strip_index_format: None,
|
||||||
shader_specialization: Default::default(),
|
shader_specialization: Default::default(),
|
||||||
primitive_topology: Default::default(),
|
primitive_topology: Default::default(),
|
||||||
dynamic_bindings: 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)
|
.any(|b| b == &binding.name)
|
||||||
{
|
{
|
||||||
if let BindType::Uniform {
|
if let BindType::Uniform {
|
||||||
ref mut dynamic, ..
|
ref mut has_dynamic_offset,
|
||||||
|
..
|
||||||
} = binding.bind_type
|
} = binding.bind_type
|
||||||
{
|
{
|
||||||
*dynamic = true;
|
*has_dynamic_offset = true;
|
||||||
binding_changed = 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
|
// 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();
|
let mut pipeline_layout = specialized_descriptor.layout.as_mut().unwrap();
|
||||||
// the vertex buffer descriptor of the mesh
|
// 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
|
// 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,
|
step_mode: InputStepMode::Vertex,
|
||||||
stride: mesh_vertex_buffer_descriptor.stride,
|
stride: mesh_vertex_buffer_layout.stride,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -212,7 +213,7 @@ impl PipelineCompiler {
|
||||||
.get(0)
|
.get(0)
|
||||||
.expect("Reflected layout has no attributes.");
|
.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
|
.attributes
|
||||||
.iter()
|
.iter()
|
||||||
.find(|x| x.name == shader_vertex_attribute.name)
|
.find(|x| x.name == shader_vertex_attribute.name)
|
||||||
|
@ -233,13 +234,14 @@ impl PipelineCompiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: add other buffers (like instancing) here
|
//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);
|
vertex_buffer_descriptors.push(compiled_vertex_buffer_descriptor);
|
||||||
|
|
||||||
pipeline_layout.vertex_buffer_descriptors = vertex_buffer_descriptors;
|
pipeline_layout.vertex_buffer_descriptors = vertex_buffer_descriptors;
|
||||||
specialized_descriptor.sample_count = pipeline_specialization.sample_count;
|
specialized_descriptor.multisample.count = pipeline_specialization.sample_count;
|
||||||
specialized_descriptor.primitive_topology = pipeline_specialization.primitive_topology;
|
specialized_descriptor.primitive.topology = pipeline_specialization.primitive_topology;
|
||||||
specialized_descriptor.index_format = pipeline_specialization.index_format;
|
specialized_descriptor.primitive.strip_index_format =
|
||||||
|
pipeline_specialization.strip_index_format;
|
||||||
|
|
||||||
let specialized_pipeline_handle = pipelines.add(specialized_descriptor);
|
let specialized_pipeline_handle = pipelines.add(specialized_descriptor);
|
||||||
render_resource_context.create_render_pipeline(
|
render_resource_context.create_render_pipeline(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{BindGroupDescriptor, VertexBufferDescriptor};
|
use super::{BindGroupDescriptor, VertexBufferLayout};
|
||||||
use crate::shader::ShaderLayout;
|
use crate::shader::ShaderLayout;
|
||||||
use bevy_utils::HashMap;
|
use bevy_utils::HashMap;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
|
@ -6,7 +6,7 @@ use std::hash::Hash;
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct PipelineLayout {
|
pub struct PipelineLayout {
|
||||||
pub bind_groups: Vec<BindGroupDescriptor>,
|
pub bind_groups: Vec<BindGroupDescriptor>,
|
||||||
pub vertex_buffer_descriptors: Vec<VertexBufferDescriptor>,
|
pub vertex_buffer_descriptors: Vec<VertexBufferLayout>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PipelineLayout {
|
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());
|
vertex_buffer_descriptors.push(vertex_buffer_descriptor.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,20 +3,48 @@ use bevy_reflect::Reflect;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DepthStencilStateDescriptor {
|
pub struct DepthStencilState {
|
||||||
pub format: TextureFormat,
|
pub format: TextureFormat,
|
||||||
pub depth_write_enabled: bool,
|
pub depth_write_enabled: bool,
|
||||||
pub depth_compare: CompareFunction,
|
pub depth_compare: CompareFunction,
|
||||||
pub stencil: StencilStateDescriptor,
|
pub stencil: StencilState,
|
||||||
|
pub bias: DepthBiasState,
|
||||||
|
pub clamp_depth: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct StencilStateDescriptor {
|
pub struct StencilState {
|
||||||
pub front: StencilStateFaceDescriptor,
|
pub front: StencilFaceState,
|
||||||
pub back: StencilStateFaceDescriptor,
|
pub back: StencilFaceState,
|
||||||
pub read_mask: u32,
|
pub read_mask: u32,
|
||||||
pub write_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)]
|
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
|
||||||
pub enum StencilOperation {
|
pub enum StencilOperation {
|
||||||
|
@ -31,15 +59,15 @@ pub enum StencilOperation {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct StencilStateFaceDescriptor {
|
pub struct StencilFaceState {
|
||||||
pub compare: CompareFunction,
|
pub compare: CompareFunction,
|
||||||
pub fail_op: StencilOperation,
|
pub fail_op: StencilOperation,
|
||||||
pub depth_fail_op: StencilOperation,
|
pub depth_fail_op: StencilOperation,
|
||||||
pub pass_op: StencilOperation,
|
pub pass_op: StencilOperation,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StencilStateFaceDescriptor {
|
impl StencilFaceState {
|
||||||
pub const IGNORE: Self = StencilStateFaceDescriptor {
|
pub const IGNORE: Self = StencilFaceState {
|
||||||
compare: CompareFunction::Always,
|
compare: CompareFunction::Always,
|
||||||
fail_op: StencilOperation::Keep,
|
fail_op: StencilOperation::Keep,
|
||||||
depth_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)]
|
#[derive(Clone, Debug, Default)]
|
||||||
pub struct RasterizationStateDescriptor {
|
pub struct PrimitiveState {
|
||||||
|
pub topology: PrimitiveTopology,
|
||||||
|
pub strip_index_format: Option<IndexFormat>,
|
||||||
pub front_face: FrontFace,
|
pub front_face: FrontFace,
|
||||||
pub cull_mode: CullMode,
|
pub cull_mode: CullMode,
|
||||||
pub depth_bias: i32,
|
pub polygon_mode: PolygonMode,
|
||||||
pub depth_bias_slope_scale: f32,
|
|
||||||
pub depth_bias_clamp: f32,
|
|
||||||
pub clamp_depth: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct ColorStateDescriptor {
|
pub struct ColorTargetState {
|
||||||
pub format: TextureFormat,
|
pub format: TextureFormat,
|
||||||
pub alpha_blend: BlendDescriptor,
|
pub alpha_blend: BlendState,
|
||||||
pub color_blend: BlendDescriptor,
|
pub color_blend: BlendState,
|
||||||
pub write_mask: ColorWrite,
|
pub write_mask: ColorWrite,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct BlendDescriptor {
|
pub struct BlendState {
|
||||||
pub src_factor: BlendFactor,
|
pub src_factor: BlendFactor,
|
||||||
pub dst_factor: BlendFactor,
|
pub dst_factor: BlendFactor,
|
||||||
pub operation: BlendOperation,
|
pub operation: BlendOperation,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlendDescriptor {
|
impl BlendState {
|
||||||
pub const REPLACE: Self = BlendDescriptor {
|
pub const REPLACE: Self = BlendState {
|
||||||
src_factor: BlendFactor::One,
|
src_factor: BlendFactor::One,
|
||||||
dst_factor: BlendFactor::Zero,
|
dst_factor: BlendFactor::Zero,
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
|
|
|
@ -8,23 +8,23 @@ use std::{
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq, Default, Reflect, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Eq, PartialEq, Default, Reflect, Serialize, Deserialize)]
|
||||||
#[reflect_value(Serialize, Deserialize, PartialEq)]
|
#[reflect_value(Serialize, Deserialize, PartialEq)]
|
||||||
pub struct VertexBufferDescriptor {
|
pub struct VertexBufferLayout {
|
||||||
pub name: Cow<'static, str>,
|
pub name: Cow<'static, str>,
|
||||||
pub stride: u64,
|
pub stride: u64,
|
||||||
pub step_mode: InputStepMode,
|
pub step_mode: InputStepMode,
|
||||||
pub attributes: Vec<VertexAttributeDescriptor>,
|
pub attributes: Vec<VertexAttribute>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VertexBufferDescriptor {
|
impl VertexBufferLayout {
|
||||||
pub fn new_from_attribute(
|
pub fn new_from_attribute(
|
||||||
attribute: VertexAttributeDescriptor,
|
attribute: VertexAttribute,
|
||||||
step_mode: InputStepMode,
|
step_mode: InputStepMode,
|
||||||
) -> VertexBufferDescriptor {
|
) -> VertexBufferLayout {
|
||||||
VertexBufferDescriptor {
|
VertexBufferLayout {
|
||||||
name: attribute.name.clone(),
|
name: attribute.name.clone(),
|
||||||
stride: attribute.format.get_size(),
|
stride: attribute.format.get_size(),
|
||||||
step_mode,
|
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)]
|
#[derive(Clone, Debug, Hash, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
pub struct VertexAttributeDescriptor {
|
pub struct VertexAttribute {
|
||||||
pub name: Cow<'static, str>,
|
pub name: Cow<'static, str>,
|
||||||
pub offset: u64,
|
|
||||||
pub format: VertexFormat,
|
pub format: VertexFormat,
|
||||||
|
pub offset: u64,
|
||||||
pub shader_location: u32,
|
pub shader_location: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@ use crate::{
|
||||||
draw::{Draw, RenderCommand},
|
draw::{Draw, RenderCommand},
|
||||||
pass::{ClearColor, LoadOp, PassDescriptor, TextureAttachment},
|
pass::{ClearColor, LoadOp, PassDescriptor, TextureAttachment},
|
||||||
pipeline::{
|
pipeline::{
|
||||||
BindGroupDescriptor, BindType, BindingDescriptor, BindingShaderStage, PipelineDescriptor,
|
BindGroupDescriptor, BindType, BindingDescriptor, BindingShaderStage, IndexFormat,
|
||||||
UniformProperty,
|
PipelineDescriptor, UniformProperty,
|
||||||
},
|
},
|
||||||
prelude::Visible,
|
prelude::Visible,
|
||||||
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
|
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
|
||||||
|
@ -109,7 +109,7 @@ impl<Q: WorldQuery> PassNode<Q> {
|
||||||
name: "Camera".to_string(),
|
name: "Camera".to_string(),
|
||||||
index: 0,
|
index: 0,
|
||||||
bind_type: BindType::Uniform {
|
bind_type: BindType::Uniform {
|
||||||
dynamic: false,
|
has_dynamic_offset: false,
|
||||||
property: UniformProperty::Struct(vec![UniformProperty::Mat4]),
|
property: UniformProperty::Struct(vec![UniformProperty::Mat4]),
|
||||||
},
|
},
|
||||||
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
|
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
|
||||||
|
@ -301,12 +301,12 @@ where
|
||||||
render_pass.set_vertex_buffer(*slot, *buffer, *offset);
|
render_pass.set_vertex_buffer(*slot, *buffer, *offset);
|
||||||
draw_state.set_vertex_buffer(*slot, *buffer, *offset);
|
draw_state.set_vertex_buffer(*slot, *buffer, *offset);
|
||||||
}
|
}
|
||||||
RenderCommand::SetIndexBuffer { buffer, offset } => {
|
RenderCommand::SetIndexBuffer { buffer, offset, index_format } => {
|
||||||
if draw_state.is_index_buffer_set(*buffer, *offset) {
|
if draw_state.is_index_buffer_set(*buffer, *offset, *index_format) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
render_pass.set_index_buffer(*buffer, *offset);
|
render_pass.set_index_buffer(*buffer, *offset, *index_format);
|
||||||
draw_state.set_index_buffer(*buffer, *offset)
|
draw_state.set_index_buffer(*buffer, *offset, *index_format);
|
||||||
}
|
}
|
||||||
RenderCommand::SetBindGroup {
|
RenderCommand::SetBindGroup {
|
||||||
index,
|
index,
|
||||||
|
@ -344,7 +344,7 @@ struct DrawState {
|
||||||
pipeline: Option<Handle<PipelineDescriptor>>,
|
pipeline: Option<Handle<PipelineDescriptor>>,
|
||||||
bind_groups: Vec<Option<BindGroupId>>,
|
bind_groups: Vec<Option<BindGroupId>>,
|
||||||
vertex_buffers: Vec<Option<(BufferId, u64)>>,
|
vertex_buffers: Vec<Option<(BufferId, u64)>>,
|
||||||
index_buffer: Option<(BufferId, u64)>,
|
index_buffer: Option<(BufferId, u64, IndexFormat)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawState {
|
impl DrawState {
|
||||||
|
@ -364,12 +364,17 @@ impl DrawState {
|
||||||
self.vertex_buffers[index as usize] == Some((buffer, offset))
|
self.vertex_buffers[index as usize] == Some((buffer, offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_index_buffer(&mut self, buffer: BufferId, offset: u64) {
|
pub fn set_index_buffer(&mut self, buffer: BufferId, offset: u64, index_format: IndexFormat) {
|
||||||
self.index_buffer = Some((buffer, offset));
|
self.index_buffer = Some((buffer, offset, index_format));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_index_buffer_set(&self, buffer: BufferId, offset: u64) -> bool {
|
pub fn is_index_buffer_set(
|
||||||
self.index_buffer == Some((buffer, offset))
|
&self,
|
||||||
|
buffer: BufferId,
|
||||||
|
offset: u64,
|
||||||
|
index_format: IndexFormat,
|
||||||
|
) -> bool {
|
||||||
|
self.index_buffer == Some((buffer, offset, index_format))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_draw(&self) -> bool {
|
pub fn can_draw(&self) -> bool {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::{BindGroup, BindGroupId, BufferId, SamplerId, TextureId};
|
use super::{BindGroup, BindGroupId, BufferId, SamplerId, TextureId};
|
||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, IndexFormat, PipelineDescriptor},
|
||||||
renderer::RenderResourceContext,
|
renderer::RenderResourceContext,
|
||||||
};
|
};
|
||||||
use bevy_asset::{Asset, Handle, HandleUntyped};
|
use bevy_asset::{Asset, Handle, HandleUntyped};
|
||||||
|
@ -69,7 +69,7 @@ pub struct RenderResourceBindings {
|
||||||
pub vertex_attribute_buffer: Option<BufferId>,
|
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.
|
/// 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 vertex_fallback_buffer: Option<BufferId>,
|
||||||
pub index_buffer: Option<BufferId>,
|
pub index_buffer: Option<(BufferId, IndexFormat)>,
|
||||||
assets: HashSet<(HandleUntyped, TypeId)>,
|
assets: HashSet<(HandleUntyped, TypeId)>,
|
||||||
bind_groups: HashMap<BindGroupId, BindGroup>,
|
bind_groups: HashMap<BindGroupId, BindGroup>,
|
||||||
bind_group_descriptors: HashMap<BindGroupDescriptorId, Option<BindGroupId>>,
|
bind_group_descriptors: HashMap<BindGroupDescriptorId, Option<BindGroupId>>,
|
||||||
|
@ -116,8 +116,8 @@ impl RenderResourceBindings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_index_buffer(&mut self, index_buffer: BufferId) {
|
pub fn set_index_buffer(&mut self, index_buffer: BufferId, index_format: IndexFormat) {
|
||||||
self.index_buffer = Some(index_buffer);
|
self.index_buffer = Some((index_buffer, index_format));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_bind_group(&mut self, descriptor: &BindGroupDescriptor) -> BindGroupStatus {
|
fn create_bind_group(&mut self, descriptor: &BindGroupDescriptor) -> BindGroupStatus {
|
||||||
|
@ -303,7 +303,7 @@ mod tests {
|
||||||
index: 0,
|
index: 0,
|
||||||
name: "a".to_string(),
|
name: "a".to_string(),
|
||||||
bind_type: BindType::Uniform {
|
bind_type: BindType::Uniform {
|
||||||
dynamic: false,
|
has_dynamic_offset: false,
|
||||||
property: UniformProperty::Struct(vec![UniformProperty::Mat4]),
|
property: UniformProperty::Struct(vec![UniformProperty::Mat4]),
|
||||||
},
|
},
|
||||||
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
|
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
|
||||||
|
@ -312,7 +312,7 @@ mod tests {
|
||||||
index: 1,
|
index: 1,
|
||||||
name: "b".to_string(),
|
name: "b".to_string(),
|
||||||
bind_type: BindType::Uniform {
|
bind_type: BindType::Uniform {
|
||||||
dynamic: false,
|
has_dynamic_offset: false,
|
||||||
property: UniformProperty::Float,
|
property: UniformProperty::Float,
|
||||||
},
|
},
|
||||||
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
|
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
|
||||||
|
|
|
@ -11,13 +11,13 @@ pub use shader_defs::*;
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
pub use shader_reflect::*;
|
pub use shader_reflect::*;
|
||||||
|
|
||||||
use crate::pipeline::{BindGroupDescriptor, VertexBufferDescriptor};
|
use crate::pipeline::{BindGroupDescriptor, VertexBufferLayout};
|
||||||
|
|
||||||
/// Defines the memory layout of a shader
|
/// Defines the memory layout of a shader
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ShaderLayout {
|
pub struct ShaderLayout {
|
||||||
pub bind_groups: Vec<BindGroupDescriptor>,
|
pub bind_groups: Vec<BindGroupDescriptor>,
|
||||||
pub vertex_buffer_descriptors: Vec<VertexBufferDescriptor>,
|
pub vertex_buffer_layout: Vec<VertexBufferLayout>,
|
||||||
pub entry_point: String,
|
pub entry_point: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
pipeline::{
|
pipeline::{
|
||||||
BindGroupDescriptor, BindType, BindingDescriptor, BindingShaderStage, InputStepMode,
|
BindGroupDescriptor, BindType, BindingDescriptor, BindingShaderStage, InputStepMode,
|
||||||
UniformProperty, VertexAttributeDescriptor, VertexBufferDescriptor, VertexFormat,
|
UniformProperty, VertexAttribute, VertexBufferLayout, VertexFormat,
|
||||||
},
|
},
|
||||||
shader::{ShaderLayout, GL_INSTANCE_INDEX, GL_VERTEX_INDEX},
|
shader::{ShaderLayout, GL_INSTANCE_INDEX, GL_VERTEX_INDEX},
|
||||||
texture::{TextureComponentType, TextureViewDimension},
|
texture::{TextureSampleType, TextureViewDimension},
|
||||||
};
|
};
|
||||||
use bevy_core::AsBytes;
|
use bevy_core::AsBytes;
|
||||||
use spirv_reflect::{
|
use spirv_reflect::{
|
||||||
|
@ -29,7 +29,7 @@ impl ShaderLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
// obtain attribute descriptors from reflection
|
// 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() {
|
for input_variable in module.enumerate_input_variables(None).unwrap() {
|
||||||
if input_variable.name == GL_VERTEX_INDEX
|
if input_variable.name == GL_VERTEX_INDEX
|
||||||
|| input_variable.name == GL_INSTANCE_INDEX
|
|| input_variable.name == GL_INSTANCE_INDEX
|
||||||
|
@ -37,7 +37,7 @@ impl ShaderLayout {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// reflect vertex attribute descriptor and record it
|
// reflect vertex attribute descriptor and record it
|
||||||
vertex_attribute_descriptors.push(VertexAttributeDescriptor {
|
vertex_attributes.push(VertexAttribute {
|
||||||
name: input_variable.name.clone().into(),
|
name: input_variable.name.clone().into(),
|
||||||
format: reflect_vertex_format(
|
format: reflect_vertex_format(
|
||||||
input_variable.type_description.as_ref().unwrap(),
|
input_variable.type_description.as_ref().unwrap(),
|
||||||
|
@ -47,20 +47,19 @@ impl ShaderLayout {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
vertex_attribute_descriptors
|
vertex_attributes.sort_by(|a, b| a.shader_location.cmp(&b.shader_location));
|
||||||
.sort_by(|a, b| a.shader_location.cmp(&b.shader_location));
|
|
||||||
|
|
||||||
let mut vertex_buffer_descriptors = Vec::new();
|
let mut vertex_buffer_layout = Vec::new();
|
||||||
for vertex_attribute_descriptor in vertex_attribute_descriptors.drain(..) {
|
for vertex_attribute in vertex_attributes.drain(..) {
|
||||||
let mut instance = false;
|
let mut instance = false;
|
||||||
// obtain buffer name and instancing flag
|
// obtain buffer name and instancing flag
|
||||||
let current_buffer_name = {
|
let current_buffer_name = {
|
||||||
if bevy_conventions {
|
if bevy_conventions {
|
||||||
if vertex_attribute_descriptor.name == GL_VERTEX_INDEX {
|
if vertex_attribute.name == GL_VERTEX_INDEX {
|
||||||
GL_VERTEX_INDEX.to_string()
|
GL_VERTEX_INDEX.to_string()
|
||||||
} else {
|
} else {
|
||||||
instance = vertex_attribute_descriptor.name.starts_with("I_");
|
instance = vertex_attribute.name.starts_with("I_");
|
||||||
vertex_attribute_descriptor.name.to_string()
|
vertex_attribute.name.to_string()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
"DefaultVertex".to_string()
|
"DefaultVertex".to_string()
|
||||||
|
@ -68,8 +67,8 @@ impl ShaderLayout {
|
||||||
};
|
};
|
||||||
|
|
||||||
// create a new buffer descriptor, per attribute!
|
// create a new buffer descriptor, per attribute!
|
||||||
vertex_buffer_descriptors.push(VertexBufferDescriptor {
|
vertex_buffer_layout.push(VertexBufferLayout {
|
||||||
attributes: vec![vertex_attribute_descriptor],
|
attributes: vec![vertex_attribute],
|
||||||
name: current_buffer_name.into(),
|
name: current_buffer_name.into(),
|
||||||
step_mode: if instance {
|
step_mode: if instance {
|
||||||
InputStepMode::Instance
|
InputStepMode::Instance
|
||||||
|
@ -82,7 +81,7 @@ impl ShaderLayout {
|
||||||
|
|
||||||
ShaderLayout {
|
ShaderLayout {
|
||||||
bind_groups,
|
bind_groups,
|
||||||
vertex_buffer_descriptors,
|
vertex_buffer_layout,
|
||||||
entry_point: entry_point_name,
|
entry_point: entry_point_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,27 +122,34 @@ fn reflect_binding(
|
||||||
ReflectDescriptorType::UniformBuffer => (
|
ReflectDescriptorType::UniformBuffer => (
|
||||||
&type_description.type_name,
|
&type_description.type_name,
|
||||||
BindType::Uniform {
|
BindType::Uniform {
|
||||||
dynamic: false,
|
has_dynamic_offset: false,
|
||||||
property: reflect_uniform(type_description),
|
property: reflect_uniform(type_description),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ReflectDescriptorType::SampledImage => (
|
ReflectDescriptorType::SampledImage => (
|
||||||
&binding.name,
|
&binding.name,
|
||||||
BindType::SampledTexture {
|
BindType::Texture {
|
||||||
dimension: reflect_dimension(type_description),
|
view_dimension: reflect_dimension(type_description),
|
||||||
component_type: TextureComponentType::Float,
|
sample_type: TextureSampleType::Float { filterable: true },
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ReflectDescriptorType::StorageBuffer => (
|
ReflectDescriptorType::StorageBuffer => (
|
||||||
&type_description.type_name,
|
&type_description.type_name,
|
||||||
BindType::StorageBuffer {
|
BindType::StorageBuffer {
|
||||||
dynamic: false,
|
has_dynamic_offset: false,
|
||||||
readonly: true,
|
readonly: true,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
// TODO: detect comparison "true" case: https://github.com/gpuweb/gpuweb/issues/552
|
// 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),
|
_ => panic!("Unsupported bind type {:?}.", binding.descriptor_type),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -302,8 +308,8 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::shader::{Shader, ShaderStage};
|
use crate::shader::{Shader, ShaderStage};
|
||||||
|
|
||||||
impl VertexBufferDescriptor {
|
impl VertexBufferLayout {
|
||||||
pub fn test_zero_stride(mut self) -> VertexBufferDescriptor {
|
pub fn test_zero_stride(mut self) -> VertexBufferLayout {
|
||||||
self.stride = 0;
|
self.stride = 0;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -338,9 +344,9 @@ mod tests {
|
||||||
layout,
|
layout,
|
||||||
ShaderLayout {
|
ShaderLayout {
|
||||||
entry_point: "main".into(),
|
entry_point: "main".into(),
|
||||||
vertex_buffer_descriptors: vec![
|
vertex_buffer_layout: vec![
|
||||||
VertexBufferDescriptor::new_from_attribute(
|
VertexBufferLayout::new_from_attribute(
|
||||||
VertexAttributeDescriptor {
|
VertexAttribute {
|
||||||
name: "Vertex_Position".into(),
|
name: "Vertex_Position".into(),
|
||||||
format: VertexFormat::Float4,
|
format: VertexFormat::Float4,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
|
@ -349,8 +355,8 @@ mod tests {
|
||||||
InputStepMode::Vertex
|
InputStepMode::Vertex
|
||||||
)
|
)
|
||||||
.test_zero_stride(),
|
.test_zero_stride(),
|
||||||
VertexBufferDescriptor::new_from_attribute(
|
VertexBufferLayout::new_from_attribute(
|
||||||
VertexAttributeDescriptor {
|
VertexAttribute {
|
||||||
name: "Vertex_Normal".into(),
|
name: "Vertex_Normal".into(),
|
||||||
format: VertexFormat::Uint4,
|
format: VertexFormat::Uint4,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
|
@ -359,8 +365,8 @@ mod tests {
|
||||||
InputStepMode::Vertex
|
InputStepMode::Vertex
|
||||||
)
|
)
|
||||||
.test_zero_stride(),
|
.test_zero_stride(),
|
||||||
VertexBufferDescriptor::new_from_attribute(
|
VertexBufferLayout::new_from_attribute(
|
||||||
VertexAttributeDescriptor {
|
VertexAttribute {
|
||||||
name: "I_TestInstancing_Property".into(),
|
name: "I_TestInstancing_Property".into(),
|
||||||
format: VertexFormat::Uint4,
|
format: VertexFormat::Uint4,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
|
@ -377,7 +383,7 @@ mod tests {
|
||||||
index: 0,
|
index: 0,
|
||||||
name: "Camera".into(),
|
name: "Camera".into(),
|
||||||
bind_type: BindType::Uniform {
|
bind_type: BindType::Uniform {
|
||||||
dynamic: false,
|
has_dynamic_offset: false,
|
||||||
property: UniformProperty::Struct(vec![UniformProperty::Mat4]),
|
property: UniformProperty::Struct(vec![UniformProperty::Mat4]),
|
||||||
},
|
},
|
||||||
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
|
shader_stage: BindingShaderStage::VERTEX | BindingShaderStage::FRAGMENT,
|
||||||
|
@ -388,10 +394,10 @@ mod tests {
|
||||||
vec![BindingDescriptor {
|
vec![BindingDescriptor {
|
||||||
index: 0,
|
index: 0,
|
||||||
name: "Texture".into(),
|
name: "Texture".into(),
|
||||||
bind_type: BindType::SampledTexture {
|
bind_type: BindType::Texture {
|
||||||
multisampled: false,
|
multisampled: false,
|
||||||
dimension: TextureViewDimension::D2,
|
view_dimension: TextureViewDimension::D2,
|
||||||
component_type: TextureComponentType::Float,
|
sample_type: TextureSampleType::Float { filterable: true }
|
||||||
},
|
},
|
||||||
shader_stage: BindingShaderStage::VERTEX,
|
shader_stage: BindingShaderStage::VERTEX,
|
||||||
}]
|
}]
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub struct SamplerDescriptor {
|
||||||
pub lod_max_clamp: f32,
|
pub lod_max_clamp: f32,
|
||||||
pub compare_function: Option<CompareFunction>,
|
pub compare_function: Option<CompareFunction>,
|
||||||
pub anisotropy_clamp: Option<NonZeroU8>,
|
pub anisotropy_clamp: Option<NonZeroU8>,
|
||||||
|
pub border_color: Option<SamplerBorderColor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SamplerDescriptor {
|
impl SamplerDescriptor {
|
||||||
|
@ -38,6 +39,7 @@ impl Default for SamplerDescriptor {
|
||||||
lod_max_clamp: std::f32::MAX,
|
lod_max_clamp: std::f32::MAX,
|
||||||
compare_function: None,
|
compare_function: None,
|
||||||
anisotropy_clamp: None,
|
anisotropy_clamp: None,
|
||||||
|
border_color: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,3 +70,10 @@ impl Default for FilterMode {
|
||||||
FilterMode::Nearest
|
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.
|
/// Type of data shaders will read from a texture.
|
||||||
#[derive(Copy, Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
#[derive(Copy, Hash, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
pub enum TextureComponentType {
|
pub enum TextureSampleType {
|
||||||
Float,
|
/// 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,
|
Sint,
|
||||||
|
/// Sampling returns unsigned integers.
|
||||||
|
///
|
||||||
|
/// Example GLSL syntax:
|
||||||
|
/// ```cpp,ignore
|
||||||
|
/// layout(binding = 0)
|
||||||
|
/// uniform utexture2D t;
|
||||||
|
/// ```
|
||||||
Uint,
|
Uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,9 +4,8 @@ use bevy_ecs::Resources;
|
||||||
use bevy_reflect::TypeUuid;
|
use bevy_reflect::TypeUuid;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pipeline::{
|
pipeline::{
|
||||||
BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite,
|
BlendFactor, BlendOperation, BlendState, ColorTargetState, ColorWrite, CompareFunction,
|
||||||
CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, PipelineDescriptor,
|
DepthBiasState, DepthStencilState, PipelineDescriptor, StencilFaceState, StencilState,
|
||||||
RasterizationStateDescriptor, StencilStateDescriptor, StencilStateFaceDescriptor,
|
|
||||||
},
|
},
|
||||||
render_graph::{base, AssetRenderResourcesNode, RenderGraph, RenderResourcesNode},
|
render_graph::{base, AssetRenderResourcesNode, RenderGraph, RenderResourcesNode},
|
||||||
shader::{Shader, ShaderStage, ShaderStages},
|
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 {
|
pub fn build_sprite_sheet_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
depth_stencil: Some(DepthStencilState {
|
||||||
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 {
|
|
||||||
format: TextureFormat::Depth32Float,
|
format: TextureFormat::Depth32Float,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: true,
|
||||||
depth_compare: CompareFunction::LessEqual,
|
depth_compare: CompareFunction::LessEqual,
|
||||||
stencil: StencilStateDescriptor {
|
stencil: StencilState {
|
||||||
front: StencilStateFaceDescriptor::IGNORE,
|
front: StencilFaceState::IGNORE,
|
||||||
back: StencilStateFaceDescriptor::IGNORE,
|
back: StencilFaceState::IGNORE,
|
||||||
read_mask: 0,
|
read_mask: 0,
|
||||||
write_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(),
|
format: TextureFormat::default(),
|
||||||
color_blend: BlendDescriptor {
|
color_blend: BlendState {
|
||||||
src_factor: BlendFactor::SrcAlpha,
|
src_factor: BlendFactor::SrcAlpha,
|
||||||
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
},
|
},
|
||||||
alpha_blend: BlendDescriptor {
|
alpha_blend: BlendState {
|
||||||
src_factor: BlendFactor::One,
|
src_factor: BlendFactor::One,
|
||||||
dst_factor: BlendFactor::One,
|
dst_factor: BlendFactor::One,
|
||||||
operation: BlendOperation::Add,
|
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 {
|
pub fn build_sprite_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
depth_stencil: Some(DepthStencilState {
|
||||||
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 {
|
|
||||||
format: TextureFormat::Depth32Float,
|
format: TextureFormat::Depth32Float,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: true,
|
||||||
depth_compare: CompareFunction::LessEqual,
|
depth_compare: CompareFunction::LessEqual,
|
||||||
stencil: StencilStateDescriptor {
|
stencil: StencilState {
|
||||||
front: StencilStateFaceDescriptor::IGNORE,
|
front: StencilFaceState::IGNORE,
|
||||||
back: StencilStateFaceDescriptor::IGNORE,
|
back: StencilFaceState::IGNORE,
|
||||||
read_mask: 0,
|
read_mask: 0,
|
||||||
write_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(),
|
format: TextureFormat::default(),
|
||||||
color_blend: BlendDescriptor {
|
color_blend: BlendState {
|
||||||
src_factor: BlendFactor::SrcAlpha,
|
src_factor: BlendFactor::SrcAlpha,
|
||||||
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
},
|
},
|
||||||
alpha_blend: BlendDescriptor {
|
alpha_blend: BlendState {
|
||||||
src_factor: BlendFactor::One,
|
src_factor: BlendFactor::One,
|
||||||
dst_factor: BlendFactor::One,
|
dst_factor: BlendFactor::One,
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
|
|
|
@ -3,13 +3,14 @@ use bevy_render::{
|
||||||
draw::{Draw, DrawContext, DrawError, Drawable},
|
draw::{Draw, DrawContext, DrawError, Drawable},
|
||||||
mesh,
|
mesh,
|
||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
pipeline::{PipelineSpecialization, VertexBufferDescriptor},
|
pipeline::{PipelineSpecialization, VertexBufferLayout},
|
||||||
prelude::Msaa,
|
prelude::Msaa,
|
||||||
renderer::{BindGroup, RenderResourceBindings, RenderResourceId},
|
renderer::{BindGroup, RenderResourceBindings, RenderResourceId},
|
||||||
};
|
};
|
||||||
use bevy_sprite::TextureAtlasSprite;
|
use bevy_sprite::TextureAtlasSprite;
|
||||||
|
|
||||||
use crate::{PositionedGlyph, TextSection};
|
use crate::{PositionedGlyph, TextSection};
|
||||||
|
use bevy_render::pipeline::IndexFormat;
|
||||||
|
|
||||||
pub struct DrawableText<'a> {
|
pub struct DrawableText<'a> {
|
||||||
pub render_resource_bindings: &'a mut RenderResourceBindings,
|
pub render_resource_bindings: &'a mut RenderResourceBindings,
|
||||||
|
@ -18,7 +19,7 @@ pub struct DrawableText<'a> {
|
||||||
pub sections: &'a [TextSection],
|
pub sections: &'a [TextSection],
|
||||||
pub text_glyphs: &'a Vec<PositionedGlyph>,
|
pub text_glyphs: &'a Vec<PositionedGlyph>,
|
||||||
pub msaa: &'a Msaa,
|
pub msaa: &'a Msaa,
|
||||||
pub font_quad_vertex_descriptor: &'a VertexBufferDescriptor,
|
pub font_quad_vertex_layout: &'a VertexBufferLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drawable for DrawableText<'a> {
|
impl<'a> Drawable for DrawableText<'a> {
|
||||||
|
@ -28,7 +29,7 @@ impl<'a> Drawable for DrawableText<'a> {
|
||||||
&bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE.typed(),
|
&bevy_sprite::SPRITE_SHEET_PIPELINE_HANDLE.typed(),
|
||||||
&PipelineSpecialization {
|
&PipelineSpecialization {
|
||||||
sample_count: self.msaa.samples,
|
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()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
|
@ -53,7 +54,7 @@ impl<'a> Drawable for DrawableText<'a> {
|
||||||
mesh::INDEX_BUFFER_ASSET_INDEX,
|
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) {
|
if let Some(buffer_info) = render_resource_context.get_buffer_info(quad_index_buffer) {
|
||||||
indices = 0..(buffer_info.size / 4) as u32;
|
indices = 0..(buffer_info.size / 4) as u32;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -73,7 +73,7 @@ pub fn draw_text2d_system(
|
||||||
>,
|
>,
|
||||||
) {
|
) {
|
||||||
let font_quad = meshes.get(&QUAD_HANDLE).unwrap();
|
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() {
|
let scale_factor = if let Some(window) = windows.get_primary() {
|
||||||
window.scale_factor() as f32
|
window.scale_factor() as f32
|
||||||
|
@ -106,7 +106,7 @@ pub fn draw_text2d_system(
|
||||||
position,
|
position,
|
||||||
msaa: &msaa,
|
msaa: &msaa,
|
||||||
text_glyphs: &text_glyphs.glyphs,
|
text_glyphs: &text_glyphs.glyphs,
|
||||||
font_quad_vertex_descriptor: &vertex_buffer_descriptor,
|
font_quad_vertex_layout: &font_quad_vertex_layout,
|
||||||
scale_factor,
|
scale_factor,
|
||||||
sections: &text.sections,
|
sections: &text.sections,
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,33 +23,31 @@ pub const UI_PIPELINE_HANDLE: HandleUntyped =
|
||||||
|
|
||||||
pub fn build_ui_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
pub fn build_ui_pipeline(shaders: &mut Assets<Shader>) -> PipelineDescriptor {
|
||||||
PipelineDescriptor {
|
PipelineDescriptor {
|
||||||
rasterization_state: Some(RasterizationStateDescriptor {
|
depth_stencil: Some(DepthStencilState {
|
||||||
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 {
|
|
||||||
format: TextureFormat::Depth32Float,
|
format: TextureFormat::Depth32Float,
|
||||||
depth_write_enabled: true,
|
depth_write_enabled: true,
|
||||||
depth_compare: CompareFunction::Less,
|
depth_compare: CompareFunction::Less,
|
||||||
stencil: StencilStateDescriptor {
|
stencil: StencilState {
|
||||||
front: StencilStateFaceDescriptor::IGNORE,
|
front: StencilFaceState::IGNORE,
|
||||||
back: StencilStateFaceDescriptor::IGNORE,
|
back: StencilFaceState::IGNORE,
|
||||||
read_mask: 0,
|
read_mask: 0,
|
||||||
write_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(),
|
format: TextureFormat::default(),
|
||||||
color_blend: BlendDescriptor {
|
color_blend: BlendState {
|
||||||
src_factor: BlendFactor::SrcAlpha,
|
src_factor: BlendFactor::SrcAlpha,
|
||||||
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
dst_factor: BlendFactor::OneMinusSrcAlpha,
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
},
|
},
|
||||||
alpha_blend: BlendDescriptor {
|
alpha_blend: BlendState {
|
||||||
src_factor: BlendFactor::One,
|
src_factor: BlendFactor::One,
|
||||||
dst_factor: BlendFactor::One,
|
dst_factor: BlendFactor::One,
|
||||||
operation: BlendOperation::Add,
|
operation: BlendOperation::Add,
|
||||||
|
|
|
@ -142,7 +142,7 @@ pub fn draw_text_system(
|
||||||
};
|
};
|
||||||
|
|
||||||
let font_quad = meshes.get(&QUAD_HANDLE).unwrap();
|
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() {
|
for (entity, mut draw, visible, text, node, global_transform) in query.iter_mut() {
|
||||||
if !visible.is_visible {
|
if !visible.is_visible {
|
||||||
|
@ -158,7 +158,7 @@ pub fn draw_text_system(
|
||||||
scale_factor: scale_factor as f32,
|
scale_factor: scale_factor as f32,
|
||||||
msaa: &msaa,
|
msaa: &msaa,
|
||||||
text_glyphs: &text_glyphs.glyphs,
|
text_glyphs: &text_glyphs.glyphs,
|
||||||
font_quad_vertex_descriptor: &vertex_buffer_descriptor,
|
font_quad_vertex_layout: &vertex_buffer_layout,
|
||||||
sections: &text.sections,
|
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" }
|
bevy_utils = { path = "../bevy_utils", version = "0.4.0" }
|
||||||
|
|
||||||
# other
|
# other
|
||||||
wgpu = "0.6"
|
wgpu = "0.7"
|
||||||
futures-lite = "1.4.0"
|
futures-lite = "1.4.0"
|
||||||
crossbeam-channel = "0.4.4"
|
crossbeam-channel = "0.4.4"
|
||||||
crossbeam-utils = "0.7.2"
|
crossbeam-utils = "0.7.2"
|
||||||
|
|
|
@ -206,6 +206,7 @@ pub fn create_render_pass<'a, 'b>(
|
||||||
encoder: &'a mut wgpu::CommandEncoder,
|
encoder: &'a mut wgpu::CommandEncoder,
|
||||||
) -> wgpu::RenderPass<'a> {
|
) -> wgpu::RenderPass<'a> {
|
||||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
|
label: None,
|
||||||
color_attachments: &pass_descriptor
|
color_attachments: &pass_descriptor
|
||||||
.color_attachments
|
.color_attachments
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
use crate::{
|
use crate::{wgpu_type_converter::WgpuInto, WgpuBindGroupInfo, WgpuResources};
|
||||||
wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto},
|
|
||||||
WgpuBindGroupInfo, WgpuResources,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
use crate::wgpu_type_converter::OwnedWgpuVertexBufferLayout;
|
||||||
use bevy_asset::{Assets, Handle, HandleUntyped};
|
use bevy_asset::{Assets, Handle, HandleUntyped};
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pipeline::{
|
pipeline::{
|
||||||
|
@ -18,7 +16,7 @@ use bevy_render::{
|
||||||
use bevy_utils::tracing::trace;
|
use bevy_utils::tracing::trace;
|
||||||
use bevy_window::{Window, WindowId};
|
use bevy_window::{Window, WindowId};
|
||||||
use futures_lite::future;
|
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;
|
use wgpu::util::DeviceExt;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -331,7 +329,11 @@ impl RenderResourceContext for WgpuRenderResourceContext {
|
||||||
let spirv: Cow<[u32]> = shader.get_spirv(None).unwrap().into();
|
let spirv: Cow<[u32]> = shader.get_spirv(None).unwrap().into();
|
||||||
let shader_module = self
|
let shader_module = self
|
||||||
.device
|
.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);
|
shader_modules.insert(shader_handle.clone_weak(), shader_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,13 +455,13 @@ impl RenderResourceContext for WgpuRenderResourceContext {
|
||||||
.vertex_buffer_descriptors
|
.vertex_buffer_descriptors
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| v.wgpu_into())
|
.map(|v| v.wgpu_into())
|
||||||
.collect::<Vec<OwnedWgpuVertexBufferDescriptor>>();
|
.collect::<Vec<OwnedWgpuVertexBufferLayout>>();
|
||||||
|
|
||||||
let color_states = pipeline_descriptor
|
let color_states = pipeline_descriptor
|
||||||
.color_states
|
.color_target_states
|
||||||
.iter()
|
.iter()
|
||||||
.map(|c| c.wgpu_into())
|
.map(|c| c.wgpu_into())
|
||||||
.collect::<Vec<wgpu::ColorStateDescriptor>>();
|
.collect::<Vec<wgpu::ColorTargetState>>();
|
||||||
|
|
||||||
self.create_shader_module(&pipeline_descriptor.shader_stages.vertex, shaders);
|
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()),
|
Some(ref fragment_handle) => Some(shader_modules.get(fragment_handle).unwrap()),
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
|
let render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
layout: Some(&pipeline_layout),
|
layout: Some(&pipeline_layout),
|
||||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
vertex: wgpu::VertexState {
|
||||||
module: &vertex_shader_module,
|
module: &vertex_shader_module,
|
||||||
entry_point: "main",
|
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 {
|
fragment: match pipeline_descriptor.shader_stages.fragment {
|
||||||
Some(_) => Some(wgpu::ProgrammableStageDescriptor {
|
Some(_) => Some(wgpu::FragmentState {
|
||||||
entry_point: "main",
|
entry_point: "main",
|
||||||
module: fragment_shader_module.as_ref().unwrap(),
|
module: fragment_shader_module.as_ref().unwrap(),
|
||||||
|
targets: color_states.as_slice(),
|
||||||
}),
|
}),
|
||||||
None => None,
|
None => None,
|
||||||
},
|
},
|
||||||
rasterization_state: pipeline_descriptor
|
primitive: pipeline_descriptor.primitive.clone().wgpu_into(),
|
||||||
.rasterization_state
|
depth_stencil: pipeline_descriptor
|
||||||
.as_ref()
|
.depth_stencil
|
||||||
.map(|r| r.wgpu_into()),
|
.clone()
|
||||||
primitive_topology: pipeline_descriptor.primitive_topology.wgpu_into(),
|
.map(|depth_stencil| depth_stencil.wgpu_into()),
|
||||||
color_states: &color_states,
|
multisample: pipeline_descriptor.multisample.clone().wgpu_into(),
|
||||||
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,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let render_pipeline = self
|
let render_pipeline = self
|
||||||
|
@ -564,7 +556,13 @@ impl RenderResourceContext for WgpuRenderResourceContext {
|
||||||
}
|
}
|
||||||
RenderResourceBinding::Buffer { buffer, range, .. } => {
|
RenderResourceBinding::Buffer { buffer, range, .. } => {
|
||||||
let wgpu_buffer = buffers.get(&buffer).unwrap();
|
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 {
|
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_asset::Handle;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pass::RenderPass,
|
pass::RenderPass,
|
||||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
pipeline::{BindGroupDescriptorId, IndexFormat, PipelineDescriptor},
|
||||||
renderer::{BindGroupId, BufferId, RenderContext},
|
renderer::{BindGroupId, BufferId, RenderContext},
|
||||||
};
|
};
|
||||||
use bevy_utils::tracing::trace;
|
use bevy_utils::tracing::trace;
|
||||||
|
@ -40,9 +40,10 @@ impl<'a> RenderPass for WgpuRenderPass<'a> {
|
||||||
self.render_pass.set_stencil_reference(reference);
|
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();
|
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>) {
|
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>) {
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl WgpuRenderer {
|
||||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||||
power_preference: match options.power_pref {
|
power_preference: match options.power_pref {
|
||||||
WgpuPowerOptions::HighPerformance => wgpu::PowerPreference::HighPerformance,
|
WgpuPowerOptions::HighPerformance => wgpu::PowerPreference::HighPerformance,
|
||||||
WgpuPowerOptions::Adaptive => wgpu::PowerPreference::Default,
|
WgpuPowerOptions::Adaptive => wgpu::PowerPreference::LowPower,
|
||||||
WgpuPowerOptions::LowPower => wgpu::PowerPreference::LowPower,
|
WgpuPowerOptions::LowPower => wgpu::PowerPreference::LowPower,
|
||||||
},
|
},
|
||||||
compatible_surface: None,
|
compatible_surface: None,
|
||||||
|
@ -53,9 +53,9 @@ impl WgpuRenderer {
|
||||||
let (device, queue) = adapter
|
let (device, queue) = adapter
|
||||||
.request_device(
|
.request_device(
|
||||||
&wgpu::DeviceDescriptor {
|
&wgpu::DeviceDescriptor {
|
||||||
|
label: None,
|
||||||
features: wgpu::Features::empty(),
|
features: wgpu::Features::empty(),
|
||||||
limits: wgpu::Limits::default(),
|
limits: wgpu::Limits::default(),
|
||||||
shader_validation: true,
|
|
||||||
},
|
},
|
||||||
trace_path,
|
trace_path,
|
||||||
)
|
)
|
||||||
|
|
|
@ -2,19 +2,21 @@ use bevy_render::{
|
||||||
color::Color,
|
color::Color,
|
||||||
pass::{LoadOp, Operations},
|
pass::{LoadOp, Operations},
|
||||||
pipeline::{
|
pipeline::{
|
||||||
BindType, BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite,
|
BindType, BlendFactor, BlendOperation, BlendState, ColorTargetState, ColorWrite,
|
||||||
CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat,
|
CompareFunction, CullMode, DepthBiasState, DepthStencilState, FrontFace, IndexFormat,
|
||||||
InputStepMode, PrimitiveTopology, RasterizationStateDescriptor, StencilOperation,
|
InputStepMode, MultisampleState, PolygonMode, PrimitiveState, PrimitiveTopology,
|
||||||
StencilStateDescriptor, StencilStateFaceDescriptor, VertexAttributeDescriptor,
|
StencilFaceState, StencilOperation, StencilState, VertexAttribute, VertexBufferLayout,
|
||||||
VertexBufferDescriptor, VertexFormat,
|
VertexFormat,
|
||||||
},
|
},
|
||||||
renderer::BufferUsage,
|
renderer::BufferUsage,
|
||||||
texture::{
|
texture::{
|
||||||
AddressMode, Extent3d, FilterMode, SamplerDescriptor, TextureComponentType,
|
AddressMode, Extent3d, FilterMode, SamplerBorderColor, SamplerDescriptor,
|
||||||
TextureDescriptor, TextureDimension, TextureFormat, TextureUsage, TextureViewDimension,
|
StorageTextureAccess, TextureDescriptor, TextureDimension, TextureFormat,
|
||||||
|
TextureSampleType, TextureUsage, TextureViewDimension,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use bevy_window::Window;
|
use bevy_window::Window;
|
||||||
|
use wgpu::BufferBindingType;
|
||||||
|
|
||||||
pub trait WgpuFrom<T> {
|
pub trait WgpuFrom<T> {
|
||||||
fn from(val: T) -> Self;
|
fn from(val: T) -> Self;
|
||||||
|
@ -70,9 +72,9 @@ impl WgpuFrom<VertexFormat> for wgpu::VertexFormat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuFrom<&VertexAttributeDescriptor> for wgpu::VertexAttributeDescriptor {
|
impl WgpuFrom<&VertexAttribute> for wgpu::VertexAttribute {
|
||||||
fn from(val: &VertexAttributeDescriptor) -> Self {
|
fn from(val: &VertexAttribute) -> Self {
|
||||||
wgpu::VertexAttributeDescriptor {
|
wgpu::VertexAttribute {
|
||||||
format: val.format.wgpu_into(),
|
format: val.format.wgpu_into(),
|
||||||
offset: val.offset,
|
offset: val.offset,
|
||||||
shader_location: val.shader_location,
|
shader_location: val.shader_location,
|
||||||
|
@ -90,34 +92,34 @@ impl WgpuFrom<InputStepMode> for wgpu::InputStepMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct OwnedWgpuVertexBufferDescriptor {
|
pub struct OwnedWgpuVertexBufferLayout {
|
||||||
pub stride: wgpu::BufferAddress,
|
pub array_stride: wgpu::BufferAddress,
|
||||||
pub step_mode: wgpu::InputStepMode,
|
pub step_mode: wgpu::InputStepMode,
|
||||||
pub attributes: Vec<wgpu::VertexAttributeDescriptor>,
|
pub attributes: Vec<wgpu::VertexAttribute>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuFrom<&VertexBufferDescriptor> for OwnedWgpuVertexBufferDescriptor {
|
impl WgpuFrom<&VertexBufferLayout> for OwnedWgpuVertexBufferLayout {
|
||||||
fn from(val: &VertexBufferDescriptor) -> OwnedWgpuVertexBufferDescriptor {
|
fn from(val: &VertexBufferLayout) -> OwnedWgpuVertexBufferLayout {
|
||||||
let attributes = val
|
let attributes = val
|
||||||
.attributes
|
.attributes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|a| a.wgpu_into())
|
.map(|a| a.wgpu_into())
|
||||||
.collect::<Vec<wgpu::VertexAttributeDescriptor>>();
|
.collect::<Vec<wgpu::VertexAttribute>>();
|
||||||
|
|
||||||
OwnedWgpuVertexBufferDescriptor {
|
OwnedWgpuVertexBufferLayout {
|
||||||
step_mode: val.step_mode.wgpu_into(),
|
step_mode: val.step_mode.wgpu_into(),
|
||||||
stride: val.stride,
|
array_stride: val.stride,
|
||||||
attributes,
|
attributes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a OwnedWgpuVertexBufferDescriptor> for wgpu::VertexBufferDescriptor<'a> {
|
impl<'a> From<&'a OwnedWgpuVertexBufferLayout> for wgpu::VertexBufferLayout<'a> {
|
||||||
fn from(val: &'a OwnedWgpuVertexBufferDescriptor) -> Self {
|
fn from(val: &'a OwnedWgpuVertexBufferLayout) -> Self {
|
||||||
wgpu::VertexBufferDescriptor {
|
wgpu::VertexBufferLayout {
|
||||||
attributes: &val.attributes,
|
attributes: &val.attributes,
|
||||||
step_mode: val.step_mode,
|
step_mode: val.step_mode,
|
||||||
stride: val.stride,
|
array_stride: val.array_stride,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,46 +183,71 @@ where
|
||||||
impl WgpuFrom<&BindType> for wgpu::BindingType {
|
impl WgpuFrom<&BindType> for wgpu::BindingType {
|
||||||
fn from(bind_type: &BindType) -> Self {
|
fn from(bind_type: &BindType) -> Self {
|
||||||
match bind_type {
|
match bind_type {
|
||||||
BindType::Uniform { dynamic, .. } => wgpu::BindingType::UniformBuffer {
|
BindType::Uniform {
|
||||||
dynamic: *dynamic,
|
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),
|
min_binding_size: bind_type.get_uniform_size().and_then(wgpu::BufferSize::new),
|
||||||
},
|
},
|
||||||
BindType::StorageBuffer { dynamic, readonly } => wgpu::BindingType::StorageBuffer {
|
BindType::StorageBuffer {
|
||||||
dynamic: *dynamic,
|
has_dynamic_offset,
|
||||||
readonly: *readonly,
|
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),
|
min_binding_size: bind_type.get_uniform_size().and_then(wgpu::BufferSize::new),
|
||||||
},
|
},
|
||||||
BindType::SampledTexture {
|
BindType::Texture {
|
||||||
dimension,
|
view_dimension,
|
||||||
multisampled,
|
multisampled,
|
||||||
component_type,
|
sample_type,
|
||||||
} => wgpu::BindingType::SampledTexture {
|
} => wgpu::BindingType::Texture {
|
||||||
dimension: (*dimension).wgpu_into(),
|
view_dimension: (*view_dimension).wgpu_into(),
|
||||||
multisampled: *multisampled,
|
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,
|
comparison: *comparison,
|
||||||
},
|
},
|
||||||
BindType::StorageTexture {
|
BindType::StorageTexture {
|
||||||
dimension,
|
view_dimension,
|
||||||
format,
|
format,
|
||||||
readonly,
|
access,
|
||||||
} => wgpu::BindingType::StorageTexture {
|
} => wgpu::BindingType::StorageTexture {
|
||||||
dimension: (*dimension).wgpu_into(),
|
access: (*access).wgpu_into(),
|
||||||
|
view_dimension: (*view_dimension).wgpu_into(),
|
||||||
format: (*format).wgpu_into(),
|
format: (*format).wgpu_into(),
|
||||||
readonly: *readonly,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuFrom<TextureComponentType> for wgpu::TextureComponentType {
|
impl WgpuFrom<TextureSampleType> for wgpu::TextureSampleType {
|
||||||
fn from(texture_component_type: TextureComponentType) -> Self {
|
fn from(texture_component_type: TextureSampleType) -> Self {
|
||||||
match texture_component_type {
|
match texture_component_type {
|
||||||
TextureComponentType::Float => wgpu::TextureComponentType::Float,
|
TextureSampleType::Float { filterable } => {
|
||||||
TextureComponentType::Sint => wgpu::TextureComponentType::Sint,
|
wgpu::TextureSampleType::Float { filterable }
|
||||||
TextureComponentType::Uint => wgpu::TextureComponentType::Uint,
|
}
|
||||||
|
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 {
|
impl WgpuFrom<&StencilState> for wgpu::StencilState {
|
||||||
fn from(val: &StencilStateDescriptor) -> Self {
|
fn from(val: &StencilState) -> Self {
|
||||||
wgpu::StencilStateDescriptor {
|
wgpu::StencilState {
|
||||||
back: (&val.back).wgpu_into(),
|
back: (&val.back).wgpu_into(),
|
||||||
front: (&val.front).wgpu_into(),
|
front: (&val.front).wgpu_into(),
|
||||||
read_mask: val.read_mask,
|
read_mask: val.read_mask,
|
||||||
|
@ -334,20 +361,32 @@ impl WgpuFrom<&StencilStateDescriptor> for wgpu::StencilStateDescriptor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuFrom<&DepthStencilStateDescriptor> for wgpu::DepthStencilStateDescriptor {
|
impl WgpuFrom<DepthStencilState> for wgpu::DepthStencilState {
|
||||||
fn from(val: &DepthStencilStateDescriptor) -> Self {
|
fn from(val: DepthStencilState) -> Self {
|
||||||
wgpu::DepthStencilStateDescriptor {
|
wgpu::DepthStencilState {
|
||||||
depth_compare: val.depth_compare.wgpu_into(),
|
depth_compare: val.depth_compare.wgpu_into(),
|
||||||
depth_write_enabled: val.depth_write_enabled,
|
depth_write_enabled: val.depth_write_enabled,
|
||||||
format: val.format.wgpu_into(),
|
format: val.format.wgpu_into(),
|
||||||
stencil: (&val.stencil).wgpu_into(),
|
stencil: (&val.stencil).wgpu_into(),
|
||||||
|
bias: val.bias.wgpu_into(),
|
||||||
|
clamp_depth: val.clamp_depth,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuFrom<&StencilStateFaceDescriptor> for wgpu::StencilStateFaceDescriptor {
|
impl WgpuFrom<MultisampleState> for wgpu::MultisampleState {
|
||||||
fn from(val: &StencilStateFaceDescriptor) -> Self {
|
fn from(val: MultisampleState) -> Self {
|
||||||
wgpu::StencilStateFaceDescriptor {
|
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(),
|
compare: val.compare.wgpu_into(),
|
||||||
depth_fail_op: val.depth_fail_op.wgpu_into(),
|
depth_fail_op: val.depth_fail_op.wgpu_into(),
|
||||||
fail_op: val.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 {
|
impl WgpuFrom<PolygonMode> for wgpu::PolygonMode {
|
||||||
fn from(val: &RasterizationStateDescriptor) -> Self {
|
fn from(val: PolygonMode) -> wgpu::PolygonMode {
|
||||||
wgpu::RasterizationStateDescriptor {
|
match val {
|
||||||
front_face: val.front_face.wgpu_into(),
|
PolygonMode::Fill => wgpu::PolygonMode::Fill,
|
||||||
cull_mode: val.cull_mode.wgpu_into(),
|
PolygonMode::Line => wgpu::PolygonMode::Line,
|
||||||
depth_bias: val.depth_bias,
|
PolygonMode::Point => wgpu::PolygonMode::Point,
|
||||||
depth_bias_slope_scale: val.depth_bias_slope_scale,
|
|
||||||
depth_bias_clamp: val.depth_bias_clamp,
|
|
||||||
clamp_depth: val.clamp_depth,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuFrom<&ColorStateDescriptor> for wgpu::ColorStateDescriptor {
|
impl WgpuFrom<DepthBiasState> for wgpu::DepthBiasState {
|
||||||
fn from(val: &ColorStateDescriptor) -> Self {
|
fn from(val: DepthBiasState) -> Self {
|
||||||
wgpu::ColorStateDescriptor {
|
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(),
|
format: val.format.wgpu_into(),
|
||||||
alpha_blend: (&val.alpha_blend).wgpu_into(),
|
alpha_blend: (&val.alpha_blend).wgpu_into(),
|
||||||
color_blend: (&val.color_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 {
|
impl WgpuFrom<ColorWrite> for wgpu::ColorWrite {
|
||||||
fn from(val: ColorWrite) -> Self {
|
fn from(val: ColorWrite) -> Self {
|
||||||
wgpu::ColorWrite::from_bits(val.bits()).unwrap()
|
wgpu::ColorWrite::from_bits(val.bits()).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuFrom<&BlendDescriptor> for wgpu::BlendDescriptor {
|
impl WgpuFrom<&BlendState> for wgpu::BlendState {
|
||||||
fn from(val: &BlendDescriptor) -> Self {
|
fn from(val: &BlendState) -> Self {
|
||||||
wgpu::BlendDescriptor {
|
wgpu::BlendState {
|
||||||
src_factor: val.src_factor.wgpu_into(),
|
src_factor: val.src_factor.wgpu_into(),
|
||||||
dst_factor: val.dst_factor.wgpu_into(),
|
dst_factor: val.dst_factor.wgpu_into(),
|
||||||
operation: val.operation.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,
|
lod_max_clamp: sampler_descriptor.lod_max_clamp,
|
||||||
compare: sampler_descriptor.compare_function.map(|c| c.wgpu_into()),
|
compare: sampler_descriptor.compare_function.map(|c| c.wgpu_into()),
|
||||||
anisotropy_clamp: sampler_descriptor.anisotropy_clamp,
|
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 {
|
impl WgpuFrom<&Window> for wgpu::SwapChainDescriptor {
|
||||||
fn from(window: &Window) -> Self {
|
fn from(window: &Window) -> Self {
|
||||||
wgpu::SwapChainDescriptor {
|
wgpu::SwapChainDescriptor {
|
||||||
usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT,
|
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
|
||||||
format: TextureFormat::default().wgpu_into(),
|
format: TextureFormat::default().wgpu_into(),
|
||||||
width: window.physical_width(),
|
width: window.physical_width(),
|
||||||
height: window.physical_height(),
|
height: window.physical_height(),
|
||||||
|
|
|
@ -9,7 +9,7 @@ fn main() {
|
||||||
.add_stage_after(stage::UPDATE, STAGE, StateStage::<AppState>::default())
|
.add_stage_after(stage::UPDATE, STAGE, StateStage::<AppState>::default())
|
||||||
.on_state_enter(STAGE, AppState::Setup, load_textures.system())
|
.on_state_enter(STAGE, AppState::Setup, load_textures.system())
|
||||||
.on_state_update(STAGE, AppState::Setup, check_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();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ const STAGE: &str = "app_state";
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum AppState {
|
enum AppState {
|
||||||
Setup,
|
Setup,
|
||||||
Finshed,
|
Finished,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
@ -38,7 +38,7 @@ fn check_textures(
|
||||||
if let LoadState::Loaded =
|
if let LoadState::Loaded =
|
||||||
asset_server.get_group_load_state(rpg_sprite_handles.handles.iter().map(|handle| handle.id))
|
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 a new issue